home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / ctlcore.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  51KB  |  2,092 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFXCTL_CORE1_SEG
  14. #pragma code_seg(AFXCTL_CORE1_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. #define new DEBUG_NEW
  23.  
  24. #define _afxTrackingMenu (AfxGetThreadState()->m_hTrackingMenu)
  25.  
  26. /////////////////////////////////////////////////////////////////////////////
  27. // Special WM_PAINT message handler that includes the HDC
  28.  
  29. #define ON_WM_PAINT_SPECIAL() \
  30.     { WM_PAINT, 0, 0, 0, AfxSig_vD, \
  31.         (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(CDC*))&OnPaint },
  32.  
  33. /////////////////////////////////////////////////////////////////////////////
  34. // Window to serve as "parking space" for not-yet-activated subclassed controls
  35.  
  36. AFX_MODULE_STATE* AFXAPI _AfxGetOleModuleState();
  37.  
  38. AFX_STATIC HWND AFXAPI _AfxGetParkingWindow()
  39. {
  40.     _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
  41.     ASSERT(pThreadState != NULL);
  42.     if (pThreadState->m_pWndPark == NULL)
  43.     {
  44.         AFX_MANAGE_STATE(_AfxGetOleModuleState());
  45.         CWnd* pWndTmp = NULL;
  46.  
  47.         TRY
  48.         {
  49. #ifdef _DEBUG
  50.             HWND hWndActive = ::GetActiveWindow();
  51. #endif
  52.             pWndTmp = new CParkingWnd;
  53.             ASSERT(pWndTmp->m_hWnd != NULL);
  54. #ifdef _DEBUG
  55.             ASSERT(hWndActive == ::GetActiveWindow());
  56. #endif
  57.         }
  58.         CATCH_ALL(e)
  59.         {
  60.             if (pWndTmp)
  61.                 delete pWndTmp;
  62.             pWndTmp = NULL;
  63.         }
  64.         END_CATCH_ALL
  65.  
  66.         pThreadState->m_pWndPark = pWndTmp;
  67.     }
  68.     return pThreadState->m_pWndPark->GetSafeHwnd();
  69. }
  70.  
  71. AFX_STATIC void AFXAPI _AfxReleaseParkingWindow()
  72. {
  73.     _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
  74.     ASSERT(pThreadState != NULL);
  75.     ASSERT(pThreadState->m_nCtrlRef == 0);
  76.     if (pThreadState->m_pWndPark != NULL)
  77.     {
  78.         AFX_MANAGE_STATE(_AfxGetOleModuleState());
  79.  
  80.         ASSERT(pThreadState->m_pWndPark->m_hWnd != NULL);
  81.         ASSERT(::GetWindow(pThreadState->m_pWndPark->m_hWnd, GW_CHILD) == NULL);
  82.         HWND hWnd = pThreadState->m_pWndPark->Detach();
  83.         ::SetWindowLong(hWnd, GWL_WNDPROC, (long)DefWindowProc);
  84.         ::DestroyWindow(hWnd);
  85.         delete pThreadState->m_pWndPark;
  86.         pThreadState->m_pWndPark = NULL;
  87.     }
  88. }
  89.  
  90. /////////////////////////////////////////////////////////////////////////////
  91. // COleControl interface map
  92.  
  93. BEGIN_INTERFACE_MAP(COleControl, CCmdTarget)
  94.     INTERFACE_PART(COleControl, IID_IQuickActivate, QuickActivate)
  95.     INTERFACE_PART(COleControl, IID_IOleObject, OleObject)
  96.     INTERFACE_PART(COleControl, IID_IViewObjectEx, ViewObject)
  97.     INTERFACE_PART(COleControl, IID_IPersistMemory, PersistMemory)
  98.     INTERFACE_PART(COleControl, IID_IPersistStreamInit, PersistStreamInit)
  99.     INTERFACE_PART(COleControl, IID_IProvideClassInfo2, ProvideClassInfo)
  100.     INTERFACE_PART(COleControl, IID_IConnectionPointContainer, ConnPtContainer)
  101.     INTERFACE_PART(COleControl, IID_IOleControl, OleControl)
  102.     INTERFACE_PART(COleControl, IID_IOleInPlaceObject, OleInPlaceObject)
  103.     INTERFACE_PART(COleControl, IID_IOleInPlaceObjectWindowless, OleInPlaceObject)
  104.     INTERFACE_PART(COleControl, IID_IOleInPlaceActiveObject, OleInPlaceActiveObject)
  105.     INTERFACE_PART(COleControl, IID_IDispatch, Dispatch)
  106.     INTERFACE_PART(COleControl, IID_IOleCache, OleCache)
  107.     INTERFACE_PART(COleControl, IID_IViewObject, ViewObject)
  108.     INTERFACE_PART(COleControl, IID_IViewObject2, ViewObject)
  109.     INTERFACE_PART(COleControl, IID_IDataObject, DataObject)
  110.     INTERFACE_PART(COleControl, IID_IPersistPropertyBag, PersistPropertyBag)
  111.     INTERFACE_PART(COleControl, IID_ISpecifyPropertyPages, SpecifyPropertyPages)
  112.     INTERFACE_PART(COleControl, IID_IPerPropertyBrowsing, PerPropertyBrowsing)
  113.     INTERFACE_PART(COleControl, IID_IProvideClassInfo, ProvideClassInfo)
  114.     INTERFACE_PART(COleControl, IID_IPersist, PersistStorage)
  115.     INTERFACE_PART(COleControl, IID_IPersistStorage, PersistStorage)
  116. END_INTERFACE_MAP()
  117.  
  118. /////////////////////////////////////////////////////////////////////////////
  119. // COleControl event map
  120.  
  121. const AFX_EVENTMAP COleControl::eventMap = { NULL, NULL };
  122.  
  123. /////////////////////////////////////////////////////////////////////////////
  124. // COleControl message map
  125.  
  126. BEGIN_MESSAGE_MAP(COleControl, CWnd)
  127.     ON_WM_PAINT_SPECIAL()
  128.     //{{AFX_MSG_MAP(COleControl)
  129.     ON_WM_ERASEBKGND()
  130.     ON_WM_NCCREATE()
  131.     ON_WM_NCCALCSIZE()
  132.     ON_WM_SIZE()
  133.     ON_WM_MOVE()
  134.     ON_WM_SHOWWINDOW()
  135.     ON_WM_CREATE()
  136.     ON_MESSAGE(WM_SETTEXT, OnSetText)
  137.     ON_WM_NCPAINT()
  138.     ON_WM_DESTROY()
  139.     ON_WM_ENTERIDLE()
  140.     ON_WM_KILLFOCUS()
  141.     ON_WM_SETFOCUS()
  142.     ON_MESSAGE(OCM_CTLCOLORBTN, OnOcmCtlColorBtn)
  143.     ON_MESSAGE(OCM_CTLCOLORDLG, OnOcmCtlColorDlg)
  144.     ON_MESSAGE(OCM_CTLCOLOREDIT, OnOcmCtlColorEdit)
  145.     ON_MESSAGE(OCM_CTLCOLORLISTBOX, OnOcmCtlColorListBox)
  146.     ON_MESSAGE(OCM_CTLCOLORMSGBOX, OnOcmCtlColorMsgBox)
  147.     ON_MESSAGE(OCM_CTLCOLORSCROLLBAR, OnOcmCtlColorScrollBar)
  148.     ON_MESSAGE(OCM_CTLCOLORSTATIC, OnOcmCtlColorStatic)
  149.     ON_WM_MOUSEMOVE()
  150.     ON_WM_NCHITTEST()
  151.     ON_WM_MOUSEACTIVATE()
  152.     ON_WM_NCLBUTTONDOWN()
  153.     ON_WM_LBUTTONDOWN()
  154.     ON_WM_LBUTTONUP()
  155.     ON_WM_LBUTTONDBLCLK()
  156.     ON_WM_MBUTTONDOWN()
  157.     ON_WM_MBUTTONUP()
  158.     ON_WM_MBUTTONDBLCLK()
  159.     ON_WM_RBUTTONDOWN()
  160.     ON_WM_RBUTTONUP()
  161.     ON_WM_RBUTTONDBLCLK()
  162.     ON_WM_KEYDOWN()
  163.     ON_WM_KEYUP()
  164.     ON_WM_CHAR()
  165.     ON_WM_SYSKEYDOWN()
  166.     ON_WM_SYSKEYUP()
  167.     ON_WM_INITMENUPOPUP()
  168.     ON_WM_MENUSELECT()
  169.     ON_WM_CANCELMODE()
  170.     ON_WM_SETCURSOR()
  171.     ON_WM_GETDLGCODE()
  172.     ON_MESSAGE(WM_SETMESSAGESTRING, OnSetMessageString)
  173.     //}}AFX_MSG_MAP
  174. END_MESSAGE_MAP()
  175.  
  176. /////////////////////////////////////////////////////////////////////////////
  177. // COleControl implementation
  178.  
  179. COleControl::COleControl() :
  180. #ifdef _AFXDLL
  181.     m_font(&m_xFontNotification)
  182. #else
  183.     m_font(NULL)
  184. #endif
  185. {
  186.     // add to parking window reference count
  187.     _AFX_THREAD_STATE* pState = AfxGetThreadState();
  188.     ASSERT(pState != NULL);
  189.     ++pState->m_nCtrlRef;
  190.  
  191.     m_bFinalReleaseCalled = FALSE;
  192.     m_bChangingExtent = FALSE;
  193.     m_bUIDead = FALSE;
  194.  
  195.     m_pReflect = NULL;
  196.     m_pRectTracker = NULL;
  197.  
  198.     m_pClientSite = NULL;
  199.     m_pOleAdviseHolder = NULL;
  200.     m_pDataAdviseHolder = NULL;
  201.     m_pInPlaceSite = NULL;
  202.     m_pInPlaceFrame = NULL;
  203.     m_pInPlaceDoc = NULL;
  204.     m_pControlSite = NULL;
  205.  
  206.     m_pDefIUnknown = NULL;
  207.     m_pDefIPersistStorage = NULL;
  208.     m_pDefIViewObject = NULL;
  209.     m_pDefIOleCache = NULL;
  210.     m_pAdviseInfo = NULL;
  211.  
  212.     m_pUIActiveInfo = NULL;
  213.     m_nIDTracking = 0;
  214.     m_nIDLastMessage = 0;
  215.     m_bAutoMenuEnable = TRUE;       // auto enable on by default
  216.  
  217.     m_bInPlaceActive = FALSE;
  218.     m_bUIActive = FALSE;
  219.     m_bPendingUIActivation = FALSE;
  220. #ifdef _AFXDLL
  221.     m_bOpen = FALSE;
  222.     m_pWndOpenFrame = NULL;
  223. #endif
  224.     m_bInitialized = FALSE;
  225.  
  226.     m_dwVersionLoaded = 0;
  227.  
  228.     m_bModified = TRUE;
  229.  
  230.     m_iButtonState = 0;
  231.     m_iDblClkState = 0;
  232.  
  233.     m_sBorderStyle = 0;
  234.     m_sAppearance = 0;
  235.     m_bEnabled = TRUE;
  236.     m_lReadyState = READYSTATE_COMPLETE;
  237.  
  238.     m_hFontPrev = NULL;
  239.  
  240.     m_cEventsFrozen = 0;
  241.  
  242.     m_bConvertVBX = FALSE;
  243.  
  244.     m_pSimpleFrameSite = NULL;
  245.     m_bSimpleFrame = FALSE;
  246.  
  247.     m_ptOffset.x = 0;
  248.     m_ptOffset.y = 0;
  249.  
  250.     m_bNoRedraw = FALSE;
  251.  
  252.     m_bInPlaceSiteEx = FALSE;
  253.     m_bInPlaceSiteWndless = FALSE;
  254.  
  255.     m_bOptimizedDraw = FALSE;
  256.  
  257.     m_bDataPathPropertiesLoaded = TRUE;
  258.  
  259.     SetInitialSize(100, 50);
  260.  
  261.     // Wire up aggregation support
  262.     EnableAggregation();
  263.  
  264.     // Wire up IDispatch support
  265.     EnableAutomation();
  266.  
  267.     // Wire up connection map support
  268.     EnableConnections();
  269.  
  270.     m_pDataSource = NULL;
  271.  
  272.     AfxOleLockApp();
  273. }
  274.  
  275.  
  276. COleControl::~COleControl()
  277. {
  278.     if (m_pDataSource != NULL)
  279.         delete m_pDataSource;
  280.  
  281.     if (m_pReflect != NULL)
  282.         m_pReflect->DestroyWindow();
  283.  
  284. #ifdef _AFXDLL
  285.     if (m_pWndOpenFrame != NULL)
  286.         m_pWndOpenFrame->DestroyWindow();
  287. #endif
  288.  
  289.     ReleaseCaches();
  290.  
  291.     if (m_hWnd != NULL)
  292.         DestroyWindow();
  293.  
  294.     // release parking window if reference count is now zero
  295.     _AFX_THREAD_STATE* pState = AfxGetThreadState();
  296.     ASSERT(pState != NULL);
  297.     if (pState->m_nCtrlRef == 0 || --pState->m_nCtrlRef == 0)
  298.         _AfxReleaseParkingWindow();
  299.  
  300.     AfxOleUnlockApp();
  301. }
  302.  
  303. void COleControl::ReleaseCaches()
  304. {
  305.     RELEASE(m_pClientSite);
  306.     RELEASE(m_pOleAdviseHolder);
  307.     RELEASE(m_pDataAdviseHolder);
  308.     RELEASE(m_pInPlaceSite);
  309.     RELEASE(m_pInPlaceFrame);
  310.     RELEASE(m_pInPlaceDoc);
  311.     RELEASE(m_pControlSite);
  312.     RELEASE(m_pSimpleFrameSite);
  313.  
  314.     LPUNKNOWN pUnk = GetControllingUnknown();
  315.  
  316.     InterlockedIncrement(&m_dwRef);  // Keep ref count from going to zero again.
  317.  
  318.     if (m_pDefIPersistStorage != NULL)
  319.     {
  320.         pUnk->AddRef();
  321.         RELEASE(m_pDefIPersistStorage);
  322.     }
  323.  
  324.     if (m_pDefIViewObject != NULL)
  325.     {
  326.         pUnk->AddRef();
  327.         RELEASE(m_pDefIViewObject);
  328.     }
  329.  
  330.     if (m_pDefIOleCache != NULL)
  331.     {
  332.         pUnk->AddRef();
  333.         RELEASE(m_pDefIOleCache);
  334.     }
  335.  
  336.     if (m_pAdviseInfo != NULL)
  337.     {
  338.         RELEASE(m_pAdviseInfo->m_pAdvSink);
  339.         delete m_pAdviseInfo;
  340.         m_pAdviseInfo = NULL;
  341.     }
  342.  
  343.     RELEASE(m_pDefIUnknown);
  344.     InterlockedDecrement(&m_dwRef);
  345. }
  346.  
  347. void COleControl::OnFinalRelease()
  348. {
  349.     if (!m_bFinalReleaseCalled)
  350.     {
  351.         m_bFinalReleaseCalled = TRUE;
  352.  
  353.         ReleaseCaches();
  354.  
  355.         if (m_hWnd != NULL)
  356.             DestroyWindow();
  357.  
  358.         CCmdTarget::OnFinalRelease();
  359.     }
  360. }
  361.  
  362. LPUNKNOWN COleControl::GetInterfaceHook(const void* piid)
  363. {
  364.     ASSERT_POINTER(piid, IID);
  365.  
  366.     if (m_piidPrimary != NULL && _AfxIsEqualGUID(*m_piidPrimary, *(IID*)piid))
  367.     {
  368.         return GetInterface((void*)&IID_IDispatch);
  369.     }
  370.  
  371.     if (_AfxIsEqualGUID(IID_IPointerInactive, *(IID*)piid) &&
  372.         (GetControlFlags() & pointerInactive))
  373.     {
  374.         return &m_xPointerInactive;
  375.     }
  376.  
  377.     return NULL;
  378. }
  379.  
  380. void COleControl::SetInitialSize(int cx, int cy)
  381. {
  382.     SIZEL szlPixels;
  383.     SIZEL szlHimetric;
  384.     szlPixels.cx = cx;
  385.     szlPixels.cy = cy;
  386.     _AfxXformSizeInPixelsToHimetric(NULL, &szlPixels, &szlHimetric);
  387.     m_cxExtent = szlHimetric.cx;
  388.     m_cyExtent = szlHimetric.cy;
  389. }
  390.  
  391. BOOL COleControl::GetDispatchIID(IID* pIID)
  392. {
  393.     if (m_piidPrimary != NULL)
  394.         *pIID = *m_piidPrimary;
  395.  
  396.     return (m_piidPrimary != NULL);
  397. }
  398.  
  399. void COleControl::InitializeIIDs(const IID* piidPrimary, const IID* piidEvents)
  400. {
  401.     m_piidPrimary = piidPrimary;
  402.     m_piidEvents = piidEvents;
  403.  
  404.     EnableTypeLib();
  405.  
  406.     // Initialize the masks for stock events and properties.
  407.     InitStockEventMask();
  408.     InitStockPropMask();
  409.  
  410. #ifdef _DEBUG
  411.  
  412.     // Verify that the type library contains all the correct information.
  413.     // If any of the following assertions fail, carefully check the IDs
  414.     // in the control's .CPP file against those in its .ODL file.
  415.  
  416.     LPTYPEINFO pTypeInfo;
  417.     HRESULT hr;
  418.     CLSID clsid;
  419.  
  420.     GetClassID(&clsid);
  421.     if (SUCCEEDED(hr = GetTypeInfoOfGuid(0, clsid, &pTypeInfo)))
  422.         RELEASE(pTypeInfo);
  423.  
  424.     ASSERT(SUCCEEDED(hr));  // Class ID may be corrupted
  425.  
  426.     if (SUCCEEDED(hr = GetTypeInfoOfGuid(0, *m_piidPrimary, &pTypeInfo)))
  427.         RELEASE(pTypeInfo);
  428.  
  429.     ASSERT(SUCCEEDED(hr));  // Primary dispatch interface ID may be corrupted
  430.  
  431.     if (SUCCEEDED(hr = GetTypeInfoOfGuid(0, *m_piidEvents, &pTypeInfo)))
  432.         RELEASE(pTypeInfo);
  433.  
  434.     ASSERT(SUCCEEDED(hr));  // Event dispatch interface ID may be corrupted
  435.  
  436. #endif
  437. }
  438.  
  439. #ifdef _DEBUG
  440.  
  441. void COleControl::AssertValid() const
  442. {
  443.     CWnd::AssertValid();
  444. }
  445.  
  446. void AFXAPI _AfxDumpGuid(CDumpContext& dc, const GUID* pGuid)
  447. {
  448.     USES_CONVERSION;
  449.  
  450.     if (pGuid == NULL)
  451.     {
  452.         dc << "(NULL)";
  453.         return;
  454.     }
  455.  
  456.     OLECHAR szGuid[40];
  457.     ::StringFromGUID2(*pGuid, szGuid, 40);
  458.     dc << OLE2CT(szGuid);
  459. }
  460.  
  461. void AFXAPI _AfxDumpHex(CDumpContext& dc, DWORD dw)
  462. {
  463.     TCHAR szHex[10];
  464.     wsprintf(szHex, _T("0x%08lx"), dw);
  465.     dc << szHex;
  466. }
  467.  
  468. void COleControl::Dump(CDumpContext& dc) const
  469. {
  470.     CWnd::Dump(dc);
  471. #ifdef _AFXDLL
  472.     dc << "\nm_pModuleState = " << m_pModuleState;
  473. #endif
  474.     dc << "\nm_piidPrimary = ";
  475.     _AfxDumpGuid(dc, m_piidPrimary);
  476.     dc << "\nm_piidEvents =  ";
  477.     _AfxDumpGuid(dc, m_piidEvents);
  478.     dc << "\nm_dwVersionLoaded = ";
  479.     _AfxDumpHex(dc, m_dwVersionLoaded);
  480.     dc << "\nm_cEventsFrozen = " << m_cEventsFrozen;
  481.     dc << "\nm_rcPos = " << m_rcPos;
  482.     dc << "\nm_cxExtent = " << m_cxExtent;
  483.     dc << "\nm_cyExtent = " << m_cyExtent;
  484.     dc << "\nm_bFinalReleaseCalled = " << m_bFinalReleaseCalled;
  485.     dc << "\nm_bModified = " << m_bModified;
  486.     dc << "\nm_bCountOnAmbients = " << m_bCountOnAmbients;
  487.     dc << "\nm_iButtonState = " << m_iButtonState;
  488.     dc << "\nm_iDblClkState = " << m_iDblClkState;
  489.     dc << "\nm_bInPlaceActive = " << m_bInPlaceActive;
  490.     dc << "\nm_bUIActive = " << m_bUIActive;
  491.     dc << "\nm_bPendingUIActivation = " << m_bPendingUIActivation;
  492. #ifdef _AFXDLL
  493.     dc << "\nm_bOpen = " << m_bOpen;
  494. #endif
  495.     dc << "\nm_bChangingExtent = " << m_bChangingExtent;
  496.     dc << "\nm_bConvertVBX = " << m_bConvertVBX;
  497.     dc << "\nm_bSimpleFrame = " << m_bSimpleFrame;
  498.     dc << "\nm_bUIDead = " << m_bUIDead;
  499. }
  500.  
  501. #endif // _DEBUG
  502.  
  503. /////////////////////////////////////////////////////////////////////////////
  504. // _AfxFillPSOnStack (WINBUG)
  505. //
  506. // Windows has a bug in the WM_PAINT code for the Button control.  If the
  507. // paint is a sub-classed paint, and if the display driver is a Win3.0
  508. // display driver, then Windows calls IsRectEmpty, passing in the rectangle
  509. // from the paint structure.  Since it was a sub-classed paint, and
  510. // BeginPaint was not called, the rectangle struct passed to IsRectEmpty is
  511. // uninitialized.  If IsRectEmpty returned True, then the control was not
  512. // painted.  To work around the bug, we call FillPSOnStack before calling
  513. // windows with the WM_PAINT.  This routine fills a buffer on the stack
  514. // 0x80 bytes of consecutive values from 0 to 0x7f.  That way, if the
  515. // rectangle falls anywhere within this buffer range, and the stack has not
  516. // been modified by other means, then IsRectEmpty will return FALSE, so that
  517. // the control will Paint.
  518.  
  519. #define WORDBUFSIZE 0x40
  520.  
  521. void AFXAPI _AfxFillPSOnStack()
  522. {
  523.     // Stack hack needed on Win32s
  524.     WORD buf[WORDBUFSIZE];
  525.     WORD i;
  526.     WORD pat;
  527.  
  528.     for (i = 0, pat = 0x0100; i < WORDBUFSIZE; i++, pat += 0x0202)
  529.         buf[i] = pat;
  530. }
  531.  
  532. void COleControl::DoSuperclassPaint(CDC* pDC, const CRect& rcBounds)
  533. {
  534.     if (m_hWnd == NULL)
  535.         CreateWindowForSubclassedControl();
  536.  
  537.     if (m_hWnd != NULL)
  538.     {
  539.         CRect rcClient;
  540.         GetClientRect(&rcClient);
  541.  
  542.         if (rcClient.Size() != rcBounds.Size())
  543.         {
  544.             pDC->SetMapMode(MM_ANISOTROPIC);
  545.             pDC->SetWindowExt(rcClient.right, rcClient.bottom);
  546.             pDC->SetViewportExt(rcBounds.Size());
  547.         }
  548.         pDC->SetWindowOrg(0, 0);
  549.         pDC->SetViewportOrg(rcBounds.left, rcBounds.top);
  550.  
  551.         BOOL bWin4 = afxData.bWin4;
  552.         _AfxFillPSOnStack();
  553.         ::CallWindowProc(
  554.                 *GetSuperWndProcAddr(),
  555.                 m_hWnd, (bWin4 ? WM_PRINT : WM_PAINT),
  556.                 (WPARAM)(pDC->m_hDC),
  557.                 (LPARAM)(bWin4 ? PRF_CHILDREN | PRF_CLIENT : 0));
  558.     }
  559. }
  560.  
  561. BOOL COleControl::IsSubclassedControl()
  562. {
  563.     // This default implementation provides some degree of backward
  564.     // compatibility with old controls. New subclassed controls should just
  565.     // override IsSubclassedControl and return TRUE.
  566.     return m_pfnSuper == NULL &&
  567.         GetSuperWndProcAddr() != CWnd::GetSuperWndProcAddr();
  568. }
  569.  
  570. BOOL COleControl::CreateControlWindow(HWND hWndParent, const CRect& rcPos,
  571.     LPCRECT prcClip)
  572. {
  573.     if (m_hWnd == NULL)
  574.     {
  575.         // If window doesn't exist, create it.
  576.  
  577.         // Test if:
  578.         // we're not subclassing a Windows control, or
  579.         // container reflects messages for us...
  580.  
  581.         DWORD dwStyle = WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
  582.         if (m_sBorderStyle)
  583.             dwStyle |= WS_BORDER;
  584.         if (!m_bEnabled)
  585.             dwStyle |= WS_DISABLED;
  586.         DWORD dwExStyle = WS_EX_NOPARENTNOTIFY;
  587.         if (m_sAppearance)
  588.             dwExStyle |= WS_EX_CLIENTEDGE;
  589.  
  590.         // we create normally if:
  591.         //       (we're not subclassing -or- the container reflects)
  592.         // -and- the container autoclips for us
  593.         if ((!IsSubclassedControl() || m_bMsgReflect) && m_bAutoClip)
  594.         {
  595.             // Just create the control's window.
  596.             VERIFY(AfxDeferRegisterClass(AFX_WNDOLECONTROL_REG));
  597.             CreateEx(dwExStyle, AFX_WNDOLECONTROL, m_strText, dwStyle,
  598.                 rcPos.left, rcPos.top, rcPos.Width(), rcPos.Height(),
  599.                 hWndParent, 0);
  600.         }
  601.         else    // ...we're subclassing a Windows control.
  602.         {
  603.             if (m_pReflect == NULL)
  604.             {
  605.                 // Create a window to reflect notification messages.
  606.                 m_pReflect = new CReflectorWnd;
  607.                 if (prcClip == NULL)
  608.                     prcClip = rcPos;
  609.                 if (!m_pReflect->Create(prcClip, hWndParent))
  610.                 {
  611.                     // If m_pReflect->Create failed, then m_pReflect deleted itself.
  612.                     m_pReflect = NULL;
  613.                 }
  614.             }
  615.             else
  616.             {
  617.                 // Reflector window already exists... just reparent it.
  618.                 if (m_pReflect->m_hWnd != NULL)
  619.                 {
  620.                     ::SetParent(m_pReflect->m_hWnd, hWndParent);
  621.                     ::SetWindowPos(m_pReflect->m_hWnd, NULL, 0, 0, 0, 0,
  622.                         SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
  623.                         SWP_SHOWWINDOW);
  624.                 }
  625.             }
  626.  
  627.             if (m_pReflect != NULL && m_pReflect->m_hWnd != NULL)
  628.             {
  629.                 // Create the control's window.
  630.                 CreateEx(dwExStyle, NULL, m_strText, dwStyle,
  631.                     m_ptOffset.x, m_ptOffset.y, rcPos.Width(), rcPos.Height(),
  632.                     m_pReflect->m_hWnd, 0);
  633.                 if (m_hWnd == NULL)
  634.                 {
  635.                     // Window creation failed: cleanup.
  636.                     m_pReflect->DestroyWindow();
  637.                     m_pReflect = NULL;
  638.                 }
  639.             }
  640.         }
  641.  
  642.         // Set the new window's font.
  643.         OnFontChanged();
  644.     }
  645.     else
  646.     {
  647.         // If window does exist, reparent it...
  648.         CWnd* pWndOuter = GetOuterWindow();
  649.         ASSERT(pWndOuter != NULL);
  650.  
  651.         if (::GetParent(pWndOuter->m_hWnd) != hWndParent)
  652.             ReparentControlWindow(pWndOuter->m_hWnd, hWndParent);
  653.  
  654.         ::SetWindowPos(pWndOuter->m_hWnd, NULL, 0, 0, 0, 0,
  655.             SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
  656.             SWP_SHOWWINDOW);
  657.  
  658.         // And then reposition it...
  659.         OnSetObjectRects(rcPos, prcClip);
  660.     }
  661.  
  662.     ASSERT(m_hWnd != NULL);
  663.     return (m_hWnd != NULL);
  664. }
  665.  
  666. void COleControl::ReparentControlWindow(HWND hWndOuter, HWND hWndParent)
  667. {
  668.     // can be overridden by subclass, if necessary
  669.     ::SetParent(hWndOuter, hWndParent);
  670. }
  671.  
  672. void COleControl::GetControlSize(int* pcx, int* pcy)
  673. {
  674.     ASSERT_POINTER(pcx, int);
  675.     ASSERT_POINTER(pcy, int);
  676.  
  677.     SIZEL szlHimetric;
  678.     SIZEL szlPixels;
  679.     szlHimetric.cx = m_cxExtent;
  680.     szlHimetric.cy = m_cyExtent;
  681.     _AfxXformSizeInHimetricToPixels(NULL, &szlHimetric, &szlPixels);
  682.     *pcx = (int)szlPixels.cx;
  683.     *pcy = (int)szlPixels.cy;
  684. }
  685.  
  686. BOOL COleControl::SetControlSize(int cx, int cy)
  687. {
  688.     SIZEL szlPixels;
  689.     SIZEL szlHimetric;
  690.     szlPixels.cx = cx;
  691.     szlPixels.cy = cy;
  692.     _AfxXformSizeInPixelsToHimetric(NULL, &szlPixels, &szlHimetric);
  693.     return SUCCEEDED(m_xOleObject.SetExtent(DVASPECT_CONTENT, &szlHimetric));
  694. }
  695.  
  696. BOOL COleControl::SetRectInContainer(LPCRECT lpRect)
  697. {
  698.     if ((m_pInPlaceSite != NULL) && m_bInPlaceActive)
  699.     {
  700.         m_pInPlaceSite->OnPosRectChange(lpRect);
  701.         return TRUE;
  702.     }
  703. #ifdef _AFXDLL
  704.     else if (m_bOpen)
  705.     {
  706.         ResizeOpenControl(lpRect->right - lpRect->left,
  707.                 lpRect->bottom - lpRect->top);
  708.         return TRUE;
  709.     }
  710. #endif
  711.  
  712.     return FALSE;
  713. }
  714.  
  715. void COleControl::OnResetState()
  716. {
  717.     CResetPropExchange px;
  718.     DoPropExchange(&px);
  719.     InvalidateControl();
  720. }
  721.  
  722. #ifndef BDR_INNER
  723. #define BDR_INNER   0x000c
  724. #endif
  725. #ifndef BDR_OUTER
  726. #define BDR_OUTER   0x0003
  727. #endif
  728.  
  729. void AFXAPI _AfxDrawBorders(CDC* pDC, CRect& rc, BOOL bBorder, BOOL bClientEdge)
  730. {
  731.     if (bBorder)
  732.         ::DrawEdge(pDC->m_hDC, &rc, (bClientEdge ? BDR_INNER : BDR_OUTER),
  733.             BF_RECT | BF_ADJUST | (bClientEdge ? BF_FLAT : BF_MONO));
  734.  
  735.     if (bClientEdge)
  736.         ::DrawEdge(pDC->m_hDC, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
  737. }
  738.  
  739. void COleControl::DrawContent(CDC* pDC, CRect& rc)
  740. {
  741.     // Map into device coordinates.
  742.  
  743.     pDC->LPtoDP(&rc);
  744.     int iSaveDC = 0;
  745.     if (! m_bOptimizedDraw)
  746.         iSaveDC = pDC->SaveDC();
  747.     pDC->SetViewportOrg(0, 0);
  748.     pDC->SetWindowOrg(0, 0);
  749.     pDC->SetMapMode(MM_TEXT);
  750.     m_rcBounds = rc;
  751.     if (pDC->GetDeviceCaps(TECHNOLOGY) == DT_RASDISPLAY)
  752.         _AfxDrawBorders(pDC, rc, (m_sBorderStyle == 1), (m_sAppearance == 1));
  753.     OnDraw(pDC, rc, rc);
  754.     if (! m_bOptimizedDraw && iSaveDC != 0)
  755.         pDC->RestoreDC(iSaveDC);
  756. }
  757.  
  758. void COleControl::DrawMetafile(CDC* pDC, CRect& rc)
  759. {
  760.     int iSaveDC = 0;
  761.     if (! m_bOptimizedDraw)
  762.         iSaveDC = pDC->SaveDC();
  763.     m_rcBounds = rc;
  764.     _AfxDrawBorders(pDC, rc, (m_sBorderStyle == 1), (m_sAppearance == 1));
  765.     OnDrawMetafile(pDC, rc);
  766.     if (! m_bOptimizedDraw && iSaveDC != 0)
  767.         pDC->RestoreDC(iSaveDC);
  768. }
  769.  
  770. void COleControl::OnDraw(CDC*, const CRect&, const CRect&)
  771. {
  772.     // To be overridden by subclass.
  773. }
  774.  
  775. void COleControl::OnDrawMetafile(CDC* pDC, const CRect& rcBounds)
  776. {
  777.     // By default, we draw into metafile the same way we would draw to the
  778.     // screen.  This may be overridden by the subclass.
  779.  
  780.     OnDraw(pDC, rcBounds, rcBounds);
  781. }
  782.  
  783. BOOL COleControl::GetMetafileData(LPFORMATETC lpFormatEtc,
  784.         LPSTGMEDIUM lpStgMedium)
  785. {
  786.     ASSERT_VALID(this);
  787.     ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE));
  788.     ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));
  789.     ASSERT(lpStgMedium->tymed == TYMED_NULL);   // GetDataHere not valid
  790.     ASSERT(lpStgMedium->pUnkForRelease == NULL);
  791.  
  792.     // medium must be TYMED_MFPICT -- cannot fill in existing HGLOBAL
  793.     if (!(lpFormatEtc->tymed & TYMED_MFPICT) || lpStgMedium->hGlobal != NULL)
  794.         return FALSE;
  795.  
  796.     // create appropriate memory metafile DC
  797.     CMetaFileDC dc;
  798.     if (!dc.Create())
  799.         return FALSE;
  800.  
  801.     // create attribute DC according to lpFormatEtc->ptd
  802.     HDC hAttribDC = ::_AfxOleCreateDC(lpFormatEtc->ptd);
  803.     dc.SetAttribDC(hAttribDC);
  804.  
  805.     // Paint directly into the metafile.
  806.     int cx;
  807.     int cy;
  808.     GetControlSize(&cx, &cy);
  809.     CRect rc(0, 0, cx, cy);
  810.     dc.SetMapMode(MM_ANISOTROPIC);
  811.     dc.SetWindowOrg(0, 0);
  812.     dc.SetWindowExt(cx, cy);
  813.     DrawMetafile(&dc, rc);
  814.  
  815.     // attribute DC is no longer necessary
  816.     dc.SetAttribDC(NULL);
  817.     ::DeleteDC(hAttribDC);
  818.  
  819.     HMETAFILE hMF;
  820.     hMF = (HMETAFILE)dc.Close();
  821.     if (hMF == NULL)
  822.         return FALSE;
  823.  
  824.     HGLOBAL hPict;
  825.     if ((hPict = ::GlobalAlloc(GMEM_DDESHARE, sizeof(METAFILEPICT))) == NULL)
  826.     {
  827.         DeleteMetaFile(hMF);
  828.         return FALSE;
  829.     }
  830.     LPMETAFILEPICT lpPict;
  831.     if ((lpPict = (LPMETAFILEPICT)::GlobalLock(hPict)) == NULL)
  832.     {
  833.         DeleteMetaFile(hMF);
  834.         ::GlobalFree(hPict);
  835.         return FALSE;
  836.     }
  837.  
  838.     // set the metafile size
  839.     lpPict->mm = MM_ANISOTROPIC;
  840.     lpPict->hMF = hMF;
  841.     lpPict->xExt = (int)m_cxExtent;
  842.     lpPict->yExt = (int)m_cyExtent;
  843.  
  844.     // return the medium with the hGlobal to the METAFILEPICT
  845.     ::GlobalUnlock(hPict);
  846.     lpStgMedium->hGlobal = hPict;
  847.     lpStgMedium->tymed = TYMED_MFPICT;
  848.     return TRUE;
  849. }
  850.  
  851. BOOL COleControl::OnCreateAggregates()
  852. {
  853.     return TRUE;
  854. }
  855.  
  856. LPVOID COleControl::QueryDefHandler(REFIID iid)
  857. {
  858.     // If we're being aggregated, we want to pass the outer unknown
  859.     // to the object we're aggregating (the default handler).
  860.     // Otherwise, we pass our own "inner" unknown.
  861.     // That's what GetControllingUnknown() does.
  862.  
  863.     LPUNKNOWN pUnk = GetControllingUnknown();
  864.  
  865.     CLSID clsid;
  866.     GetClassID(&clsid);
  867.  
  868.     if (m_pDefIUnknown == NULL)
  869.     {
  870.         // Note: This call will not increment pUnk's reference count.
  871.         HRESULT hr = CreateDataCache(pUnk, clsid,
  872.             IID_IUnknown, (LPLPVOID)&m_pDefIUnknown);
  873.  
  874.         if (FAILED(hr))
  875.             return NULL;
  876.     }
  877.  
  878.     LPVOID pNew;
  879.  
  880.     // Note: For the following QueryInterface call, we want to prevent
  881.     // pUnk's reference count from being incremented.  So, if the
  882.     // call succeeds, we immediately force a decrement of the reference count.
  883.  
  884.     if (SUCCEEDED(m_pDefIUnknown->QueryInterface(iid, &pNew)))
  885.     {
  886.         ASSERT(pNew != NULL);
  887.         pUnk->Release();
  888.     }
  889.  
  890.     return pNew;
  891. }
  892.  
  893. void COleControl::InvalidateControl(LPCRECT lpRect, BOOL bErase)
  894. {
  895.     if (m_bInPlaceActive && m_bInPlaceSiteWndless)
  896.     {
  897.         CRect rect;
  898.         if (lpRect != NULL)
  899.         {
  900.             CPoint point(0, 0);
  901.             ClientToParent(m_rcPos, &point);
  902.             rect.CopyRect(lpRect);
  903.             rect.OffsetRect(point);
  904.             lpRect = ▭
  905.         }
  906.         m_pInPlaceSiteWndless->InvalidateRect(lpRect, bErase);
  907.     }
  908. #ifdef _AFXDLL
  909.     else if (m_bInPlaceActive || m_bOpen)
  910. #else
  911.     else if (m_bInPlaceActive)
  912. #endif
  913.     {
  914.         InvalidateRect(lpRect, bErase);
  915.     }
  916.     else
  917.     {
  918.         SendAdvise(OBJECTCODE_VIEWCHANGED);
  919.     }
  920.  
  921.     if (m_bModified)
  922.         SendAdvise(OBJECTCODE_DATACHANGED);
  923. }
  924.  
  925. CWnd* COleControl::GetOuterWindow() const
  926. {
  927.     return (m_pReflect != NULL ? (CWnd*)m_pReflect : (CWnd*)this);
  928. }
  929.  
  930. void COleControl::OnReflectorDestroyed()
  931. {
  932.     m_pReflect = NULL;
  933. }
  934.  
  935. HRESULT COleControl::SaveState(IStream* pstm)
  936. {
  937.     HRESULT hr = S_OK;
  938.  
  939.     TRY
  940.     {
  941.         // Delegate to the Serialize method.
  942.         COleStreamFile file(pstm);
  943.         CArchive ar(&file, CArchive::store);
  944.         Serialize(ar);
  945.     }
  946.     CATCH_ALL(e)
  947.     {
  948.         hr = E_FAIL;
  949.         DELETE_EXCEPTION(e);
  950.     }
  951.     END_CATCH_ALL
  952.  
  953.     return hr;
  954. }
  955.  
  956. HRESULT COleControl::LoadState(IStream* pstm)
  957. {
  958.     HRESULT hr = S_OK;
  959.  
  960.     TRY
  961.     {
  962.         // Delegate to the Serialize method.
  963.         COleStreamFile file(pstm);
  964.         CArchive ar(&file, CArchive::load);
  965.         Serialize(ar);
  966.     }
  967.     CATCH_ALL(e)
  968.     {
  969.         // The load failed.  Delete any partially-initialized state.
  970.         OnResetState();
  971.         m_bInitialized = TRUE;
  972.         hr = E_FAIL;
  973.         DELETE_EXCEPTION(e);
  974.     }
  975.     END_CATCH_ALL
  976.  
  977.     // Clear the modified flag.
  978.     m_bModified = FALSE;
  979.  
  980.     // Unless IOleObject::SetClientSite is called after this, we can
  981.     // count on ambient properties being available while loading.
  982.     m_bCountOnAmbients = TRUE;
  983.  
  984.     // Properties have been initialized
  985.     m_bInitialized = TRUE;
  986.  
  987.     // Uncache cached ambient properties
  988.     _afxAmbientCache->Cache(NULL);
  989.  
  990.     return hr;
  991. }
  992.  
  993. void COleControl::SendAdvise(UINT uCode)
  994. {
  995.     // Calls the appropriate IOleClientSite or IAdviseSink member function
  996.     // for various events such as closure, renaming, saving, etc.
  997.  
  998.     switch (uCode)
  999.     {
  1000.     case OBJECTCODE_SAVED:
  1001.         if (m_pOleAdviseHolder != NULL)
  1002.             m_pOleAdviseHolder->SendOnSave();
  1003.         break;
  1004.  
  1005.     case OBJECTCODE_CLOSED:
  1006.         if (m_pOleAdviseHolder != NULL)
  1007.             m_pOleAdviseHolder->SendOnClose();
  1008.         break;
  1009.  
  1010.     case OBJECTCODE_SAVEOBJECT:
  1011.         if (m_bModified && m_pClientSite != NULL)
  1012.             m_pClientSite->SaveObject();
  1013.         break;
  1014.  
  1015.     case OBJECTCODE_DATACHANGED:
  1016.         //No flags are necessary here.
  1017.         if (m_pDataAdviseHolder != NULL)
  1018.             m_pDataAdviseHolder->SendOnDataChange(&m_xDataObject, 0, 0);
  1019.         break;
  1020.  
  1021.     case OBJECTCODE_SHOWWINDOW:
  1022.         if (m_pClientSite != NULL)
  1023.             m_pClientSite->OnShowWindow(TRUE);
  1024.         break;
  1025.  
  1026.     case OBJECTCODE_HIDEWINDOW:
  1027.         if (m_pClientSite != NULL)
  1028.             m_pClientSite->OnShowWindow(FALSE);
  1029.         break;
  1030.  
  1031.     case OBJECTCODE_SHOWOBJECT:
  1032.         if (m_pClientSite != NULL)
  1033.             m_pClientSite->ShowObject();
  1034.         break;
  1035.  
  1036.     case OBJECTCODE_VIEWCHANGED:
  1037.         {
  1038.             DWORD aspects;
  1039.             DWORD advf;
  1040.             LPADVISESINK pAdvSink;
  1041.  
  1042.             if (SUCCEEDED(m_xViewObject.GetAdvise(&aspects, &advf, &pAdvSink)) &&
  1043.                 (pAdvSink != NULL))
  1044.             {
  1045.                 pAdvSink->OnViewChange(DVASPECT_CONTENT, -1);
  1046.                 pAdvSink->Release();
  1047.             }
  1048.         }
  1049.         break;
  1050.     }
  1051. }
  1052.  
  1053. HRESULT COleControl::OnHide()
  1054. {
  1055. #ifdef _AFXDLL
  1056.     CWnd* pWnd = m_bOpen ? m_pWndOpenFrame : GetOuterWindow();
  1057. #else
  1058.     CWnd* pWnd = GetOuterWindow();
  1059. #endif
  1060.     if (pWnd != NULL && pWnd->m_hWnd != NULL)
  1061.         ::ShowWindow(pWnd->m_hWnd, SW_HIDE);
  1062.  
  1063.     RELEASE(m_pInPlaceFrame);
  1064.     RELEASE(m_pInPlaceDoc);
  1065.  
  1066. #ifdef _AFXDLL
  1067.     if (m_bOpen)
  1068.         SendAdvise(OBJECTCODE_HIDEWINDOW);
  1069. #endif
  1070.  
  1071.     return S_OK;
  1072. }
  1073.  
  1074. HRESULT COleControl::OnOpen(BOOL bTryInPlace, LPMSG pMsg)
  1075. {
  1076. #ifndef _AFXDLL
  1077.     ASSERT(bTryInPlace);    // fully-open mode not supported in static builds
  1078.     UNUSED_ALWAYS(bTryInPlace);
  1079. #endif
  1080.  
  1081. #ifndef _AFXDLL
  1082.     return OnActivateInPlace(TRUE, pMsg);
  1083. #else
  1084.     if (!m_bOpen)
  1085.     {
  1086.         // If not already open, try in-place activating.
  1087.         if (bTryInPlace && SUCCEEDED(OnActivateInPlace(bTryInPlace, pMsg)))
  1088.             return S_OK;
  1089.  
  1090.         // If already in-place active, deactivate first.
  1091.         if (m_bInPlaceActive)
  1092.             m_xOleInPlaceObject.InPlaceDeactivate();
  1093.  
  1094.         m_bOpen = TRUE;
  1095.  
  1096.         // Open a separate window.
  1097.         if (m_pWndOpenFrame == NULL)
  1098.         {
  1099.             // Create frame window
  1100.             m_pWndOpenFrame = CreateFrameWindow();
  1101.  
  1102.             if (m_pWndOpenFrame == NULL)
  1103.                 return E_FAIL;
  1104.  
  1105.             // Size frame window to exactly contain the control.
  1106.             int cx;
  1107.             int cy;
  1108.             GetControlSize(&cx, &cy);
  1109.             ResizeFrameWindow(cx, cy);
  1110.  
  1111.             // Create and/or reparent the control's window.
  1112.             CRect rectClient;
  1113.             m_pWndOpenFrame->GetClientRect(&rectClient);
  1114.             if (!CreateControlWindow(m_pWndOpenFrame->m_hWnd, rectClient, rectClient))
  1115.                 return E_FAIL;
  1116.         }
  1117.     }
  1118.  
  1119.     // Make the frame window visible and activate it.
  1120.     ASSERT(m_pWndOpenFrame != NULL);
  1121.     m_pWndOpenFrame->ShowWindow(SW_SHOW);
  1122.     m_pWndOpenFrame->SetActiveWindow();
  1123.     SendAdvise(OBJECTCODE_SHOWWINDOW);
  1124.     return S_OK;
  1125. #endif
  1126. }
  1127.  
  1128. #ifdef _AFXDLL
  1129. CControlFrameWnd* COleControl::CreateFrameWindow()
  1130. {
  1131.     TCHAR szUserType[256];
  1132.     GetUserType(szUserType);
  1133.  
  1134.     CControlFrameWnd* pWnd = new CControlFrameWnd(this);
  1135.     if (!pWnd->Create(szUserType))
  1136.     {
  1137.         // If Create failed, then frame window has deleted itself.
  1138.         pWnd = NULL;
  1139.     }
  1140.  
  1141.     return pWnd;
  1142. }
  1143.  
  1144. void COleControl::OnFrameClose()
  1145. {
  1146.     // Reparent control to prevent its window from being destroyed.
  1147.     CWnd* pWnd = GetOuterWindow();
  1148.     if (pWnd != NULL)
  1149.     {
  1150.         ::SetWindowPos(pWnd->m_hWnd, NULL, 0, 0, 0, 0,
  1151.             SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
  1152.             SWP_HIDEWINDOW);
  1153.         pWnd->SetParent(NULL);
  1154.     }
  1155.  
  1156.     m_pWndOpenFrame = NULL;
  1157.     m_bOpen = FALSE;
  1158.  
  1159.     m_xOleObject.Close(OLECLOSE_SAVEIFDIRTY);
  1160.  
  1161.     SendAdvise(OBJECTCODE_HIDEWINDOW);
  1162.     SendAdvise(OBJECTCODE_CLOSED);
  1163. }
  1164.  
  1165. void COleControl::ResizeOpenControl(int cx, int cy)
  1166. {
  1167.     CWnd* pWndOuter = GetOuterWindow();
  1168.     if ((pWndOuter != NULL) && (pWndOuter->m_hWnd != NULL))
  1169.         ::SetWindowPos(pWndOuter->m_hWnd, NULL, 0, 0, cx, cy,
  1170.                     SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
  1171.     ResizeFrameWindow(cx, cy);
  1172. }
  1173.  
  1174. void COleControl::ResizeFrameWindow(int cxCtrl, int cyCtrl)
  1175. {
  1176.     m_pWndOpenFrame->SetWindowPos(NULL, 0, 0, 100, 100,
  1177.                 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
  1178.     CRect rectClient;
  1179.     m_pWndOpenFrame->GetClientRect(&rectClient);
  1180.     CRect rectWindow;
  1181.     m_pWndOpenFrame->GetWindowRect(&rectWindow);
  1182.     int cx = cxCtrl + rectWindow.Width()  - rectClient.Width();
  1183.     int cy = cyCtrl + rectWindow.Height() - rectClient.Height();
  1184.     m_pWndOpenFrame->SetWindowPos(NULL, 0, 0, cx, cy,
  1185.                 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
  1186. }
  1187.  
  1188. #endif //_AFXDLL
  1189.  
  1190. BOOL COleControl::GetRectInContainer(LPRECT lpRect)
  1191. {
  1192.     if (m_bInPlaceActive)
  1193.         CopyRect(lpRect, &m_rcPos);
  1194.  
  1195.     return m_bInPlaceActive;
  1196. }
  1197.  
  1198. LPCLSID COleControl::GetPropPageIDs(ULONG& cPropPages)
  1199. {
  1200.     cPropPages = 0;
  1201.     return NULL;
  1202. }
  1203.  
  1204. BOOL COleControl::OnEdit(LPMSG lpMsg, HWND, LPCRECT lpRect)
  1205. {
  1206.     CopyRect(m_rcPos, lpRect);
  1207.     return SUCCEEDED(OnActivateInPlace(TRUE, lpMsg));
  1208. }
  1209.  
  1210. HWND AFXAPI _AfxGetTopLevelWindow(HWND hWnd)
  1211. {
  1212.     HWND hWndTop;
  1213.  
  1214.     do
  1215.     {
  1216.         hWndTop = hWnd;
  1217.         hWnd = ::GetParent(hWnd);
  1218.     }
  1219.     while (hWnd != NULL);
  1220.  
  1221.     return hWndTop;
  1222. }
  1223.  
  1224. BOOL COleControl::OnProperties(LPMSG, HWND hWndParent, LPCRECT)
  1225. {
  1226.     USES_CONVERSION;
  1227.  
  1228.     HRESULT hr;
  1229.  
  1230.     if ((m_pControlSite == NULL) ||
  1231.         FAILED(hr = m_pControlSite->ShowPropertyFrame()))
  1232.     {
  1233.         LPUNKNOWN pUnk = GetIDispatch(FALSE);
  1234.         HWND hWndOwner = CWnd::GetSafeOwner_(hWndParent, NULL);
  1235.  
  1236.         LCID lcid = AmbientLocaleID();
  1237.  
  1238.         ULONG cPropPages;
  1239.         LPCLSID pclsidPropPages = GetPropPageIDs(cPropPages);
  1240.  
  1241.         RECT rectParent;
  1242.         RECT rectTop;
  1243.         ::GetWindowRect(hWndParent, &rectParent);
  1244.         ::GetWindowRect(hWndOwner, &rectTop);
  1245.  
  1246.         TCHAR szUserType[256];
  1247.         GetUserType(szUserType);
  1248.  
  1249.         PreModalDialog(hWndOwner);
  1250.         hr = ::OleCreatePropertyFrame(hWndOwner, rectParent.left - rectTop.left,
  1251.                 rectParent.top - rectTop.top, T2COLE(szUserType), 1, &pUnk,
  1252.                 cPropPages, pclsidPropPages, lcid, NULL, 0);
  1253.         PostModalDialog(hWndOwner);
  1254.     }
  1255.  
  1256.     return SUCCEEDED(hr);
  1257. }
  1258.  
  1259. DWORD COleControl::GetControlFlags()
  1260. {
  1261.     return clipPaintDC;
  1262. }
  1263.  
  1264. void COleControl::OnPaint(CDC* pDC)
  1265. {
  1266.     if (m_bNoRedraw)
  1267.     {
  1268.         // flicker-free activation: no need to repaint
  1269.         ValidateRect(NULL);
  1270.         m_bNoRedraw = FALSE;    // one time only
  1271.         return;
  1272.     }
  1273.  
  1274.     AfxLockTempMaps();
  1275.  
  1276.     GetWindowRect(m_rcBounds);
  1277.     m_rcBounds.OffsetRect(-m_rcBounds.left, -m_rcBounds.top);
  1278.  
  1279.     // Adjust bounds for size of UI Active tracker, if any.
  1280. #ifdef _AFXDLL
  1281.     if (!m_bOpen && (m_pRectTracker != NULL))
  1282. #else
  1283.     if (m_pRectTracker != NULL)
  1284. #endif
  1285.     {
  1286.         int nHandleSize = (int)m_pRectTracker->m_nHandleSize - 1;
  1287.         m_rcBounds.InflateRect(-nHandleSize, -nHandleSize);
  1288.     }
  1289.  
  1290.     CRect rcClient;
  1291.     GetClientRect(rcClient);
  1292.  
  1293.     if (pDC != NULL)
  1294.     {
  1295.         // We were passed a device context: use it.
  1296.         int iSaveDC = pDC->SaveDC();
  1297.         OnDraw(pDC, rcClient, rcClient);
  1298.         pDC->RestoreDC(iSaveDC);
  1299.     }
  1300.     else
  1301.     {
  1302. #ifdef _DEBUG
  1303.         int nFlags = GetControlFlags();
  1304.         if (nFlags & fastBeginPaint)
  1305.             TRACE0("Warning: COleControl::fastBeginPaint is obsolete.\n");
  1306. #endif
  1307.  
  1308.         CPaintDC dc(this);
  1309.         OnDraw(&dc, rcClient, &dc.m_ps.rcPaint);
  1310.     }
  1311.  
  1312.     AfxUnlockTempMaps();
  1313. }
  1314.  
  1315. BOOL COleControl::OnEraseBkgnd(CDC* pDC)
  1316. {
  1317.     // do nothing -- controls erase their background in their OnDraw
  1318.     if (IsSubclassedControl())
  1319.         return CWnd::OnEraseBkgnd(pDC);
  1320.     else
  1321.         return TRUE;
  1322. }
  1323.  
  1324. void  COleControl::Serialize(CArchive& ar)
  1325. {
  1326.     CArchivePropExchange px(ar);
  1327.     DoPropExchange(&px);
  1328.     if (ar.IsLoading())
  1329.     {
  1330.         BoundPropertyChanged(DISPID_UNKNOWN);
  1331.         InvalidateControl();
  1332.     }
  1333. }
  1334.  
  1335. void COleControl::DoPropExchange(CPropExchange* pPX)
  1336. {
  1337.     ASSERT_POINTER(pPX, CPropExchange);
  1338.  
  1339.     ExchangeExtent(pPX);
  1340.     ExchangeStockProps(pPX);
  1341. }
  1342.  
  1343. /////////////////////////////////////////////////////////////////////////////
  1344. // Wrappers for IOleControlSite
  1345.  
  1346. void COleControl::ControlInfoChanged()
  1347. {
  1348.     if (m_pControlSite != NULL)
  1349.         m_pControlSite->OnControlInfoChanged();
  1350. }
  1351.  
  1352. BOOL COleControl::LockInPlaceActive(BOOL bLock)
  1353. {
  1354.     if (m_pControlSite != NULL)
  1355.         return SUCCEEDED(m_pControlSite->LockInPlaceActive(bLock));
  1356.  
  1357.     return FALSE;
  1358. }
  1359.  
  1360. LPDISPATCH COleControl::GetExtendedControl()
  1361. {
  1362.     LPDISPATCH pDispatch = NULL;
  1363.     if (m_pControlSite != NULL)
  1364.         m_pControlSite->GetExtendedControl(&pDispatch);
  1365.  
  1366.     return pDispatch;
  1367. }
  1368.  
  1369. void COleControl::TransformCoords(POINTL* lpptlHimetric,
  1370.     POINTF* lpptfContainer, DWORD flags)
  1371. {
  1372.     if ((m_pControlSite == NULL) ||
  1373.         (FAILED(m_pControlSite->TransformCoords(lpptlHimetric,
  1374.             lpptfContainer, flags))))
  1375.     {
  1376.         // Transformation failed, use the identity transformation
  1377.  
  1378.         if (flags & XFORMCOORDS_CONTAINERTOHIMETRIC)
  1379.         {
  1380.             lpptlHimetric->x = (long)lpptfContainer->x;
  1381.             lpptlHimetric->y = (long)lpptfContainer->y;
  1382.         }
  1383.         else
  1384.         {
  1385.             lpptfContainer->x = (float)lpptlHimetric->x;
  1386.             lpptfContainer->y = (float)lpptlHimetric->y;
  1387.         }
  1388.     }
  1389. }
  1390.  
  1391. /////////////////////////////////////////////////////////////////////////////
  1392. // COleControl::XOleControl
  1393.  
  1394. STDMETHODIMP_(ULONG) COleControl::XOleControl::AddRef()
  1395. {
  1396.     METHOD_PROLOGUE_EX_(COleControl, OleControl)
  1397.     return (ULONG)pThis->ExternalAddRef();
  1398. }
  1399.  
  1400. STDMETHODIMP_(ULONG) COleControl::XOleControl::Release()
  1401. {
  1402.     METHOD_PROLOGUE_EX_(COleControl, OleControl)
  1403.     return (ULONG)pThis->ExternalRelease();
  1404. }
  1405.  
  1406. STDMETHODIMP COleControl::XOleControl::QueryInterface(
  1407.     REFIID iid, LPVOID* ppvObj)
  1408. {
  1409.     METHOD_PROLOGUE_EX_(COleControl, OleControl)
  1410.     return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
  1411. }
  1412.  
  1413. STDMETHODIMP COleControl::XOleControl::GetControlInfo(LPCONTROLINFO pCI)
  1414. {
  1415.     METHOD_PROLOGUE_EX(COleControl, OleControl)
  1416.     pThis->OnGetControlInfo(pCI);
  1417.     return S_OK;
  1418. }
  1419.  
  1420. STDMETHODIMP COleControl::XOleControl::OnMnemonic(LPMSG pMsg)
  1421. {
  1422.     METHOD_PROLOGUE_EX(COleControl, OleControl)
  1423.     pThis->OnMnemonic(pMsg);
  1424.     return S_OK;
  1425. }
  1426.  
  1427. STDMETHODIMP COleControl::XOleControl::OnAmbientPropertyChange(DISPID dispid)
  1428. {
  1429.     METHOD_PROLOGUE_EX(COleControl, OleControl)
  1430.  
  1431.     if (dispid == DISPID_AMBIENT_UIDEAD || dispid == DISPID_UNKNOWN)
  1432.         pThis->m_bUIDead = (BYTE)(pThis->AmbientUIDead());
  1433.  
  1434.     pThis->OnAmbientPropertyChange(dispid);
  1435.     return S_OK;
  1436. }
  1437.  
  1438. STDMETHODIMP COleControl::XOleControl::FreezeEvents(BOOL bFreeze)
  1439. {
  1440.     METHOD_PROLOGUE_EX(COleControl, OleControl)
  1441.  
  1442.     ULONG& cEventsFrozen = pThis->m_cEventsFrozen;
  1443.  
  1444.     if (bFreeze)
  1445.         ++(cEventsFrozen);
  1446.     else
  1447.         --(cEventsFrozen);
  1448.  
  1449.     ASSERT(cEventsFrozen >= 0); // Should never go below zero!
  1450.  
  1451.     if ((cEventsFrozen == 1 && bFreeze) ||
  1452.         (cEventsFrozen == 0 && !bFreeze))
  1453.     {
  1454.         pThis->OnFreezeEvents(bFreeze);
  1455.     }
  1456.  
  1457.     return S_OK;
  1458. }
  1459.  
  1460. void COleControl::OnGetControlInfo(LPCONTROLINFO pControlInfo)
  1461. {
  1462.     // Subclass may override
  1463.  
  1464.     pControlInfo->hAccel = NULL;
  1465.     pControlInfo->cAccel = 0;
  1466.     pControlInfo->dwFlags = 0;
  1467. }
  1468.  
  1469. void COleControl::OnMnemonic(LPMSG)
  1470. {
  1471.     // To be implemented by subclass
  1472. }
  1473.  
  1474. void COleControl::OnAmbientPropertyChange(DISPID)
  1475. {
  1476.     // To be implemented by subclass
  1477. }
  1478.  
  1479. void COleControl::OnFreezeEvents(BOOL)
  1480. {
  1481.     // To be implemented by subclass
  1482. }
  1483.  
  1484. void COleControl::OnSetClientSite()
  1485. {
  1486.     if (!m_bDataPathPropertiesLoaded)
  1487.     {
  1488.         CAsyncPropExchange PX(m_dwDataPathVersionToReport);
  1489.         DoPropExchange(&PX);
  1490.         m_bDataPathPropertiesLoaded=TRUE;
  1491.     }
  1492. }
  1493.  
  1494. LPOLECLIENTSITE COleControl::GetClientSite()
  1495. {
  1496.     return m_pClientSite;
  1497. }
  1498.  
  1499. COLORREF COleControl::TranslateColor(OLE_COLOR clrColor, HPALETTE hpal)
  1500. {
  1501.     COLORREF cr = RGB(0x00,0x00,0x00);
  1502.     ::OleTranslateColor(clrColor, hpal, &cr);
  1503.     return cr;
  1504. }
  1505.  
  1506. void COleControl::Refresh()
  1507. {
  1508.     InvalidateControl();
  1509.     if (m_hWnd != NULL)
  1510.         UpdateWindow();
  1511. }
  1512.  
  1513. void COleControl::DoClick()
  1514. {
  1515.     OnClick(LEFT_BUTTON);
  1516. }
  1517.  
  1518. BOOL COleControl::OnNcCreate(LPCREATESTRUCT lpCreateStruct)
  1519. {
  1520.     if (m_pReflect != NULL)
  1521.         m_pReflect->SetControl(this);
  1522.  
  1523.     return CWnd::OnNcCreate(lpCreateStruct);
  1524. }
  1525.  
  1526. void COleControl::RecreateControlWindow()
  1527. {
  1528.     if (m_bInPlaceActive)
  1529.     {
  1530.         BOOL bUIActive = m_bUIActive;
  1531.         m_xOleInPlaceObject.InPlaceDeactivate();
  1532.         DestroyWindow();
  1533.         OnActivateInPlace(bUIActive, NULL);
  1534.     }
  1535. #ifdef _AFXDLL
  1536.     else if (m_bOpen)
  1537.     {
  1538.         DestroyWindow();
  1539.         CRect rectClient;
  1540.         m_pWndOpenFrame->GetClientRect(&rectClient);
  1541.         CreateControlWindow(m_pWndOpenFrame->m_hWnd, rectClient, rectClient);
  1542.     }
  1543. #endif //_AFXDLL
  1544.     else
  1545.     {
  1546.         HWND hWndParent = _AfxGetParkingWindow();
  1547.         if (hWndParent != NULL)
  1548.         {
  1549.             DestroyWindow();
  1550.             int cx;
  1551.             int cy;
  1552.             GetControlSize(&cx, &cy);
  1553.             CRect rect(0, 0, cx, cy);
  1554.             CreateControlWindow(hWndParent, rect);
  1555.         }
  1556.     }
  1557. }
  1558.  
  1559. void COleControl::CreateWindowForSubclassedControl()
  1560. {
  1561.     if (IsSubclassedControl() && (m_hWnd == NULL))
  1562.     {
  1563.         // If this is a subclassed control, we should create the window
  1564.         // for it now, in case the window is needed by the DoSuperclassPaint
  1565.         // implementation.
  1566.  
  1567.         HWND hWndParent = _AfxGetParkingWindow();
  1568.         if (hWndParent != NULL)
  1569.         {
  1570.             SIZEL szlHimetric;
  1571.             SIZEL szlPixels;
  1572.             szlHimetric.cx = m_cxExtent;
  1573.             szlHimetric.cy = m_cyExtent;
  1574.             _AfxXformSizeInHimetricToPixels(NULL, &szlHimetric, &szlPixels);
  1575.             CRect rcPos(0, 0, (int)szlPixels.cx, (int)szlPixels.cy);
  1576.             CreateControlWindow(hWndParent, rcPos);
  1577.         }
  1578.     }
  1579. }
  1580.  
  1581. int COleControl::OnMouseActivate(CWnd *pDesktopWnd, UINT nHitTest, UINT message)
  1582. {
  1583.     if (m_bInPlaceActive && !m_bUIActive)
  1584.         m_bPendingUIActivation = TRUE;
  1585.  
  1586.     return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
  1587. }
  1588.  
  1589. void COleControl::PreModalDialog(HWND hWndParent)
  1590. {
  1591.     if (m_pInPlaceFrame != NULL)
  1592.     {
  1593.         m_pInPlaceFrame->EnableModeless(FALSE);
  1594.     }
  1595.     else
  1596.     {
  1597.         HWND hWndTop = _AfxGetTopLevelWindow(hWndParent);
  1598.         if (hWndTop != NULL)
  1599.             ::EnableWindow(hWndTop, FALSE);
  1600.     }
  1601. }
  1602.  
  1603. void COleControl::PostModalDialog(HWND hWndParent)
  1604. {
  1605.     if (m_pInPlaceFrame != NULL)
  1606.     {
  1607.         m_pInPlaceFrame->EnableModeless(TRUE);
  1608.     }
  1609.     else
  1610.     {
  1611.         HWND hWndTop = _AfxGetTopLevelWindow(hWndParent);
  1612.         if (hWndTop != NULL)
  1613.             ::EnableWindow(hWndTop, TRUE);
  1614.     }
  1615. }
  1616.  
  1617. void COleControl::SetModifiedFlag(BOOL bModified)
  1618. {
  1619.     m_bModified = (BYTE)bModified;
  1620. }
  1621.  
  1622. BOOL COleControl::IsModified()
  1623. {
  1624.     return m_bModified;
  1625. }
  1626.  
  1627. BOOL COleControl::WillAmbientsBeValidDuringLoad()
  1628. {
  1629.     return m_bCountOnAmbients;
  1630. }
  1631.  
  1632. void COleControl::EnableSimpleFrame()
  1633. {
  1634.     m_bSimpleFrame = TRUE;
  1635. }
  1636.  
  1637. BOOL COleControl::IgnoreWindowMessage(UINT msg, WPARAM wParam, LPARAM lParam,
  1638.     LRESULT* plResult)
  1639. {
  1640.     if (!m_bUIDead)
  1641.         return FALSE;
  1642.  
  1643.     switch (msg)
  1644.     {
  1645.     case WM_NCHITTEST:
  1646.         *plResult = HTNOWHERE;
  1647.         return TRUE;
  1648.  
  1649.     case WM_SETCURSOR:
  1650.         *plResult = ::SendMessage(::GetParent(m_hWnd), msg, wParam, lParam);
  1651.         return TRUE;
  1652.     }
  1653.  
  1654.     if ((msg >= WM_KEYFIRST) && (msg <= WM_KEYLAST))
  1655.     {
  1656.         *plResult = 0;
  1657.         return TRUE;
  1658.     }
  1659.  
  1660.     return FALSE;
  1661. }
  1662.  
  1663. LRESULT COleControl::WindowProc(UINT msg, WPARAM wParam, LPARAM lParam)
  1664. {
  1665.     DWORD dwCookie;
  1666.     LRESULT lResult;
  1667.     HRESULT hr;
  1668.  
  1669.     ExternalAddRef();   // "Insurance" addref -- keeps control alive
  1670.  
  1671.     // allow OCM_ reflections to be handled by ON_XXX_REFLECT macros
  1672.     switch (msg)
  1673.     {
  1674.     case OCM_COMMAND:
  1675.     case OCM_CTLCOLORBTN:
  1676.     case OCM_CTLCOLOREDIT:
  1677.     case OCM_CTLCOLORDLG:
  1678.     case OCM_CTLCOLORLISTBOX:
  1679.     case OCM_CTLCOLORMSGBOX:
  1680.     case OCM_CTLCOLORSCROLLBAR:
  1681.     case OCM_CTLCOLORSTATIC:
  1682.     case OCM_DRAWITEM:
  1683.     case OCM_MEASUREITEM:
  1684.     case OCM_DELETEITEM:
  1685.     case OCM_VKEYTOITEM:
  1686.     case OCM_CHARTOITEM:
  1687.     case OCM_COMPAREITEM:
  1688.     case OCM_HSCROLL:
  1689.     case OCM_VSCROLL:
  1690.     case OCM_PARENTNOTIFY:
  1691.     case OCM_NOTIFY:
  1692.         if (ReflectChildNotify(msg-OCM__BASE, wParam, lParam, &lResult))
  1693.         {
  1694.             ExternalRelease();
  1695.             return lResult;
  1696.         }
  1697.     }
  1698.  
  1699.     // Give the simple frame site the opportunity to filter the message
  1700.     if ((m_pSimpleFrameSite != NULL) &&
  1701.         SUCCEEDED(hr = m_pSimpleFrameSite->PreMessageFilter(
  1702.             m_hWnd, msg, wParam, lParam, &lResult, &dwCookie)))
  1703.     {
  1704.         if (hr == S_OK)
  1705.         {
  1706.             if (!IgnoreWindowMessage(msg, wParam, lParam, &lResult))
  1707.                 lResult = CWnd::WindowProc(msg, wParam, lParam);
  1708.  
  1709.             // Simple frame site may have been cleared...
  1710.             // check before calling again.
  1711.  
  1712.             if (m_pSimpleFrameSite != NULL)
  1713.                 m_pSimpleFrameSite->PostMessageFilter(
  1714.                     m_hWnd, msg, wParam, lParam, &lResult, dwCookie);
  1715.         }
  1716.     }
  1717.     else
  1718.     {
  1719.         if (!IgnoreWindowMessage(msg, wParam, lParam, &lResult))
  1720.             lResult = CWnd::WindowProc(msg, wParam, lParam);
  1721.     }
  1722.  
  1723.     ExternalRelease();
  1724.  
  1725.     return lResult;
  1726. }
  1727.  
  1728. LRESULT COleControl::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
  1729. {
  1730.     if (m_hWnd != NULL)
  1731.         return CWnd::DefWindowProc(nMsg, wParam, lParam);
  1732.     else
  1733.         return 0;
  1734. }
  1735.  
  1736. int COleControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
  1737. {
  1738.     if (IsSubclassedControl())
  1739.         return CWnd::OnCreate(lpCreateStruct);
  1740.     else
  1741.         return 0;
  1742. }
  1743.  
  1744. void COleControl::OnSize(UINT nType, int cx, int cy)
  1745. {
  1746.     if (IsSubclassedControl())
  1747.         CWnd::OnSize(nType, cx, cy);
  1748. }
  1749.  
  1750. void COleControl::OnMove(int x, int y)
  1751. {
  1752.     if (IsSubclassedControl())
  1753.         CWnd::OnMove(x, y);
  1754. }
  1755.  
  1756. void COleControl::OnShowWindow(BOOL bShow, UINT nStatus)
  1757. {
  1758.     if (IsSubclassedControl())
  1759.         CWnd::OnShowWindow(bShow, nStatus);
  1760. }
  1761.  
  1762. /////////////////////////////////////////////////////////////////////////////
  1763. // Command prompts
  1764.  
  1765. void COleControl::OnInitMenuPopup(CMenu* pMenu, UINT, BOOL bSysMenu)
  1766. {
  1767.     AfxCancelModes(m_hWnd);
  1768.  
  1769.     if (bSysMenu)
  1770.         return;     // don't support system menu
  1771.  
  1772.     ASSERT(pMenu != NULL);
  1773.     // check the enabled state of various menu items
  1774.  
  1775.     CCmdUI state;
  1776.     state.m_pMenu = pMenu;
  1777.     ASSERT(state.m_pOther == NULL);
  1778.     ASSERT(state.m_pParentMenu == NULL);
  1779.  
  1780.     // determine if menu is popup in top-level menu and set m_pOther to
  1781.     // it if so (m_pParentMenu == NULL indicates that it is secondary popup)
  1782.     HMENU hParentMenu;
  1783.     if (_afxTrackingMenu == pMenu->m_hMenu)
  1784.         state.m_pParentMenu = pMenu;    // parent == child for tracking popup
  1785.     else
  1786.     {
  1787.         CWnd* pParent = GetTopLevelParent();
  1788.             // child windows don't have menus -- need to go to the top!
  1789.         if (pParent != NULL &&
  1790.             (hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
  1791.         {
  1792.             int nIndexMax = ::GetMenuItemCount(hParentMenu);
  1793.             for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
  1794.             {
  1795.                 if (::GetSubMenu(hParentMenu, nIndex) == pMenu->m_hMenu)
  1796.                 {
  1797.                     // when popup is found, m_pParentMenu is containing menu
  1798.                     state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
  1799.                     break;
  1800.                 }
  1801.             }
  1802.         }
  1803.     }
  1804.  
  1805.     state.m_nIndexMax = pMenu->GetMenuItemCount();
  1806.     for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
  1807.       state.m_nIndex++)
  1808.     {
  1809.         state.m_nID = pMenu->GetMenuItemID(state.m_nIndex);
  1810.         if (state.m_nID == 0)
  1811.             continue; // menu separator or invalid cmd - ignore it
  1812.  
  1813.         ASSERT(state.m_pOther == NULL);
  1814.         ASSERT(state.m_pMenu != NULL);
  1815.         if (state.m_nID == (UINT)-1)
  1816.         {
  1817.             // possibly a popup menu, route to first item of that popup
  1818.             state.m_pSubMenu = pMenu->GetSubMenu(state.m_nIndex);
  1819.             if (state.m_pSubMenu == NULL ||
  1820.                 (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
  1821.                 state.m_nID == (UINT)-1)
  1822.             {
  1823.                 continue;       // first item of popup can't be routed to
  1824.             }
  1825.             state.DoUpdate(this, FALSE);    // popups are never auto disabled
  1826.         }
  1827.         else
  1828.         {
  1829.             // normal menu item
  1830.             // Auto enable/disable if frame window has 'm_bAutoMenuEnable'
  1831.             // set and command is _not_ a system command.
  1832.             state.m_pSubMenu = NULL;
  1833.             state.DoUpdate(this, m_bAutoMenuEnable && state.m_nID < 0xF000);
  1834.         }
  1835.     }
  1836. }
  1837.  
  1838. void COleControl::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU /*hSysMenu*/)
  1839. {
  1840.     // set the tracking state (update on idle)
  1841.     if (nFlags == 0xFFFF)
  1842.     {
  1843.         m_nIDTracking = AFX_IDS_IDLEMESSAGE;
  1844.         SendMessage(WM_SETMESSAGESTRING, (WPARAM)m_nIDTracking);
  1845.         ASSERT(m_nIDTracking == m_nIDLastMessage);
  1846.     }
  1847.     else if (nItemID == 0 ||
  1848.         nFlags & (MF_SEPARATOR|MF_POPUP|MF_MENUBREAK|MF_MENUBARBREAK))
  1849.     {
  1850.         // nothing should be displayed
  1851.         m_nIDTracking = 0;
  1852.     }
  1853.     else if (nItemID >= 0xF000 && nItemID < 0xF1F0) // max of 31 SC_s
  1854.     {
  1855.         // special strings table entries for system commands
  1856.         m_nIDTracking = ID_COMMAND_FROM_SC(nItemID);
  1857.         ASSERT(m_nIDTracking >= AFX_IDS_SCFIRST &&
  1858.             m_nIDTracking < AFX_IDS_SCFIRST + 31);
  1859.     }
  1860.     else if (nItemID >= AFX_IDM_FIRST_MDICHILD)
  1861.     {
  1862.         // all MDI Child windows map to the same help id
  1863.         m_nIDTracking = AFX_IDS_MDICHILD;
  1864.     }
  1865.     else
  1866.     {
  1867.         // track on idle
  1868.         m_nIDTracking = nItemID;
  1869.     }
  1870.  
  1871.     // when running in-place, it is necessary to cause a message to
  1872.     // be pumped through the queue.
  1873.     if (m_nIDTracking != m_nIDLastMessage && GetParent() != NULL)
  1874.         PostMessage(WM_NULL);
  1875. }
  1876.  
  1877. void COleControl::GetMessageString(UINT nID, CString& rMessage) const
  1878. {
  1879.     // load appropriate string
  1880.     LPTSTR lpsz = rMessage.GetBuffer(255);
  1881.     if (AfxLoadString(nID, lpsz) != 0)
  1882.     {
  1883.         // first newline terminates actual string
  1884.         lpsz = _tcschr(lpsz, '\n');
  1885.         if (lpsz != NULL)
  1886.             *lpsz = '\0';
  1887.     }
  1888.     else
  1889.     {
  1890.         // not found
  1891.         TRACE1("Warning: no message line prompt for ID 0x%04X.\n", nID);
  1892.     }
  1893.     rMessage.ReleaseBuffer();
  1894. }
  1895.  
  1896. LRESULT COleControl::OnSetMessageString(WPARAM wParam, LPARAM lParam)
  1897. {
  1898.     USES_CONVERSION;
  1899.  
  1900.     if (m_pInPlaceFrame != NULL)
  1901.     {
  1902.         LPCTSTR lpsz = NULL;
  1903.         CString strMessage;
  1904.  
  1905.         // set the message bar text
  1906.         if (lParam != 0)
  1907.         {
  1908.             ASSERT(wParam == 0);    // can't have both an ID and a string
  1909.             lpsz = (LPCTSTR)lParam; // set an explicit string
  1910.         }
  1911.         else if (wParam != 0)
  1912.         {
  1913.             // use the wParam as a string ID
  1914.             GetMessageString(wParam, strMessage);
  1915.             lpsz = strMessage;
  1916.         }
  1917.  
  1918.         // notify container of new status text
  1919.         m_pInPlaceFrame->SetStatusText(T2COLE(lpsz));
  1920.     }
  1921.  
  1922.     UINT nIDLast = m_nIDLastMessage;
  1923.     m_nIDLastMessage = (UINT)wParam;    // new ID (or 0)
  1924.     m_nIDTracking = (UINT)wParam;       // so F1 on toolbar buttons work
  1925.     return nIDLast;
  1926. }
  1927.  
  1928. void COleControl::OnEnterIdle(UINT nWhy, CWnd* /*pWho*/)
  1929. {
  1930.     if (nWhy != MSGF_MENU || m_nIDTracking == m_nIDLastMessage)
  1931.         return;
  1932.  
  1933.     SendMessage(WM_SETMESSAGESTRING, (WPARAM)m_nIDTracking);
  1934.     ASSERT(m_nIDTracking == m_nIDLastMessage);
  1935. }
  1936.  
  1937. /////////////////////////////////////////////////////////////////////////////
  1938. // COleControl::XSpecifyPropertyPages
  1939.  
  1940. STDMETHODIMP_(ULONG) COleControl::XSpecifyPropertyPages::AddRef()
  1941. {
  1942.     // Delegate to our exported AddRef.
  1943.     METHOD_PROLOGUE_EX_(COleControl, SpecifyPropertyPages)
  1944.     return (ULONG)pThis->ExternalAddRef();
  1945. }
  1946.  
  1947. STDMETHODIMP_(ULONG) COleControl::XSpecifyPropertyPages::Release()
  1948. {
  1949.     // Delegate to our exported Release.
  1950.     METHOD_PROLOGUE_EX_(COleControl, SpecifyPropertyPages)
  1951.     return (ULONG)pThis->ExternalRelease();
  1952. }
  1953.  
  1954. STDMETHODIMP COleControl::XSpecifyPropertyPages::QueryInterface(
  1955.     REFIID iid, LPVOID* ppvObj)
  1956. {
  1957.     // Delegate to our exported QueryInterface.
  1958.     METHOD_PROLOGUE_EX_(COleControl, SpecifyPropertyPages)
  1959.     return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
  1960. }
  1961.  
  1962. STDMETHODIMP COleControl::XSpecifyPropertyPages::GetPages(CAUUID* pPages)
  1963. {
  1964.     METHOD_PROLOGUE_EX(COleControl, SpecifyPropertyPages)
  1965.  
  1966.     ASSERT(pPages != NULL);
  1967.  
  1968.     if (pPages == NULL)
  1969.         return E_POINTER;
  1970.  
  1971.     pPages->cElems = 0;
  1972.     pPages->pElems = NULL;
  1973.  
  1974.     HRESULT hr = S_OK;
  1975.     ULONG cElems;
  1976.     LPCLSID pClassID = pThis->GetPropPageIDs(cElems);
  1977.  
  1978.     if (cElems > 0)
  1979.     {
  1980.         if ((pPages->pElems = (LPCLSID)(CoTaskMemAlloc(cElems * sizeof(CLSID)))) != NULL)
  1981.         {
  1982.             ASSERT(pPages->pElems != NULL);
  1983.             pPages->cElems = cElems;
  1984.             memcpy(pPages->pElems, pClassID, (int)(cElems * sizeof(CLSID)));
  1985.         }
  1986.         else
  1987.             hr = E_OUTOFMEMORY;
  1988.     }
  1989.     else
  1990.     {
  1991.         pPages->cElems = 0;
  1992.         pPages->pElems = NULL;
  1993.     }
  1994.  
  1995.     return hr;
  1996. }
  1997.  
  1998. void COleControl::OnDestroy()
  1999. {
  2000.     // Release hfont, if any.
  2001.     if (m_hFontPrev != NULL)
  2002.     {
  2003.         SendMessage(WM_SETFONT, (WPARAM)NULL, 0);
  2004.         InternalGetFont().m_pFont->ReleaseHfont(m_hFontPrev);
  2005.         m_hFontPrev = NULL;
  2006.     }
  2007.  
  2008.     CWnd::OnDestroy();
  2009. }
  2010.  
  2011. void COleControl::OnKillFocus(CWnd* pNewWnd)
  2012. {
  2013.     CWnd::OnKillFocus(pNewWnd);
  2014.  
  2015.     if (m_pControlSite != NULL)
  2016.         m_pControlSite->OnFocus(FALSE);
  2017. }
  2018.  
  2019. void COleControl::OnSetFocus(CWnd* pOldWnd)
  2020. {
  2021.     CWnd::OnSetFocus(pOldWnd);
  2022.  
  2023.     if (m_pControlSite != NULL)
  2024.         m_pControlSite->OnFocus(TRUE);
  2025. }
  2026.  
  2027. LRESULT COleControl::OnOcmCtlColorBtn(WPARAM wParam, LPARAM lParam)
  2028. {
  2029.     return ::DefWindowProc(m_hWnd, WM_CTLCOLORBTN, wParam, lParam);
  2030. }
  2031.  
  2032. LRESULT COleControl::OnOcmCtlColorDlg(WPARAM wParam, LPARAM lParam)
  2033. {
  2034.     return ::DefWindowProc(m_hWnd, WM_CTLCOLORDLG, wParam, lParam);
  2035. }
  2036.  
  2037. LRESULT COleControl::OnOcmCtlColorEdit(WPARAM wParam, LPARAM lParam)
  2038. {
  2039.     return ::DefWindowProc(m_hWnd, WM_CTLCOLOREDIT, wParam, lParam);
  2040. }
  2041.  
  2042. LRESULT COleControl::OnOcmCtlColorListBox(WPARAM wParam, LPARAM lParam)
  2043. {
  2044.     return ::DefWindowProc(m_hWnd, WM_CTLCOLORLISTBOX, wParam, lParam);
  2045. }
  2046.  
  2047. LRESULT COleControl::OnOcmCtlColorMsgBox(WPARAM wParam, LPARAM lParam)
  2048. {
  2049.     return ::DefWindowProc(m_hWnd, WM_CTLCOLORMSGBOX, wParam, lParam);
  2050. }
  2051.  
  2052. LRESULT COleControl::OnOcmCtlColorScrollBar(WPARAM wParam, LPARAM lParam)
  2053. {
  2054.     return ::DefWindowProc(m_hWnd, WM_CTLCOLORSCROLLBAR, wParam, lParam);
  2055. }
  2056.  
  2057. LRESULT COleControl::OnOcmCtlColorStatic(WPARAM wParam, LPARAM lParam)
  2058. {
  2059.     return ::DefWindowProc(m_hWnd, WM_CTLCOLORSTATIC, wParam, lParam);
  2060. }
  2061.  
  2062. void COleControl::ThrowError(SCODE sc, UINT nDescriptionID, UINT nHelpID)
  2063. {
  2064.     TCHAR szBuffer[256];
  2065.     AfxLoadString(nDescriptionID, szBuffer);
  2066.     if (nHelpID == -1)
  2067.         nHelpID = nDescriptionID;
  2068.     ThrowError(sc, szBuffer, nHelpID);
  2069. }
  2070.  
  2071. void COleControl::ThrowError(SCODE sc, LPCTSTR pszDescription, UINT nHelpID)
  2072. {
  2073.     COleDispatchException* pExcept = new COleDispatchException(pszDescription,
  2074.         nHelpID, 0);
  2075.     pExcept->m_scError = sc;
  2076.     THROW(pExcept);
  2077. }
  2078.  
  2079. BOOL COleControl::IsInvokeAllowed(DISPID)
  2080. {
  2081.     return m_bInitialized;
  2082. }
  2083.  
  2084. /////////////////////////////////////////////////////////////////////////////
  2085. // Force any extra compiler-generated code into AFX_INIT_SEG
  2086.  
  2087. #ifdef AFX_INIT_SEG
  2088. #pragma code_seg(AFX_INIT_SEG)
  2089. #endif
  2090.  
  2091. IMPLEMENT_DYNAMIC(COleControl, CWnd)
  2092.