📄 occsite.cpp
字号:
ASSERT(pLockBytes != NULL);
LPSTORAGE pStorage = NULL;
if (SUCCEEDED(hr = StgCreateDocfileOnILockBytes(pLockBytes,
STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0,
&pStorage)))
{
ASSERT(pStorage != NULL);
hr = pPersStg->InitNew(pStorage);
pStorage->Release();
}
pLockBytes->Release();
}
}
else if (bStorage)
{
// copy data to an HGLOBAL, so we can build an IStorage on it
UINT cb = pFile->GetLength();
HGLOBAL hGlobal;
BYTE* pbData;
if (((hGlobal = GlobalAlloc(GMEM_FIXED, cb)) != NULL) &&
((pbData = (BYTE*)GlobalLock(hGlobal)) != NULL))
{
pFile->Read(pbData, cb);
GlobalUnlock(hGlobal);
}
else
{
hr = E_OUTOFMEMORY;
hGlobal = NULL;
}
// open an IStorage on the data and pass it to Load
LPLOCKBYTES pLockBytes = NULL;
if ((hGlobal != NULL) &&
SUCCEEDED(hr = CreateILockBytesOnHGlobal(hGlobal, TRUE,
&pLockBytes)))
{
ASSERT(pLockBytes != NULL);
LPSTORAGE pStorage = NULL;
if (SUCCEEDED(hr = StgOpenStorageOnILockBytes(pLockBytes, NULL,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage)))
{
ASSERT(pStorage != NULL);
hr = pPersStg->Load(pStorage);
pStorage->Release();
}
pLockBytes->Release();
}
}
else
{
hr = E_UNEXPECTED;
}
pPersStg->Release();
if (FAILED(hr))
{
TRACE1("InitNew or Load on OLE control %ls failed.\n", wszClsid);
TRACE1(">>> Result code: 0x%08lx\n", hr);
goto CreateOrLoadFailed;
}
}
else
{
TRACE1("Persistence not supported on OLE control %ls.\n", wszClsid);
TRACE1(">>> Result code: 0x%08lx\n", hr);
goto CreateOrLoadFailed;
}
if (!bQuickActivated)
{
// set client site last, if appropriate
if (!(m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
{
if (FAILED(hr = m_pObject->SetClientSite(&m_xOleClientSite)))
{
TRACE1("SetClientSite on OLE control %ls failed.\n", wszClsid);
TRACE1(">>> Result code: 0x%08lx\n", hr);
goto CreateOrLoadFailed;
}
}
}
CreateOrLoadFailed:
if (FAILED(hr) && (m_pObject != NULL))
{
m_pObject->Close(OLECLOSE_NOSAVE);
m_pObject->Release();
m_pObject = NULL;
}
if (pPersMem != NULL)
pPersMem->Release();
if (bQuickActivated && SUCCEEDED(hr))
hr = S_QUICKACTIVATED;
return hr;
}
UINT COleControlSite::GetID()
{
return m_nID;
}
HRESULT COleControlSite::DoVerb(LONG nVerb, LPMSG lpMsg)
{
return m_pObject->DoVerb(nVerb, lpMsg, &m_xOleClientSite, 0,
m_pCtrlCont->m_pWnd->m_hWnd, m_rect);
}
BOOL COleControlSite::IsDefaultButton()
{
return ((m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON) &&
(m_dwStyle & BS_DEFPUSHBUTTON));
}
DWORD COleControlSite::GetDefBtnCode()
{
if (m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON)
return (m_dwStyle & BS_DEFPUSHBUTTON) ?
DLGC_DEFPUSHBUTTON :
DLGC_UNDEFPUSHBUTTON;
else
return 0;
}
void COleControlSite::SetDefaultButton(BOOL bDefault)
{
if (!(m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON))
return;
if (((m_dwStyle & BS_DEFPUSHBUTTON) != 0) == bDefault)
return;
m_dwStyle ^= BS_DEFPUSHBUTTON;
// Notify control that its "defaultness" has changed.
LPOLECONTROL pOleCtl = NULL;
if (SUCCEEDED(m_pObject->QueryInterface(IID_IOleControl,
(LPVOID*)&pOleCtl)))
{
ASSERT(pOleCtl != NULL);
pOleCtl->OnAmbientPropertyChange(DISPID_AMBIENT_DISPLAYASDEFAULT);
pOleCtl->Release();
}
}
DWORD COleControlSite::ConnectSink(REFIID iid, LPUNKNOWN punkSink)
{
ASSERT(m_pObject != NULL);
LPCONNECTIONPOINTCONTAINER pConnPtCont;
if ((m_pObject != NULL) &&
SUCCEEDED(m_pObject->QueryInterface(IID_IConnectionPointContainer,
(LPVOID*)&pConnPtCont)))
{
ASSERT(pConnPtCont != NULL);
LPCONNECTIONPOINT pConnPt = NULL;
DWORD dwCookie = 0;
if (SUCCEEDED(pConnPtCont->FindConnectionPoint(iid, &pConnPt)))
{
ASSERT(pConnPt != NULL);
pConnPt->Advise(punkSink, &dwCookie);
pConnPt->Release();
}
pConnPtCont->Release();
return dwCookie;
}
return 0;
}
void COleControlSite::DisconnectSink(REFIID iid, DWORD dwCookie)
{
if (dwCookie == 0 || m_pObject == NULL)
return;
LPCONNECTIONPOINTCONTAINER pConnPtCont;
if (SUCCEEDED(m_pObject->QueryInterface(IID_IConnectionPointContainer,
(LPVOID*)&pConnPtCont)))
{
ASSERT(pConnPtCont != NULL);
LPCONNECTIONPOINT pConnPt = NULL;
if (SUCCEEDED(pConnPtCont->FindConnectionPoint(iid, &pConnPt)))
{
ASSERT(pConnPt != NULL);
pConnPt->Unadvise(dwCookie);
pConnPt->Release();
}
pConnPtCont->Release();
}
}
#define IMPLTYPE_MASK \
(IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE | IMPLTYPEFLAG_FRESTRICTED)
#define IMPLTYPE_DEFAULTSOURCE \
(IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE)
BOOL COleControlSite::GetEventIID(IID* piid)
{
*piid = GUID_NULL;
ASSERT(m_pObject != NULL);
// Use IProvideClassInfo2, if control supports it.
LPPROVIDECLASSINFO2 pPCI2 = NULL;
if (SUCCEEDED(m_pObject->QueryInterface(IID_IProvideClassInfo2,
(LPVOID*)&pPCI2)))
{
ASSERT(pPCI2 != NULL);
if (SUCCEEDED(pPCI2->GetGUID(GUIDKIND_DEFAULT_SOURCE_DISP_IID, piid)))
ASSERT(!IsEqualIID(*piid, GUID_NULL));
else
ASSERT(IsEqualIID(*piid, GUID_NULL));
pPCI2->Release();
}
// Fall back on IProvideClassInfo, if IProvideClassInfo2 not supported.
LPPROVIDECLASSINFO pPCI = NULL;
if (IsEqualIID(*piid, GUID_NULL) &&
SUCCEEDED(m_pObject->QueryInterface(IID_IProvideClassInfo,
(LPVOID*)&pPCI)))
{
ASSERT(pPCI != NULL);
LPTYPEINFO pClassInfo = NULL;
if (SUCCEEDED(pPCI->GetClassInfo(&pClassInfo)))
{
ASSERT(pClassInfo != NULL);
LPTYPEATTR pClassAttr;
if (SUCCEEDED(pClassInfo->GetTypeAttr(&pClassAttr)))
{
ASSERT(pClassAttr != NULL);
ASSERT(pClassAttr->typekind == TKIND_COCLASS);
// Search for typeinfo of the default events interface.
int nFlags;
HREFTYPE hRefType;
for (unsigned int i = 0; i < pClassAttr->cImplTypes; i++)
{
if (SUCCEEDED(pClassInfo->GetImplTypeFlags(i, &nFlags)) &&
((nFlags & IMPLTYPE_MASK) == IMPLTYPE_DEFAULTSOURCE))
{
// Found it. Now look at its attributes to get IID.
LPTYPEINFO pEventInfo = NULL;
if (SUCCEEDED(pClassInfo->GetRefTypeOfImplType(i,
&hRefType)) &&
SUCCEEDED(pClassInfo->GetRefTypeInfo(hRefType,
&pEventInfo)))
{
ASSERT(pEventInfo != NULL);
LPTYPEATTR pEventAttr;
if (SUCCEEDED(pEventInfo->GetTypeAttr(&pEventAttr)))
{
ASSERT(pEventAttr != NULL);
*piid = pEventAttr->guid;
pEventInfo->ReleaseTypeAttr(pEventAttr);
}
pEventInfo->Release();
}
break;
}
}
pClassInfo->ReleaseTypeAttr(pClassAttr);
}
pClassInfo->Release();
}
pPCI->Release();
}
return (!IsEqualIID(*piid, GUID_NULL));
}
void COleControlSite::GetControlInfo()
{
memset(&m_ctlInfo, 0, sizeof(CONTROLINFO));
m_ctlInfo.cb = sizeof(CONTROLINFO);
LPOLECONTROL pOleCtl = NULL;
if (SUCCEEDED(m_pObject->QueryInterface(IID_IOleControl,
(LPVOID*)&pOleCtl)))
{
ASSERT(pOleCtl != NULL);
pOleCtl->GetControlInfo(&m_ctlInfo);
pOleCtl->Release();
}
}
BOOL COleControlSite::IsMatchingMnemonic(LPMSG lpMsg)
{
// return IsAccelerator(m_ctlInfo.hAccel, m_ctlInfo.cAccel, lpMsg, NULL);
if ((m_ctlInfo.cAccel == 0) || (m_ctlInfo.hAccel == NULL))
return FALSE;
ACCEL* pAccel = new ACCEL[m_ctlInfo.cAccel];
int cAccel = CopyAcceleratorTable(m_ctlInfo.hAccel, pAccel, m_ctlInfo.cAccel);
ASSERT(cAccel == m_ctlInfo.cAccel);
BOOL bMatch = FALSE;
for (int i = 0; i < cAccel; i++)
{
BOOL fVirt = (lpMsg->message == WM_SYSCHAR ? FALT : 0);
WORD key = LOWORD(lpMsg->wParam);
if (((pAccel[i].fVirt & ~FNOINVERT) == fVirt) &&
(pAccel[i].key == key))
{
bMatch = TRUE;
break;
}
}
delete [] pAccel;
return bMatch;
}
void COleControlSite::SendMnemonic(LPMSG lpMsg)
{
if (!(m_dwMiscStatus & OLEMISC_NOUIACTIVATE))
SetFocus();
LPOLECONTROL pOleCtl = NULL;
if (SUCCEEDED(m_pObject->QueryInterface(IID_IOleControl,
(LPVOID*)&pOleCtl)))
{
ASSERT(pOleCtl != NULL);
pOleCtl->OnMnemonic(lpMsg);
pOleCtl->Release();
}
}
void COleControlSite::FreezeEvents(BOOL bFreeze)
{
LPOLECONTROL pOleCtl = NULL;
if (SUCCEEDED(m_pObject->QueryInterface(IID_IOleControl,
(LPVOID*)&pOleCtl)))
{
ASSERT(pOleCtl != NULL);
pOleCtl->FreezeEvents(bFreeze);
pOleCtl->Release();
}
}
void COleControlSite::AttachWindow()
{
HWND hWnd = NULL;
if (SUCCEEDED(m_pInPlaceObject->GetWindow(&hWnd)))
{
ASSERT(hWnd != NULL);
if (m_hWnd != hWnd)
{
m_hWnd = hWnd;
if (m_pWndCtrl != NULL)
{
ASSERT(m_pWndCtrl->m_hWnd == NULL); // Window already attached?
m_pWndCtrl->Attach(m_hWnd);
ASSERT(m_pWndCtrl->m_pCtrlSite == NULL ||
m_pWndCtrl->m_pCtrlSite == this);
m_pWndCtrl->m_pCtrlSite = this;
}
}
}
}
void COleControlSite::DetachWindow()
{
m_hWnd = NULL;
if (m_pWndCtrl != NULL)
{
if (m_pWndCtrl->m_hWnd != NULL)
{
WNDPROC* lplpfn = m_pWndCtrl->GetSuperWndProcAddr();
ASSERT(lplpfn != NULL);
if (::IsWindow(m_pWndCtrl->m_hWnd) && *lplpfn != NULL)
m_pWndCtrl->UnsubclassWindow();
m_pWndCtrl->Detach();
}
m_pWndCtrl->m_pCtrlSite = NULL;
}
}
BOOL COleControlSite::OnEvent(AFX_EVENT* pEvent)
{
// If this control has a proxy CWnd, look for a matching ON_*_REFLECT
// entry for this event in its event map.
if ((m_pWndCtrl != NULL) &&
m_pWndCtrl->OnCmdMsg(m_nID, CN_EVENT, pEvent, NULL))
{
return TRUE;
}
// Proxy CWnd isn't interested, so pass the event along to the container.
return m_pCtrlCont->m_pWnd->OnCmdMsg(m_nID, CN_EVENT, pEvent, NULL);
}
/////////////////////////////////////////////////////////////////////////////
// invoke helpers
void COleControlSite::InvokeHelperV(DISPID dwDispID, WORD wFlags,
VARTYPE vtRet, void* pvRet, const BYTE* pbParamInfo, va_list argList)
{
if (m_dispDriver.m_lpDispatch == NULL)
{
// no dispatch pointer yet; find it now
LPDISPATCH pDispatch;
if ((m_pObject != NULL) &&
SUCCEEDED(m_pObject->QueryInterface(IID_IDispatch,
(LPVOID*)&pDispatch)))
{
ASSERT(pDispatch != NULL);
m_dispDriver.AttachDispatch(pDispatch);
}
}
if (m_dispDriver.m_lpDispatch == NULL)
{
// couldn't find dispatch pointer
TRACE0("Warning: control has no IDispatch interface.");
return;
}
// delegate call to m_dispDriver
m_dispDriver.InvokeHelperV(dwDispID, wFlags, vtRet, pvRet, pbParamInfo,
argList);
}
void COleControlSite::SetPropertyV(DISPID dwDispID, VARTYPE vtProp, va_list argList)
{
BYTE rgbParams[2];
if (vtProp & VT_BYREF)
{
vtProp &= ~VT_BYREF;
vtProp |= VT_MFCBYREF;
}
#if !defined(_UNICODE) && !defined(OLE2ANSI)
if (vtProp == VT_BSTR)
vtProp = VT_BSTRA;
#endif
WORD wFlags;
if (vtProp & VT_MFCFORCEPUTREF)
{
wFlags = DISPATCH_PROPERTYPUTREF;
vtProp &= ~VT_MFCFORCEPUTREF;
}
else
{
if (vtProp == VT_DISPATCH)
wFlags = DISPATCH_PROPERTYPUTREF;
else
wFlags = DISPATCH_PROPERTYPUT;
}
rgbParams[0] = (BYTE)vtProp;
rgbParams[1] = 0;
InvokeHelperV(dwDispID, wFlags, VT_EMPTY, NULL, rgbParams, argList);
}
void AFX_CDECL COleControlSite::InvokeHelper(DISPID dwDispID, WORD wFlags, VARTYPE vtRet,
void* pvRet, const BYTE* pbParamInfo, ...)
{
va_list argList;
va_start(argList, pbParamInfo);
InvokeHelperV(dwDispID, wFlags, vtRet, pvRet, pbParamInfo, argList);
va_end(argList);
}
void COleControlSite::GetProperty(DISPID dwDispID, VARTYPE vtProp,
void* pvProp) const
{
const_cast<COleControlSite*>(this)->InvokeHelper(dwDispID,
DISPATCH_PROPERTYGET, vtProp, pvProp, NULL);
}
void AFX_CDECL COleControlSite::SetProperty(DISPID dwDispID, VARTYPE vtProp, ...)
{
va_list argList; // really only one arg, but...
va_start(argList, vtProp);
SetPropertyV(dwDispID, vtProp, argList);
va_end(argList);
}
BOOL AFX_CDECL COleControlSite::SafeSetProperty(DISPID dwDispID, VARTYPE vtProp, ...)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -