您的位置:首页 > 编程语言

利用API发送和接收消息,本代码测试全通过

2012-11-18 17:15 627 查看
~_~一个程序员的淘宝店: 点击打开链接

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;

namespace Set_Get_Messages

{

class APISendMsg

{

#region 常数

const int WM_COPYDATA = 0x004A;//发送消息到窗口

const int WM_SETTEXT = 0xC;//发送消息到控件

const int WM_CLOSE = 0x0010;//关闭窗口

const int BM_CLICK = 0xF5;//点击窗体

public const int WM_GETTEXT = 0x000D;//得到消息

#endregion

#region API函数

//查找窗体

[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]

public static extern IntPtr FindWindow(String classname, String text);

//查找子窗体

[DllImport("User32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)]

public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);

/// <summary>

/// 将指定的消息发送到一个或多个窗口

/// </summary>

/// <param name="hwnd">目标窗口句柄</param>

/// <param name="msg">消息类型</param>

/// <param name="hwndFrom">返回的消息</param>

/// <param name="cd">发送的消息</param>

/// <returns></returns>

[DllImport("user32.dll", EntryPoint = "SendMessage")]

public static extern long SendMessage(IntPtr hwnd, Int32 msg, Int32 hwndFrom, ref COPYDATASTRUCT cd);

[DllImport("user32.dll", EntryPoint = "SendMessage")]

public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);

/// <summary>

/// 将指定的消息发送到一个或多个窗体

/// </summary>

/// <param name="hWnd">窗体句柄</param>

/// <param name="Msg">消息类别</param>

/// <param name="wParam">返回消息</param>

/// <param name="lParam">发送的消息</param>

/// <returns></returns>

[DllImport("user32.dll", EntryPoint = "SendMessage")]

public static extern long SendMessage(IntPtr hWnd, Int32 Msg, Int32 wParam, [MarshalAs(UnmanagedType.LPStr)] string lParam);

//获取消息

[DllImport("user32.dll", EntryPoint = "SendMessage")]

public static extern bool SendMessageSetText(IntPtr hwnd, uint wMsg, uint wParam, string lParam);

[DllImport("user32.dll", EntryPoint = "SendMessage")]

public static extern int SendMessageGetText(IntPtr hwnd, uint wMsg, uint wParam, StringBuilder lParam);

#endregion

#region 发送消息

//发送消息结构体

[StructLayout(LayoutKind.Sequential)]

public struct COPYDATASTRUCT

{

public IntPtr dwData;//目标

public int cbData;//数据长度

[MarshalAs(UnmanagedType.LPStr)]

public string lpData;//消息

}

/// <summary>

/// 发送消息

/// </summary>

/// <param name="strMsg">消息</param>

/// <returns>成功非0,失败0</returns>

public static long API_sendMsgWindows(IntPtr windowHwnd, string strMsg)

{

long longResult = 0;

if (windowHwnd != IntPtr.Zero && !string.IsNullOrEmpty(strMsg.Replace(" ", "")))

{

//定义c,是为了取得字符串中一些非英文字符的长度,比如一个中文,占两个字长。

int longMsg = StrLength(strMsg);

Int32 id = 1;

COPYDATASTRUCT cd = new COPYDATASTRUCT();

cd.dwData = (IntPtr)id;

cd.lpData = strMsg + "/$";//一定要加上结束标志,不加的话会得到不确定的字符。

cd.cbData = strMsg.Length + longMsg + 2;//另外加上双字节的东西和结束符的长度

//发送消息

longResult = SendMessage(windowHwnd, WM_COPYDATA, 0, ref cd);

}

return longResult;

}

/// <summary>

/// 字符串长度(按字节算)

/// </summary>

/// <param name="str"></param>

/// <returns>字符串长度</returns>

private static int StrLength(string str)

{

int len = 0;

byte[] b;

if (!string.IsNullOrEmpty (str.Replace(" ","")))

{

for (int i = 0; i < str.Length; i++)

{

b = Encoding.Default.GetBytes(str.Substring(i, 1));//每个字

if (b.Length > 1)

len += 2;

else

len++;

}

}

return len;

}

#endregion

#region 得到窗体消息

/// <summary>

/// 取得指定句柄的窗口的Caption字符串

/// </summary>

/// <param name="hWnd"></param>

/// <param name="strWndText"></param>

/// <returns></returns>

public static int GetWindowControlTextX(IntPtr hWnd, out string strWndText)

{

/*

StringBuffer sLimitedString;

int nLen = GetWindowText(hWnd, out sLimitedString, 256);

if (nLen > 0)

strWndText = sLimitedString.szText;

else

strWndText = @"";

return nLen;

*/

//由于针对不同的进程的窗体控件,不能使用GetWindowText函数,只能使用WM_GETTEXT

StringBuilder strBuffer = new StringBuilder(1024);

int nLen = SendMessageGetText(hWnd,WM_GETTEXT, 1024, strBuffer);

strWndText = strBuffer.ToString();

return nLen;

}

#endregion

#region 共用方法

/// <summary>

/// 为控件赋值

/// </summary>

/// <param name="childControID">控件句柄</param>

/// <param name="strMsg">消息</param>

/// <returns>成功非0,失败0</returns>

public static long API_SetTextValue(IntPtr childControID, string strMsg)

{

long longResult = 0;

if (childControID != IntPtr.Zero && !string.IsNullOrEmpty(strMsg.Replace(" ", "")))

{

longResult = SendMessage(childControID, WM_SETTEXT, 0, strMsg);

}

return longResult;

}

/// <summary>

/// 点击控件

/// </summary>

/// <param name="childControID">按钮控件句柄</param>

/// <returns>成功非0,失败0</returns>

public static long API_ClickButton(IntPtr childControID)

{

long longResult = 0;

if (childControID != IntPtr.Zero)

{

longResult = SendMessage(childControID, BM_CLICK, 0, 0);

}

return longResult;

}

#endregion

}

}

//补

//另一种比较稳定的方法接收窗体中的代码

//自动接收消息

[StructLayout(LayoutKind.Sequential)]

public struct COPYDATASTRUCT

{

public IntPtr dwData;

public int cbData;

public IntPtr lpData;

}

protected override void DefWndProc(ref Message m)

{

try

{

switch (m.Msg)

{

//接收CopyData消息,读取发送过来的数据

case WM_COPYDATA:

COPYDATASTRUCT cds = new COPYDATASTRUCT();

Type mytype = cds.GetType();

cds = (COPYDATASTRUCT)m.GetLParam(mytype);

uint flag = (uint)(cds.dwData);

byte[] bt = new byte[cds.cbData];

Marshal.Copy(cds.lpData, bt, 0, bt.Length);

if (cds.cbData > 0)

{

string tmp = System.Text.Encoding.Default.GetString(bt);

if (!string.IsNullOrEmpty(tmp))

{

//交易方法

getRunPlan(tmp);

}

}

// MessageBox.Show(tmp);

break;

default:

base.DefWndProc(ref m);

break;

}

}

catch (Exception ex)

{

XtraMessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

// throw ex;

}

}

~_~一个程序员的淘宝店: 点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐