Как получить HWND безоконный элемент управления ATL? - PullRequest
0 голосов
/ 27 февраля 2010

Я создал элемент управления без окон ATL, и определение класса выглядит следующим образом:

    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 от Microsoft!

Ответы [ 2 ]

3 голосов
/ 03 марта 2012

Весь смысл элемента управления без окон в том, что он работает без дескриптора окна. Если вы хотите использовать дескриптор окна, если он, случайно, существует и элемент управления вернулся в оконный режим, тогда это просто: m_hWndCD .

Если в противном случае у вас должно быть окно, тогда у вас есть m_bWindowOnly , чтобы пометить в конструкторе и указать, что вам понадобится HWND:

Флаг, указывающий, что элемент управления должен быть оконным, даже если контейнер поддерживает элементы управления без окон.

Если вы по-прежнему хотите, чтобы оно оставалось без окон, и вам иногда нужно окно, при определенных условиях, возникающих во время выполнения, у вас всегда есть возможность создать личное окно только для сообщений и отправлять через него сообщения.

3 голосов
/ 10 июля 2010

Вот некоторый код, взятый из примера 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;
}
...