home *** CD-ROM | disk | FTP | other *** search
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
-
- #include "stdafx.h"
-
- #ifdef AFXCTL_CORE1_SEG
- #pragma code_seg(AFXCTL_CORE1_SEG)
- #endif
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- #define new DEBUG_NEW
-
- #define _afxTrackingMenu (AfxGetThreadState()->m_hTrackingMenu)
-
- /////////////////////////////////////////////////////////////////////////////
- // Special WM_PAINT message handler that includes the HDC
-
- #define ON_WM_PAINT_SPECIAL() \
- { WM_PAINT, 0, 0, 0, AfxSig_vD, \
- (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(CDC*))&OnPaint },
-
- /////////////////////////////////////////////////////////////////////////////
- // Window to serve as "parking space" for not-yet-activated subclassed controls
-
- AFX_MODULE_STATE* AFXAPI _AfxGetOleModuleState();
-
- AFX_STATIC HWND AFXAPI _AfxGetParkingWindow()
- {
- _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
- ASSERT(pThreadState != NULL);
- if (pThreadState->m_pWndPark == NULL)
- {
- AFX_MANAGE_STATE(_AfxGetOleModuleState());
- CWnd* pWndTmp = NULL;
-
- TRY
- {
- #ifdef _DEBUG
- HWND hWndActive = ::GetActiveWindow();
- #endif
- pWndTmp = new CParkingWnd;
- ASSERT(pWndTmp->m_hWnd != NULL);
- #ifdef _DEBUG
- ASSERT(hWndActive == ::GetActiveWindow());
- #endif
- }
- CATCH_ALL(e)
- {
- if (pWndTmp)
- delete pWndTmp;
- pWndTmp = NULL;
- }
- END_CATCH_ALL
-
- pThreadState->m_pWndPark = pWndTmp;
- }
- return pThreadState->m_pWndPark->GetSafeHwnd();
- }
-
- AFX_STATIC void AFXAPI _AfxReleaseParkingWindow()
- {
- _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
- ASSERT(pThreadState != NULL);
- ASSERT(pThreadState->m_nCtrlRef == 0);
- if (pThreadState->m_pWndPark != NULL)
- {
- AFX_MANAGE_STATE(_AfxGetOleModuleState());
-
- ASSERT(pThreadState->m_pWndPark->m_hWnd != NULL);
- ASSERT(::GetWindow(pThreadState->m_pWndPark->m_hWnd, GW_CHILD) == NULL);
- HWND hWnd = pThreadState->m_pWndPark->Detach();
- ::SetWindowLong(hWnd, GWL_WNDPROC, (long)DefWindowProc);
- ::DestroyWindow(hWnd);
- delete pThreadState->m_pWndPark;
- pThreadState->m_pWndPark = NULL;
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControl interface map
-
- BEGIN_INTERFACE_MAP(COleControl, CCmdTarget)
- INTERFACE_PART(COleControl, IID_IQuickActivate, QuickActivate)
- INTERFACE_PART(COleControl, IID_IOleObject, OleObject)
- INTERFACE_PART(COleControl, IID_IViewObjectEx, ViewObject)
- INTERFACE_PART(COleControl, IID_IPersistMemory, PersistMemory)
- INTERFACE_PART(COleControl, IID_IPersistStreamInit, PersistStreamInit)
- INTERFACE_PART(COleControl, IID_IProvideClassInfo2, ProvideClassInfo)
- INTERFACE_PART(COleControl, IID_IConnectionPointContainer, ConnPtContainer)
- INTERFACE_PART(COleControl, IID_IOleControl, OleControl)
- INTERFACE_PART(COleControl, IID_IOleInPlaceObject, OleInPlaceObject)
- INTERFACE_PART(COleControl, IID_IOleInPlaceObjectWindowless, OleInPlaceObject)
- INTERFACE_PART(COleControl, IID_IOleInPlaceActiveObject, OleInPlaceActiveObject)
- INTERFACE_PART(COleControl, IID_IDispatch, Dispatch)
- INTERFACE_PART(COleControl, IID_IOleCache, OleCache)
- INTERFACE_PART(COleControl, IID_IViewObject, ViewObject)
- INTERFACE_PART(COleControl, IID_IViewObject2, ViewObject)
- INTERFACE_PART(COleControl, IID_IDataObject, DataObject)
- INTERFACE_PART(COleControl, IID_IPersistPropertyBag, PersistPropertyBag)
- INTERFACE_PART(COleControl, IID_ISpecifyPropertyPages, SpecifyPropertyPages)
- INTERFACE_PART(COleControl, IID_IPerPropertyBrowsing, PerPropertyBrowsing)
- INTERFACE_PART(COleControl, IID_IProvideClassInfo, ProvideClassInfo)
- INTERFACE_PART(COleControl, IID_IPersist, PersistStorage)
- INTERFACE_PART(COleControl, IID_IPersistStorage, PersistStorage)
- END_INTERFACE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControl event map
-
- const AFX_EVENTMAP COleControl::eventMap = { NULL, NULL };
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControl message map
-
- BEGIN_MESSAGE_MAP(COleControl, CWnd)
- ON_WM_PAINT_SPECIAL()
- //{{AFX_MSG_MAP(COleControl)
- ON_WM_ERASEBKGND()
- ON_WM_NCCREATE()
- ON_WM_NCCALCSIZE()
- ON_WM_SIZE()
- ON_WM_MOVE()
- ON_WM_SHOWWINDOW()
- ON_WM_CREATE()
- ON_MESSAGE(WM_SETTEXT, OnSetText)
- ON_WM_NCPAINT()
- ON_WM_DESTROY()
- ON_WM_ENTERIDLE()
- ON_WM_KILLFOCUS()
- ON_WM_SETFOCUS()
- ON_MESSAGE(OCM_CTLCOLORBTN, OnOcmCtlColorBtn)
- ON_MESSAGE(OCM_CTLCOLORDLG, OnOcmCtlColorDlg)
- ON_MESSAGE(OCM_CTLCOLOREDIT, OnOcmCtlColorEdit)
- ON_MESSAGE(OCM_CTLCOLORLISTBOX, OnOcmCtlColorListBox)
- ON_MESSAGE(OCM_CTLCOLORMSGBOX, OnOcmCtlColorMsgBox)
- ON_MESSAGE(OCM_CTLCOLORSCROLLBAR, OnOcmCtlColorScrollBar)
- ON_MESSAGE(OCM_CTLCOLORSTATIC, OnOcmCtlColorStatic)
- ON_WM_MOUSEMOVE()
- ON_WM_NCHITTEST()
- ON_WM_MOUSEACTIVATE()
- ON_WM_NCLBUTTONDOWN()
- ON_WM_LBUTTONDOWN()
- ON_WM_LBUTTONUP()
- ON_WM_LBUTTONDBLCLK()
- ON_WM_MBUTTONDOWN()
- ON_WM_MBUTTONUP()
- ON_WM_MBUTTONDBLCLK()
- ON_WM_RBUTTONDOWN()
- ON_WM_RBUTTONUP()
- ON_WM_RBUTTONDBLCLK()
- ON_WM_KEYDOWN()
- ON_WM_KEYUP()
- ON_WM_CHAR()
- ON_WM_SYSKEYDOWN()
- ON_WM_SYSKEYUP()
- ON_WM_INITMENUPOPUP()
- ON_WM_MENUSELECT()
- ON_WM_CANCELMODE()
- ON_WM_SETCURSOR()
- ON_WM_GETDLGCODE()
- ON_MESSAGE(WM_SETMESSAGESTRING, OnSetMessageString)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControl implementation
-
- COleControl::COleControl() :
- #ifdef _AFXDLL
- m_font(&m_xFontNotification)
- #else
- m_font(NULL)
- #endif
- {
- // add to parking window reference count
- _AFX_THREAD_STATE* pState = AfxGetThreadState();
- ASSERT(pState != NULL);
- ++pState->m_nCtrlRef;
-
- m_bFinalReleaseCalled = FALSE;
- m_bChangingExtent = FALSE;
- m_bUIDead = FALSE;
-
- m_pReflect = NULL;
- m_pRectTracker = NULL;
-
- m_pClientSite = NULL;
- m_pOleAdviseHolder = NULL;
- m_pDataAdviseHolder = NULL;
- m_pInPlaceSite = NULL;
- m_pInPlaceFrame = NULL;
- m_pInPlaceDoc = NULL;
- m_pControlSite = NULL;
-
- m_pDefIUnknown = NULL;
- m_pDefIPersistStorage = NULL;
- m_pDefIViewObject = NULL;
- m_pDefIOleCache = NULL;
- m_pAdviseInfo = NULL;
-
- m_pUIActiveInfo = NULL;
- m_nIDTracking = 0;
- m_nIDLastMessage = 0;
- m_bAutoMenuEnable = TRUE; // auto enable on by default
-
- m_bInPlaceActive = FALSE;
- m_bUIActive = FALSE;
- m_bPendingUIActivation = FALSE;
- #ifdef _AFXDLL
- m_bOpen = FALSE;
- m_pWndOpenFrame = NULL;
- #endif
- m_bInitialized = FALSE;
-
- m_dwVersionLoaded = 0;
-
- m_bModified = TRUE;
-
- m_iButtonState = 0;
- m_iDblClkState = 0;
-
- m_sBorderStyle = 0;
- m_sAppearance = 0;
- m_bEnabled = TRUE;
- m_lReadyState = READYSTATE_COMPLETE;
-
- m_hFontPrev = NULL;
-
- m_cEventsFrozen = 0;
-
- m_bConvertVBX = FALSE;
-
- m_pSimpleFrameSite = NULL;
- m_bSimpleFrame = FALSE;
-
- m_ptOffset.x = 0;
- m_ptOffset.y = 0;
-
- m_bNoRedraw = FALSE;
-
- m_bInPlaceSiteEx = FALSE;
- m_bInPlaceSiteWndless = FALSE;
-
- m_bOptimizedDraw = FALSE;
-
- m_bDataPathPropertiesLoaded = TRUE;
-
- SetInitialSize(100, 50);
-
- // Wire up aggregation support
- EnableAggregation();
-
- // Wire up IDispatch support
- EnableAutomation();
-
- // Wire up connection map support
- EnableConnections();
-
- m_pDataSource = NULL;
-
- AfxOleLockApp();
- }
-
-
- COleControl::~COleControl()
- {
- if (m_pDataSource != NULL)
- delete m_pDataSource;
-
- if (m_pReflect != NULL)
- m_pReflect->DestroyWindow();
-
- #ifdef _AFXDLL
- if (m_pWndOpenFrame != NULL)
- m_pWndOpenFrame->DestroyWindow();
- #endif
-
- ReleaseCaches();
-
- if (m_hWnd != NULL)
- DestroyWindow();
-
- // release parking window if reference count is now zero
- _AFX_THREAD_STATE* pState = AfxGetThreadState();
- ASSERT(pState != NULL);
- if (pState->m_nCtrlRef == 0 || --pState->m_nCtrlRef == 0)
- _AfxReleaseParkingWindow();
-
- AfxOleUnlockApp();
- }
-
- void COleControl::ReleaseCaches()
- {
- RELEASE(m_pClientSite);
- RELEASE(m_pOleAdviseHolder);
- RELEASE(m_pDataAdviseHolder);
- RELEASE(m_pInPlaceSite);
- RELEASE(m_pInPlaceFrame);
- RELEASE(m_pInPlaceDoc);
- RELEASE(m_pControlSite);
- RELEASE(m_pSimpleFrameSite);
-
- LPUNKNOWN pUnk = GetControllingUnknown();
-
- InterlockedIncrement(&m_dwRef); // Keep ref count from going to zero again.
-
- if (m_pDefIPersistStorage != NULL)
- {
- pUnk->AddRef();
- RELEASE(m_pDefIPersistStorage);
- }
-
- if (m_pDefIViewObject != NULL)
- {
- pUnk->AddRef();
- RELEASE(m_pDefIViewObject);
- }
-
- if (m_pDefIOleCache != NULL)
- {
- pUnk->AddRef();
- RELEASE(m_pDefIOleCache);
- }
-
- if (m_pAdviseInfo != NULL)
- {
- RELEASE(m_pAdviseInfo->m_pAdvSink);
- delete m_pAdviseInfo;
- m_pAdviseInfo = NULL;
- }
-
- RELEASE(m_pDefIUnknown);
- InterlockedDecrement(&m_dwRef);
- }
-
- void COleControl::OnFinalRelease()
- {
- if (!m_bFinalReleaseCalled)
- {
- m_bFinalReleaseCalled = TRUE;
-
- ReleaseCaches();
-
- if (m_hWnd != NULL)
- DestroyWindow();
-
- CCmdTarget::OnFinalRelease();
- }
- }
-
- LPUNKNOWN COleControl::GetInterfaceHook(const void* piid)
- {
- ASSERT_POINTER(piid, IID);
-
- if (m_piidPrimary != NULL && _AfxIsEqualGUID(*m_piidPrimary, *(IID*)piid))
- {
- return GetInterface((void*)&IID_IDispatch);
- }
-
- if (_AfxIsEqualGUID(IID_IPointerInactive, *(IID*)piid) &&
- (GetControlFlags() & pointerInactive))
- {
- return &m_xPointerInactive;
- }
-
- return NULL;
- }
-
- void COleControl::SetInitialSize(int cx, int cy)
- {
- SIZEL szlPixels;
- SIZEL szlHimetric;
- szlPixels.cx = cx;
- szlPixels.cy = cy;
- _AfxXformSizeInPixelsToHimetric(NULL, &szlPixels, &szlHimetric);
- m_cxExtent = szlHimetric.cx;
- m_cyExtent = szlHimetric.cy;
- }
-
- BOOL COleControl::GetDispatchIID(IID* pIID)
- {
- if (m_piidPrimary != NULL)
- *pIID = *m_piidPrimary;
-
- return (m_piidPrimary != NULL);
- }
-
- void COleControl::InitializeIIDs(const IID* piidPrimary, const IID* piidEvents)
- {
- m_piidPrimary = piidPrimary;
- m_piidEvents = piidEvents;
-
- EnableTypeLib();
-
- // Initialize the masks for stock events and properties.
- InitStockEventMask();
- InitStockPropMask();
-
- #ifdef _DEBUG
-
- // Verify that the type library contains all the correct information.
- // If any of the following assertions fail, carefully check the IDs
- // in the control's .CPP file against those in its .ODL file.
-
- LPTYPEINFO pTypeInfo;
- HRESULT hr;
- CLSID clsid;
-
- GetClassID(&clsid);
- if (SUCCEEDED(hr = GetTypeInfoOfGuid(0, clsid, &pTypeInfo)))
- RELEASE(pTypeInfo);
-
- ASSERT(SUCCEEDED(hr)); // Class ID may be corrupted
-
- if (SUCCEEDED(hr = GetTypeInfoOfGuid(0, *m_piidPrimary, &pTypeInfo)))
- RELEASE(pTypeInfo);
-
- ASSERT(SUCCEEDED(hr)); // Primary dispatch interface ID may be corrupted
-
- if (SUCCEEDED(hr = GetTypeInfoOfGuid(0, *m_piidEvents, &pTypeInfo)))
- RELEASE(pTypeInfo);
-
- ASSERT(SUCCEEDED(hr)); // Event dispatch interface ID may be corrupted
-
- #endif
- }
-
- #ifdef _DEBUG
-
- void COleControl::AssertValid() const
- {
- CWnd::AssertValid();
- }
-
- void AFXAPI _AfxDumpGuid(CDumpContext& dc, const GUID* pGuid)
- {
- USES_CONVERSION;
-
- if (pGuid == NULL)
- {
- dc << "(NULL)";
- return;
- }
-
- OLECHAR szGuid[40];
- ::StringFromGUID2(*pGuid, szGuid, 40);
- dc << OLE2CT(szGuid);
- }
-
- void AFXAPI _AfxDumpHex(CDumpContext& dc, DWORD dw)
- {
- TCHAR szHex[10];
- wsprintf(szHex, _T("0x%08lx"), dw);
- dc << szHex;
- }
-
- void COleControl::Dump(CDumpContext& dc) const
- {
- CWnd::Dump(dc);
- #ifdef _AFXDLL
- dc << "\nm_pModuleState = " << m_pModuleState;
- #endif
- dc << "\nm_piidPrimary = ";
- _AfxDumpGuid(dc, m_piidPrimary);
- dc << "\nm_piidEvents = ";
- _AfxDumpGuid(dc, m_piidEvents);
- dc << "\nm_dwVersionLoaded = ";
- _AfxDumpHex(dc, m_dwVersionLoaded);
- dc << "\nm_cEventsFrozen = " << m_cEventsFrozen;
- dc << "\nm_rcPos = " << m_rcPos;
- dc << "\nm_cxExtent = " << m_cxExtent;
- dc << "\nm_cyExtent = " << m_cyExtent;
- dc << "\nm_bFinalReleaseCalled = " << m_bFinalReleaseCalled;
- dc << "\nm_bModified = " << m_bModified;
- dc << "\nm_bCountOnAmbients = " << m_bCountOnAmbients;
- dc << "\nm_iButtonState = " << m_iButtonState;
- dc << "\nm_iDblClkState = " << m_iDblClkState;
- dc << "\nm_bInPlaceActive = " << m_bInPlaceActive;
- dc << "\nm_bUIActive = " << m_bUIActive;
- dc << "\nm_bPendingUIActivation = " << m_bPendingUIActivation;
- #ifdef _AFXDLL
- dc << "\nm_bOpen = " << m_bOpen;
- #endif
- dc << "\nm_bChangingExtent = " << m_bChangingExtent;
- dc << "\nm_bConvertVBX = " << m_bConvertVBX;
- dc << "\nm_bSimpleFrame = " << m_bSimpleFrame;
- dc << "\nm_bUIDead = " << m_bUIDead;
- }
-
- #endif // _DEBUG
-
- /////////////////////////////////////////////////////////////////////////////
- // _AfxFillPSOnStack (WINBUG)
- //
- // Windows has a bug in the WM_PAINT code for the Button control. If the
- // paint is a sub-classed paint, and if the display driver is a Win3.0
- // display driver, then Windows calls IsRectEmpty, passing in the rectangle
- // from the paint structure. Since it was a sub-classed paint, and
- // BeginPaint was not called, the rectangle struct passed to IsRectEmpty is
- // uninitialized. If IsRectEmpty returned True, then the control was not
- // painted. To work around the bug, we call FillPSOnStack before calling
- // windows with the WM_PAINT. This routine fills a buffer on the stack
- // 0x80 bytes of consecutive values from 0 to 0x7f. That way, if the
- // rectangle falls anywhere within this buffer range, and the stack has not
- // been modified by other means, then IsRectEmpty will return FALSE, so that
- // the control will Paint.
-
- #define WORDBUFSIZE 0x40
-
- void AFXAPI _AfxFillPSOnStack()
- {
- // Stack hack needed on Win32s
- WORD buf[WORDBUFSIZE];
- WORD i;
- WORD pat;
-
- for (i = 0, pat = 0x0100; i < WORDBUFSIZE; i++, pat += 0x0202)
- buf[i] = pat;
- }
-
- void COleControl::DoSuperclassPaint(CDC* pDC, const CRect& rcBounds)
- {
- if (m_hWnd == NULL)
- CreateWindowForSubclassedControl();
-
- if (m_hWnd != NULL)
- {
- CRect rcClient;
- GetClientRect(&rcClient);
-
- if (rcClient.Size() != rcBounds.Size())
- {
- pDC->SetMapMode(MM_ANISOTROPIC);
- pDC->SetWindowExt(rcClient.right, rcClient.bottom);
- pDC->SetViewportExt(rcBounds.Size());
- }
- pDC->SetWindowOrg(0, 0);
- pDC->SetViewportOrg(rcBounds.left, rcBounds.top);
-
- BOOL bWin4 = afxData.bWin4;
- _AfxFillPSOnStack();
- ::CallWindowProc(
- *GetSuperWndProcAddr(),
- m_hWnd, (bWin4 ? WM_PRINT : WM_PAINT),
- (WPARAM)(pDC->m_hDC),
- (LPARAM)(bWin4 ? PRF_CHILDREN | PRF_CLIENT : 0));
- }
- }
-
- BOOL COleControl::IsSubclassedControl()
- {
- // This default implementation provides some degree of backward
- // compatibility with old controls. New subclassed controls should just
- // override IsSubclassedControl and return TRUE.
- return m_pfnSuper == NULL &&
- GetSuperWndProcAddr() != CWnd::GetSuperWndProcAddr();
- }
-
- BOOL COleControl::CreateControlWindow(HWND hWndParent, const CRect& rcPos,
- LPCRECT prcClip)
- {
- if (m_hWnd == NULL)
- {
- // If window doesn't exist, create it.
-
- // Test if:
- // we're not subclassing a Windows control, or
- // container reflects messages for us...
-
- DWORD dwStyle = WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
- if (m_sBorderStyle)
- dwStyle |= WS_BORDER;
- if (!m_bEnabled)
- dwStyle |= WS_DISABLED;
- DWORD dwExStyle = WS_EX_NOPARENTNOTIFY;
- if (m_sAppearance)
- dwExStyle |= WS_EX_CLIENTEDGE;
-
- // we create normally if:
- // (we're not subclassing -or- the container reflects)
- // -and- the container autoclips for us
- if ((!IsSubclassedControl() || m_bMsgReflect) && m_bAutoClip)
- {
- // Just create the control's window.
- VERIFY(AfxDeferRegisterClass(AFX_WNDOLECONTROL_REG));
- CreateEx(dwExStyle, AFX_WNDOLECONTROL, m_strText, dwStyle,
- rcPos.left, rcPos.top, rcPos.Width(), rcPos.Height(),
- hWndParent, 0);
- }
- else // ...we're subclassing a Windows control.
- {
- if (m_pReflect == NULL)
- {
- // Create a window to reflect notification messages.
- m_pReflect = new CReflectorWnd;
- if (prcClip == NULL)
- prcClip = rcPos;
- if (!m_pReflect->Create(prcClip, hWndParent))
- {
- // If m_pReflect->Create failed, then m_pReflect deleted itself.
- m_pReflect = NULL;
- }
- }
- else
- {
- // Reflector window already exists... just reparent it.
- if (m_pReflect->m_hWnd != NULL)
- {
- ::SetParent(m_pReflect->m_hWnd, hWndParent);
- ::SetWindowPos(m_pReflect->m_hWnd, NULL, 0, 0, 0, 0,
- SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
- SWP_SHOWWINDOW);
- }
- }
-
- if (m_pReflect != NULL && m_pReflect->m_hWnd != NULL)
- {
- // Create the control's window.
- CreateEx(dwExStyle, NULL, m_strText, dwStyle,
- m_ptOffset.x, m_ptOffset.y, rcPos.Width(), rcPos.Height(),
- m_pReflect->m_hWnd, 0);
- if (m_hWnd == NULL)
- {
- // Window creation failed: cleanup.
- m_pReflect->DestroyWindow();
- m_pReflect = NULL;
- }
- }
- }
-
- // Set the new window's font.
- OnFontChanged();
- }
- else
- {
- // If window does exist, reparent it...
- CWnd* pWndOuter = GetOuterWindow();
- ASSERT(pWndOuter != NULL);
-
- if (::GetParent(pWndOuter->m_hWnd) != hWndParent)
- ReparentControlWindow(pWndOuter->m_hWnd, hWndParent);
-
- ::SetWindowPos(pWndOuter->m_hWnd, NULL, 0, 0, 0, 0,
- SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
- SWP_SHOWWINDOW);
-
- // And then reposition it...
- OnSetObjectRects(rcPos, prcClip);
- }
-
- ASSERT(m_hWnd != NULL);
- return (m_hWnd != NULL);
- }
-
- void COleControl::ReparentControlWindow(HWND hWndOuter, HWND hWndParent)
- {
- // can be overridden by subclass, if necessary
- ::SetParent(hWndOuter, hWndParent);
- }
-
- void COleControl::GetControlSize(int* pcx, int* pcy)
- {
- ASSERT_POINTER(pcx, int);
- ASSERT_POINTER(pcy, int);
-
- SIZEL szlHimetric;
- SIZEL szlPixels;
- szlHimetric.cx = m_cxExtent;
- szlHimetric.cy = m_cyExtent;
- _AfxXformSizeInHimetricToPixels(NULL, &szlHimetric, &szlPixels);
- *pcx = (int)szlPixels.cx;
- *pcy = (int)szlPixels.cy;
- }
-
- BOOL COleControl::SetControlSize(int cx, int cy)
- {
- SIZEL szlPixels;
- SIZEL szlHimetric;
- szlPixels.cx = cx;
- szlPixels.cy = cy;
- _AfxXformSizeInPixelsToHimetric(NULL, &szlPixels, &szlHimetric);
- return SUCCEEDED(m_xOleObject.SetExtent(DVASPECT_CONTENT, &szlHimetric));
- }
-
- BOOL COleControl::SetRectInContainer(LPCRECT lpRect)
- {
- if ((m_pInPlaceSite != NULL) && m_bInPlaceActive)
- {
- m_pInPlaceSite->OnPosRectChange(lpRect);
- return TRUE;
- }
- #ifdef _AFXDLL
- else if (m_bOpen)
- {
- ResizeOpenControl(lpRect->right - lpRect->left,
- lpRect->bottom - lpRect->top);
- return TRUE;
- }
- #endif
-
- return FALSE;
- }
-
- void COleControl::OnResetState()
- {
- CResetPropExchange px;
- DoPropExchange(&px);
- InvalidateControl();
- }
-
- #ifndef BDR_INNER
- #define BDR_INNER 0x000c
- #endif
- #ifndef BDR_OUTER
- #define BDR_OUTER 0x0003
- #endif
-
- void AFXAPI _AfxDrawBorders(CDC* pDC, CRect& rc, BOOL bBorder, BOOL bClientEdge)
- {
- if (bBorder)
- ::DrawEdge(pDC->m_hDC, &rc, (bClientEdge ? BDR_INNER : BDR_OUTER),
- BF_RECT | BF_ADJUST | (bClientEdge ? BF_FLAT : BF_MONO));
-
- if (bClientEdge)
- ::DrawEdge(pDC->m_hDC, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
- }
-
- void COleControl::DrawContent(CDC* pDC, CRect& rc)
- {
- // Map into device coordinates.
-
- pDC->LPtoDP(&rc);
- int iSaveDC = 0;
- if (! m_bOptimizedDraw)
- iSaveDC = pDC->SaveDC();
- pDC->SetViewportOrg(0, 0);
- pDC->SetWindowOrg(0, 0);
- pDC->SetMapMode(MM_TEXT);
- m_rcBounds = rc;
- if (pDC->GetDeviceCaps(TECHNOLOGY) == DT_RASDISPLAY)
- _AfxDrawBorders(pDC, rc, (m_sBorderStyle == 1), (m_sAppearance == 1));
- OnDraw(pDC, rc, rc);
- if (! m_bOptimizedDraw && iSaveDC != 0)
- pDC->RestoreDC(iSaveDC);
- }
-
- void COleControl::DrawMetafile(CDC* pDC, CRect& rc)
- {
- int iSaveDC = 0;
- if (! m_bOptimizedDraw)
- iSaveDC = pDC->SaveDC();
- m_rcBounds = rc;
- _AfxDrawBorders(pDC, rc, (m_sBorderStyle == 1), (m_sAppearance == 1));
- OnDrawMetafile(pDC, rc);
- if (! m_bOptimizedDraw && iSaveDC != 0)
- pDC->RestoreDC(iSaveDC);
- }
-
- void COleControl::OnDraw(CDC*, const CRect&, const CRect&)
- {
- // To be overridden by subclass.
- }
-
- void COleControl::OnDrawMetafile(CDC* pDC, const CRect& rcBounds)
- {
- // By default, we draw into metafile the same way we would draw to the
- // screen. This may be overridden by the subclass.
-
- OnDraw(pDC, rcBounds, rcBounds);
- }
-
- BOOL COleControl::GetMetafileData(LPFORMATETC lpFormatEtc,
- LPSTGMEDIUM lpStgMedium)
- {
- ASSERT_VALID(this);
- ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE));
- ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));
- ASSERT(lpStgMedium->tymed == TYMED_NULL); // GetDataHere not valid
- ASSERT(lpStgMedium->pUnkForRelease == NULL);
-
- // medium must be TYMED_MFPICT -- cannot fill in existing HGLOBAL
- if (!(lpFormatEtc->tymed & TYMED_MFPICT) || lpStgMedium->hGlobal != NULL)
- return FALSE;
-
- // create appropriate memory metafile DC
- CMetaFileDC dc;
- if (!dc.Create())
- return FALSE;
-
- // create attribute DC according to lpFormatEtc->ptd
- HDC hAttribDC = ::_AfxOleCreateDC(lpFormatEtc->ptd);
- dc.SetAttribDC(hAttribDC);
-
- // Paint directly into the metafile.
- int cx;
- int cy;
- GetControlSize(&cx, &cy);
- CRect rc(0, 0, cx, cy);
- dc.SetMapMode(MM_ANISOTROPIC);
- dc.SetWindowOrg(0, 0);
- dc.SetWindowExt(cx, cy);
- DrawMetafile(&dc, rc);
-
- // attribute DC is no longer necessary
- dc.SetAttribDC(NULL);
- ::DeleteDC(hAttribDC);
-
- HMETAFILE hMF;
- hMF = (HMETAFILE)dc.Close();
- if (hMF == NULL)
- return FALSE;
-
- HGLOBAL hPict;
- if ((hPict = ::GlobalAlloc(GMEM_DDESHARE, sizeof(METAFILEPICT))) == NULL)
- {
- DeleteMetaFile(hMF);
- return FALSE;
- }
- LPMETAFILEPICT lpPict;
- if ((lpPict = (LPMETAFILEPICT)::GlobalLock(hPict)) == NULL)
- {
- DeleteMetaFile(hMF);
- ::GlobalFree(hPict);
- return FALSE;
- }
-
- // set the metafile size
- lpPict->mm = MM_ANISOTROPIC;
- lpPict->hMF = hMF;
- lpPict->xExt = (int)m_cxExtent;
- lpPict->yExt = (int)m_cyExtent;
-
- // return the medium with the hGlobal to the METAFILEPICT
- ::GlobalUnlock(hPict);
- lpStgMedium->hGlobal = hPict;
- lpStgMedium->tymed = TYMED_MFPICT;
- return TRUE;
- }
-
- BOOL COleControl::OnCreateAggregates()
- {
- return TRUE;
- }
-
- LPVOID COleControl::QueryDefHandler(REFIID iid)
- {
- // If we're being aggregated, we want to pass the outer unknown
- // to the object we're aggregating (the default handler).
- // Otherwise, we pass our own "inner" unknown.
- // That's what GetControllingUnknown() does.
-
- LPUNKNOWN pUnk = GetControllingUnknown();
-
- CLSID clsid;
- GetClassID(&clsid);
-
- if (m_pDefIUnknown == NULL)
- {
- // Note: This call will not increment pUnk's reference count.
- HRESULT hr = CreateDataCache(pUnk, clsid,
- IID_IUnknown, (LPLPVOID)&m_pDefIUnknown);
-
- if (FAILED(hr))
- return NULL;
- }
-
- LPVOID pNew;
-
- // Note: For the following QueryInterface call, we want to prevent
- // pUnk's reference count from being incremented. So, if the
- // call succeeds, we immediately force a decrement of the reference count.
-
- if (SUCCEEDED(m_pDefIUnknown->QueryInterface(iid, &pNew)))
- {
- ASSERT(pNew != NULL);
- pUnk->Release();
- }
-
- return pNew;
- }
-
- void COleControl::InvalidateControl(LPCRECT lpRect, BOOL bErase)
- {
- if (m_bInPlaceActive && m_bInPlaceSiteWndless)
- {
- CRect rect;
- if (lpRect != NULL)
- {
- CPoint point(0, 0);
- ClientToParent(m_rcPos, &point);
- rect.CopyRect(lpRect);
- rect.OffsetRect(point);
- lpRect = ▭
- }
- m_pInPlaceSiteWndless->InvalidateRect(lpRect, bErase);
- }
- #ifdef _AFXDLL
- else if (m_bInPlaceActive || m_bOpen)
- #else
- else if (m_bInPlaceActive)
- #endif
- {
- InvalidateRect(lpRect, bErase);
- }
- else
- {
- SendAdvise(OBJECTCODE_VIEWCHANGED);
- }
-
- if (m_bModified)
- SendAdvise(OBJECTCODE_DATACHANGED);
- }
-
- CWnd* COleControl::GetOuterWindow() const
- {
- return (m_pReflect != NULL ? (CWnd*)m_pReflect : (CWnd*)this);
- }
-
- void COleControl::OnReflectorDestroyed()
- {
- m_pReflect = NULL;
- }
-
- HRESULT COleControl::SaveState(IStream* pstm)
- {
- HRESULT hr = S_OK;
-
- TRY
- {
- // Delegate to the Serialize method.
- COleStreamFile file(pstm);
- CArchive ar(&file, CArchive::store);
- Serialize(ar);
- }
- CATCH_ALL(e)
- {
- hr = E_FAIL;
- DELETE_EXCEPTION(e);
- }
- END_CATCH_ALL
-
- return hr;
- }
-
- HRESULT COleControl::LoadState(IStream* pstm)
- {
- HRESULT hr = S_OK;
-
- TRY
- {
- // Delegate to the Serialize method.
- COleStreamFile file(pstm);
- CArchive ar(&file, CArchive::load);
- Serialize(ar);
- }
- CATCH_ALL(e)
- {
- // The load failed. Delete any partially-initialized state.
- OnResetState();
- m_bInitialized = TRUE;
- hr = E_FAIL;
- DELETE_EXCEPTION(e);
- }
- END_CATCH_ALL
-
- // Clear the modified flag.
- m_bModified = FALSE;
-
- // Unless IOleObject::SetClientSite is called after this, we can
- // count on ambient properties being available while loading.
- m_bCountOnAmbients = TRUE;
-
- // Properties have been initialized
- m_bInitialized = TRUE;
-
- // Uncache cached ambient properties
- _afxAmbientCache->Cache(NULL);
-
- return hr;
- }
-
- void COleControl::SendAdvise(UINT uCode)
- {
- // Calls the appropriate IOleClientSite or IAdviseSink member function
- // for various events such as closure, renaming, saving, etc.
-
- switch (uCode)
- {
- case OBJECTCODE_SAVED:
- if (m_pOleAdviseHolder != NULL)
- m_pOleAdviseHolder->SendOnSave();
- break;
-
- case OBJECTCODE_CLOSED:
- if (m_pOleAdviseHolder != NULL)
- m_pOleAdviseHolder->SendOnClose();
- break;
-
- case OBJECTCODE_SAVEOBJECT:
- if (m_bModified && m_pClientSite != NULL)
- m_pClientSite->SaveObject();
- break;
-
- case OBJECTCODE_DATACHANGED:
- //No flags are necessary here.
- if (m_pDataAdviseHolder != NULL)
- m_pDataAdviseHolder->SendOnDataChange(&m_xDataObject, 0, 0);
- break;
-
- case OBJECTCODE_SHOWWINDOW:
- if (m_pClientSite != NULL)
- m_pClientSite->OnShowWindow(TRUE);
- break;
-
- case OBJECTCODE_HIDEWINDOW:
- if (m_pClientSite != NULL)
- m_pClientSite->OnShowWindow(FALSE);
- break;
-
- case OBJECTCODE_SHOWOBJECT:
- if (m_pClientSite != NULL)
- m_pClientSite->ShowObject();
- break;
-
- case OBJECTCODE_VIEWCHANGED:
- {
- DWORD aspects;
- DWORD advf;
- LPADVISESINK pAdvSink;
-
- if (SUCCEEDED(m_xViewObject.GetAdvise(&aspects, &advf, &pAdvSink)) &&
- (pAdvSink != NULL))
- {
- pAdvSink->OnViewChange(DVASPECT_CONTENT, -1);
- pAdvSink->Release();
- }
- }
- break;
- }
- }
-
- HRESULT COleControl::OnHide()
- {
- #ifdef _AFXDLL
- CWnd* pWnd = m_bOpen ? m_pWndOpenFrame : GetOuterWindow();
- #else
- CWnd* pWnd = GetOuterWindow();
- #endif
- if (pWnd != NULL && pWnd->m_hWnd != NULL)
- ::ShowWindow(pWnd->m_hWnd, SW_HIDE);
-
- RELEASE(m_pInPlaceFrame);
- RELEASE(m_pInPlaceDoc);
-
- #ifdef _AFXDLL
- if (m_bOpen)
- SendAdvise(OBJECTCODE_HIDEWINDOW);
- #endif
-
- return S_OK;
- }
-
- HRESULT COleControl::OnOpen(BOOL bTryInPlace, LPMSG pMsg)
- {
- #ifndef _AFXDLL
- ASSERT(bTryInPlace); // fully-open mode not supported in static builds
- UNUSED_ALWAYS(bTryInPlace);
- #endif
-
- #ifndef _AFXDLL
- return OnActivateInPlace(TRUE, pMsg);
- #else
- if (!m_bOpen)
- {
- // If not already open, try in-place activating.
- if (bTryInPlace && SUCCEEDED(OnActivateInPlace(bTryInPlace, pMsg)))
- return S_OK;
-
- // If already in-place active, deactivate first.
- if (m_bInPlaceActive)
- m_xOleInPlaceObject.InPlaceDeactivate();
-
- m_bOpen = TRUE;
-
- // Open a separate window.
- if (m_pWndOpenFrame == NULL)
- {
- // Create frame window
- m_pWndOpenFrame = CreateFrameWindow();
-
- if (m_pWndOpenFrame == NULL)
- return E_FAIL;
-
- // Size frame window to exactly contain the control.
- int cx;
- int cy;
- GetControlSize(&cx, &cy);
- ResizeFrameWindow(cx, cy);
-
- // Create and/or reparent the control's window.
- CRect rectClient;
- m_pWndOpenFrame->GetClientRect(&rectClient);
- if (!CreateControlWindow(m_pWndOpenFrame->m_hWnd, rectClient, rectClient))
- return E_FAIL;
- }
- }
-
- // Make the frame window visible and activate it.
- ASSERT(m_pWndOpenFrame != NULL);
- m_pWndOpenFrame->ShowWindow(SW_SHOW);
- m_pWndOpenFrame->SetActiveWindow();
- SendAdvise(OBJECTCODE_SHOWWINDOW);
- return S_OK;
- #endif
- }
-
- #ifdef _AFXDLL
- CControlFrameWnd* COleControl::CreateFrameWindow()
- {
- TCHAR szUserType[256];
- GetUserType(szUserType);
-
- CControlFrameWnd* pWnd = new CControlFrameWnd(this);
- if (!pWnd->Create(szUserType))
- {
- // If Create failed, then frame window has deleted itself.
- pWnd = NULL;
- }
-
- return pWnd;
- }
-
- void COleControl::OnFrameClose()
- {
- // Reparent control to prevent its window from being destroyed.
- CWnd* pWnd = GetOuterWindow();
- if (pWnd != NULL)
- {
- ::SetWindowPos(pWnd->m_hWnd, NULL, 0, 0, 0, 0,
- SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
- SWP_HIDEWINDOW);
- pWnd->SetParent(NULL);
- }
-
- m_pWndOpenFrame = NULL;
- m_bOpen = FALSE;
-
- m_xOleObject.Close(OLECLOSE_SAVEIFDIRTY);
-
- SendAdvise(OBJECTCODE_HIDEWINDOW);
- SendAdvise(OBJECTCODE_CLOSED);
- }
-
- void COleControl::ResizeOpenControl(int cx, int cy)
- {
- CWnd* pWndOuter = GetOuterWindow();
- if ((pWndOuter != NULL) && (pWndOuter->m_hWnd != NULL))
- ::SetWindowPos(pWndOuter->m_hWnd, NULL, 0, 0, cx, cy,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
- ResizeFrameWindow(cx, cy);
- }
-
- void COleControl::ResizeFrameWindow(int cxCtrl, int cyCtrl)
- {
- m_pWndOpenFrame->SetWindowPos(NULL, 0, 0, 100, 100,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
- CRect rectClient;
- m_pWndOpenFrame->GetClientRect(&rectClient);
- CRect rectWindow;
- m_pWndOpenFrame->GetWindowRect(&rectWindow);
- int cx = cxCtrl + rectWindow.Width() - rectClient.Width();
- int cy = cyCtrl + rectWindow.Height() - rectClient.Height();
- m_pWndOpenFrame->SetWindowPos(NULL, 0, 0, cx, cy,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
- }
-
- #endif //_AFXDLL
-
- BOOL COleControl::GetRectInContainer(LPRECT lpRect)
- {
- if (m_bInPlaceActive)
- CopyRect(lpRect, &m_rcPos);
-
- return m_bInPlaceActive;
- }
-
- LPCLSID COleControl::GetPropPageIDs(ULONG& cPropPages)
- {
- cPropPages = 0;
- return NULL;
- }
-
- BOOL COleControl::OnEdit(LPMSG lpMsg, HWND, LPCRECT lpRect)
- {
- CopyRect(m_rcPos, lpRect);
- return SUCCEEDED(OnActivateInPlace(TRUE, lpMsg));
- }
-
- HWND AFXAPI _AfxGetTopLevelWindow(HWND hWnd)
- {
- HWND hWndTop;
-
- do
- {
- hWndTop = hWnd;
- hWnd = ::GetParent(hWnd);
- }
- while (hWnd != NULL);
-
- return hWndTop;
- }
-
- BOOL COleControl::OnProperties(LPMSG, HWND hWndParent, LPCRECT)
- {
- USES_CONVERSION;
-
- HRESULT hr;
-
- if ((m_pControlSite == NULL) ||
- FAILED(hr = m_pControlSite->ShowPropertyFrame()))
- {
- LPUNKNOWN pUnk = GetIDispatch(FALSE);
- HWND hWndOwner = CWnd::GetSafeOwner_(hWndParent, NULL);
-
- LCID lcid = AmbientLocaleID();
-
- ULONG cPropPages;
- LPCLSID pclsidPropPages = GetPropPageIDs(cPropPages);
-
- RECT rectParent;
- RECT rectTop;
- ::GetWindowRect(hWndParent, &rectParent);
- ::GetWindowRect(hWndOwner, &rectTop);
-
- TCHAR szUserType[256];
- GetUserType(szUserType);
-
- PreModalDialog(hWndOwner);
- hr = ::OleCreatePropertyFrame(hWndOwner, rectParent.left - rectTop.left,
- rectParent.top - rectTop.top, T2COLE(szUserType), 1, &pUnk,
- cPropPages, pclsidPropPages, lcid, NULL, 0);
- PostModalDialog(hWndOwner);
- }
-
- return SUCCEEDED(hr);
- }
-
- DWORD COleControl::GetControlFlags()
- {
- return clipPaintDC;
- }
-
- void COleControl::OnPaint(CDC* pDC)
- {
- if (m_bNoRedraw)
- {
- // flicker-free activation: no need to repaint
- ValidateRect(NULL);
- m_bNoRedraw = FALSE; // one time only
- return;
- }
-
- AfxLockTempMaps();
-
- GetWindowRect(m_rcBounds);
- m_rcBounds.OffsetRect(-m_rcBounds.left, -m_rcBounds.top);
-
- // Adjust bounds for size of UI Active tracker, if any.
- #ifdef _AFXDLL
- if (!m_bOpen && (m_pRectTracker != NULL))
- #else
- if (m_pRectTracker != NULL)
- #endif
- {
- int nHandleSize = (int)m_pRectTracker->m_nHandleSize - 1;
- m_rcBounds.InflateRect(-nHandleSize, -nHandleSize);
- }
-
- CRect rcClient;
- GetClientRect(rcClient);
-
- if (pDC != NULL)
- {
- // We were passed a device context: use it.
- int iSaveDC = pDC->SaveDC();
- OnDraw(pDC, rcClient, rcClient);
- pDC->RestoreDC(iSaveDC);
- }
- else
- {
- #ifdef _DEBUG
- int nFlags = GetControlFlags();
- if (nFlags & fastBeginPaint)
- TRACE0("Warning: COleControl::fastBeginPaint is obsolete.\n");
- #endif
-
- CPaintDC dc(this);
- OnDraw(&dc, rcClient, &dc.m_ps.rcPaint);
- }
-
- AfxUnlockTempMaps();
- }
-
- BOOL COleControl::OnEraseBkgnd(CDC* pDC)
- {
- // do nothing -- controls erase their background in their OnDraw
- if (IsSubclassedControl())
- return CWnd::OnEraseBkgnd(pDC);
- else
- return TRUE;
- }
-
- void COleControl::Serialize(CArchive& ar)
- {
- CArchivePropExchange px(ar);
- DoPropExchange(&px);
- if (ar.IsLoading())
- {
- BoundPropertyChanged(DISPID_UNKNOWN);
- InvalidateControl();
- }
- }
-
- void COleControl::DoPropExchange(CPropExchange* pPX)
- {
- ASSERT_POINTER(pPX, CPropExchange);
-
- ExchangeExtent(pPX);
- ExchangeStockProps(pPX);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Wrappers for IOleControlSite
-
- void COleControl::ControlInfoChanged()
- {
- if (m_pControlSite != NULL)
- m_pControlSite->OnControlInfoChanged();
- }
-
- BOOL COleControl::LockInPlaceActive(BOOL bLock)
- {
- if (m_pControlSite != NULL)
- return SUCCEEDED(m_pControlSite->LockInPlaceActive(bLock));
-
- return FALSE;
- }
-
- LPDISPATCH COleControl::GetExtendedControl()
- {
- LPDISPATCH pDispatch = NULL;
- if (m_pControlSite != NULL)
- m_pControlSite->GetExtendedControl(&pDispatch);
-
- return pDispatch;
- }
-
- void COleControl::TransformCoords(POINTL* lpptlHimetric,
- POINTF* lpptfContainer, DWORD flags)
- {
- if ((m_pControlSite == NULL) ||
- (FAILED(m_pControlSite->TransformCoords(lpptlHimetric,
- lpptfContainer, flags))))
- {
- // Transformation failed, use the identity transformation
-
- if (flags & XFORMCOORDS_CONTAINERTOHIMETRIC)
- {
- lpptlHimetric->x = (long)lpptfContainer->x;
- lpptlHimetric->y = (long)lpptfContainer->y;
- }
- else
- {
- lpptfContainer->x = (float)lpptlHimetric->x;
- lpptfContainer->y = (float)lpptlHimetric->y;
- }
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControl::XOleControl
-
- STDMETHODIMP_(ULONG) COleControl::XOleControl::AddRef()
- {
- METHOD_PROLOGUE_EX_(COleControl, OleControl)
- return (ULONG)pThis->ExternalAddRef();
- }
-
- STDMETHODIMP_(ULONG) COleControl::XOleControl::Release()
- {
- METHOD_PROLOGUE_EX_(COleControl, OleControl)
- return (ULONG)pThis->ExternalRelease();
- }
-
- STDMETHODIMP COleControl::XOleControl::QueryInterface(
- REFIID iid, LPVOID* ppvObj)
- {
- METHOD_PROLOGUE_EX_(COleControl, OleControl)
- return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
- }
-
- STDMETHODIMP COleControl::XOleControl::GetControlInfo(LPCONTROLINFO pCI)
- {
- METHOD_PROLOGUE_EX(COleControl, OleControl)
- pThis->OnGetControlInfo(pCI);
- return S_OK;
- }
-
- STDMETHODIMP COleControl::XOleControl::OnMnemonic(LPMSG pMsg)
- {
- METHOD_PROLOGUE_EX(COleControl, OleControl)
- pThis->OnMnemonic(pMsg);
- return S_OK;
- }
-
- STDMETHODIMP COleControl::XOleControl::OnAmbientPropertyChange(DISPID dispid)
- {
- METHOD_PROLOGUE_EX(COleControl, OleControl)
-
- if (dispid == DISPID_AMBIENT_UIDEAD || dispid == DISPID_UNKNOWN)
- pThis->m_bUIDead = (BYTE)(pThis->AmbientUIDead());
-
- pThis->OnAmbientPropertyChange(dispid);
- return S_OK;
- }
-
- STDMETHODIMP COleControl::XOleControl::FreezeEvents(BOOL bFreeze)
- {
- METHOD_PROLOGUE_EX(COleControl, OleControl)
-
- ULONG& cEventsFrozen = pThis->m_cEventsFrozen;
-
- if (bFreeze)
- ++(cEventsFrozen);
- else
- --(cEventsFrozen);
-
- ASSERT(cEventsFrozen >= 0); // Should never go below zero!
-
- if ((cEventsFrozen == 1 && bFreeze) ||
- (cEventsFrozen == 0 && !bFreeze))
- {
- pThis->OnFreezeEvents(bFreeze);
- }
-
- return S_OK;
- }
-
- void COleControl::OnGetControlInfo(LPCONTROLINFO pControlInfo)
- {
- // Subclass may override
-
- pControlInfo->hAccel = NULL;
- pControlInfo->cAccel = 0;
- pControlInfo->dwFlags = 0;
- }
-
- void COleControl::OnMnemonic(LPMSG)
- {
- // To be implemented by subclass
- }
-
- void COleControl::OnAmbientPropertyChange(DISPID)
- {
- // To be implemented by subclass
- }
-
- void COleControl::OnFreezeEvents(BOOL)
- {
- // To be implemented by subclass
- }
-
- void COleControl::OnSetClientSite()
- {
- if (!m_bDataPathPropertiesLoaded)
- {
- CAsyncPropExchange PX(m_dwDataPathVersionToReport);
- DoPropExchange(&PX);
- m_bDataPathPropertiesLoaded=TRUE;
- }
- }
-
- LPOLECLIENTSITE COleControl::GetClientSite()
- {
- return m_pClientSite;
- }
-
- COLORREF COleControl::TranslateColor(OLE_COLOR clrColor, HPALETTE hpal)
- {
- COLORREF cr = RGB(0x00,0x00,0x00);
- ::OleTranslateColor(clrColor, hpal, &cr);
- return cr;
- }
-
- void COleControl::Refresh()
- {
- InvalidateControl();
- if (m_hWnd != NULL)
- UpdateWindow();
- }
-
- void COleControl::DoClick()
- {
- OnClick(LEFT_BUTTON);
- }
-
- BOOL COleControl::OnNcCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (m_pReflect != NULL)
- m_pReflect->SetControl(this);
-
- return CWnd::OnNcCreate(lpCreateStruct);
- }
-
- void COleControl::RecreateControlWindow()
- {
- if (m_bInPlaceActive)
- {
- BOOL bUIActive = m_bUIActive;
- m_xOleInPlaceObject.InPlaceDeactivate();
- DestroyWindow();
- OnActivateInPlace(bUIActive, NULL);
- }
- #ifdef _AFXDLL
- else if (m_bOpen)
- {
- DestroyWindow();
- CRect rectClient;
- m_pWndOpenFrame->GetClientRect(&rectClient);
- CreateControlWindow(m_pWndOpenFrame->m_hWnd, rectClient, rectClient);
- }
- #endif //_AFXDLL
- else
- {
- HWND hWndParent = _AfxGetParkingWindow();
- if (hWndParent != NULL)
- {
- DestroyWindow();
- int cx;
- int cy;
- GetControlSize(&cx, &cy);
- CRect rect(0, 0, cx, cy);
- CreateControlWindow(hWndParent, rect);
- }
- }
- }
-
- void COleControl::CreateWindowForSubclassedControl()
- {
- if (IsSubclassedControl() && (m_hWnd == NULL))
- {
- // If this is a subclassed control, we should create the window
- // for it now, in case the window is needed by the DoSuperclassPaint
- // implementation.
-
- HWND hWndParent = _AfxGetParkingWindow();
- if (hWndParent != NULL)
- {
- SIZEL szlHimetric;
- SIZEL szlPixels;
- szlHimetric.cx = m_cxExtent;
- szlHimetric.cy = m_cyExtent;
- _AfxXformSizeInHimetricToPixels(NULL, &szlHimetric, &szlPixels);
- CRect rcPos(0, 0, (int)szlPixels.cx, (int)szlPixels.cy);
- CreateControlWindow(hWndParent, rcPos);
- }
- }
- }
-
- int COleControl::OnMouseActivate(CWnd *pDesktopWnd, UINT nHitTest, UINT message)
- {
- if (m_bInPlaceActive && !m_bUIActive)
- m_bPendingUIActivation = TRUE;
-
- return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
- }
-
- void COleControl::PreModalDialog(HWND hWndParent)
- {
- if (m_pInPlaceFrame != NULL)
- {
- m_pInPlaceFrame->EnableModeless(FALSE);
- }
- else
- {
- HWND hWndTop = _AfxGetTopLevelWindow(hWndParent);
- if (hWndTop != NULL)
- ::EnableWindow(hWndTop, FALSE);
- }
- }
-
- void COleControl::PostModalDialog(HWND hWndParent)
- {
- if (m_pInPlaceFrame != NULL)
- {
- m_pInPlaceFrame->EnableModeless(TRUE);
- }
- else
- {
- HWND hWndTop = _AfxGetTopLevelWindow(hWndParent);
- if (hWndTop != NULL)
- ::EnableWindow(hWndTop, TRUE);
- }
- }
-
- void COleControl::SetModifiedFlag(BOOL bModified)
- {
- m_bModified = (BYTE)bModified;
- }
-
- BOOL COleControl::IsModified()
- {
- return m_bModified;
- }
-
- BOOL COleControl::WillAmbientsBeValidDuringLoad()
- {
- return m_bCountOnAmbients;
- }
-
- void COleControl::EnableSimpleFrame()
- {
- m_bSimpleFrame = TRUE;
- }
-
- BOOL COleControl::IgnoreWindowMessage(UINT msg, WPARAM wParam, LPARAM lParam,
- LRESULT* plResult)
- {
- if (!m_bUIDead)
- return FALSE;
-
- switch (msg)
- {
- case WM_NCHITTEST:
- *plResult = HTNOWHERE;
- return TRUE;
-
- case WM_SETCURSOR:
- *plResult = ::SendMessage(::GetParent(m_hWnd), msg, wParam, lParam);
- return TRUE;
- }
-
- if ((msg >= WM_KEYFIRST) && (msg <= WM_KEYLAST))
- {
- *plResult = 0;
- return TRUE;
- }
-
- return FALSE;
- }
-
- LRESULT COleControl::WindowProc(UINT msg, WPARAM wParam, LPARAM lParam)
- {
- DWORD dwCookie;
- LRESULT lResult;
- HRESULT hr;
-
- ExternalAddRef(); // "Insurance" addref -- keeps control alive
-
- // allow OCM_ reflections to be handled by ON_XXX_REFLECT macros
- switch (msg)
- {
- case OCM_COMMAND:
- case OCM_CTLCOLORBTN:
- case OCM_CTLCOLOREDIT:
- case OCM_CTLCOLORDLG:
- case OCM_CTLCOLORLISTBOX:
- case OCM_CTLCOLORMSGBOX:
- case OCM_CTLCOLORSCROLLBAR:
- case OCM_CTLCOLORSTATIC:
- case OCM_DRAWITEM:
- case OCM_MEASUREITEM:
- case OCM_DELETEITEM:
- case OCM_VKEYTOITEM:
- case OCM_CHARTOITEM:
- case OCM_COMPAREITEM:
- case OCM_HSCROLL:
- case OCM_VSCROLL:
- case OCM_PARENTNOTIFY:
- case OCM_NOTIFY:
- if (ReflectChildNotify(msg-OCM__BASE, wParam, lParam, &lResult))
- {
- ExternalRelease();
- return lResult;
- }
- }
-
- // Give the simple frame site the opportunity to filter the message
- if ((m_pSimpleFrameSite != NULL) &&
- SUCCEEDED(hr = m_pSimpleFrameSite->PreMessageFilter(
- m_hWnd, msg, wParam, lParam, &lResult, &dwCookie)))
- {
- if (hr == S_OK)
- {
- if (!IgnoreWindowMessage(msg, wParam, lParam, &lResult))
- lResult = CWnd::WindowProc(msg, wParam, lParam);
-
- // Simple frame site may have been cleared...
- // check before calling again.
-
- if (m_pSimpleFrameSite != NULL)
- m_pSimpleFrameSite->PostMessageFilter(
- m_hWnd, msg, wParam, lParam, &lResult, dwCookie);
- }
- }
- else
- {
- if (!IgnoreWindowMessage(msg, wParam, lParam, &lResult))
- lResult = CWnd::WindowProc(msg, wParam, lParam);
- }
-
- ExternalRelease();
-
- return lResult;
- }
-
- LRESULT COleControl::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
- {
- if (m_hWnd != NULL)
- return CWnd::DefWindowProc(nMsg, wParam, lParam);
- else
- return 0;
- }
-
- int COleControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (IsSubclassedControl())
- return CWnd::OnCreate(lpCreateStruct);
- else
- return 0;
- }
-
- void COleControl::OnSize(UINT nType, int cx, int cy)
- {
- if (IsSubclassedControl())
- CWnd::OnSize(nType, cx, cy);
- }
-
- void COleControl::OnMove(int x, int y)
- {
- if (IsSubclassedControl())
- CWnd::OnMove(x, y);
- }
-
- void COleControl::OnShowWindow(BOOL bShow, UINT nStatus)
- {
- if (IsSubclassedControl())
- CWnd::OnShowWindow(bShow, nStatus);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Command prompts
-
- void COleControl::OnInitMenuPopup(CMenu* pMenu, UINT, BOOL bSysMenu)
- {
- AfxCancelModes(m_hWnd);
-
- if (bSysMenu)
- return; // don't support system menu
-
- ASSERT(pMenu != NULL);
- // check the enabled state of various menu items
-
- CCmdUI state;
- state.m_pMenu = pMenu;
- ASSERT(state.m_pOther == NULL);
- ASSERT(state.m_pParentMenu == NULL);
-
- // determine if menu is popup in top-level menu and set m_pOther to
- // it if so (m_pParentMenu == NULL indicates that it is secondary popup)
- HMENU hParentMenu;
- if (_afxTrackingMenu == pMenu->m_hMenu)
- state.m_pParentMenu = pMenu; // parent == child for tracking popup
- else
- {
- CWnd* pParent = GetTopLevelParent();
- // child windows don't have menus -- need to go to the top!
- if (pParent != NULL &&
- (hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
- {
- int nIndexMax = ::GetMenuItemCount(hParentMenu);
- for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
- {
- if (::GetSubMenu(hParentMenu, nIndex) == pMenu->m_hMenu)
- {
- // when popup is found, m_pParentMenu is containing menu
- state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
- break;
- }
- }
- }
- }
-
- state.m_nIndexMax = pMenu->GetMenuItemCount();
- for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
- state.m_nIndex++)
- {
- state.m_nID = pMenu->GetMenuItemID(state.m_nIndex);
- if (state.m_nID == 0)
- continue; // menu separator or invalid cmd - ignore it
-
- ASSERT(state.m_pOther == NULL);
- ASSERT(state.m_pMenu != NULL);
- if (state.m_nID == (UINT)-1)
- {
- // possibly a popup menu, route to first item of that popup
- state.m_pSubMenu = pMenu->GetSubMenu(state.m_nIndex);
- if (state.m_pSubMenu == NULL ||
- (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
- state.m_nID == (UINT)-1)
- {
- continue; // first item of popup can't be routed to
- }
- state.DoUpdate(this, FALSE); // popups are never auto disabled
- }
- else
- {
- // normal menu item
- // Auto enable/disable if frame window has 'm_bAutoMenuEnable'
- // set and command is _not_ a system command.
- state.m_pSubMenu = NULL;
- state.DoUpdate(this, m_bAutoMenuEnable && state.m_nID < 0xF000);
- }
- }
- }
-
- void COleControl::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU /*hSysMenu*/)
- {
- // set the tracking state (update on idle)
- if (nFlags == 0xFFFF)
- {
- m_nIDTracking = AFX_IDS_IDLEMESSAGE;
- SendMessage(WM_SETMESSAGESTRING, (WPARAM)m_nIDTracking);
- ASSERT(m_nIDTracking == m_nIDLastMessage);
- }
- else if (nItemID == 0 ||
- nFlags & (MF_SEPARATOR|MF_POPUP|MF_MENUBREAK|MF_MENUBARBREAK))
- {
- // nothing should be displayed
- m_nIDTracking = 0;
- }
- else if (nItemID >= 0xF000 && nItemID < 0xF1F0) // max of 31 SC_s
- {
- // special strings table entries for system commands
- m_nIDTracking = ID_COMMAND_FROM_SC(nItemID);
- ASSERT(m_nIDTracking >= AFX_IDS_SCFIRST &&
- m_nIDTracking < AFX_IDS_SCFIRST + 31);
- }
- else if (nItemID >= AFX_IDM_FIRST_MDICHILD)
- {
- // all MDI Child windows map to the same help id
- m_nIDTracking = AFX_IDS_MDICHILD;
- }
- else
- {
- // track on idle
- m_nIDTracking = nItemID;
- }
-
- // when running in-place, it is necessary to cause a message to
- // be pumped through the queue.
- if (m_nIDTracking != m_nIDLastMessage && GetParent() != NULL)
- PostMessage(WM_NULL);
- }
-
- void COleControl::GetMessageString(UINT nID, CString& rMessage) const
- {
- // load appropriate string
- LPTSTR lpsz = rMessage.GetBuffer(255);
- if (AfxLoadString(nID, lpsz) != 0)
- {
- // first newline terminates actual string
- lpsz = _tcschr(lpsz, '\n');
- if (lpsz != NULL)
- *lpsz = '\0';
- }
- else
- {
- // not found
- TRACE1("Warning: no message line prompt for ID 0x%04X.\n", nID);
- }
- rMessage.ReleaseBuffer();
- }
-
- LRESULT COleControl::OnSetMessageString(WPARAM wParam, LPARAM lParam)
- {
- USES_CONVERSION;
-
- if (m_pInPlaceFrame != NULL)
- {
- LPCTSTR lpsz = NULL;
- CString strMessage;
-
- // set the message bar text
- if (lParam != 0)
- {
- ASSERT(wParam == 0); // can't have both an ID and a string
- lpsz = (LPCTSTR)lParam; // set an explicit string
- }
- else if (wParam != 0)
- {
- // use the wParam as a string ID
- GetMessageString(wParam, strMessage);
- lpsz = strMessage;
- }
-
- // notify container of new status text
- m_pInPlaceFrame->SetStatusText(T2COLE(lpsz));
- }
-
- UINT nIDLast = m_nIDLastMessage;
- m_nIDLastMessage = (UINT)wParam; // new ID (or 0)
- m_nIDTracking = (UINT)wParam; // so F1 on toolbar buttons work
- return nIDLast;
- }
-
- void COleControl::OnEnterIdle(UINT nWhy, CWnd* /*pWho*/)
- {
- if (nWhy != MSGF_MENU || m_nIDTracking == m_nIDLastMessage)
- return;
-
- SendMessage(WM_SETMESSAGESTRING, (WPARAM)m_nIDTracking);
- ASSERT(m_nIDTracking == m_nIDLastMessage);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControl::XSpecifyPropertyPages
-
- STDMETHODIMP_(ULONG) COleControl::XSpecifyPropertyPages::AddRef()
- {
- // Delegate to our exported AddRef.
- METHOD_PROLOGUE_EX_(COleControl, SpecifyPropertyPages)
- return (ULONG)pThis->ExternalAddRef();
- }
-
- STDMETHODIMP_(ULONG) COleControl::XSpecifyPropertyPages::Release()
- {
- // Delegate to our exported Release.
- METHOD_PROLOGUE_EX_(COleControl, SpecifyPropertyPages)
- return (ULONG)pThis->ExternalRelease();
- }
-
- STDMETHODIMP COleControl::XSpecifyPropertyPages::QueryInterface(
- REFIID iid, LPVOID* ppvObj)
- {
- // Delegate to our exported QueryInterface.
- METHOD_PROLOGUE_EX_(COleControl, SpecifyPropertyPages)
- return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
- }
-
- STDMETHODIMP COleControl::XSpecifyPropertyPages::GetPages(CAUUID* pPages)
- {
- METHOD_PROLOGUE_EX(COleControl, SpecifyPropertyPages)
-
- ASSERT(pPages != NULL);
-
- if (pPages == NULL)
- return E_POINTER;
-
- pPages->cElems = 0;
- pPages->pElems = NULL;
-
- HRESULT hr = S_OK;
- ULONG cElems;
- LPCLSID pClassID = pThis->GetPropPageIDs(cElems);
-
- if (cElems > 0)
- {
- if ((pPages->pElems = (LPCLSID)(CoTaskMemAlloc(cElems * sizeof(CLSID)))) != NULL)
- {
- ASSERT(pPages->pElems != NULL);
- pPages->cElems = cElems;
- memcpy(pPages->pElems, pClassID, (int)(cElems * sizeof(CLSID)));
- }
- else
- hr = E_OUTOFMEMORY;
- }
- else
- {
- pPages->cElems = 0;
- pPages->pElems = NULL;
- }
-
- return hr;
- }
-
- void COleControl::OnDestroy()
- {
- // Release hfont, if any.
- if (m_hFontPrev != NULL)
- {
- SendMessage(WM_SETFONT, (WPARAM)NULL, 0);
- InternalGetFont().m_pFont->ReleaseHfont(m_hFontPrev);
- m_hFontPrev = NULL;
- }
-
- CWnd::OnDestroy();
- }
-
- void COleControl::OnKillFocus(CWnd* pNewWnd)
- {
- CWnd::OnKillFocus(pNewWnd);
-
- if (m_pControlSite != NULL)
- m_pControlSite->OnFocus(FALSE);
- }
-
- void COleControl::OnSetFocus(CWnd* pOldWnd)
- {
- CWnd::OnSetFocus(pOldWnd);
-
- if (m_pControlSite != NULL)
- m_pControlSite->OnFocus(TRUE);
- }
-
- LRESULT COleControl::OnOcmCtlColorBtn(WPARAM wParam, LPARAM lParam)
- {
- return ::DefWindowProc(m_hWnd, WM_CTLCOLORBTN, wParam, lParam);
- }
-
- LRESULT COleControl::OnOcmCtlColorDlg(WPARAM wParam, LPARAM lParam)
- {
- return ::DefWindowProc(m_hWnd, WM_CTLCOLORDLG, wParam, lParam);
- }
-
- LRESULT COleControl::OnOcmCtlColorEdit(WPARAM wParam, LPARAM lParam)
- {
- return ::DefWindowProc(m_hWnd, WM_CTLCOLOREDIT, wParam, lParam);
- }
-
- LRESULT COleControl::OnOcmCtlColorListBox(WPARAM wParam, LPARAM lParam)
- {
- return ::DefWindowProc(m_hWnd, WM_CTLCOLORLISTBOX, wParam, lParam);
- }
-
- LRESULT COleControl::OnOcmCtlColorMsgBox(WPARAM wParam, LPARAM lParam)
- {
- return ::DefWindowProc(m_hWnd, WM_CTLCOLORMSGBOX, wParam, lParam);
- }
-
- LRESULT COleControl::OnOcmCtlColorScrollBar(WPARAM wParam, LPARAM lParam)
- {
- return ::DefWindowProc(m_hWnd, WM_CTLCOLORSCROLLBAR, wParam, lParam);
- }
-
- LRESULT COleControl::OnOcmCtlColorStatic(WPARAM wParam, LPARAM lParam)
- {
- return ::DefWindowProc(m_hWnd, WM_CTLCOLORSTATIC, wParam, lParam);
- }
-
- void COleControl::ThrowError(SCODE sc, UINT nDescriptionID, UINT nHelpID)
- {
- TCHAR szBuffer[256];
- AfxLoadString(nDescriptionID, szBuffer);
- if (nHelpID == -1)
- nHelpID = nDescriptionID;
- ThrowError(sc, szBuffer, nHelpID);
- }
-
- void COleControl::ThrowError(SCODE sc, LPCTSTR pszDescription, UINT nHelpID)
- {
- COleDispatchException* pExcept = new COleDispatchException(pszDescription,
- nHelpID, 0);
- pExcept->m_scError = sc;
- THROW(pExcept);
- }
-
- BOOL COleControl::IsInvokeAllowed(DISPID)
- {
- return m_bInitialized;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Force any extra compiler-generated code into AFX_INIT_SEG
-
- #ifdef AFX_INIT_SEG
- #pragma code_seg(AFX_INIT_SEG)
- #endif
-
- IMPLEMENT_DYNAMIC(COleControl, CWnd)
-