通过windows api向程序发送数据消息
使用消息类型
//当一个应用程序传递数据给另一个应用程序时发送此消息
public const int WM_COPYDATA = 0x4A;
一、消息发送
SendMessage
消息同步发送,接收端消息处理完成后则进行下一步,接收端未将消息处理完成,则堵塞线程SendMessageTimeout
含消息处理超时时间,在时间范围内堵塞线程等待接收端消息处理完毕,超过时间范围接收端仍未处理完毕则取消堵塞自动到下一步
1、SendMessage使用
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
//调用
COPYDATASTRUCT cds;
cds.dwData = (IntPtr)100;
cds.lpData = "将要发送的参数";
cds.cbData = len + 1;
SendMessage(IntPtr,WM_COPYDATA,IntPtr.Zero, ref cds);
2、SendMessageTimeout使用
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
[Flags]
public enum SendMessageTimeoutFlags : uint
{
SMTO_NORMAL = 0x0,
SMTO_BLOCK = 0x1,
SMTO_ABORTIFHUNG = 0x2,
SMTO_NOTIMEOUTIFNOTHUNG = 0x8,
SMTO_ERRORONEXIT = 0x20
}
[DllImport("User32.dll")]
public static extern int SendMessageTimeout(IntPtr hWnd, uint Msg, IntPtr wParam, ref COPYDATASTRUCT lParam, SendMessageTimeoutFlags fuFlags, uint timeout,out int result);
//调用
COPYDATASTRUCT cds;
cds.dwData = (IntPtr)100;
cds.lpData = "将要发送的参数";
cds.cbData = len + 1;
int resultIndex = 0;
SendMessageTimeout(WINDOW_HANDLER, WM_COPYDATA, IntPtr.Zero, ref cds, SendMessageTimeoutFlags.SMTO_NOTIMEOUTIFNOTHUNG, 10000, out resultIndex);
二、消息接收
1、winform接收端
public const int WM_COPYDATA = 0x004A;
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
protected override void WndProc(ref System.Windows.Forms.Message m)
{
switch (m.Msg)
{
case WM_COPYDATA:
COPYDATASTRUCT MyKeyboardHookStruct = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
this.textBox2.Text = MyKeyboardHookStruct.lpData;
break;
default:
base.WndProc(ref m); // 调用基类函数处理其他消息。
break;
}
}
2、WPF接收端
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource hWndSource;
WindowInteropHelper wih = new WindowInteropHelper(this);
hWndSource = HwndSource.FromHwnd(wih.Handle);
//添加处理程序
hWndSource.AddHook(MainWindowProc);
}
private IntPtr MainWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case WM_COPYDATA:
{
COPYDATASTRUCT mystr = new COPYDATASTRUCT();
Type mytype = mystr.GetType();
COPYDATASTRUCT MyKeyboardHookStruct = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
string GEMsg = MyKeyboardHookStruct.lpData;
}
break;
default:
{
break;
}
}
return IntPtr.Zero;
}
三、python平台sendmessage处理
1、消息发送
class COPYDATASTRUCT(ctypes.Structure):
_fields_ = [
('dwData', ctypes.wintypes.LPARAM),
('cbData', ctypes.wintypes.DWORD),
('lpData', ctypes.c_char_p)
]
def SetMessage(msg):
try:
FindWindow = ctypes.windll.user32.FindWindowW
SendMessageTimeout = ctypes.windll.user32.SendMessageTimeoutW
cds = COPYDATASTRUCT()
msg_bytes = msg.encode(encoding="GBK")
cds.cbData = ctypes.sizeof(ctypes.create_string_buffer(msg_bytes))
cds.lpData = ctypes.c_char_p(msg_bytes)
SMTO_NORMAL = 0x000
hwnd = FindWindow(None, '我的应用')
if hwnd != 0:
SendMessageTimeout(hwnd, win32con.WM_COPYDATA, 0, ctypes.byref(cds), SMTO_NORMAL, 10, 0)
pass
except Exception as r:
print('错误 %s' %r)
2、消息接收
class COPYDATASTRUCT(ctypes.Structure):
_fields_ = [
('dwData', ctypes.wintypes.LPARAM),
('cbData', ctypes.wintypes.DWORD),
('lpData', ctypes.c_void_p)
]
PCOPYDATASTRUCT = ctypes.POINTER(COPYDATASTRUCT)
class Listener:
def __init__(self,msg):
WindowName ="CopyDataName"
message_map = {
win32con.WM_COPYDATA: self.OnCopyData
}
wc = win32gui.WNDCLASS()
wc.lpfnWndProc = message_map
wc.lpszClassName = WindowName
self.m=msg
hinst = wc.hInstance = win32api.GetModuleHandle(None)
classAtom = win32gui.RegisterClass(wc)
self.hwnd = win32gui.CreateWindow(classAtom,"她的应用",0,0,0,win32con.CW_USEDEFAULT,win32con.CW_USEDEFAULT,0,0,hinst,None)
def OnCopyData(self, hwnd, msg, wparam, lparam):
pCDS = ctypes.cast(lparam, PCOPYDATASTRUCT)
s = ctypes.string_at(pCDS.contents.lpData).decode(encoding="GBK")
return 1