home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / CTLCORE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-13  |  51.4 KB  |  2,105 lines

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