【问题标题】:Handle when IE window moves - Visual C++IE 窗口移动时的处理 - Visual C++
【发布时间】:2010-11-25 01:17:18
【问题描述】:

我想处理窗口移动事件。我的第一次尝试是处理DWebBrowserEvents2::WindowSetHeightWindowSetLeftWindowSetTopWindowSetWidth 事件,但由于某些原因,这些事件根本没有被触发。我已经通过处理HTMLWindowEvents2::onresize 来调整窗口大小。窗口移动时如何处理?

我也尝试过实现IHTMLOMWindowServices,但是当窗口位置改变时它的成员不会被调用。关于什么是一个好的接口来实现有什么建议吗?我正在使用 Visual C++ 中的 ATL 创建一个 IE 扩展。

【问题讨论】:

    标签: internet-explorer visual-c++ com atl bho


    【解决方案1】:

    HTML 窗口不是正确的位置。您需要上一级浏览器窗口级别,例如:

                // Get a handle for the IE window and set a hook for the window resize/move events
            m_spWebBrowser->get_HWND(reinterpret_cast<SHANDLE_PTR*>(&m_pWebBrowserHwnd));
            if(m_pWebBrowserHwnd)
            {
                int idHook = WH_CALLWNDPROC; // Type of hook: all Window calls
                HOOKPROC hookProc = MyClass::OnWindowMessage; // Procedure to be called
                HINSTANCE hMod = NULL; // DLL to monitor
                DWORD dwThreadId = GetWindowThreadProcessId(m_pWebBrowserHwnd,NULL); // IE Thread to monitor
                m_ResizeHook = SetWindowsHookEx(idHook, hookProc, hMod, dwThreadId); 
                Trace (L"Hook for window move/resize is set up");
            }
    

    然后 onWindowMessage 处理正确的消息:

    LRESULT CALLBACK MyClass::OnWindowMessage(int nCode, WPARAM wParam, LPARAM lParam)
    {
    
    LRESULT result = CallNextHookEx(NULL, nCode, wParam, lParam);
    
    if( (lParam!=NULL) && (nCode == HC_ACTION))
    {
        CWPSTRUCT *CwpStruct = (CWPSTRUCT *) lParam;
        switch(CwpStruct->message)
        {
        case WM_MOVE:
            HWND manipluatedHWND = CwpStruct->hwnd;
                //Code to execute when window moves
            break;
        }
    }
    

    享受:)

    【讨论】:

    • 不幸的是,这个技巧没有奏效。我设置了 WindowsHook(这似乎没问题),但从未调用过回调函数 OnWindowMessage :(
    • 也许回调函数需要是静态的...为我工作。
    • 是的,回调函数是静态的。不会以任何其他方式工作。
    • 不,我的意思是如果不将 OnWindowMessage 设为静态,代码将无法编译。但是,移动事件仍然没有被处理:(
    • 嗯,奇怪。也许你应该在这里发布相关代码,以便我们仔细检查它......
    【解决方案2】:

    使用计时器处理这种情况。不太优雅,但很有效!

    【讨论】:

      【解决方案3】:

      好的,这里有一些粗略的代码

          class ATL_NO_VTABLE CHelloWorldBHO :
             public CComObjectRootEx<CComSingleThreadModel>,
             public CComCoClass<CHelloWorldBHO, &CLSID_HelloWorldBHO>,
             public IObjectWithSiteImpl<CHelloWorldBHO>,
             public IDispatchImpl<IHelloWorldBHO, &IID_IHelloWorldBHO, &LIBID_HelloWorldLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
             public IDispEventImpl<1, CHelloWorldBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>, 
            //Other interfaces here
      {
      
                   BEGIN_SINK_MAP(CHelloWorldBHO)
                      SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)//Do stuff OnDocumentComplete
                   END_SINK_MAP()
      
               void STDMETHODCALLTYPE OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL){
                   //Do other stuff here
                   SetUpWindowsHook();//This calls a function that sets a window hook, similar to the code that you've posted
               }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2013-07-20
        • 2017-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-28
        • 2013-05-12
        • 1970-01-01
        • 2022-01-19
        相关资源
        最近更新 更多