抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

通过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