写下这是为了自己复习的。
主要实现的是给File Explorer注入鼠标钩子,以检测鼠标是否在File Explorer上点击
.cpp
#include <Windows.h> #include <stdio.h> #include <psapi.h> #include <shlwapi.h> #include <tchar.h> #pragma comment(lib,"Kernel32.lib") #pragma comment(lib,"shlwapi.lib") #pragma comment(linker, "/SECTION:.shared,RWS") using namespace std; DWORD dwPID; LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_DESTROY) { PostQuitMessage(0); } return DefWindowProc(hwnd, message, wParam, lParam); }; HINSTANCE hinst; int main() { Sleep(3000); //用作选择file explorer,可以用定时器代替 CHAR lpFileName[MAX_PATH] = { 0 }; HANDLE hProcess; HWND hwnd = GetForegroundWindow(); DWORD threadID = GetWindowThreadProcessId(hwnd, &dwPID); hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, dwPID); GetModuleFileNameEx(hProcess, NULL, lpFileName, _countof(lpFileName)); PathStripPath(lpFileName); if (_tcscmp(_T("explorer.exe"), lpFileName) == 0) { _tprintf(_T("explorer window found")); } else { _tprintf(_T("foreground window was not explorer window")); } CloseHandle(hProcess); HINSTANCE hinstDLL = LoadLibrary(TEXT("DLL.dll")); //这里需要新创建的dll的路径 HHOOK(*AttachHookProc)(DWORD); AttachHookProc = (HHOOK(*)(DWORD)) GetProcAddress(hinstDLL, "AttachHook"); HHOOK HOOK = AttachHookProc(threadID); int err = GetLastError();//检测是否有错误 MSG msg = {}; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
.dll
// dllmain.cpp : Defines the entry point for the DLL application. #include "stdafx.h" #include <Windows.h> #include <stdio.h> HMODULE thisModule; HHOOK hook; LRESULT CALLBACK LaunchListener(int nCode, WPARAM wParam, LPARAM lParam); BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { thisModule = hModule; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } #ifdef __cplusplus //If used by C++ code. extern "C" { //we need to export the C interface #endif _declspec(dllexport) HHOOK AttachHook(DWORD threadID) { hook = SetWindowsHookEx(WH_MOUSE, LaunchListener, thisModule, threadID); return hook; } #ifdef __cplusplus } #endif LRESULT CALLBACK LaunchListener(int nCode, WPARAM wParam, LPARAM lParam) { // process event here if (nCode >= 0) { switch (wParam & 0x0001) { case MK_LBUTTON: { MessageBox(NULL, TEXT("Click"), NULL, MB_OK); } break; } } return CallNextHookEx(NULL, nCode, wParam, lParam); }
相关: How do I unhook a global hook from another process?
对于不需要的钩子,可以对其unhook。
原理类似于下面的例子:
#include <windows.h> HMODULE hModule = NULL; HANDLE hTERM = NULL; HHOOK hCBT = NULL; HHOOK hShell = NULL; static bool Continue() { return (WAIT_TIMEOUT == WaitForSingleObject(hTERM, 0)); } LRESULT CALLBACK _cbtProc(int code, WPARAM wParam, LPARAM lParam) { if (Continue()) { // Handle the message ... } return CallNextHookEx(NULL, code, wParam, lParam); } LRESULT CALLBACK _shellProc(int code, WPARAM wParam, LPARAM lParam) { if (Continue()) { // Handle the message ... } return CallNextHookEx(NULL, code, wParam, lParam); } __declspec(dllexport) BOOL WINAPI InstallHooks() { if (!Continue()) return FALSE; if (!hCBT) hCBT = SetWindowsHookEx(WH_CBT, _cbtProc, hModule, 0); if (!hShell) hShell = SetWindowsHookEx(WH_SHELL, _shellProc, hModule, 0); return ((hCBT) && (hShell)) ? TRUE : FALSE; } __declspec(dllexport) void WINAPI RemoveHooks() { if (hTERM) SetEvent(hTERM); if (hCBT) { UnhookWindowsHookEx(hCBT); hCBT = NULL; } if (hShell) { UnhookWindowsHookEx(hShell); hShell = NULL; } } BOOL WINAPI DllMain(HMODULE hinstDLL, DWORD fdwReason, void* lpvReserved) { hModule = hinstDLL; switch (fdwReason) { case DLL_PROCESS_ATTACH: hTERM = CreateEvent(NULL, TRUE, FALSE, TEXT("{0C3ED513-F38C-4996-8130-F9A3C93D890B}")); if (!hTERM) return FALSE; break; case DLL_PROCESS_DETACH: if (hTERM) { CloseHandle(hTERM); hTERM = NULL; } break; } return TRUE; }
需要钩子的时候,在主程序中调用InstallHooks, 不需要的时候,调用RemoveHooks...
新的例子: 使用WH_CBT阻止浏览器最大化
DLL:
// dllmain.cpp : Defines the entry point for the DLL application. #include "pch.h" #include "stdio.h" #include <string> #include <windows.h> #pragma warning(disable:4996) HHOOK hCBT = NULL; static HWND hTarget, hTarget1; BOOL done = FALSE; WNDPROC g_OldWndProc; HMODULE thisModule; LRESULT CALLBACK NewWndProc(HWND hwnd, UINT mesg, WPARAM wParam, LPARAM lParam) { switch (mesg) { case WM_SYSCOMMAND: { if (wParam == SC_MAXIMIZE) { MessageBox(NULL, L"SC_MAXIMIZE", L" ", MB_OK); return 1; } } break; } return CallWindowProc(g_OldWndProc, hwnd, mesg, wParam, lParam); } LRESULT CALLBACK _cbtProc(int code, WPARAM wParam, LPARAM lParam) { FILE* logfile; char buffer[256] = {}; char buffer_[256] = {}; char buffer1[256] = {}; if (code < 0) return CallNextHookEx(0, code, wParam, lParam); // if (code == HCBT_ACTIVATE) // { // CBTACTIVATESTRUCT *cb = (CBTACTIVATESTRUCT*)lParam; // int m = (int)cb->hWndActive; // int n = (int)hTarget; // int x = (int)(HWND)(wParam); // logfile = fopen("log.txt", "w"); // sprintf(buffer, "%d", m); // fprintf(logfile, "cb->hWndActive:"); // fprintf(logfile, buffer); // fprintf(logfile, " "); // sprintf(buffer_, "%d", n); // fprintf(logfile, "hTarget:"); // fprintf(logfile, buffer_); // fprintf(logfile, " "); // sprintf(buffer1, "%d", x); // fprintf(logfile, "(HWND)(wParam):"); // fprintf(logfile, buffer1); // fprintf(logfile, " "); // if ((HWND)(wParam)) // { //// MessageBox(NULL, L"activate", L" ", MB_OK); // if (done == FALSE) // { // g_OldWndProc = (WNDPROC)(SetWindowLongPtr((HWND)(wParam), GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(NewWndProc))); // done = TRUE; // } // } // } if (code == HCBT_MINMAX) { if (LOWORD(lParam) == SW_SHOWMAXIMIZED) { return 1; } } return CallNextHookEx(0, code, wParam, lParam); } #ifdef __cplusplus //If used by C++ code. extern "C" { //we need to export the C interface #endif __declspec(dllexport) BOOL WINAPI InstallHooks(HWND HandleofTarget) { wchar_t buffer[100] = {}; hTarget = HandleofTarget; hTarget1 = HandleofTarget; DWORD tid = GetWindowThreadProcessId(hTarget, NULL); hCBT = SetWindowsHookEx(WH_CBT, _cbtProc, thisModule, tid); return (hCBT) ? TRUE : FALSE; } #ifdef __cplusplus } #endif #ifdef __cplusplus //If used by C++ code. extern "C" { //we need to export the C interface #endif __declspec(dllexport) void WINAPI RemoveHooks() { UnhookWindowsHookEx(hCBT); MessageBox(NULL, L"unhook", L" ", MB_OK); hCBT = NULL; } #ifdef __cplusplus } #endif BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { thisModule = hModule; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
.cpp
#include <Windows.h> #include <stdio.h> #include <psapi.h> #include <shlwapi.h> #include <tchar.h> #pragma comment(lib,"Kernel32.lib") #pragma comment(lib,"shlwapi.lib") #pragma comment(linker, "/SECTION:.shared,RWS") using namespace std; HINSTANCE hinstDLL; typedef void (*RemoveHooks)(); DWORD __stdcall CreateThreadFunc(LPVOID) { while (1) { if (GetAsyncKeyState(0x50) & 0x0001) { RemoveHooks removeHooks = (RemoveHooks)GetProcAddress(hinstDLL, "RemoveHooks"); removeHooks(); } } return 0; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_DESTROY) { PostQuitMessage(0); } return DefWindowProc(hwnd, message, wParam, lParam); }; HINSTANCE hinst; int main() { HWND hwnd = FindWindow(L"Chrome_WidgetWin_1", L"Google Translate - Google Chrome"); CreateThread(NULL, 0, CreateThreadFunc, 0, 0, 0); hinstDLL = LoadLibrary(TEXT("D:\Start from 11.2\WM_CBT_DLL\x64\Debug\WM_CBT_DLL.dll")); BOOL(*InstallHooks)(HWND); InstallHooks = (BOOL(*)(HWND)) GetProcAddress(hinstDLL, "InstallHooks"); BOOL l = InstallHooks(hwnd); int err = GetLastError(); MSG msg = {}; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } }