📄 atlctl.h
字号:
ATLASSERT(pIPO != NULL);
if (m_hWndCD)
{
if (m_spClientSite)
m_spClientSite->OnShowWindow(FALSE);
}
if (m_bInPlaceActive)
{
HRESULT hr = pIPO->InPlaceDeactivate();
if (FAILED(hr))
return hr;
ATLASSERT(!m_bInPlaceActive);
}
if (m_hWndCD)
{
ATLTRACE2(atlTraceControls,2,_T("Destroying Window\n"));
if (::IsWindow(m_hWndCD))
DestroyWindow(m_hWndCD);
m_hWndCD = NULL;
}
// handle the save flag.
//
if ((dwSaveOption == OLECLOSE_SAVEIFDIRTY ||
dwSaveOption == OLECLOSE_PROMPTSAVE) && m_bRequiresSave)
{
if (m_spClientSite)
m_spClientSite->SaveObject();
SendOnSave();
}
m_spInPlaceSite.Release();
m_bNegotiatedWnd = FALSE;
m_bWndLess = FALSE;
m_bInPlaceSiteEx = FALSE;
m_spAdviseSink.Release();
return S_OK;
}
inline HRESULT CComControlBase::IOleInPlaceObject_InPlaceDeactivate(void)
{
CComPtr<IOleInPlaceObject> pIPO;
ControlQueryInterface(IID_IOleInPlaceObject, (void**)&pIPO);
ATLASSERT(pIPO != NULL);
if (!m_bInPlaceActive)
return S_OK;
pIPO->UIDeactivate();
m_bInPlaceActive = FALSE;
// if we have a window, tell it to go away.
//
if (m_hWndCD)
{
ATLTRACE2(atlTraceControls,2,_T("Destroying Window\n"));
if (::IsWindow(m_hWndCD))
DestroyWindow(m_hWndCD);
m_hWndCD = NULL;
}
if (m_spInPlaceSite)
m_spInPlaceSite->OnInPlaceDeactivate();
return S_OK;
}
inline HRESULT CComControlBase::IOleInPlaceObject_UIDeactivate(void)
{
// if we're not UIActive, not much to do.
//
if (!m_bUIActive)
return S_OK;
m_bUIActive = FALSE;
// notify frame windows, if appropriate, that we're no longer ui-active.
//
CComPtr<IOleInPlaceFrame> spInPlaceFrame;
CComPtr<IOleInPlaceUIWindow> spInPlaceUIWindow;
OLEINPLACEFRAMEINFO frameInfo;
frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
RECT rcPos, rcClip;
HWND hwndParent;
// This call to GetWindow is a fix for Delphi
if (m_spInPlaceSite->GetWindow(&hwndParent) == S_OK)
{
m_spInPlaceSite->GetWindowContext(&spInPlaceFrame,
&spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
if (spInPlaceUIWindow)
spInPlaceUIWindow->SetActiveObject(NULL, NULL);
if (spInPlaceFrame)
spInPlaceFrame->SetActiveObject(NULL, NULL);
}
// we don't need to explicitly release the focus here since somebody
// else grabbing the focus is what is likely to cause us to get lose it
//
m_spInPlaceSite->OnUIDeactivate(FALSE);
return S_OK;
}
inline HRESULT CComControlBase::IOleInPlaceObject_SetObjectRects(LPCRECT prcPos,LPCRECT prcClip)
{
if (prcPos == NULL || prcClip == NULL)
return E_POINTER;
m_rcPos = *prcPos;
if (m_hWndCD)
{
// the container wants us to clip, so figure out if we really
// need to
//
RECT rcIXect;
BOOL b = IntersectRect(&rcIXect, prcPos, prcClip);
HRGN tempRgn = NULL;
if (b && !EqualRect(&rcIXect, prcPos))
{
OffsetRect(&rcIXect, -(prcPos->left), -(prcPos->top));
tempRgn = CreateRectRgnIndirect(&rcIXect);
}
SetWindowRgn(m_hWndCD, tempRgn, TRUE);
// set our control's location, but don't change it's size at all
// [people for whom zooming is important should set that up here]
//
SIZEL size = {prcPos->right - prcPos->left, prcPos->bottom - prcPos->top};
SetWindowPos(m_hWndCD, NULL, prcPos->left,
prcPos->top, size.cx, size.cy, SWP_NOZORDER | SWP_NOACTIVATE);
}
return S_OK;
}
inline HRESULT CComControlBase::IOleObject_SetExtent(DWORD dwDrawAspect, SIZEL *psizel)
{
if (dwDrawAspect != DVASPECT_CONTENT)
return DV_E_DVASPECT;
if (psizel == NULL)
return E_POINTER;
BOOL bSizeMatchesNatural =
memcmp(psizel, &m_sizeNatural, sizeof(SIZE)) == 0;
if (m_bAutoSize) //object can't do any other size
return (bSizeMatchesNatural) ? S_OK : E_FAIL;
BOOL bResized = FALSE;
if (memcmp(psizel, &m_sizeExtent, sizeof(SIZE)) != 0)
{
m_sizeExtent = *psizel;
bResized = TRUE;
}
if (m_bResizeNatural && !bSizeMatchesNatural)
{
m_sizeNatural = *psizel;
bResized = TRUE;
}
if (m_bRecomposeOnResize && bResized)
{
SendOnDataChange();
FireViewChange();
}
return S_OK;
}
inline HRESULT CComControlBase::IViewObject_Draw(DWORD dwDrawAspect, LONG lindex,
void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw,
LPCRECTL prcBounds, LPCRECTL prcWBounds)
{
ATLTRACE2(atlTraceControls,2,_T("Draw dwDrawAspect=%x lindex=%d ptd=%x hic=%x hdc=%x\n"),
dwDrawAspect, lindex, ptd, hicTargetDev, hdcDraw);
#ifdef _DEBUG
if (prcBounds == NULL)
ATLTRACE2(atlTraceControls,2,_T("\tprcBounds=NULL\n"));
else
ATLTRACE2(atlTraceControls,2,_T("\tprcBounds=%d,%d,%d,%d\n"), prcBounds->left,
prcBounds->top, prcBounds->right, prcBounds->bottom);
if (prcWBounds == NULL)
ATLTRACE2(atlTraceControls,2,_T("\tprcWBounds=NULL\n"));
else
ATLTRACE2(atlTraceControls,2,_T("\tprcWBounds=%d,%d,%d,%d\n"), prcWBounds->left,
prcWBounds->top, prcWBounds->right, prcWBounds->bottom);
#endif
if (prcBounds == NULL)
{
if (!m_bWndLess)
return E_INVALIDARG;
prcBounds = (RECTL*)&m_rcPos;
}
// support the aspects required for multi-pass drawing
switch (dwDrawAspect)
{
case DVASPECT_CONTENT:
case DVASPECT_OPAQUE:
case DVASPECT_TRANSPARENT:
break;
default:
ATLASSERT(FALSE);
return DV_E_DVASPECT;
break;
}
// make sure nobody forgets to do this
if (ptd == NULL)
hicTargetDev = NULL;
BOOL bOptimize = FALSE;
if (pvAspect && ((DVASPECTINFO *)pvAspect)->cb >= sizeof(DVASPECTINFO))
bOptimize = (((DVASPECTINFO *)pvAspect)->dwFlags & DVASPECTINFOFLAG_CANOPTIMIZE);
ATL_DRAWINFO di;
memset(&di, 0, sizeof(di));
di.cbSize = sizeof(di);
di.dwDrawAspect = dwDrawAspect;
di.lindex = lindex;
di.ptd = ptd;
di.hicTargetDev = hicTargetDev;
di.hdcDraw = hdcDraw;
di.prcBounds = prcBounds;
di.prcWBounds = prcWBounds;
di.bOptimize = bOptimize;
return OnDrawAdvanced(di);
}
inline HRESULT CComControlBase::IDataObject_GetData(FORMATETC *pformatetcIn,
STGMEDIUM *pmedium)
{
if (pmedium == NULL)
return E_POINTER;
memset(pmedium, 0, sizeof(STGMEDIUM));
ATLTRACE2(atlTraceControls,2,_T("Format = %x\n"), pformatetcIn->cfFormat);
ATLTRACE2(atlTraceControls,2,_T("TYMED = %x\n"), pformatetcIn->tymed);
if ((pformatetcIn->tymed & TYMED_MFPICT) == 0)
return DATA_E_FORMATETC;
SIZEL sizeMetric, size;
if (m_bDrawFromNatural)
sizeMetric = m_sizeNatural;
else
sizeMetric = m_sizeExtent;
if (!m_bDrawGetDataInHimetric)
AtlHiMetricToPixel(&sizeMetric, &size);
else
size = sizeMetric;
RECTL rectl = {0 ,0, size.cx, size.cy};
ATL_DRAWINFO di;
memset(&di, 0, sizeof(di));
di.cbSize = sizeof(di);
di.dwDrawAspect = DVASPECT_CONTENT;
di.lindex = -1;
di.ptd = NULL;
di.hicTargetDev = NULL;
di.prcBounds = &rectl;
di.prcWBounds = &rectl;
di.bOptimize = TRUE; //we do a SaveDC/RestoreDC
di.bRectInHimetric = m_bDrawGetDataInHimetric;
// create appropriate memory metafile DC
di.hdcDraw = CreateMetaFile(NULL);
// create attribute DC according to pformatetcIn->ptd
SaveDC(di.hdcDraw);
SetWindowOrgEx(di.hdcDraw, 0, 0, NULL);
SetWindowExtEx(di.hdcDraw, rectl.right, rectl.bottom, NULL);
OnDrawAdvanced(di);
RestoreDC(di.hdcDraw, -1);
HMETAFILE hMF = CloseMetaFile(di.hdcDraw);
if (hMF == NULL)
return E_UNEXPECTED;
HGLOBAL hMem=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(METAFILEPICT));
if (NULL==hMem)
{
DeleteMetaFile(hMF);
return ResultFromScode(STG_E_MEDIUMFULL);
}
LPMETAFILEPICT pMF=(LPMETAFILEPICT)GlobalLock(hMem);
pMF->hMF=hMF;
pMF->mm=MM_ANISOTROPIC;
pMF->xExt=sizeMetric.cx;
pMF->yExt=sizeMetric.cy;
GlobalUnlock(hMem);
pmedium->tymed = TYMED_MFPICT;
pmedium->hGlobal = hMem;
pmedium->pUnkForRelease = NULL;
return S_OK;
}
inline HRESULT CComControlBase::FireViewChange()
{
if (m_bInPlaceActive)
{
// Active
if (m_hWndCD != NULL)
::InvalidateRect(m_hWndCD, NULL, TRUE); // Window based
else if (m_spInPlaceSite != NULL)
m_spInPlaceSite->InvalidateRect(NULL, TRUE); // Windowless
}
else // Inactive
SendOnViewChange(DVASPECT_CONTENT);
return S_OK;
}
inline void CComControlBase::GetZoomInfo(ATL_DRAWINFO& di)
{
const RECTL& rcPos = *di.prcBounds;
SIZEL sizeDen;
if (m_bDrawFromNatural)
sizeDen = m_sizeNatural;
else
sizeDen = m_sizeExtent;
if (!di.bRectInHimetric)
AtlHiMetricToPixel(&sizeDen, &sizeDen);
SIZEL sizeNum = {rcPos.right-rcPos.left, rcPos.bottom-rcPos.top};
di.ZoomNum.cx = sizeNum.cx;
di.ZoomNum.cy = sizeNum.cy;
di.ZoomDen.cx = sizeDen.cx;
di.ZoomDen.cy = sizeDen.cy;
if (sizeDen.cx == 0 || sizeDen.cy == 0 ||
sizeNum.cx == 0 || sizeNum.cy == 0)
{
di.ZoomNum.cx = di.ZoomNum.cy = di.ZoomDen.cx = di.ZoomDen.cy = 1;
di.bZoomed = FALSE;
}
else if (sizeNum.cx != sizeDen.cx || sizeNum.cy != sizeDen.cy)
di.bZoomed = TRUE;
else
di.bZoomed = FALSE;
}
inline HRESULT CComControlBase::OnDrawAdvanced(ATL_DRAWINFO& di)
{
BOOL bDeleteDC = FALSE;
if (di.hicTargetDev == NULL)
{
di.hicTargetDev = AtlCreateTargetDC(di.hdcDraw, di.ptd);
bDeleteDC = (di.hicTargetDev != di.hdcDraw);
}
RECTL rectBoundsDP = *di.prcBounds;
BOOL bMetafile = GetDeviceCaps(di.hdcDraw, TECHNOLOGY) == DT_METAFILE;
if (!bMetafile)
{
::LPtoDP(di.hicTargetDev, (LPPOINT)&rectBoundsDP, 2);
SaveDC(di.hdcDraw);
SetMapMode(di.hdcDraw, MM_TEXT);
SetWindowOrgEx(di.hdcDraw, 0, 0, NULL);
SetViewportOrgEx(di.hdcDraw, 0, 0, NULL);
di.bOptimize = TRUE; //since we save the DC we can do this
}
di.prcBounds = &rectBoundsDP;
GetZoomInfo(di);
HRESULT hRes = OnDraw(di);
if (bDeleteDC)
::DeleteDC(di.hicTargetDev);
if (!bMetafile)
RestoreDC(di.hdcDraw, -1);
return hRes;
}
inline LRESULT CComControlBase::OnPaint(UINT /* uMsg */, WPARAM wParam,
LPARAM /* lParam */, BOOL& /* lResult */)
{
RECT rc;
PAINTSTRUCT ps;
HDC hdc = (wParam != NULL) ? (HDC)wParam : ::BeginPaint(m_hWndCD, &ps);
if (hdc == NULL)
return 0;
::GetClientRect(m_hWndCD, &rc);
ATL_DRAWINFO di;
memset(&di, 0, sizeof(di));
di.cbSize = sizeof(di);
di.dwDrawAspect = DVASPECT_CONTENT;
di.lindex = -1;
di.hdcDraw = hdc;
di.prcBounds = (LPCRECTL)&rc;
OnDrawAdvanced(di);
if (wParam == NULL)
::EndPaint(m_hWndCD, &ps);
return 0;
}
template <class T, class WinBase = CWindowImpl< T > >
class ATL_NO_VTABLE CComControl : public CComControlBase, public WinBase
{
public:
CComControl() : CComControlBase(m_hWnd) {}
HRESULT FireOnRequestEdit(DISPID dispID)
{
T* pT = static_cast<T*>(this);
return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnRequestEdit(pT->GetUnknown(), dispID);
}
HRESULT FireOnChanged(DISPID dispID)
{
T* pT = static_cast<T*>(this);
return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnChanged(pT->GetUnknown(), dispID);
}
virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv)
{
T* pT = static_cast<T*>(this);
return pT->_InternalQueryInterface(iid, ppv);
}
virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos)
{
T* pT = static_cast<T*>(this);
return pT->Create(hWndParent, rcPos);
}
typedef CComControl< T, WinBase > thisClass;
BEGIN_MSG_MAP(thisClass)
MESSAGE_HANDLER(WM_PAINT, CComControlBase::OnPaint)
MESSAGE_HANDLER(WM_SETFOCUS, CComControlBase::OnSetFocus)
MESSAGE_HANDLER(WM_KILLFOCUS, CComControlBase::OnKillFocus)
MESSAGE_HANDLER(WM_MOUSEACTIVATE, CComControlBase::OnMouseActivate)
END_MSG_MAP()
};
//////////////////////////////////////////////////////////////////////////////
// CComCompositeControl
#ifndef _ATL_NO_HOSTING
template <class T>
class CComCompositeControl : public CComControl< T, CAxDialogImpl< T > >
{
public:
CComCompositeControl()
{
m_hbrBackground = NULL;
}
~CComCompositeControl()
{
DeleteObject(m_hbrBackground);
}
HRESULT AdviseSinkMap(bool bAdvise)
{
if(!bAdvise && m_hWnd == NULL)
{
// window is gone, controls are already unadvised
ATLTRACE2(atlTraceControls, 1, _T("CComCompositeControl::AdviseSinkMap called after the window was destroyed\n"));
return S_OK;
}
T* pT = static_cast<T*>(this);
return AtlAdviseSinkMap(pT, bAdvise);
}
HBRUSH m_hbrBackground;
HRESULT SetBackgroundColorFromAmbient()
{
if (m_hbrBackground != NULL)
{
DeleteObject(m_hbrBackground);
m_hbrBackground = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -