I created a ATL windows less control and the class definition is like this:
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>
Then for some purpose I need to post message to the window. I tried to get the handle of the window in quite many ways and ALL of them failed:
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(Ge开发者_C百科tDC());
return hwndRet;
}
Anybody know be there any way to get the HWND?
OMG I'm totally frustrated by microsoft's great ATL framework!
The whole point of the windowless control is that it works without a window handle. If you wanted to use window handle in case it, by any chance, exists and the control falled back into windowed mode, then it's easy: m_hWndCD.
If otherwise you have to have a window, then you have m_bWindowOnly to flag in constructor and indicate that you will need a HWND
:
Flag indicating the control should be windowed, even if the container supports windowless controls.
If you still want it windowless and need a window just sometimes, under certain condition that come up on runtime, you always have an option to create a private message only window and dispatch messages through it.
Here is some code taken from Microsoft's Direct3D ATL sample. I haven't tested it yet.
// 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;
}
精彩评论