Simple example of WM_CopyData and mouse hooks
Author: enoloo
This applet creates a global mouse hook to get some properties of the target window, and then pass the result to the main program via WM_COPYDATA. The program effect and part of the code are as follows:
============================================================================================================================================================================================================= ========= / ** File name: mouse_hook.h * Use: Hook DLL and programs Use * Use: State: Book Class, Message Structure * / Class AFX_EXT_CLASS CMOUSEHOOK: PUBLIC COBJECT / / AFX_EXT_CLASS Output class { Public: cmousehook (); ~ cmousehook (); // Set hook Bool StartHook (hwnd hwnd); // Cancel the hook bool stophook ();}; #define sirtext 100struct msg {hwnd hwnd; // window handle long style; / / Window Style Long Exstyle; // Extension Style Char Caption [Sirtext]; // Window Name CHAR PARENTCAPTION [Sirtext]; // Parent Window Name Char ClassName [Sirtext]; // Class Name DWORD THREADID; // Thread ID DWORD Processid ; // process ID}; 1, DLL program part: ======================================= ============================== // mouse_hook.cpp [part]
#pragma data_seg ("Shared") hwnd g_hwnd = null; // The window handle of the main program is used to send a message to the main program
// Temporary window handle, avoid multiple excitation mouse messages in the same window to send to the program hWnd g_prehwnd = null; hHOOK G_HOOK = NULL; // Hook handle MSG msg = {0}; // The above header file defined message, Pass to the main program #pragma data_seg () #pragma Comment (Linker, "/ Section: Shared, RWS")
// Example Handle Hinstance G_HINSTANCE = NULL; // Send WM_COPYDATA Message Bool Sendmsg (HWnd HWnd, Long Style, Char * BUF1, CHAR * BUF2, CHAR * BUF3) { Msg msg; msg.hwnd = hwnd; msg.style = style; msg.ExStyle = exstyle; msg.threadid = TID; msg.processid = pid; strcpy (msg.caption, buf1); // Window text STRCPY (MSG. ParentCaption, BUF2); // Parent window text strcpy (msg.classname, buf3); // window class name IF (iswindow (g_hwnd)) {copyDataStruct cs; cs.cbdata = sizeof (msg); // Send data CS. LPDATA size cs.dwdata = 0; // Now no cs.lpdata = & msg; // To send data pointer // Send message to the main program Return SendMessage (G_hWnd, WM_CopyData, (WPARAM) HWnd, (LPARAM) & CS );} Runturn :: cmousehook () {} cmousehook :: ~ cmousehook () {stophook ();
// Open mouse hook BOOL Cmousehook :: starthook (HWND hwnd) {ASSERT (hwnd); // global hook g_hook = SetWindowsHookEx (WH_MOUSE, HOOKPROC (hookproc), g_hInstance, 0); if (g_hook!) {Return false;} g_hwnd = hwnd; return true;}
LResult WinAPI HookProc (INT Code, WPARAM WPARAM, LPARAM LPARAM) {Assert (g_hook); char buf1 [sirtext]; // Storage window text char buf2 [sizetext]; // Storage parent window text char buf3 [sizetext]; // Store class name dword tid; // thread id dword pid; // process ID long style; // window style long exstyle; // window expansion style hWnd htarget; hwnd htarget2; // far pointer lpmousehooktruct pmousehook = (MousehookTRuct Far *) lParam; if (code> = 0) {htarget = pMouseHook-> hwnd; if (htarget = g_prehwnd!) {GetWindowText (htarget, buf1, SIZETEXT); style = GetWindowLong (htarget, GWL_STYLE); exstyle = GetWindowLong (htarget, GWL_EXSTYLE ); TID = getWindowThreadProcessId (htarget, & pid); pid = pid; // Get processes id getclassname (htarget, buf3, sirtext); // get class htarget2 = htarget; // Temporarily save the handle hwnd hparent = htarget; while HParent! = null) // Get the parent window handle {htarget = hparent; hparent = getparent (htarget);} getWindowText (htarget, buf2,100); // Send message to the main program Sendmsg (htarget2, style, exstyle, TID, PID, BUF1, BUF2, BUF3); g_prehwnd = htarget2;}} return Thookex (g_hook, code, wparam, lparam);} 2, test program part: ================================ =========================== // mousehook_testdlg.cpp [section]
#pragma comment (lib, "mouse_hook.lib") // DLL library cmousehook g_hook; // Define hook object
// When the program is initialized, set the hook g_hook.startHOK (getsafehwnd ());
When the program exits, uninstall the hook g_hook.stophook ();
// pass from the received data over the hook dll BOOL CMousehook_testDlg :: OnCopyData (CWnd * pWnd, COPYDATASTRUCT * pCopyDataStruct) {// TODO: Add your message handler code here and / or call default Msg * pmsg = (Msg *) (pCopyDataStruct -> LPDATA); CSTRING STR; Str.Format ("% D", PMSG-> hWnd); m_list.setitemtext (0, 1, str); str.format ("% D", PMSG-> style); m_list .SETITEMTEXT (1, 1, Str); str.format ("% d", pmsg-> exstyle); m_list.setitemtext (2, 1, str); str.format ("% d", pmsg-> threadID) ; M_list.setitemtext (3, 1, str); str.format ("% d", pmsg-> processid); m_list.setitemtext (4, 1, str); m_list.setitemtext (5, 1, pmsg-> classname ); M_list.setitemtext (6, 1, pmsg-> caption); m_list.setitemtext (7, 1, pmsg-> parentcaption);
Return CDialog :: ONCOPYDATA (PWND, PcopyDataStruct);} ====================================== =====================
3, Description: The WM_COPYDATA message can communicate between processes. You can communicate with the target process by such a structure: typedef struct tagcopyDataStruct {ulong_ptr dwdata; // The included information DWORD CBDATA; / / Send data size PVOID LPDATA; // To send data pointer} CopyDataStruct, * pcopyDataStruct; goal The process should accept processing data, add the processing of the WM_CopyData message, AFX_MSG Bool OnCopyData (CWND * PWnd, CopyDataStruct * pcopyDataStruct); where PcopyDataStruct includes the structure you just introduced, LPDATA is the data you sent.
It should be noted that the WM_COPYDATA message ensures that the transmitted data is copied from the original process to the target process. However, WM_CopyData messages cannot send things such as HDC, Hbitmap, and they are invalid for target processes. The target process gets these data cannot be done in the original process because they are different processes.
About global hooks. If a thread in the system creates a global mouse hook, when the mouse is moved under a window in a process, the system first wants to determine whether the DLL in which the hook handler hookproc is mapped to this process, if not, It is forced to map this DLL to the process address space. Therefore, the DLL that sends a message to the main program may vary. So how do these DLLs communicate? This requires a DLL shared data segment. ============================================================================================================================================================================================================= ========= # pragma data_seg ("Shared") hwnd g_hwnd = null; // The window handle of the main program is used to send a message // temporary window handle to the main program to avoid more in the same window. Secondary excitation mouse message to the program hWnd g_prehwnd = null; hHOOK G_HOOK = NULL; // Hook handle MSG msg = {0}; // The above header file defined message, passed to the main program #pragma data_seg () #pragma comment Linker, "/ Section: Shared, RWS") ======================================= ====================
For example, g_hook is the created hook handle. Because the entire system is not one of every DLL, it should be shared, he is used in CallNexthookex, if not shared, it will be wrong; for example, G_hWnd, the main program is passed to the handle of the DLL, put it in the shared area All DLLs are in one; g_prehwnd is used to avoid repeating the message to the output window (see code) in a window, if you move it out, you look at the effect ...
Complete code from here: enoloo.icpcn.com/hook.rar