ctlcore.cpp 50 KB

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