这是我与setWindowsHookEx
相关的另一个问题,我编写了一个小型应用程序来将dll
挂钩到窗口calculator applicatio
中。基本上,exe
应用程序将dll
注入calculator
并监视计算器应用程序中发生的所有鼠标停止事件。目前,我可以禁用计算器上发生的所有鼠标按下事件。但是,我想根据鼠标指向的位置完成它。具体来说,当鼠标按钮单击特定菜单栏项目时。我试图通过使用GetWindowText来检索按钮指向的文本来完成此操作,但大多数时候它返回窗口文本而不是它指向的窗口项(menu item
)。以下是我为此编写的代码。如何禁用菜单栏上的特定窗口元素。
调用SetWindowsHookEx的EXE代码
// program.exe.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include <string>
#include <io.h>
using namespace std;
void Usage()
{
printf("Usage: InjectDLL pid path-to-dll [-privilege]");
}
int _tmain(int argc, char* argv[])
{
/*
* Load library in which we'll be hooking our functions.
*/
HMODULE dll = LoadLibrary(L"C:\\drivers\\dllinject.dll");
if (dll == NULL) {
printf("The DLL could not be found.\n");
getchar();
return -1;
}
/*
* Get the address of the function inside the DLL.
* _hookmethod@12 is used to hook into 32bit applications
*/
//HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, "_hookmethod@12");
HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, "hookmethod");
if (addr == NULL) {
printf("The function was not found.\n");
getchar();
return -1;
}
/*
* Hook the function.
*/
DWORD procID=0;
HWND targetWnd = FindWindowA("CalcFrame", "Calculator");
wchar_t msgBuf[1024] = L"";
wchar_t msgBuf2[1024] = L"";
wsprintf(msgBuf, L"the thread Id is : %d , process id is : %d ", threadID, procID);
OutputDebugString(msgBuf);
//
//WH_KEYBOARD_LL
HHOOK handle = SetWindowsHookEx(WH_GETMESSAGE, addr, dll, threadID);
//HHOOK handle = SetWindowsHookEx(WH_CALLWNDPROC, addr, dll, threadID);
//HHOOK handle = SetWindowsHookEx(WH_MSGFILTER, addr, dll, threadID);
DWORD x = GetLastError();
wsprintf(msgBuf2, L"the last error is %d", x);
OutputDebugString(msgBuf2);
if (handle == NULL) {
printf("The KEYBOARD could not be hooked.\n");
}
else{
printf("Program successfully hooked.\nPress enter to unhook the function and stop the program.\n");
}
/*
* Unhook the function.
*/
getchar();
UnhookWindowsHookEx(handle);
return 0;
}
用于阻止点击菜单栏项目的dll。
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
static HWND s_hWndButton;
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) {
switch (Reason) {
case DLL_PROCESS_ATTACH:
OutputDebugString(L"DLL attach function called11.\n");
break;
case DLL_PROCESS_DETACH:
OutputDebugString(L"DLL detach function called.\n");
break;
case DLL_THREAD_ATTACH:
OutputDebugString(L"DLL thread attach function called.\n");
break;
case DLL_THREAD_DETACH:
OutputDebugString(L"DLL thread detach function called.\n");
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) LRESULT __stdcall hookmethod(int code, WPARAM wParam, LPARAM lParam) {
TCHAR msgBuftext[65536];
TCHAR msgBufhandle[65536];
TCHAR msgBufhandletext[65536];
TCHAR msgBufwintext[2048];
if (code >= 0) {
MSG* cp = (MSG*)lParam;
int txtlen = GetWindowTextLengthW(cp->hwnd);
GetWindowText(cp->hwnd, msgBufhandletext, txtlen);
wsprintf(msgBufhandle, L"Handle %X", cp->hwnd);
wsprintf(msgBufwintext, L"Window Text %s", msgBufhandletext);
LPMSG msg = (LPMSG)lParam;
if (msg->message == WM_LBUTTONDOWN) {
OutputDebugString(msgBufwintext);
msg->message = WM_NULL;
}
}
return(CallNextHookEx(NULL, code, wParam, lParam));
}
答案 0 :(得分:0)
对于那些感兴趣的人,我想发布我能够实现的答案。基本上,我没有收听WH_GETMESSAGE
,而是将钩链更改为WH_MSGFILTER
。原因是,它允许我在菜单项上移动鼠标时找到菜单项ID,当按钮启动事件发生时,我可以通过将消息更改为WM_NULL来检查菜单项ID并禁用鼠标单击。以下是工作代码示例。如果用户是navigat,它还可以阻止事件
dll代码
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <Winuser.h>
#include <Lmcons.h>
#include "nxlrunner.h"
WORD wMenuItemID;
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) {
switch (Reason) {
case DLL_PROCESS_ATTACH:
OutputDebugString(L"DLL attach function called11.\n");
break;
case DLL_PROCESS_DETACH:
OutputDebugString(L"DLL detach function called.\n");
break;
case DLL_THREAD_ATTACH:
OutputDebugString(L"DLL thread attach function called.\n");
break;
case DLL_THREAD_DETACH:
OutputDebugString(L"DLL thread detach function called.\n");
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) LRESULT __stdcall meconnect(int code, WPARAM wParam, LPARAM lParam) {
switch (code)
{
case MSGF_MENU: // message is for a menu
{
MSG* pMSG = (MSG*)lParam;
switch (pMSG->message)
{
case WM_MENUSELECT:
{
wMenuItemID = LOWORD(pMSG->wParam);
break;
}
case WM_LBUTTONDOWN:
{
break;
}
case WM_LBUTTONUP:
{
if (wMenuItemID == 10353){
wchar_t usernamew[UNLEN];
DWORD username_len = UNLEN + 1;
GetUserNameW(usernamew, &username_len);
MessageBoxW(NULL, usernamew, L"Title", MB_OK);
pMSG->message = WM_NULL;
}
break;
}
case WM_LBUTTONDBLCLK:
{
if (wMenuItemID == 10353){
pMSG->message = WM_NULL;
}
break;
}
case WM_KEYDOWN:
{
switch (pMSG->wParam)
{
case VK_RETURN:
{
if (wMenuItemID == 10353){
MessageBoxW(NULL, L"Message to user", L"Title.", MB_OK);
pMSG->message = WM_NULL;
}
break;
}
}
break;
}
case WM_KEYUP:
{
switch (pMSG->wParam)
{
case VK_RETURN:
{
if (wMenuItemID == 10353){
MessageBoxW(NULL, L"Message to user", L"Title", MB_OK);
pMSG->message = WM_NULL;
}
break;
}
}
break;
}
}
break;
}
}
return false;
}