我创建了一个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?
OMG我对微软强大的ATL框架感到非常沮丧!答案 0 :(得分:3)
以下是一些代码来自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;
}
答案 1 :(得分:3)
无窗口控制的重点在于它没有窗口句柄。如果你想使用窗口句柄,万一它存在并且控件重新进入窗口模式,那么很容易:m_hWndCD。
如果不是你必须有一个窗口,那么你有m_bWindowOnly在构造函数中标记并表明你需要一个HWND
:
表示控件的标志应该加窗,即使容器支持无窗口控件。
如果您仍然希望它无窗口并且有时需要一个窗口,在运行时出现的某些条件下,您始终可以选择创建私有message only window并通过它发送消息。