我在做一个浏览器插件,我在SetSite函数里面使用SetWindowLong传GWL_WNDPROC替换浏览器消息处理函数,用来捕获处理浏览器的关闭事件为最小化事件。在IE6的某些机器上面会出现浏览器标题乱码的问题。问题好像是出在
return CallWindowProc(g_gwOldListExitProc,hwnd,uMsg,wParam,lParam);//用这句有问题!!
因为使用 //return DefWindowProc(hwnd,uMsg,wParam,lParam);//使用此句没有问题IE5和IE7下面没有问题,部分IE6有问题。大概代码如下:C/C++ code    #ifdef STRICT typedef WNDPROC MYPROC; #else typedef FARPROC MYPROC; #endif MYPROC g_gwOldListExitProc= NULL; LRESULT CALLBACK ListExitProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { if(Msg == WM_SYSCOMMAND && wParam ==SC_CLOSE && g_bEnableSSLTray) { ATLTRACE("Brower SC_CLOSE"); g_pWebbrowser2->get_HWND((long *)&hIeWnd); ... if(hIeWnd != hWnd) return CallWindowProc(g_gwOldListExitProc,hWnd,Msg,wParam,lParam); ShowWindow(hIeWnd,SW_HIDE); ... return 0; } return CallWindowProc(g_gwOldListExitProc,hwnd,uMsg,wParam,lParam);//用这句有问题!! //return DefWindowProc(hwnd,uMsg,wParam,lParam);//使用此句没有问题 } STDMETHODIMP CSinforIEBHO::SetSite(IUnknown *pUnkSite) { ... //启用托盘的时候同时将IE窗口的消息处理过程函数替换为自己的处理过程 if(g_bReplaceWndProc == FALSE) { ATLTRACE("g_bReplaceWndProc == FALSE Replace WndProc"); HWND hIeWnd = NULL; m_spWebBrowser2->get_HWND((long *)&hIeWnd); g_gwOldListExitProc = (MYPROC)SetWindowLongPtr(hIeWnd,GWLP_WNDPROC,(LONG_PTR)ListExitProc); g_bReplaceWndProc = TRUE; } ... }

解决方案 »

  1.   

    #ifdef STRICT typedef WNDPROC MYPROC; #else typedef FARPROC MYPROC; #endif MYPROC g_gwOldListExitProc= NULL; LRESULT CALLBACK ListExitProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { if(Msg == WM_SYSCOMMAND && wParam ==SC_CLOSE && g_bEnableSSLTray) { ATLTRACE("Brower SC_CLOSE"); g_pWebbrowser2->get_HWND((long *)&hIeWnd); ... if(hIeWnd != hWnd) return CallWindowProc(g_gwOldListExitProc,hWnd,Msg,wParam,lParam); ShowWindow(hIeWnd,SW_HIDE); ... return 0; } return CallWindowProc(g_gwOldListExitProc,hwnd,uMsg,wParam,lParam);//用这句有问题!! //return DefWindowProc(hwnd,uMsg,wParam,lParam);//使用此句没有问题 } STDMETHODIMP CSinforIEBHO::SetSite(IUnknown *pUnkSite) { ... //启用托盘的时候同时将IE窗口的消息处理过程函数替换为自己的处理过程  if(g_bReplaceWndProc == FALSE) { ATLTRACE("g_bReplaceWndProc == FALSE Replace WndProc"); HWND hIeWnd = NULL; m_spWebBrowser2->get_HWND((long *)&hIeWnd); g_gwOldListExitProc = (MYPROC)SetWindowLongPtr(hIeWnd,GWLP_WNDPROC,(LONG_PTR)ListExitProc); g_bReplaceWndProc = TRUE; } ... }
      

  2.   

    #ifdef STRICT 
    typedef WNDPROC MYPROC;
    #else 
    typedef FARPROC MYPROC;
    #endif MYPROC g_gwOldListExitProc= NULL;LRESULT CALLBACK ListExitProc( HWND hwnd,
        UINT uMsg,
        WPARAM wParam,
        LPARAM lParam
        )
    {    if(Msg == WM_SYSCOMMAND && wParam ==SC_CLOSE && g_bEnableSSLTray)
        {
            ATLTRACE("Brower SC_CLOSE");
            g_pWebbrowser2->get_HWND((long *)&hIeWnd);
            ...
            if(hIeWnd != hWnd)
                return CallWindowProc(g_gwOldListExitProc,hWnd,Msg,wParam,lParam);
            ShowWindow(hIeWnd,SW_HIDE);
            ...
            return 0;
        }
        return CallWindowProc(g_gwOldListExitProc,hwnd,uMsg,wParam,lParam);//用这句有问题!!
        //return DefWindowProc(hwnd,uMsg,wParam,lParam);//使用此句没有问题
    }STDMETHODIMP CSinforIEBHO::SetSite(IUnknown *pUnkSite)
    {
    ...
                //启用托盘的时候同时将IE窗口的消息处理过程函数替换为自己的处理过程
                if(g_bReplaceWndProc == FALSE)
                {
                    ATLTRACE("g_bReplaceWndProc == FALSE Replace WndProc");
                    HWND hIeWnd = NULL;
                    m_spWebBrowser2->get_HWND((long *)&hIeWnd);
                    g_gwOldListExitProc = (MYPROC)SetWindowLongPtr(hIeWnd,GWLP_WNDPROC,(LONG_PTR)ListExitProc);
                    g_bReplaceWndProc = TRUE;
                            }
    ...
    }
      

  3.   

    这样试试,把:
    g_gwOldListExitProc = (MYPROC)SetWindowLongPtr(hIeWnd,GWLP_WNDPROC,(LONG_PTR)ListExitProc);
    改成:
    g_gwOldListExitProc = (MYPROC)GetWindowLongPtr(hIeWnd,GWLP_WNDPROC);
    SetWindowLongPtr(hIeWnd,GWLP_WNDPROC,(LONG_PTR)ListExitProc);
      

  4.   

    最开始是这样写的。
    没有作用的。想改用钩子了,
    我想用SetWindowsHook来给浏览器当前窗口装一个钩子,后来发现,sc_close的消息是钩到了,但是处理完后浏览器照样关闭。
    我想可能是浏览器窗口线程的退出消息是由它浏览器的维护线程来处理的,类似使用subclasswindow,窗口退出的时候先把退出消息发给了维护线程,维护线程处理完了,才发一份消息副本给浏览器窗口。所以即使捕获到了,窗口还是退出。
    所以不知道IE进程里面,维护线程的ID怎么获取!!
      

  5.   

    SetWindowsHook不行。
    看看你的程序有没有其它地方修改(或者内存越界破坏)了g_gwOldListExitProc。