The implementation of Win32 Global Hook in VC5 · The Windows system is built on event-driven mechanisms, saying that the entire system is implemented through the transmission of messages. The hook is a very important system interface in the Windows system, which can intercept and process messages that are given to other applications to complete the functionality of common applications. There are many types of hooks, each hook can intercept and process the corresponding message, such as the keyboard hook can intercept the keyboard message, the hook hook can take, start, and turn off the application. This article implements a simple mouse hook program in the VC5 programming environment, and the WIN32 global hook operation mechanism, the characteristics of Win32 DLL, the MFC DLL in the VC5 environment, and the related knowledge of shared data are simple to explain. One. The running mechanism of the Win32 global hook is actually a block that handles the message, and it is hung into the system through the system call. Whenever a specific message is issued, the hook program will capture the message first before the destination window is not reached, that is, the hook function is controlled first. At this time, the hook function can be processed (changing) the message, or it can continue to pass the message without processing, and can also force the passage of the message. For each type of hook is maintained by the system, a hook chain is maintained, and the recently installed hook is placed in the beginning of the chain, and the first-installed hook is finally added, which is the first to get control. To implement the Win32 system hook, you must call the API function setWindowshookex in the SDK to install this hook function, the prototype of this function is HHOOK SETWINDOWSHOKEX (int IDHOK, HOOKPROC LPFN, HINSTANCE HMOD, DWORD DWTHREADID); wherein the first parameter is The type of hook; the second parameter is the address of the hook function; the third parameter is a module handle containing the hook function; the fourth parameter specifies the monitoring thread. If the determined thread is specified, it is a thread dedicated hook; if specified is empty, it is a global hook. Where the global hook function must be included in the DLL (dynamic link library), and the thread dedicated hook can also be included in the executable. The hook function obtained by the control is after the processing of the message, if you want the message to continue to pass, it must call the API function callNexthooKex in another SDK to pass it. The hook function can also discard the message by directly returning True and blocks the passage of the message. Two. The characteristics of Win32 DLL WIN32 DLL have great differences from Win16 DLL, which is mainly determined by the design idea of the operating system. On the one hand, in the Win16 DLL in the process entry point function and the exit point function (libmain and WEP) are respectively implemented; in the Win32 DLL, it is implemented by the same function Dllmain.
Whenever, when a process or thread loads and unresses the DLL, the function is called, and its prototype is Bool WinApi Dllmain (Hinstance Hinstdll, DWord FDWREASON, LPVOID LPVRESERVED); wherein the first parameter represents the DLL Example handle; the third parameter system is reserved; here mainly introduces the second parameters, it has four possible values: DLL_PROCESS_ATTACH (process load), DLL_THREAD_ATTACH (thread), DLL_THREAD_DETACH (thread uninstall), DLL_Process_Detach (process) Uninstall), in the DLLMAIN function, the value of the passing parameter can be discriminated, and the DLL is necessary to initialize or clean up according to different parameter values. For example, when a process is loaded into a DLL, the system assists the second parameter of the DLL is DLL_Process_attach, where you can initialize specific data based on this parameter. On the other hand, in the Win16 environment, all applications are in the same address space; and in the Win32 environment, all applications have their own private space, each process is independent, which reduces the application. Mutual influence, but also increased programming. Everyone knows that in the Win16 environment, the global data of the DLL is the same for each process loaded; in the Win32 environment, the situation has changed, and when the process is loaded, the system automatically The DLL address is mapped to the private space of the process, and a copy of the global data of the DLL is also copied to the process space, that is, the same DLL's global data owned by each process is not necessarily the same. of. Therefore, in the Win32 environment, you must share the data in multiple processes, you must make the necessary settings. That is, the data that needs to be shared is separated, placed in a separate data segment, and set the properties of the segment to sharing. three. The classification and characteristics of MFC DLL in VC5 have three forms of MFC DLL in VC5 (available and inherited in the DLL) Alternative, ie Regular StaticLinked to MFC DLL (Static Link MFC DLL) And Regular Using The Shared MFC DLL (Standard Dynamic Link MFC DLL) and Extension MFC DLL (Extended MFC DLL). The first DLL is characterized by adding the MFC code used when compiling to the DLL, so there is no need to exist in other MFC dynamic link class libraries when using the program, but the space for the occupied disk is relatively large; second DLL The feature is that when running, dynamically link to the MFC class library, thereby reducing the occupation of space, but relies on the MFC dynamic link class library at runtime; these two DLLs can be used only by the MFC program or by Win32 program use. The third DLL is similar to the second, as an extension of the MFC class library, can only be used by the MFC program.
four. In the main file, the implementation of the global shared data in the VC5, build a new data segment with #pragma data_seg and define shared data, the specific format is: #pragma data_seg ("shareddata") hWnd sharedWnd = null; // Share data #pragma data_seg () Only a data segment does not reach the purpose of sharing data, but also tell the compiler that the properties of this segment can achieve this (the effect is the same), one method is. The following statement is added to the DEF file: SetCTION SharedData Read Write Shared Another method is to add the following statement in the project settings link option: / section: SharedData, RWS 5. Specific implementation Steps Since the global hook function must be included in the dynamic link library, this example is implemented by two programs.
1. Create a hook mousehook.dll (1) Select MFC AppWizard (DLL) Create a project mousehook; (2) Select the MFC Extension DLL type; (3) Because VC5 has no ready-made hook class, you have to create in the project directory. Mousehook.h file, built in it: Class AFX_EXT_CLASS CMOUSEHOOK: PUBLIC COBJECT {public: cmousehook (); // Hook class constructor ~ cmousehook (); // Hook class Destructure function Bool StartHook (hwnd hwnd) ; // Install the hook function bool stophook (); unload hook functions}; (4) Add to the #include "mousehook.h" statement at the top of the mousehook.app file; (5) Add global shared data variable: #pragma data_seg (" MyData ") HWND GLHPREVTARWND = NULL; // The window handle of the last mouse is hwnd glhdisplayWnd = null; // Displays the HHOOK GLHHOK = NULL of the target window title edit; // Installed Mouse Hook Hinstance Glhinstance = Null ; // DLL Example Hervice #pragma data_seg () (6) Defining segment properties in the DEF file: Sections MyData Read Write Shared (7) Add the statement to save the DLL instance handle in the dllmain function of the main file mousehook.cpp: DLLMAIN hINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {// If the parameter lpReserved delete this line UNREFERENCED_PARAMETER (lpReserved); if (dwReason == DLL_PROCESS_ATTACH) {TRACE0 ( "MOUSEHOOK.DLL Initializing / n!"); // Extension DLL initialization only once if (AfxInitExtensionModule (MousehookDLL, hInstance)!) Return 0; new CDynLinkLibrary (MousehookDLL); // Add the DLL dynamically MFC class libraries glhInstance = hInstance; // Insert a DLL instance handle} else if (dwReason == DLL_PROCESS_DETACH) {trace0 ("Mousehook.dll Terminating! //); // Terminate this link library before calling it AfxterMextensionModule;} Return 1;} (8) Specific implementation of member functions of class cmousehook: cmousehook :: cmousehook () // Class constructor {} cmousehook :: ~ cmousehook () // classification function {stophook ();
} BOOL Cmousehook :: starthook (HWND hWnd) // sets the reception and mounting hook display window handle {BOOL bResult = FALSE; glhHook = SetWindowsHookEx (WH_MOUSE, MouseProc, glhInstance, 0); if (! GlhHook = NULL) bResult = TRUE ; glhDisplayWnd = hWnd; // set the title of the window displaying the edit box handle return bResult;} BOOL Cmousehook :: stophook () // unloading hook {BOOL bResult = FALSE; if (glhHook) {bResult = UnhookWindowsHookEx (glhHook); if (bResult) {glhPrevTarWnd = NULL; glhDisplayWnd = NULL; // clear variable glhHook = NULL;}} return bResult;} implement (9) hook function: LRESULT WINAPI MouseProc (int nCode, wPARAM wparam, lPARAM lparam) {LPMOUSEHOOKSTRUCT pMouseHook = (MOUSEHOOKSTRUCT FAR *) lparam; if (nCode> = 0) {HWND glhTargetWnd = pMouseHook-> hwnd; // get the target window handle HWND ParentWnd = glhTargetWnd; while (! ParentWnd = NULL) {glhTargetWnd = ParentWnd; ParentWnd = GetParent (GLHTARGETWND); // Take the application main window handle} if (GLHTARGETWND! = GLHPREVTARWND) {char Szcaption [100]; getWindowText (Glhtarg etWnd, szCaption, 100); // get title of the window if (IsWindow (glhDisplayWnd)) SendMessage (glhDisplayWnd, WM_SETTEXT, 0, (LPARAM) (LPCTSTR) szCaption); glhPrevTarWnd = glhTargetWnd; // save the target window}} return CallNextHookEx (GLHHOOK, NCODE, WPARAM, LPARAM); // Continue to pass messages} (10) Compiling the project to generate mousehook.dll.