📄 activex.cpp
字号:
DEFINE_OLE_TABLE(wxActiveXEvents)
OLE_IINTERFACE(IUnknown)
OLE_INTERFACE(IID_IDispatch, IDispatch)
OLE_INTERFACE_CUSTOM(wxActiveXEventsInterface)
END_OLE_TABLE
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// wxActiveXContainer
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//---------------------------------------------------------------------------
// wxActiveXContainer Constructor
//
// Initializes members and creates the native ActiveX container
//---------------------------------------------------------------------------
wxActiveXContainer::wxActiveXContainer(wxWindow * parent,
REFIID iid, IUnknown* pUnk)
: m_realparent(parent)
{
m_bAmbientUserMode = true;
m_docAdviseCookie = 0;
CreateActiveX(iid, pUnk);
}
//---------------------------------------------------------------------------
// wxActiveXContainer Destructor
//
// Destroys members (the FrameSite et al. are destroyed implicitly
// through COM ref counting)
//---------------------------------------------------------------------------
wxActiveXContainer::~wxActiveXContainer()
{
// disconnect connection points
if (m_oleInPlaceObject.Ok())
{
m_oleInPlaceObject->InPlaceDeactivate();
m_oleInPlaceObject->UIDeactivate();
}
if (m_oleObject.Ok())
{
if (m_docAdviseCookie != 0)
m_oleObject->Unadvise(m_docAdviseCookie);
m_oleObject->DoVerb(
OLEIVERB_HIDE, NULL, m_clientSite, 0, (HWND) GetHWND(), NULL);
m_oleObject->Close(OLECLOSE_NOSAVE);
m_oleObject->SetClientSite(NULL);
}
}
//---------------------------------------------------------------------------
// wxActiveXContainer::CreateActiveX
//
// Actually creates the ActiveX container through the FrameSite
// and sets up ActiveX events
//
// TODO: Document this more
//---------------------------------------------------------------------------
void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
{
HRESULT hret;
hret = m_ActiveX.QueryInterface(iid, pUnk);
wxASSERT(SUCCEEDED(hret));
// FrameSite
FrameSite *frame = new FrameSite(m_realparent, this);
// oleClientSite
hret = m_clientSite.QueryInterface(
IID_IOleClientSite, (IDispatch *) frame);
wxASSERT(SUCCEEDED(hret));
// adviseSink
wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) frame);
wxASSERT(adviseSink.Ok());
// Get Dispatch interface
hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX);
//
// SETUP TYPEINFO AND ACTIVEX EVENTS
//
// get type info via class info
wxAutoIProvideClassInfo classInfo(IID_IProvideClassInfo, m_ActiveX);
wxASSERT(classInfo.Ok());
// type info
wxAutoITypeInfo typeInfo;
hret = classInfo->GetClassInfo(typeInfo.GetRef());
wxASSERT(typeInfo.Ok());
// TYPEATTR
TYPEATTR *ta = NULL;
hret = typeInfo->GetTypeAttr(&ta);
wxASSERT(ta);
// this should be a TKIND_COCLASS
wxASSERT(ta->typekind == TKIND_COCLASS);
// iterate contained interfaces
for (int i = 0; i < ta->cImplTypes; i++)
{
HREFTYPE rt = 0;
// get dispatch type info handle
hret = typeInfo->GetRefTypeOfImplType(i, &rt);
if (! SUCCEEDED(hret))
continue;
// get dispatch type info interface
wxAutoITypeInfo ti;
hret = typeInfo->GetRefTypeInfo(rt, ti.GetRef());
if (! ti.Ok())
continue;
// check if default event sink
bool defInterface = false;
bool defEventSink = false;
int impTypeFlags = 0;
typeInfo->GetImplTypeFlags(i, &impTypeFlags);
if (impTypeFlags & IMPLTYPEFLAG_FDEFAULT)
{
if (impTypeFlags & IMPLTYPEFLAG_FSOURCE)
{
// WXOLE_TRACEOUT("Default Event Sink");
defEventSink = true;
if (impTypeFlags & IMPLTYPEFLAG_FDEFAULTVTABLE)
{
// WXOLE_TRACEOUT("*ERROR* - Default Event Sink is via vTable");
defEventSink = false;
wxFAIL_MSG(wxT("Default event sink is in vtable!"));
}
}
else
{
// WXOLE_TRACEOUT("Default Interface");
defInterface = true;
}
}
// wxAutoOleInterface<> assumes a ref has already been added
// TYPEATTR
TYPEATTR *ta = NULL;
hret = ti->GetTypeAttr(&ta);
wxASSERT(ta);
if (ta->typekind == TKIND_DISPATCH)
{
// WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str());
if (defEventSink)
{
wxAutoIConnectionPoint cp;
DWORD adviseCookie = 0;
wxAutoIConnectionPointContainer cpContainer(IID_IConnectionPointContainer, m_ActiveX);
wxASSERT( cpContainer.Ok());
HRESULT hret =
cpContainer->FindConnectionPoint(ta->guid, cp.GetRef());
wxASSERT ( SUCCEEDED(hret));
IDispatch* disp;
frame->QueryInterface(IID_IDispatch, (void**)&disp);
hret = cp->Advise(new wxActiveXEvents(this, ta->guid),
&adviseCookie);
wxASSERT_MSG( SUCCEEDED(hret),
wxString::Format(wxT("Cannot connect!\nHRESULT:%X"), (unsigned int)hret)
);
}
}
ti->ReleaseTypeAttr(ta);
}
// free
typeInfo->ReleaseTypeAttr(ta);
//
// END
//
// Get IOleObject interface
hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
wxASSERT(SUCCEEDED(hret));
// get IViewObject Interface
hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX);
wxASSERT(SUCCEEDED(hret));
// document advise
m_docAdviseCookie = 0;
hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
// TODO:Needed?
// hret = m_viewObject->SetAdvise(DVASPECT_CONTENT, 0, adviseSink);
m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
OleSetContainedObject(m_oleObject, TRUE);
OleRun(m_oleObject);
// Get IOleInPlaceObject interface
hret = m_oleInPlaceObject.QueryInterface(
IID_IOleInPlaceObject, m_ActiveX);
wxASSERT(SUCCEEDED(hret));
// status
DWORD dwMiscStatus;
m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
wxASSERT(SUCCEEDED(hret));
// set client site first ?
if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
m_oleObject->SetClientSite(m_clientSite);
// stream init
wxAutoIPersistStreamInit
pPersistStreamInit(IID_IPersistStreamInit, m_oleObject);
if (pPersistStreamInit.Ok())
{
hret = pPersistStreamInit->InitNew();
}
if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
m_oleObject->SetClientSite(m_clientSite);
RECT posRect;
::GetClientRect((HWND)m_realparent->GetHWND(), &posRect);
m_oleObjectHWND = 0;
if (m_oleInPlaceObject.Ok())
{
hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
if (SUCCEEDED(hret))
::SetActiveWindow(m_oleObjectHWND);
}
if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
{
if (posRect.right > 0 && posRect.bottom > 0 &&
m_oleInPlaceObject.Ok())
m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL,
m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect);
hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
(HWND)m_realparent->GetHWND(), &posRect);
}
if (! m_oleObjectHWND && m_oleInPlaceObject.Ok())
{
hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
}
if (m_oleObjectHWND)
{
::SetActiveWindow(m_oleObjectHWND);
::ShowWindow(m_oleObjectHWND, SW_SHOW);
this->AssociateHandle(m_oleObjectHWND);
this->Reparent(m_realparent);
wxWindow* pWnd = m_realparent;
int id = m_realparent->GetId();
pWnd->Connect(id, wxEVT_SIZE,
wxSizeEventHandler(wxActiveXContainer::OnSize), 0, this);
// this->Connect(GetId(), wxEVT_PAINT,
// wxPaintEventHandler(wxActiveXContainer::OnPaint), 0, this);
pWnd->Connect(id, wxEVT_SET_FOCUS,
wxFocusEventHandler(wxActiveXContainer::OnSetFocus), 0, this);
pWnd->Connect(id, wxEVT_KILL_FOCUS,
wxFocusEventHandler(wxActiveXContainer::OnKillFocus), 0, this);
}
}
//---------------------------------------------------------------------------
// wxActiveXContainer::OnSize
//
// Called when the parent is resized - we need to do this to actually
// move the ActiveX control to where the parent is
//---------------------------------------------------------------------------
void wxActiveXContainer::OnSize(wxSizeEvent& event)
{
int w, h;
GetParent()->GetClientSize(&w, &h);
RECT posRect;
posRect.left = 0;
posRect.top = 0;
posRect.right = w;
posRect.bottom = h;
if (w <= 0 && h <= 0)
return;
// extents are in HIMETRIC units
if (m_oleObject.Ok())
{
m_oleObject->DoVerb(OLEIVERB_HIDE, 0, m_clientSite, 0,
(HWND)m_realparent->GetHWND(), &posRect);
SIZEL sz = {w, h};
PixelsToHimetric(sz);
SIZEL sz2;
m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
if (sz2.cx != sz.cx || sz.cy != sz2.cy)
m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
(HWND)m_realparent->GetHWND(), &posRect);
}
if (m_oleInPlaceObject.Ok())
m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
event.Skip();
}
//---------------------------------------------------------------------------
// wxActiveXContainer::OnPaint
//
// Called when the parent is resized - repaints the ActiveX control
//---------------------------------------------------------------------------
void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxPaintDC dc(this);
// Draw only when control is windowless or deactivated
if (m_viewObject)
{
int w, h;
GetParent()->GetSize(&w, &h);
RECT posRect;
posRect.left = 0;
posRect.top = 0;
posRect.right = w;
posRect.bottom = h;
#if !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
#else
::InvalidateRect(m_oleObjectHWND, NULL, false);
#endif
RECTL *prcBounds = (RECTL *) &posRect;
m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
(HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
}
}
//---------------------------------------------------------------------------
// wxActiveXContainer::OnSetFocus
//
// Called when the focus is set on the parent - activates the activex control
//---------------------------------------------------------------------------
void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
{
if (m_oleInPlaceActiveObject.Ok())
m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
event.Skip();
}
//---------------------------------------------------------------------------
// wxActiveXContainer::OnKillFocus
//
// Called when the focus is killed on the parent -
// deactivates the activex control
//---------------------------------------------------------------------------
void wxActiveXContainer::OnKillFocus(wxFocusEvent& event)
{
if (m_oleInPlaceActiveObject.Ok())
m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
event.Skip();
}
#endif
// __WINE__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -