【问题标题】:How to get HWND of a windowless ATL control?如何获取无窗口 ATL 控件的 HWND?
【发布时间】:2011-01-21 17:31:34
【问题描述】:

我创建了一个ATL windowsless控件,类定义是这样的:

    class ATL_NO_VTABLE CRSPClient :
    public IObjectSafetyImpl<CRSPClient, INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA>,
    public CComObjectRootEx<CComSingleThreadModel>,
    public IDispatchImpl<IRSPClient, &IID_IRSPClient, &LIBID_axBanckleRSPClientLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
    public IPersistStreamInitImpl<CRSPClient>,
    public IOleControlImpl<CRSPClient>,
    public IOleObjectImpl<CRSPClient>,
    public IOleInPlaceActiveObjectImpl<CRSPClient>,
    public IQuickActivateImpl<CRSPClient>,
    public IViewObjectExImpl<CRSPClient>,
    public IOleInPlaceObjectWindowlessImpl<CRSPClient>,
#ifdef _WIN32_WCE // IObjectSafety is required on Windows CE for the control to be loaded correctly
    public IObjectSafetyImpl<CRSPClient, INTERFACESAFE_FOR_UNTRUSTED_CALLER>,
#endif
    public CComCoClass<CRSPClient, &CLSID_RSPClient>,
    public CComControl<CRSPClient>

然后出于某种目的,我需要将消息发布到窗口。我尝试了很多方法来获取窗口的句柄,但都失败了:

    HWND CRSPClient::GetHwnd()
{
    HWND hwndRet = NULL;
    // hwndRet = m_hWnd;
    //IOleInPlaceActiveObjectImpl<CRSPClient>::GetWindow(&hwndRet);
    //IOleWindow<CRSPClient>::GetWindow(&hwndRet);
    //this->m_spInPlaceSite->GetWindow(&hwndRet);
    //CComQIPtr<IOleInPlaceSite> spSite = this->m_spClientSite;
    //spSite->GetWindow(&hwndRet);
    //hwndRet = ::WindowFromDC(GetDC());
    return hwndRet;
}

有人知道有什么方法可以得到 HWND 吗?

天哪,我对微软出色的 ATL 框架感到非常沮丧!

【问题讨论】:

    标签: com activex atl


    【解决方案1】:

    无窗口控件的全部意义在于它可以在没有窗口句柄的情况下工作。如果您想使用窗口句柄以防万一它存在并且控件回到窗口模式,那么很容易:m_hWndCD

    如果否则你必须有一个窗口,那么你有m_bWindowOnly 在构造函数中标记并表明你需要一个HWND

    指示控件应该有窗口的标志,即使容器支持无窗口控件。

    如果您仍然希望它没有窗口并且只是有时需要一个窗口,在运行时出现的特定条件下,您始终可以选择创建一个私有 message only window 并通过它发送消息。

    【讨论】:

      【解决方案2】:

      下面是一些取自 Microsoft 的 Direct3D ATL 示例的代码。我还没有测试过。

      // Get the window we need to use. This will either be the window that has already
      // been created if we are window. If we are windowless the HWND of the client
      // will be retrieved from the HDC.
      void GetOurWindow()
      {
          // If we're windowless we still need an HWND for Direct3d
          if (m_bWndLess)
          {
              HDC hDC;
      
              // Get the HDC from the client
              m_spInPlaceSite->GetDC(NULL, OLEDC_NODRAW, &hDC);
              m_hOurWnd = WindowFromDC(hDC);
          #if 1
              // Code to make VB5 paint properly now it has clipped it's own hDC
              RECT rect;
              ::GetClientRect(m_hOurWnd,&rect);
              HRGN hRegion = CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
              SelectClipRgn(hDC,hRegion);
          #endif
              m_spInPlaceSite->ReleaseDC(hDC);
          }
          else
              m_hOurWnd = m_hWnd;
      }
      

      【讨论】:

        猜你喜欢
        • 2020-02-03
        • 1970-01-01
        • 2013-07-13
        • 2013-01-17
        • 1970-01-01
        • 1970-01-01
        • 2020-10-22
        • 1970-01-01
        • 2011-08-14
        相关资源
        最近更新 更多