注册协议
http://www.cnblogs.com/CodingArt/p/4532465.html
利用SendMessage实现winform与wpf之间的消息传递
UnsafeNativeMethods.cs
/* * https://msdn.microsoft.com/zh-cn/library/843s5s5x%28v=vs.100%29.aspx * 输出本地计算机上每个窗口的句柄值 * 使用 EnumWindows 函数来逐步浏览窗口列表,并使用一个托管回调函数(名为 WNDENUMPROC)来输出窗口句柄的值。 */ public delegate bool WNDENUMPROC(IntPtr hwnd, uint lParam); [DllImport("user32.dll", EntryPoint = "EnumWindows", SetLastError = true)] public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, uint lParam);
/// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms633528(v=vs.85).aspx</devdoc> [DllImport("user32", CharSet = CharSet.Auto, ExactSpelling = true)] internal static extern bool IsWindow([In] [Optional] IntPtr hWnd);
/*Retrieves a handle to the specified window's parent or owner.*/
[DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)] public static extern IntPtr GetParent(IntPtr hWnd); [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref uint lpdwProcessId); [DllImport("kernel32.dll", EntryPoint = "SetLastError")] public static extern void SetLastError(uint dwErrCode);
private static Hashtable processWnd = new Hashtable();
private static bool EnumWindowsProc(IntPtr hwnd, uint lParam) { uint uiPid = 0; if (GetParent(hwnd) == IntPtr.Zero) { GetWindowThreadProcessId(hwnd, ref uiPid); if (uiPid == lParam) // 找到进程对应的主窗口句柄 { processWnd.Add(uiPid, hwnd); // 把句柄缓存起来 SetLastError(0); // 设置无错误 return false; // 返回 false 以终止枚举窗口 } } return true; }
public static IntPtr GetCurrentWindowHandle(uint proid) { IntPtr ptrWnd = IntPtr.Zero; uint uiPid = proid; object objWnd = processWnd[uiPid]; if (objWnd != null) { ptrWnd = (IntPtr)objWnd; if (ptrWnd != IntPtr.Zero && IsWindow(ptrWnd)) // 从缓存中获取句柄 { return ptrWnd; } else { ptrWnd = IntPtr.Zero; } } bool bResult = EnumWindows(EnumWindowsProc, uiPid); // 枚举窗口返回 false 并且没有错误号时表明获取成功 if (!bResult && Marshal.GetLastWin32Error() == 0) { objWnd = processWnd[uiPid]; if (objWnd != null) { ptrWnd = (IntPtr)objWnd; } } return ptrWnd; }
[StructLayout(LayoutKind.Sequential)] public struct CopyDataStruct { public IntPtr dwData; public int cbData;//字符串长度 [MarshalAs(UnmanagedType.LPStr)] public string lpData;//字符串 }
https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms644950%28v=vs.85%29.aspx
Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.
向窗口发送消息。
IntPtr hWnd
A handle to the window whose window procedure will receive the message.
int msg
The message to be sent.
int wParam
Additional message-specific information.
CopyDataStruct lParam
The return value specifies the result of the message processing; it depends on the message sent.
[DllImport("user32.dll")] public static extern void SendMessage(IntPtr hWnd, int msg, int wParam, ref CopyDataStruct lParam);
public static class Constants { public const int WM_COPYDATA = 0x004A; }
向指定进程窗口发送消息
public static void SendMessage(Process process, string msg) { IntPtr hwnd = UnsafeNativeMethods.GetCurrentWindowHandle((uint)process.Id); CopyDataStruct d = new CopyDataStruct(); d.dwData = IntPtr.Zero; d.lpData = msg; d.cbData = System.Text.Encoding.Default.GetBytes(msg).Length + 1; UnsafeNativeMethods.SendMessage(hwnd, Constants.WM_COPYDATA, 0, ref d); }
WPF
MainWindow
Loaded += MainWindow_Loaded;
void MainWindow_Loaded(object sender, RoutedEventArgs e) { (PresentationSource.FromVisual(this) as HwndSource).AddHook(new HwndSourceHook(WndProc)); }
[StructLayout(LayoutKind.Sequential)] public struct CopyDataStruct { public IntPtr dwData; public int cbData;//字符串长度 [MarshalAs(UnmanagedType.LPStr)] public string lpData;//字符串 }
IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == Constants.WM_COPYDATA) { var cds = (CopyDataStruct)Marshal.PtrToStructure(lParam, typeof(CopyDataStruct)); var cmd = cds.lpData; if (oid.IsNotEmpty()) { ... } } return hwnd; }