Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

417 lines
9.9 KiB

  1. // SplitterCtl.cpp : Implementation of the CSplitterCtrl ActiveX Control class.
  2. #include "stdafx.h"
  3. #include "Splitter.h"
  4. #include "SplitterCtl.h"
  5. #include "SplitterPpg.h"
  6. #include "CtrlWnd.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. IMPLEMENT_DYNCREATE(CSplitterCtrl, COleControl)
  13. /////////////////////////////////////////////////////////////////////////////
  14. // Message map
  15. BEGIN_MESSAGE_MAP(CSplitterCtrl, COleControl)
  16. //{{AFX_MSG_MAP(CSplitterCtrl)
  17. ON_WM_CREATE()
  18. //}}AFX_MSG_MAP
  19. ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
  20. END_MESSAGE_MAP()
  21. /////////////////////////////////////////////////////////////////////////////
  22. // Dispatch map
  23. BEGIN_DISPATCH_MAP(CSplitterCtrl, COleControl)
  24. //{{AFX_DISPATCH_MAP(CSplitterCtrl)
  25. DISP_FUNCTION(CSplitterCtrl, "CreateControl", CreateControl, VT_BOOL, VTS_I4 VTS_I4 VTS_BSTR)
  26. DISP_FUNCTION(CSplitterCtrl, "GetControl", GetControl, VT_BOOL, VTS_I4 VTS_I4 VTS_PI4)
  27. DISP_FUNCTION(CSplitterCtrl, "GetControlIUnknown", GetControlIUnknown, VT_UNKNOWN, VTS_I4 VTS_I4)
  28. //}}AFX_DISPATCH_MAP
  29. DISP_FUNCTION_ID(CSplitterCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
  30. END_DISPATCH_MAP()
  31. /////////////////////////////////////////////////////////////////////////////
  32. // Event map
  33. BEGIN_EVENT_MAP(CSplitterCtrl, COleControl)
  34. //{{AFX_EVENT_MAP(CSplitterCtrl)
  35. // NOTE - ClassWizard will add and remove event map entries
  36. // DO NOT EDIT what you see in these blocks of generated code !
  37. //}}AFX_EVENT_MAP
  38. END_EVENT_MAP()
  39. /////////////////////////////////////////////////////////////////////////////
  40. // Property pages
  41. // TODO: Add more property pages as needed. Remember to increase the count!
  42. BEGIN_PROPPAGEIDS(CSplitterCtrl, 1)
  43. PROPPAGEID(CSplitterPropPage::guid)
  44. END_PROPPAGEIDS(CSplitterCtrl)
  45. /////////////////////////////////////////////////////////////////////////////
  46. // Initialize class factory and guid
  47. IMPLEMENT_OLECREATE_EX(CSplitterCtrl, "SPLITTER.SplitterCtrl.1",
  48. 0x668e5408, 0x8e05, 0x11d2, 0x8a, 0xda, 0, 0, 0xf8, 0x7a, 0x39, 0x12)
  49. /////////////////////////////////////////////////////////////////////////////
  50. // Type library ID and version
  51. IMPLEMENT_OLETYPELIB(CSplitterCtrl, _tlid, _wVerMajor, _wVerMinor)
  52. /////////////////////////////////////////////////////////////////////////////
  53. // Interface IDs
  54. const IID BASED_CODE IID_DSplitter =
  55. { 0x58bb5d60, 0x8e20, 0x11d2, { 0x8a, 0xda, 0, 0, 0xf8, 0x7a, 0x39, 0x12 } };
  56. const IID BASED_CODE IID_DSplitterEvents =
  57. { 0x58bb5d61, 0x8e20, 0x11d2, { 0x8a, 0xda, 0, 0, 0xf8, 0x7a, 0x39, 0x12 } };
  58. /////////////////////////////////////////////////////////////////////////////
  59. // Control type information
  60. static const DWORD BASED_CODE _dwSplitterOleMisc =
  61. OLEMISC_ACTIVATEWHENVISIBLE |
  62. OLEMISC_IGNOREACTIVATEWHENVISIBLE |
  63. OLEMISC_SETCLIENTSITEFIRST |
  64. OLEMISC_INSIDEOUT |
  65. OLEMISC_CANTLINKINSIDE |
  66. OLEMISC_RECOMPOSEONRESIZE;
  67. IMPLEMENT_OLECTLTYPE(CSplitterCtrl, IDS_SPLITTER, _dwSplitterOleMisc)
  68. /////////////////////////////////////////////////////////////////////////////
  69. // CSplitterCtrl::CSplitterCtrlFactory::UpdateRegistry -
  70. // Adds or removes system registry entries for CSplitterCtrl
  71. BOOL CSplitterCtrl::CSplitterCtrlFactory::UpdateRegistry(BOOL bRegister)
  72. {
  73. // TODO: Verify that your control follows apartment-model threading rules.
  74. // Refer to MFC TechNote 64 for more information.
  75. // If your control does not conform to the apartment-model rules, then
  76. // you must modify the code below, changing the 6th parameter from
  77. // afxRegApartmentThreading to 0.
  78. if (bRegister)
  79. return AfxOleRegisterControlClass(
  80. AfxGetInstanceHandle(),
  81. m_clsid,
  82. m_lpszProgID,
  83. IDS_SPLITTER,
  84. IDB_SPLITTER,
  85. afxRegApartmentThreading,
  86. _dwSplitterOleMisc,
  87. _tlid,
  88. _wVerMajor,
  89. _wVerMinor);
  90. else
  91. return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
  92. }
  93. /////////////////////////////////////////////////////////////////////////////
  94. // Licensing strings
  95. static const TCHAR BASED_CODE _szLicFileName[] = _T("Splitter.lic");
  96. static const WCHAR BASED_CODE _szLicString[] =
  97. L"Copyright (c) 1998 Microsoft";
  98. /////////////////////////////////////////////////////////////////////////////
  99. // CSplitterCtrl::CSplitterCtrlFactory::VerifyUserLicense -
  100. // Checks for existence of a user license
  101. BOOL CSplitterCtrl::CSplitterCtrlFactory::VerifyUserLicense()
  102. {
  103. return AfxVerifyLicFile(AfxGetInstanceHandle(), _szLicFileName,
  104. _szLicString);
  105. }
  106. /////////////////////////////////////////////////////////////////////////////
  107. // CSplitterCtrl::CSplitterCtrlFactory::GetLicenseKey -
  108. // Returns a runtime licensing key
  109. BOOL CSplitterCtrl::CSplitterCtrlFactory::GetLicenseKey(DWORD dwReserved,
  110. BSTR FAR* pbstrKey)
  111. {
  112. if (pbstrKey == NULL)
  113. return FALSE;
  114. *pbstrKey = SysAllocString(_szLicString);
  115. return (*pbstrKey != NULL);
  116. }
  117. /////////////////////////////////////////////////////////////////////////////
  118. // CSplitterCtrl::CSplitterCtrl - Constructor
  119. CSplitterCtrl::CSplitterCtrl()
  120. {
  121. InitializeIIDs(&IID_DSplitter, &IID_DSplitterEvents);
  122. // TODO: Initialize your control's instance data here.
  123. }
  124. /////////////////////////////////////////////////////////////////////////////
  125. // CSplitterCtrl::~CSplitterCtrl - Destructor
  126. CSplitterCtrl::~CSplitterCtrl()
  127. {
  128. // TODO: Cleanup your control's instance data here.
  129. }
  130. /////////////////////////////////////////////////////////////////////////////
  131. // CSplitterCtrl::OnDraw - Drawing function
  132. void CSplitterCtrl::OnDraw(
  133. CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
  134. {
  135. if( pdc == NULL )
  136. {
  137. return;
  138. }
  139. if( rcBounds.IsRectEmpty() )
  140. {
  141. return;
  142. }
  143. if( rcInvalid.IsRectEmpty() )
  144. {
  145. return;
  146. }
  147. }
  148. /////////////////////////////////////////////////////////////////////////////
  149. // CSplitterCtrl::DoPropExchange - Persistence support
  150. void CSplitterCtrl::DoPropExchange(CPropExchange* pPX)
  151. {
  152. ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
  153. COleControl::DoPropExchange(pPX);
  154. // TODO: Call PX_ functions for each persistent custom property.
  155. }
  156. /////////////////////////////////////////////////////////////////////////////
  157. // CSplitterCtrl::GetControlFlags -
  158. // Flags to customize MFC's implementation of ActiveX controls.
  159. //
  160. // For information on using these flags, please see MFC technical note
  161. // #nnn, "Optimizing an ActiveX Control".
  162. DWORD CSplitterCtrl::GetControlFlags()
  163. {
  164. DWORD dwFlags = COleControl::GetControlFlags();
  165. // The control can receive mouse notifications when inactive.
  166. // TODO: if you write handlers for WM_SETCURSOR and WM_MOUSEMOVE,
  167. // avoid using the m_hWnd member variable without first
  168. // checking that its value is non-NULL.
  169. dwFlags |= pointerInactive;
  170. return dwFlags;
  171. }
  172. /////////////////////////////////////////////////////////////////////////////
  173. // CSplitterCtrl::OnResetState - Reset control to default state
  174. void CSplitterCtrl::OnResetState()
  175. {
  176. COleControl::OnResetState(); // Resets defaults found in DoPropExchange
  177. // TODO: Reset any other control state here.
  178. }
  179. /////////////////////////////////////////////////////////////////////////////
  180. // CSplitterCtrl::AboutBox - Display an "About" box to the user
  181. void CSplitterCtrl::AboutBox()
  182. {
  183. CDialog dlgAbout(IDD_ABOUTBOX_SPLITTER);
  184. dlgAbout.DoModal();
  185. }
  186. /////////////////////////////////////////////////////////////////////////////
  187. // CSplitterCtrl message handlers
  188. int CSplitterCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
  189. {
  190. if (COleControl::OnCreate(lpCreateStruct) == -1)
  191. return -1;
  192. m_wndSplitter.CreateStatic(this,2,1);
  193. int iHeight = lpCreateStruct->cy > 100 ? lpCreateStruct->cy / 2 : 300;
  194. m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CCtrlWnd),CSize(50,iHeight),NULL);
  195. m_wndSplitter.CreateView(1,0,RUNTIME_CLASS(CCtrlWnd),CSize(0,iHeight),NULL);
  196. m_wndSplitter.MoveWindow(CRect(0,0,lpCreateStruct->cx,lpCreateStruct->cy));
  197. m_wndSplitter.ShowWindow(SW_SHOW);
  198. m_wndSplitter.UpdateWindow();
  199. return 0;
  200. }
  201. BOOL CSplitterCtrl::OnSetExtent(LPSIZEL lpSizeL)
  202. {
  203. if( GetSafeHwnd() )
  204. {
  205. CClientDC dc(this);
  206. SIZE size = *lpSizeL;
  207. dc.HIMETRICtoDP(&size);
  208. m_wndSplitter.SetWindowPos(NULL,0,0,size.cx,size.cy,SWP_NOZORDER|SWP_NOMOVE|SWP_SHOWWINDOW);
  209. }
  210. return COleControl::OnSetExtent(lpSizeL);
  211. }
  212. BOOL CSplitterCtrl::CreateControl(long lRow, long lColumn, LPCTSTR lpszControlID)
  213. {
  214. if( lRow < 0 || lColumn < 0 )
  215. {
  216. return FALSE;
  217. }
  218. if( lRow > 2 || lColumn > 2 )
  219. {
  220. return FALSE;
  221. }
  222. if( lpszControlID == NULL )
  223. {
  224. return FALSE;
  225. }
  226. CWnd* pWnd = m_wndSplitter.GetPane(lRow,lColumn);
  227. if( pWnd && ! pWnd->IsKindOf(RUNTIME_CLASS(CCtrlWnd)) )
  228. {
  229. return FALSE;
  230. }
  231. CCtrlWnd* pCtrlWnd = (CCtrlWnd*)pWnd;
  232. BOOL bResult = pCtrlWnd->CreateControl(lpszControlID);
  233. if( bResult == FALSE )
  234. {
  235. return FALSE;
  236. }
  237. pWnd = pCtrlWnd->GetControl();
  238. if( pWnd == NULL )
  239. {
  240. return FALSE;
  241. }
  242. if( ! pWnd->GetSafeHwnd() || ! ::IsWindow(pWnd->GetSafeHwnd()) )
  243. {
  244. return FALSE;
  245. }
  246. return TRUE;
  247. }
  248. BOOL CSplitterCtrl::GetControl(long lRow, long lColumn, long FAR* phCtlWnd)
  249. {
  250. if( phCtlWnd == NULL )
  251. {
  252. return FALSE;
  253. }
  254. if( lRow < 0 || lColumn < 0 )
  255. {
  256. *phCtlWnd = NULL;
  257. return FALSE;
  258. }
  259. if( lRow > 2 || lColumn > 2 )
  260. {
  261. *phCtlWnd = NULL;
  262. return FALSE;
  263. }
  264. CWnd* pWnd = m_wndSplitter.GetPane(lRow,lColumn);
  265. if( pWnd && ! pWnd->IsKindOf(RUNTIME_CLASS(CCtrlWnd)) )
  266. {
  267. *phCtlWnd = NULL;
  268. return FALSE;
  269. }
  270. CCtrlWnd* pCtrlWnd = (CCtrlWnd*)pWnd;
  271. pWnd = pCtrlWnd->GetControl();
  272. if( pWnd == NULL )
  273. {
  274. *phCtlWnd = NULL;
  275. return FALSE;
  276. }
  277. if( ! pWnd->GetSafeHwnd() || ! ::IsWindow(pWnd->GetSafeHwnd()) )
  278. {
  279. *phCtlWnd = NULL;
  280. return FALSE;
  281. }
  282. #ifndef IA64
  283. *phCtlWnd = (long)pWnd->GetSafeHwnd();
  284. #endif // IA64
  285. return TRUE;
  286. }
  287. LPUNKNOWN CSplitterCtrl::GetControlIUnknown(long lRow, long lColumn)
  288. {
  289. if( lRow < 0 || lColumn < 0 )
  290. {
  291. return NULL;
  292. }
  293. if( lRow > 2 || lColumn > 2 )
  294. {
  295. return NULL;
  296. }
  297. CWnd* pWnd = m_wndSplitter.GetPane(lRow,lColumn);
  298. if( pWnd && ! pWnd->IsKindOf(RUNTIME_CLASS(CCtrlWnd)) )
  299. {
  300. return NULL;
  301. }
  302. CCtrlWnd* pCtrlWnd = (CCtrlWnd*)pWnd;
  303. LPUNKNOWN lpUnk = pCtrlWnd->GetControlIUnknown();
  304. return lpUnk;
  305. }