令人苦笑不的问题:怎样在程序运行时在cview上动态创建一个com可视化组件??

时间:2021-11-09 09:27:10
令人苦笑不的问题:怎样在程序运行时在cview上动态创建一个com可视化组件??
我迷惑啊。。。我自己写的可视化com组件,想在程序中动态显示。。。可是怎样做到呢??

8 个解决方案

#1


MFC用Cwin.creatcontrol()好像可以,我想把一个COM与HWND句柄连接起来,你有相关资料么?

#2


摘自msdn,仔细看看。。。。。。。。。

HRESULT COleControlSite::CreateControl(CWnd* pWndCtrl, REFCLSID clsid,
LPCTSTR lpszWindowName, DWORD dwStyle, const POINT* ppt, const SIZE* psize,
   UINT nID, CFile* pPersist, BOOL bStorage, BSTR bstrLicKey)
{
HRESULT hr = E_FAIL;
m_hWnd = NULL;
   CSize size;

// Connect the OLE Control with its proxy CWnd object
if (pWndCtrl != NULL)
{
ASSERT(pWndCtrl->m_pCtrlSite == NULL);
m_pWndCtrl = pWndCtrl;
pWndCtrl->m_pCtrlSite = this;
}

// Initialize OLE, if necessary
_AFX_THREAD_STATE* pState = AfxGetThreadState();
if (!pState->m_bNeedTerm && !AfxOleInit())
return hr;

if (SUCCEEDED(hr = CreateOrLoad(clsid, pPersist, bStorage, bstrLicKey)))
{
ASSERT(m_pObject != NULL);
m_nID = nID;

if (psize == NULL)
{
// If psize is NULL, ask the object how big it wants to be.
CClientDC dc(NULL);

m_pObject->GetExtent(DVASPECT_CONTENT, &size);
dc.HIMETRICtoDP(&size);
m_rect = CRect(*ppt, size);
}
else
{
m_rect = CRect(*ppt, *psize);
}

m_dwStyleMask = WS_GROUP | WS_TABSTOP;

if (m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON)
m_dwStyleMask |= BS_DEFPUSHBUTTON;

if (m_dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME)
dwStyle &= ~WS_VISIBLE;

m_dwStyle = dwStyle & m_dwStyleMask;

// If control wasn't quick-activated, then connect sinks now.
if (hr != S_QUICKACTIVATED)
{
m_dwEventSink = ConnectSink(m_iidEvents, &m_xEventSink);
m_dwPropNotifySink = ConnectSink(IID_IPropertyNotifySink,
&m_xPropertyNotifySink);
}
m_dwNotifyDBEvents = ConnectSink(IID_INotifyDBEvents, &m_xNotifyDBEvents);

// Now that the object has been created, attempt to
// in-place activate it.

SetExtent();

if (SUCCEEDED(hr = m_pObject->QueryInterface(IID_IOleInPlaceObject,
(LPVOID*)&m_pInPlaceObject)))
{
if (dwStyle & WS_VISIBLE)
{
// control is visible: just activate it
hr = DoVerb(OLEIVERB_INPLACEACTIVATE);
}
else
{
// control is not visible: activate off-screen, hide, then move
m_rect.OffsetRect(-32000, -32000);
if (SUCCEEDED(hr = DoVerb(OLEIVERB_INPLACEACTIVATE)) &&
SUCCEEDED(hr = DoVerb(OLEIVERB_HIDE)))
{
m_rect.OffsetRect(32000, 32000);
hr = m_pInPlaceObject->SetObjectRects(m_rect, m_rect);
}
}
}
else
{
TRACE1("IOleInPlaceObject not supported on OLE control (dialog ID %d).\n", nID);
TRACE1(">>> Result code: 0x%08lx\n", hr);
}

if (SUCCEEDED(hr))
GetControlInfo();

// if QueryInterface or activation failed, cleanup everything
if (FAILED(hr))
{
if (m_pInPlaceObject != NULL)
{
m_pInPlaceObject->Release();
m_pInPlaceObject = NULL;
}
DisconnectSink(m_iidEvents, m_dwEventSink);
DisconnectSink(IID_IPropertyNotifySink, m_dwPropNotifySink);
DisconnectSink(IID_INotifyDBEvents, m_dwNotifyDBEvents);
m_dwEventSink = 0;
m_dwPropNotifySink = 0;
m_dwNotifyDBEvents = 0;
m_pObject->Release();
m_pObject = NULL;
}
}

if (SUCCEEDED(hr))
{
AttachWindow();

ASSERT(m_hWnd != NULL);

// Initialize the control's Caption or Text property, if any
if (lpszWindowName != NULL)
SetWindowText(lpszWindowName);

// Initialize styles
ModifyStyle(0, m_dwStyle | (dwStyle & (WS_DISABLED|WS_BORDER)), 0);
}

return hr;
}

#3


不用MFC,怎么处理IOleClientSite

#4


自己实现IOleClientSite,不然怎么和控件通信

#5


具体怎么做呢?能讲一下么。

#6


比较复杂,参见ms的tstcon列子。在msdn中有的。

#7


creatcontrol()据我使用要报错,,报错信息是assert(iswind())通不过。。
我现在是用loe的Cclientitem(好象是这个类)的来创建的。。。。不过。。呵呵。。
这样我无法将组件通过idispach的ivoke调用。。。我需要给用户提供一个类似vb设计器
的功能,,,,让用户通过组件设计自定义界面,,所以需要调用invoke...
=----------------欢迎大家继续帮助我。。。

#8


哦。。不是clientitem,是COleControlSite,,

#1


MFC用Cwin.creatcontrol()好像可以,我想把一个COM与HWND句柄连接起来,你有相关资料么?

#2


摘自msdn,仔细看看。。。。。。。。。

HRESULT COleControlSite::CreateControl(CWnd* pWndCtrl, REFCLSID clsid,
LPCTSTR lpszWindowName, DWORD dwStyle, const POINT* ppt, const SIZE* psize,
   UINT nID, CFile* pPersist, BOOL bStorage, BSTR bstrLicKey)
{
HRESULT hr = E_FAIL;
m_hWnd = NULL;
   CSize size;

// Connect the OLE Control with its proxy CWnd object
if (pWndCtrl != NULL)
{
ASSERT(pWndCtrl->m_pCtrlSite == NULL);
m_pWndCtrl = pWndCtrl;
pWndCtrl->m_pCtrlSite = this;
}

// Initialize OLE, if necessary
_AFX_THREAD_STATE* pState = AfxGetThreadState();
if (!pState->m_bNeedTerm && !AfxOleInit())
return hr;

if (SUCCEEDED(hr = CreateOrLoad(clsid, pPersist, bStorage, bstrLicKey)))
{
ASSERT(m_pObject != NULL);
m_nID = nID;

if (psize == NULL)
{
// If psize is NULL, ask the object how big it wants to be.
CClientDC dc(NULL);

m_pObject->GetExtent(DVASPECT_CONTENT, &size);
dc.HIMETRICtoDP(&size);
m_rect = CRect(*ppt, size);
}
else
{
m_rect = CRect(*ppt, *psize);
}

m_dwStyleMask = WS_GROUP | WS_TABSTOP;

if (m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON)
m_dwStyleMask |= BS_DEFPUSHBUTTON;

if (m_dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME)
dwStyle &= ~WS_VISIBLE;

m_dwStyle = dwStyle & m_dwStyleMask;

// If control wasn't quick-activated, then connect sinks now.
if (hr != S_QUICKACTIVATED)
{
m_dwEventSink = ConnectSink(m_iidEvents, &m_xEventSink);
m_dwPropNotifySink = ConnectSink(IID_IPropertyNotifySink,
&m_xPropertyNotifySink);
}
m_dwNotifyDBEvents = ConnectSink(IID_INotifyDBEvents, &m_xNotifyDBEvents);

// Now that the object has been created, attempt to
// in-place activate it.

SetExtent();

if (SUCCEEDED(hr = m_pObject->QueryInterface(IID_IOleInPlaceObject,
(LPVOID*)&m_pInPlaceObject)))
{
if (dwStyle & WS_VISIBLE)
{
// control is visible: just activate it
hr = DoVerb(OLEIVERB_INPLACEACTIVATE);
}
else
{
// control is not visible: activate off-screen, hide, then move
m_rect.OffsetRect(-32000, -32000);
if (SUCCEEDED(hr = DoVerb(OLEIVERB_INPLACEACTIVATE)) &&
SUCCEEDED(hr = DoVerb(OLEIVERB_HIDE)))
{
m_rect.OffsetRect(32000, 32000);
hr = m_pInPlaceObject->SetObjectRects(m_rect, m_rect);
}
}
}
else
{
TRACE1("IOleInPlaceObject not supported on OLE control (dialog ID %d).\n", nID);
TRACE1(">>> Result code: 0x%08lx\n", hr);
}

if (SUCCEEDED(hr))
GetControlInfo();

// if QueryInterface or activation failed, cleanup everything
if (FAILED(hr))
{
if (m_pInPlaceObject != NULL)
{
m_pInPlaceObject->Release();
m_pInPlaceObject = NULL;
}
DisconnectSink(m_iidEvents, m_dwEventSink);
DisconnectSink(IID_IPropertyNotifySink, m_dwPropNotifySink);
DisconnectSink(IID_INotifyDBEvents, m_dwNotifyDBEvents);
m_dwEventSink = 0;
m_dwPropNotifySink = 0;
m_dwNotifyDBEvents = 0;
m_pObject->Release();
m_pObject = NULL;
}
}

if (SUCCEEDED(hr))
{
AttachWindow();

ASSERT(m_hWnd != NULL);

// Initialize the control's Caption or Text property, if any
if (lpszWindowName != NULL)
SetWindowText(lpszWindowName);

// Initialize styles
ModifyStyle(0, m_dwStyle | (dwStyle & (WS_DISABLED|WS_BORDER)), 0);
}

return hr;
}

#3


不用MFC,怎么处理IOleClientSite

#4


自己实现IOleClientSite,不然怎么和控件通信

#5


具体怎么做呢?能讲一下么。

#6


比较复杂,参见ms的tstcon列子。在msdn中有的。

#7


creatcontrol()据我使用要报错,,报错信息是assert(iswind())通不过。。
我现在是用loe的Cclientitem(好象是这个类)的来创建的。。。。不过。。呵呵。。
这样我无法将组件通过idispach的ivoke调用。。。我需要给用户提供一个类似vb设计器
的功能,,,,让用户通过组件设计自定义界面,,所以需要调用invoke...
=----------------欢迎大家继续帮助我。。。

#8


哦。。不是clientitem,是COleControlSite,,