全局钩子dll的代码#include <windows.h>HWND g_hWnd = NULL;
HHOOK g_hMouse = NULL;
HHOOK g_hKeyBoard = NULL;LRESULT CALLBACK MouseProc(int ncode, WPARAM wParam, LPARAM lParam)
{
return 1;
//return CallNextHookEx(g_hMouse, ncode, wParam, lParam);
}LRESULT CALLBACK KeyBoardProc(int ncode, WPARAM wParam, LPARAM lParam)
{
if(wParam == VK_F2)
{
::PostMessage(g_hWnd, WM_CLOSE, 0, 0);
UnhookWindowsHookEx(g_hMouse);
UnhookWindowsHookEx(g_hKeyBoard);
}
else
{
return 1;
}
}void SetHook(HWND hwnd)
{
g_hWnd = hwnd;
g_hMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, GetModuleHandle("HOOK.DLL"), 0);
g_hKeyBoard = SetWindowsHookEx(WH_KEYBOARD, KeyBoardProc, GetModuleHandle("HOOK.DLL"), 0);
}调用:
BOOL CTestHookDlg::OnInitDialog()
{
CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
SetHook(m_hWnd);
SetWindowPos(&wndTopMost, 0, 0, 100, 100, SWP_SHOWWINDOW);
return TRUE; // return TRUE unless you set the focus to a control
}
问题 :
为什么我按f2 不能将窗口关闭 如果我注掉鼠标钩子的代码则可以关闭 那位能给我解答下
HHOOK g_hMouse = NULL;
HHOOK g_hKeyBoard = NULL;LRESULT CALLBACK MouseProc(int ncode, WPARAM wParam, LPARAM lParam)
{
return 1;
//return CallNextHookEx(g_hMouse, ncode, wParam, lParam);
}LRESULT CALLBACK KeyBoardProc(int ncode, WPARAM wParam, LPARAM lParam)
{
if(wParam == VK_F2)
{
::PostMessage(g_hWnd, WM_CLOSE, 0, 0);
UnhookWindowsHookEx(g_hMouse);
UnhookWindowsHookEx(g_hKeyBoard);
}
else
{
return 1;
}
}void SetHook(HWND hwnd)
{
g_hWnd = hwnd;
g_hMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, GetModuleHandle("HOOK.DLL"), 0);
g_hKeyBoard = SetWindowsHookEx(WH_KEYBOARD, KeyBoardProc, GetModuleHandle("HOOK.DLL"), 0);
}调用:
BOOL CTestHookDlg::OnInitDialog()
{
CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
SetHook(m_hWnd);
SetWindowPos(&wndTopMost, 0, 0, 100, 100, SWP_SHOWWINDOW);
return TRUE; // return TRUE unless you set the focus to a control
}
问题 :
为什么我按f2 不能将窗口关闭 如果我注掉鼠标钩子的代码则可以关闭 那位能给我解答下
这个必须放到共享段中。#pragma data_seg("Share")
HWND g_hWnd = NULL;
#pragma data_seg()
#pragma comment(linker,"/SECTION:Share,RWS")
dll模块,当被不同的进程加载的时候,代码段段是被不同的进程共享的,而普通的数据段不同进程没有共享,而是通过映射,映射到不同的模块。
假如你在A进程中调用了void SetHook(HWND hwnd)
{
g_hWnd = hwnd;
g_hMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, GetModuleHandle("HOOK.DLL"), 0);
g_hKeyBoard = SetWindowsHookEx(WH_KEYBOARD, KeyBoardProc, GetModuleHandle("HOOK.DLL"), 0);
}
这个函数,那么将A进程的一个窗口句柄保存在dll模块映射到A进程的数据段中。
而当你切换到B进程时候,
再调用::PostMessage(g_hWnd, WM_CLOSE, 0, 0);的时候,这里的g_hWnd存储在dll模块映射到B进程的数据段中,但是这里面没有存储实际的句柄值,所有关闭失败。
你看 我在安装钩子的时候对g_hWnd进行赋值 那么无论多少个副本都应该是我最初保存的那个句柄啊