全局钩子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 不能将窗口关闭 如果我注掉鼠标钩子的代码则可以关闭 那位能给我解答下

解决方案 »

  1.   

    HWND g_hWnd = NULL;
    这个必须放到共享段中。#pragma data_seg("Share")
    HWND g_hWnd = NULL;
    #pragma data_seg()
    #pragma comment(linker,"/SECTION:Share,RWS")
      

  2.   

    至于原因嘛是:
    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进程的数据段中,但是这里面没有存储实际的句柄值,所有关闭失败。
      

  3.   

    楼主没有理解“写时复制”的概念。简单的说就是任何进程要去修改 g_hWnd 这个变量,它修改的只是一个仅它自己能使用的副本,而原始的变量是没有修改的。所以才要引入“共享段”机制,取代“写时复制”
      

  4.   


    你看 我在安装钩子的时候对g_hWnd进行赋值 那么无论多少个副本都应该是我最初保存的那个句柄啊 
      

  5.   

    如果不共享,安装钩子时改变g_hWnd,只是改变当前进程内存中的g_hWnd
      

  6.   

    如果没有享,其他进程加载dll时得到的g_hWnd 是文件中规定的初始值