我在DLL中设置了一个捕获消息的钩子过程!然后在钩子过程第一次触发的时候替换了当前进程的窗口过程,然后在我自己的窗口过程中判断,当按下某一个按钮次数超过限制之后,就不让他的消息响应函数来处理此消息!!!
代码如下://钩子过程
LRESULT CALLBACK GetMsgProc(int code,WPARAM wParam,LPARAM lParam)
{
TRACE(TEXT("Initial hook!\n"));
g_hWnd = FindWindowEx(NULL,NULL,NULL,TEXT("TestHook"));
if(g_dwWndProc == 0 && g_hWnd != NULL)
{
TRACE(TEXT("GO to SetWindowLong\n"));
if(g_hWnd == NULL)
{
TRACE(TEXT("Get Window Handle Failed!:%d\n"),GetLastError());
return FALSE;
}
g_dwWndProc = GetWindowLongPtr(g_hWnd,GWL_WNDPROC); if(g_dwWndProc == 0)
{
return FALSE;
}
if(!SetWindowLongPtr(g_hWnd,GWL_WNDPROC,(long)MyWindowProc))
{
TRACE(TEXT("set proc failed!:%d\n"),GetLastError());
return FALSE;
}
}
return TRUE;
}//替换后的窗口过程窗口过程
LRESULT CALLBACK MyWindowProc(HWND hwnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
)
{
if(g_uCount < 5)
{
if(uMsg == WM_COMMAND && LOWORD(wParam) == 1000 && HIWORD(wParam) == BN_CLICKED)
{
g_uCount++;
TRACE(TEXT("%d\n"),g_uCount);
try{
return CallWindowProc((WNDPROC)g_dwWndProc,hwnd,uMsg,wParam,lParam);//问题所在语句!!!
}
catch(...)
{ }
}
else
{
//TRACE(TEXT("g_uCount<5:%d\n"),g_uCount);
return CallWindowProc((WNDPROC)g_dwWndProc,g_hWnd,uMsg,wParam,lParam);
}
}
else
{
//TRACE(TEXT("g_uCount>5:%d\n"),g_uCount);
return 1;
}
return 0;}return CallWindowProc((WNDPROC)g_dwWndProc,hwnd,uMsg,wParam,lParam);//问题所在语句!!!
调试的时候发现,每当进入这条语句的时候,就弹出“TestHook.exe触发了一个断点!!!!!”的对话框。跟踪进去发现在Wincore.cpp里面
AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
// special message which identifies the window as using AfxWndProc
if (nMsg == WM_QUERYAFXWNDPROC)
return 1; // all other messages route through message map
CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
ASSERT(pWnd != NULL);.。//这里的pWnd = NULL;
ASSERT(pWnd==NULL || pWnd->m_hWnd == hWnd);
if (pWnd == NULL || pWnd->m_hWnd != hWnd)
return ::DefWindowProc(hWnd, nMsg, wParam, lParam);
return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
}
实在是搞不清楚是为什么??高手帮帮忙!!!!!!!!!!!!!!!!!

解决方案 »

  1.   

    你用MFC处理其它窗口的消当然会有问题
    MFC 是和线程相关的,窗口和线程相关,所以绑定进程外的窗口到本进程中当然会有问题。
    解决办法,使用WinApi处理
     
      

  2.   

    我没有绑定进程外的窗口啊!!是DLL绑定当前进程的窗口!!!
      

  3.   

    GetMsgProc 是否是全局钩子?
    g_dwWndProc or g_hWnd 是否是全局共享变量?
      

  4.   

    不是全局钩子但是针对当前进程的钩子!我是在应用程序中SetWindowsHookEx的,g_dwWndProc or g_hWnd是全局变量,但没有共享!
    这个有问题吗??
      

  5.   

    void CMyHook::SetMessageHook()
    {
    g_hMsgHook = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,NULL,::GetCurrentThreadId());
    if(g_hMsgHook == NULL)
    {
    TRACE(TEXT("钩子安装失败!\n"));
    }}
      

  6.   

    因为拦截的button的消息,我猜测,当进入这里的时候if(uMsg == WM_COMMAND && LOWORD(wParam) == 1000 && HIWORD(wParam) == BN_CLICKED)
            {
                g_uCount++;
                TRACE(TEXT("%d\n"),g_uCount);
                try{
                return CallWindowProc((WNDPROC)g_dwWndProc,hwnd,uMsg,wParam,lParam);//问题所在语句!!!
                }
                catch(...)
                {            }
            }
    此时的hwnd 虽然是父窗口的句柄,但是调试发现进入wincore里面的AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) 

    // special message which identifies the window as using AfxWndProc 
    if (nMsg == WM_QUERYAFXWNDPROC) 
    return 1; // all other messages route through message map 
    CWnd* pWnd = CWnd::FromHandlePermanent(hWnd); 
    ASSERT(pWnd != NULL);.。//这里的pWnd = NULL; 
    ASSERT(pWnd==NULL || pWnd->m_hWnd == hWnd); 
    if (pWnd == NULL || pWnd->m_hWnd != hWnd) 
    return ::DefWindowProc(hWnd, nMsg, wParam, lParam); 
    return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam); 

    的时候,hWnd的值就是不父窗口的句柄的值了,我猜测这个经过user32.dll的变换后,此时的hwnd可能成了button的句柄了!而且当经过CWnd::FromHandlePermanent(hWnd); 后,pWnd 就等于NULL 了!!!不知道为什么??
      

  7.   

    这是你的全部代码?
    怎么没有 CallNextHookEx
    MFC 中也有使用 HOOK
      

  8.   

    我改成这样了,但是还是不行!//钩子过程
    LRESULT CALLBACK GetMsgProc(int code,WPARAM wParam,LPARAM lParam)
    {
    TRACE(TEXT("Initial hook!\n"));
    g_hWnd = FindWindowEx(NULL,NULL,NULL,TEXT("TestHook"));
    if(g_dwWndProc == 0 && g_hWnd != NULL)
    {
    TRACE(TEXT("GO to SetWindowLong\n"));
    if(g_hWnd == NULL)
    {
    TRACE(TEXT("Get Window Handle Failed!:%d\n"),GetLastError());
    return CallNextHookEx(g_hMsgHook,code,wParam,lParam);
    }
    g_dwWndProc = GetWindowLongPtr(g_hWnd,GWL_WNDPROC); if(g_dwWndProc == 0)
    {
    return CallNextHookEx(g_hMsgHook,code,wParam,lParam);
    }
    if(!SetWindowLongPtr(g_hWnd,GWL_WNDPROC,(long)MyWindowProc))
    {
    TRACE(TEXT("set proc failed!:%d\n"),GetLastError());
    return CallNextHookEx(g_hMsgHook,code,wParam,lParam);
    }
    }
    return CallNextHookEx(g_hMsgHook,code,wParam,lParam);
    }
      

  9.   

    lz不妨用SendMessage代替CallWindowProc试试。