XFloorWndCtl.cpp
上传用户:zhout2004
上传日期:2007-01-02
资源大小:218k
文件大小:45k
源码类别:

ActiveX/DCOM/ATL

开发平台:

Visual C++

  1. /************************************
  2.   REVISION LOG ENTRY
  3.   Revision By: Mihai Filimon
  4.   Revised on 10/8/98 3:52:57 PM
  5.   Comments: XFloorWndCtl.cpp : Implementation of the CXFloorWndCtrl ActiveX Control class.
  6.  ************************************/
  7. #include "stdafx.h"
  8. #include "XFloorWnd.h"
  9. #include "XFloorWndCtl.h"
  10. #include "XFloorWndPpg.h"
  11. #include "FloorLabeObject.h"
  12. #include "gdi.h"
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. IMPLEMENT_DYNCREATE(CXFloorWndCtrl, COleControl)
  19. #ifdef _OBEJCTISSAFETY
  20. //Implementation IObjectSafety
  21. BEGIN_INTERFACE_MAP(CXFloorWndCtrl, COleControl)
  22.   INTERFACE_PART(CXFloorWndCtrl, IID_IObjectSafety, ObjectSafety)
  23. END_INTERFACE_MAP()
  24. STDMETHODIMP CXFloorWndCtrl::XObjectSafety::GetInterfaceSafetyOptions(
  25. REFIID riid, 
  26. DWORD __RPC_FAR *pdwSupportedOptions, 
  27. DWORD __RPC_FAR *pdwEnabledOptions)
  28. {
  29. METHOD_PROLOGUE_EX(CXFloorWndCtrl, ObjectSafety)
  30. if (!pdwSupportedOptions || !pdwEnabledOptions)
  31. {
  32. return E_POINTER;
  33. }
  34. *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
  35. *pdwEnabledOptions = 0;
  36. if (NULL == pThis->GetInterface(&riid))
  37. {
  38. TRACE("Requested interface is not supported.n");
  39. return E_NOINTERFACE;
  40. }
  41. // What interface is being checked out anyhow?
  42. OLECHAR szGUID[39];
  43. int i = StringFromGUID2(riid, szGUID, 39);
  44. if (riid == IID_IDispatch)
  45. {
  46. // Client wants to know if object is safe for scripting
  47. *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
  48. return S_OK;
  49. }
  50. else if (riid == IID_IPersistPropertyBag 
  51.   || riid == IID_IPersistStreamInit
  52.   || riid == IID_IPersistStorage
  53.   || riid == IID_IPersistMemory)
  54. {
  55. // Those are the persistence interfaces COleControl derived controls support
  56. // as indicated in AFXCTL.H
  57. // Client wants to know if object is safe for initializing from persistent data
  58. *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
  59. return S_OK;
  60. }
  61. else
  62. {
  63. // Find out what interface this is, and decide what options to enable
  64. TRACE("We didn't account for the safety of this interface, and it's one we support...n");
  65. return E_NOINTERFACE;
  66. }
  67. }
  68. STDMETHODIMP CXFloorWndCtrl::XObjectSafety::SetInterfaceSafetyOptions(
  69. REFIID riid, 
  70. DWORD dwOptionSetMask, 
  71. DWORD dwEnabledOptions)
  72. {
  73. METHOD_PROLOGUE_EX(CXFloorWndCtrl, ObjectSafety)
  74. OLECHAR szGUID[39];
  75. // What is this interface anyway?
  76. // We can do a quick lookup in the registry under HKEY_CLASSES_ROOTInterface
  77. int i = StringFromGUID2(riid, szGUID, 39);
  78. if (0 == dwOptionSetMask && 0 == dwEnabledOptions)
  79. {
  80. // the control certainly supports NO requests through the specified interface
  81. // so it's safe to return S_OK even if the interface isn't supported.
  82. return S_OK;
  83. }
  84. // Do we support the specified interface?
  85. if (NULL == pThis->GetInterface(&riid))
  86. {
  87. TRACE1("%s is not support.n", szGUID);
  88. return E_FAIL;
  89. }
  90. if (riid == IID_IDispatch)
  91. {
  92. TRACE("Client asking if it's safe to call through IDispatch.n");
  93. TRACE("In other words, is the control safe for scripting?n");
  94. if (INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwOptionSetMask && INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwEnabledOptions)
  95. {
  96. return S_OK;
  97. }
  98. else
  99. {
  100. return E_FAIL;
  101. }
  102. }
  103. else if (riid == IID_IPersistPropertyBag 
  104.   || riid == IID_IPersistStreamInit
  105.   || riid == IID_IPersistStorage
  106.   || riid == IID_IPersistMemory)
  107. {
  108. TRACE("Client asking if it's safe to call through IPersist*.n");
  109. TRACE("In other words, is the control safe for initializing from persistent data?n");
  110. if (INTERFACESAFE_FOR_UNTRUSTED_DATA == dwOptionSetMask && INTERFACESAFE_FOR_UNTRUSTED_DATA == dwEnabledOptions)
  111. {
  112. return NOERROR;
  113. }
  114. else
  115. {
  116. return E_FAIL;
  117. }
  118. }
  119. else
  120. {
  121. TRACE1("We didn't account for the safety of %s, and it's one we support...n", szGUID);
  122. return E_FAIL;
  123. }
  124. }
  125. STDMETHODIMP_(ULONG) CXFloorWndCtrl::XObjectSafety::AddRef()
  126. {
  127. METHOD_PROLOGUE_EX_(CXFloorWndCtrl, ObjectSafety)
  128. return (ULONG)pThis->ExternalAddRef();
  129. }
  130. STDMETHODIMP_(ULONG) CXFloorWndCtrl::XObjectSafety::Release()
  131. {
  132. METHOD_PROLOGUE_EX_(CXFloorWndCtrl, ObjectSafety)
  133. return (ULONG)pThis->ExternalRelease();
  134. }
  135. STDMETHODIMP CXFloorWndCtrl::XObjectSafety::QueryInterface(
  136. REFIID iid, LPVOID* ppvObj)
  137. {
  138. METHOD_PROLOGUE_EX_(CXFloorWndCtrl, ObjectSafety)
  139. return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
  140. }
  141. #endif //_OBEJCTISSAFETY
  142. /////////////////////////////////////////////////////////////////////////////
  143. // Message map
  144. BEGIN_MESSAGE_MAP(CXFloorWndCtrl, COleControl)
  145. //{{AFX_MSG_MAP(CXFloorWndCtrl)
  146. ON_WM_SIZE()
  147. ON_WM_LBUTTONDOWN()
  148. ON_WM_LBUTTONUP()
  149. ON_WM_MOUSEMOVE()
  150. ON_WM_TIMER()
  151. ON_WM_ERASEBKGND()
  152. ON_WM_CREATE()
  153. //}}AFX_MSG_MAP
  154. ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
  155. END_MESSAGE_MAP()
  156. /////////////////////////////////////////////////////////////////////////////
  157. // Dispatch map
  158. BEGIN_DISPATCH_MAP(CXFloorWndCtrl, COleControl)
  159. //{{AFX_DISPATCH_MAP(CXFloorWndCtrl)
  160. DISP_PROPERTY_NOTIFY(CXFloorWndCtrl, "Animation", m_bAnimation, OnAnimationChanged, VT_BOOL)
  161. DISP_PROPERTY_NOTIFY(CXFloorWndCtrl, "Sleep", m_nSleep, OnSleepChanged, VT_I4)
  162. DISP_PROPERTY_NOTIFY(CXFloorWndCtrl, "Sign", m_bSign, OnSignChanged, VT_BOOL)
  163. DISP_PROPERTY_NOTIFY(CXFloorWndCtrl, "Pages", m_sPages, OnPagesChanged, VT_BSTR)
  164. DISP_PROPERTY_NOTIFY(CXFloorWndCtrl, "AsPage", m_bAsPage, OnAsPageChanged, VT_BOOL)
  165. DISP_FUNCTION(CXFloorWndCtrl, "AddPage", _AddPage, VT_I2, VTS_BSTR)
  166. DISP_FUNCTION(CXFloorWndCtrl, "DeletePage", _DeletePage, VT_BOOL, VTS_I2)
  167. DISP_FUNCTION(CXFloorWndCtrl, "GetPageName", _GetPageName, VT_BSTR, VTS_I2)
  168. DISP_FUNCTION(CXFloorWndCtrl, "GetPage", _GetPage, VT_I2, VTS_BSTR)
  169. DISP_FUNCTION(CXFloorWndCtrl, "ActivatePage", _ActivatePage, VT_BOOL, VTS_I2)
  170. DISP_FUNCTION(CXFloorWndCtrl, "AttachWindow", _AttachWindow, VT_BOOL, VTS_I2 VTS_I4)
  171. DISP_FUNCTION(CXFloorWndCtrl, "SetPageName", _SetPageName, VT_BOOL, VTS_I2 VTS_BSTR)
  172. DISP_FUNCTION(CXFloorWndCtrl, "Init", _Init, VT_EMPTY, VTS_NONE)
  173. DISP_FUNCTION(CXFloorWndCtrl, "GetActivePage", _GetActivePage, VT_I2, VTS_NONE)
  174. DISP_FUNCTION(CXFloorWndCtrl, "GetPagesCount", _GetPagesCount, VT_I4, VTS_NONE)
  175. DISP_FUNCTION(CXFloorWndCtrl, "IsPage", _IsPage, VT_BOOL, VTS_I2)
  176. DISP_FUNCTION(CXFloorWndCtrl, "GetLeftTopPage", _GetLeftTopPage, VT_I4, VTS_I2)
  177. DISP_FUNCTION(CXFloorWndCtrl, "GetBottomRightPage", _GetBottomRightPage, VT_I4, VTS_I2)
  178. DISP_FUNCTION(CXFloorWndCtrl, "StyleAs", StyleAs, VT_EMPTY, VTS_BOOL)
  179. DISP_FUNCTION(CXFloorWndCtrl, "GetHWnd", GetHWnd, VT_I4, VTS_I4)
  180. DISP_PROPERTY_PARAM(CXFloorWndCtrl, "Height", GetHeight, SetHeight, VT_I2, VTS_I2)
  181. DISP_PROPERTY_PARAM(CXFloorWndCtrl, "Color", GetColor, SetColor, VT_COLOR, VTS_I2)
  182. DISP_PROPERTY_PARAM(CXFloorWndCtrl, "UserData", GetUserData, SetUserData, VT_I4, VTS_I2)
  183. DISP_STOCKPROP_BACKCOLOR()
  184. DISP_STOCKPROP_FONT()
  185. //}}AFX_DISPATCH_MAP
  186. DISP_FUNCTION_ID(CXFloorWndCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
  187. END_DISPATCH_MAP()
  188. /////////////////////////////////////////////////////////////////////////////
  189. // Event map
  190. BEGIN_EVENT_MAP(CXFloorWndCtrl, COleControl)
  191. //{{AFX_EVENT_MAP(CXFloorWndCtrl)
  192. EVENT_CUSTOM("ActivatePage", FireActivatePage, VTS_I2)
  193. EVENT_CUSTOM("ClickOnActivePage", FireClickOnActivePage, VTS_I2)
  194. EVENT_STOCK_CLICK()
  195. //}}AFX_EVENT_MAP
  196. END_EVENT_MAP()
  197. /////////////////////////////////////////////////////////////////////////////
  198. // Property pages
  199. // TODO: Add more property pages as needed.  Remember to increase the count!
  200. BEGIN_PROPPAGEIDS(CXFloorWndCtrl, 3)
  201. PROPPAGEID(CXFloorWndPropPage::guid)
  202.     PROPPAGEID(CLSID_CColorPropPage)
  203. PROPPAGEID(CLSID_CFontPropPage)
  204. END_PROPPAGEIDS(CXFloorWndCtrl)
  205. /////////////////////////////////////////////////////////////////////////////
  206. // Initialize class factory and guid
  207. IMPLEMENT_OLECREATE_EX(CXFloorWndCtrl, "XFLOORWND.XFloorWndCtrl.1",
  208. 0x24ffd1ed, 0x5ea9, 0x11d2, 0x86, 0xb1, 0, 0x40, 0x5, 0x5c, 0x8, 0xd9)
  209. /////////////////////////////////////////////////////////////////////////////
  210. // Type library ID and version
  211. IMPLEMENT_OLETYPELIB(CXFloorWndCtrl, _tlid, _wVerMajor, _wVerMinor)
  212. /////////////////////////////////////////////////////////////////////////////
  213. // Interface IDs
  214. const IID BASED_CODE IID_DXFloorWnd =
  215. { 0x24ffd1eb, 0x5ea9, 0x11d2, { 0x86, 0xb1, 0, 0x40, 0x5, 0x5c, 0x8, 0xd9 } };
  216. const IID BASED_CODE IID_DXFloorWndEvents =
  217. { 0x24ffd1ec, 0x5ea9, 0x11d2, { 0x86, 0xb1, 0, 0x40, 0x5, 0x5c, 0x8, 0xd9 } };
  218. /////////////////////////////////////////////////////////////////////////////
  219. // Control type information
  220. static const DWORD BASED_CODE _dwXFloorWndOleMisc =
  221. OLEMISC_ACTIVATEWHENVISIBLE |
  222. OLEMISC_SETCLIENTSITEFIRST |
  223. OLEMISC_INSIDEOUT |
  224. OLEMISC_CANTLINKINSIDE |
  225. OLEMISC_RECOMPOSEONRESIZE;
  226. IMPLEMENT_OLECTLTYPE(CXFloorWndCtrl, IDS_XFLOORWND, _dwXFloorWndOleMisc)
  227. /////////////////////////////////////////////////////////////////////////////
  228. // CXFloorWndCtrl::CXFloorWndCtrlFactory::UpdateRegistry -
  229. // Adds or removes system registry entries for CXFloorWndCtrl
  230. BOOL CXFloorWndCtrl::CXFloorWndCtrlFactory::UpdateRegistry(BOOL bRegister)
  231. {
  232. // TODO: Verify that your control follows apartment-model threading rules.
  233. // Refer to MFC TechNote 64 for more information.
  234. // If your control does not conform to the apartment-model rules, then
  235. // you must modify the code below, changing the 6th parameter from
  236. // afxRegApartmentThreading to 0.
  237. if (bRegister)
  238. return AfxOleRegisterControlClass(
  239. AfxGetInstanceHandle(),
  240. m_clsid,
  241. m_lpszProgID,
  242. IDS_XFLOORWND,
  243. IDB_XFLOORWND,
  244. afxRegApartmentThreading,
  245. _dwXFloorWndOleMisc,
  246. _tlid,
  247. _wVerMajor,
  248. _wVerMinor);
  249. else
  250. return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
  251. }
  252. /////////////////////////////////////////////////////////////////////////////
  253. // CXFloorWndCtrl::CXFloorWndCtrl - Constructor
  254. CFloorPageObject* CXFloorWndCtrl::m_pFocusPage = NULL;
  255. UINT CXFloorWndCtrl::m_nMessageChange = NULL;
  256. CRect CXFloorWndCtrl::m_rtBorder(CPoint(-2,-2), CSize(0,0));
  257. // Function name : CXFloorWndCtrl::CXFloorWndCtrl
  258. // Description     : Default constructor
  259. // Return type : 
  260. CXFloorWndCtrl::CXFloorWndCtrl()
  261. {
  262. InitializeIIDs(&IID_DXFloorWnd, &IID_DXFloorWndEvents);
  263. RegClassFloorWnd();
  264. m_pActivePage = NULL;
  265. m_nSleep = 0;
  266. m_pArPage = new CArrayPage();
  267. m_nDYLabel = GetSystemMetrics(SM_CYCAPTION); // a default value...
  268. m_nDYCombo = 10 * m_nDYLabel; // a default value...
  269. }
  270. /////////////////////////////////////////////////////////////////////////////
  271. // CXFloorWndCtrl::~CXFloorWndCtrl - Destructor
  272. // Function name : CXFloorWndCtrl::~CXFloorWndCtrl
  273. // Description     : default destructor
  274. // Return type : 
  275. CXFloorWndCtrl::~CXFloorWndCtrl()
  276. {
  277. while (DeletePage(0));
  278. if (m_pArPage)
  279. delete m_pArPage;
  280. m_pArPage = NULL;
  281. }
  282. /////////////////////////////////////////////////////////////////////////////
  283. // CXFloorWndCtrl::OnDraw - Drawing function
  284. void CXFloorWndCtrl::OnDraw(
  285. CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
  286. {
  287. if (m_hWnd)
  288. if (::IsWindow(m_hWnd))
  289. {
  290. CDC dcMem; CBitmap bmpMem;
  291. CRect r; GetClientRect(r);
  292. if (dcMem.CreateCompatibleDC(pdc))
  293. if (bmpMem.CreateCompatibleBitmap(pdc, r.Width(), r.Height()))
  294. {
  295. CBitmap* pBitmap = dcMem.SelectObject(&bmpMem);
  296. COLORREF colorBkGnd = TranslateColor(GetBackColor());
  297. CBrush brBkGnd(colorBkGnd);
  298. CBrush* pBrush = dcMem.SelectObject(&brBkGnd);
  299. //Erase the bkgnd of this
  300. dcMem.PatBlt(r.left, r.top, r.right, r.bottom, PATCOPY);
  301. for (int i = 0; i < GetCountPage(); i++)
  302. GetPage(i)->OnDraw(&dcMem, TRUE);
  303. pdc->BitBlt(r.left,r.top,r.Width(), r.Height(), &dcMem, 0,0, SRCCOPY);
  304. dcMem.SelectObject(pBitmap);
  305. dcMem.SelectObject(pBrush);
  306. }
  307. return;
  308. }
  309. // Write the version
  310. COLORREF colorBkGnd = TranslateColor(GetBackColor());
  311. CBrush brBkGnd(colorBkGnd);
  312. CBrush* pBrush = pdc->SelectObject(&brBkGnd);
  313. //Erase the bkgnd of this
  314. pdc->PatBlt(rcInvalid.left, rcInvalid.top, rcInvalid.right, rcInvalid.bottom, PATCOPY);
  315. CFont* pFont = SelectStockFont(pdc);
  316. CString version; version.Format(_T("XFloorWnd %i.%02i"), _wVerMajor, _wVerMinor);
  317. pdc->SetBkMode(TRANSPARENT);
  318. pdc->DrawText(version, CRect(rcInvalid), DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  319. pdc->SelectObject(pFont);
  320. pdc->SelectObject(pBrush);
  321. }
  322. /////////////////////////////////////////////////////////////////////////////
  323. // CXFloorWndCtrl::DoPropExchange - Persistence support
  324. void CXFloorWndCtrl::DoPropExchange(CPropExchange* pPX)
  325. {
  326. ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
  327. COleControl::DoPropExchange(pPX);
  328. PX_Bool(pPX, _T("Animation"), m_bAnimation, TRUE);
  329. PX_Long(pPX, _T("Sleep"), m_nSleep, 0);
  330. PX_Bool(pPX, _T("Sign"), m_bSign, TRUE);
  331. PX_Bool(pPX, _T("AsPage"), m_bAsPage, TRUE);
  332. PX_String(pPX, _T("Pages"), m_sPages, _T(""));
  333. if (pPX->IsLoading())
  334. OnPagesChanged();
  335. }
  336. /////////////////////////////////////////////////////////////////////////////
  337. // CXFloorWndCtrl::OnResetState - Reset control to default state
  338. void CXFloorWndCtrl::OnResetState()
  339. {
  340. COleControl::OnResetState();  // Resets defaults found in DoPropExchange
  341. COLORREF clrBack = defaultRGBBkGnd;
  342. SetBackColor((OLE_COLOR)clrBack);
  343. }
  344. /////////////////////////////////////////////////////////////////////////////
  345. // CXFloorWndCtrl::AboutBox - Display an "About" box to the user
  346. void CXFloorWndCtrl::AboutBox()
  347. {
  348. CDialog dlgAbout(IDD_ABOUTBOX_XFLOORWND);
  349. dlgAbout.DoModal();
  350. }
  351. /////////////////////////////////////////////////////////////////////////////
  352. // CXFloorWndCtrl message handlers
  353. // Function name : CXFloorWndCtrl::GetCountPage
  354. // Description     : Get count of pages
  355. // Return type : int 
  356. int CXFloorWndCtrl::GetCountPage()
  357. {
  358. return m_pArPage->GetSize();
  359. }
  360. // Function name : CXFloorWndCtrl::GetPage
  361. // Description     : Return the page index nIndex
  362. // Return type : CFloorPageObject* 
  363. // Argument         : int nIndex
  364. CFloorPageObject* CXFloorWndCtrl::GetPage(int nIndex)
  365. {
  366. if (nIndex >=0)
  367. if (nIndex < GetCountPage() )
  368. return (*m_pArPage)[nIndex];
  369. return NULL;
  370. }
  371. // Function name : CXFloorWndCtrl::GetPage
  372. // Description     : Return the page with name lpszPageName
  373. // Return type : CFloorPageObject* 
  374. // Argument         : LPCTSTR lpszPageName
  375. CFloorPageObject* CXFloorWndCtrl::GetPage(LPCTSTR lpszPageName)
  376. {
  377. for (int i = 0; i < GetCountPage(); i++)
  378. if (GetPage(i)->GetName().CompareNoCase(lpszPageName) == 0)
  379. return GetPage(i);
  380. return NULL;
  381. }
  382. // Function name : CXFloorWndCtrl::RecalcLayout
  383. // Description     : Called this function when a page was added, removed, or his size, position changes
  384. // This function can recalc all rect of windows.
  385. // Return type : void 
  386. void CXFloorWndCtrl::RecalcLayout()
  387. {
  388. if (::IsWindow(m_hWnd))
  389. {
  390. if (m_bAsPage)
  391. {
  392. CRect rClient; GetClientRect(rClient);
  393. rClient.InflateRect(-1,-1);
  394. int uY = rClient.top, dY = rClient.bottom;
  395. for (int i = 0; i < GetCountPage(); i++)
  396. {
  397. CFloorObject* pPage = GetPage(i);
  398. if (pPage->IsPullUp())
  399. {
  400. pPage->m_rect = CRect(rClient.left,uY,rClient.right,uY + pPage->GetHeight());
  401. uY += pPage->GetHeight() + 1;
  402. ValidateRect(pPage->m_rect);
  403. }
  404. }
  405. for (i = GetCountPage() - 1; i >= 0 ; i--)
  406. {
  407. CFloorObject* pPage = GetPage(i);
  408. if (pPage->IsPullDown())
  409. {
  410. pPage->m_rect = CRect(rClient.left,dY - pPage->GetHeight(),rClient.right,dY);
  411. dY -= pPage->GetHeight() + 1;
  412. ValidateRect(pPage->m_rect);
  413. }
  414. }
  415. m_rectClient = CRect(rClient.left + 1, uY, rClient.right - 2, dY - 1);
  416. }
  417. else
  418. {
  419. CRect rect; GetClientRect(rect);
  420. CRect rPage = ChangeHeightLabel(rect.Size());
  421. m_rectClient = rect;
  422. m_rectClient.top += m_nDYLabel;
  423. m_rectClient.InflateRect(m_rtBorder);
  424. for (int i = 0; i < m_pArPage->GetSize(); i++)
  425. (*m_pArPage)[i]->m_rect = rPage;
  426. if (CFloorPageObject* pPage = GetActivePage())
  427. pPage->SetRectClient(m_rectClient);
  428. }
  429. Invalidate();
  430. }
  431. }
  432. // Function name : CXFloorWndCtrl::Preview
  433. // Description     : Preview of window to a bitmap, If pWnd == NULL then
  434. // function will return the bitmap with bkgnd color of thsi window
  435. // Return type : CBitmap* 
  436. // Argument         : CWnd * pWnd
  437. CBitmap* CXFloorWndCtrl::Preview(CWnd * pWnd)
  438. {
  439. CBitmap *pBitmap = NULL, bitmapNonClient;
  440. CWnd *pDrawWnd = pWnd ? pWnd : this;
  441. if (pDrawWnd && ::IsWindow(pDrawWnd->m_hWnd))
  442. {
  443. CRect rectWindow; pDrawWnd->GetWindowRect(rectWindow);
  444. CRect rectClient; pDrawWnd->GetClientRect(rectClient);
  445. CPoint p(0,0);
  446. pDrawWnd->ClientToScreen(&p);
  447. rectClient.OffsetRect(p.x - rectWindow.left, p.y - rectWindow.top);
  448. CDC* pDC = pDrawWnd->GetDC();
  449. CDC dcMemSourceNonClient, dcMemDestination;
  450. COLORREF colorBkGnd = TranslateColor(GetBackColor());
  451. CBrush brBkGnd(colorBkGnd);
  452. CGdiStack stack;
  453. if (dcMemSourceNonClient.CreateCompatibleDC(pDC))
  454. if (dcMemDestination.CreateCompatibleDC(pDC))
  455. if (pBitmap = new CBitmap())
  456. if (pBitmap->CreateCompatibleBitmap(pDC, rectWindow.Width(), rectWindow.Height()))
  457. if (bitmapNonClient.CreateCompatibleBitmap(pDC, rectWindow.Width(), rectWindow.Height()))
  458. {
  459. stack.Push(&dcMemSourceNonClient,&bitmapNonClient);
  460. stack.Push(&dcMemSourceNonClient,&brBkGnd);
  461. dcMemSourceNonClient.PatBlt(0,0,rectWindow.Width(), rectWindow.Height(), PATCOPY);
  462. stack.Push(&dcMemDestination, pBitmap);
  463. if (pWnd)
  464. pDrawWnd->Print(&dcMemSourceNonClient, PRF_NONCLIENT);
  465. dcMemDestination.BitBlt(0,0,rectWindow.Width(), rectWindow.Height(), &dcMemSourceNonClient, 0,0, SRCCOPY);
  466. if (pWnd)
  467. {
  468. CPoint pLT(0,0);
  469. pDrawWnd->ClientToScreen(&pLT);
  470. dcMemDestination.SetViewportOrg(pLT.x - rectWindow.left, pLT.y - rectWindow.top);
  471. pDrawWnd->Print(&dcMemDestination, PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND);
  472. }
  473. stack.Pop();
  474. stack.Pop();
  475. stack.Pop();
  476. bitmapNonClient.DeleteObject();
  477. dcMemDestination.DeleteDC();
  478. dcMemSourceNonClient.DeleteDC();
  479. }
  480. pDrawWnd->ReleaseDC(pDC);
  481. }
  482. return pBitmap;
  483. }
  484. // Function name : CXFloorWndCtrl::AddPage
  485. // Description     : Call to add a new page into floorwindow control
  486. // Updated : Version 1.01
  487. // Return type : CFloorPageObject* 
  488. // Argument         : LPCTSTR lpszPageName
  489. // Argument         : int * pIndex
  490. CFloorPageObject* CXFloorWndCtrl::AddPage(LPCTSTR lpszPageName, int * pIndex)
  491. {
  492. ActivatePage(GetCountPage() - 1);
  493. if (CFloorPageObject* pPage = NewPage(m_bAsPage, lpszPageName))
  494. {
  495. int index = m_pArPage->Add(pPage);
  496. if (pIndex) *pIndex = index;
  497. RecalcLayout();
  498. OnActivatePage(pPage);
  499. return pPage;
  500. }
  501. return NULL;
  502. }
  503. // Function name : CXFloorWndCtrl::OnActivatePage
  504. // Description     : Activate page pPage, and notify the parent of this object
  505. // Update : Version 1.01. Focus bug
  506. // Return type : void 
  507. // Argument         : CFloorPageObject * pPage
  508. void CXFloorWndCtrl::OnActivatePage(CFloorPageObject * pPage)
  509. {
  510. if (::IsWindow(m_hWnd))
  511. {
  512. // Always, this function must be called after RecalcLayout
  513. if (m_pActivePage)
  514. m_pActivePage->OnDeactivateObject();
  515. m_pActivePage = pPage;
  516. m_pActivePage->SetRectClient(m_rectClient);
  517. m_pActivePage->OnActivateObject();
  518. if (CWnd* pParentWnd = GetParent())
  519. pParentWnd->SendMessage(m_nMessageChange, (WPARAM)m_pActivePage, (LPARAM)pPage);
  520. FireActivatePage(PtrPageToIndex(pPage));
  521. m_pFocusPage = NULL;
  522. }
  523. }
  524. // Function name : CXFloorWndCtrl::RegClassFloorWnd
  525. // Description     : Call once this function to register FloorWnd class name
  526. // Return type : BOOL 
  527. BOOL CXFloorWndCtrl::RegClassFloorWnd()
  528. {
  529. if (!m_nMessageChange)
  530. {
  531. //At the first call set the new page's font
  532. m_nMessageChange = RegisterWindowMessage(MessageChange);
  533. return TRUE;
  534. }
  535. return FALSE;
  536. }
  537. // Function name : CXFloorWndCtrl::GetActivePage
  538. // Description     : Return the active page
  539. // Return type : CFloorPageObject* 
  540. CFloorPageObject* CXFloorWndCtrl::GetActivePage()
  541. {
  542. return m_pActivePage;
  543. }
  544. // Function name : CXFloorWndCtrl::GetRectClient
  545. // Description     : Return the emtpy rect of this
  546. // Return type : CRect 
  547. CRect CXFloorWndCtrl::GetRectClient()
  548. {
  549. return m_rectClient;
  550. }
  551. // Function name : CXFloorWndCtrl::OnSize
  552. // Description     : Call to recall all height's page
  553. // Return type : void 
  554. // Argument         : UINT nType
  555. // Argument         : int cx
  556. // Argument         : int cy
  557. void CXFloorWndCtrl::OnSize(UINT nType, int cx, int cy) 
  558. {
  559. COleControl::OnSize(nType, cx, cy);
  560. RecalcLayout();
  561. if (CFloorPageObject* pPage = GetActivePage())
  562. pPage->SetRectClient(GetRectClient());
  563. }
  564. // Function name : CXFloorWndCtrl::ActivatePage
  565. // Description     : Activate the page nIndex.
  566. // Return type : BOOL 
  567. // Argument         : int nIndex
  568. BOOL CXFloorWndCtrl::ActivatePage(int nIndex)
  569. {
  570. if (CFloorPageObject* pPage = GetPage(nIndex))
  571. if (pPage != GetActivePage())
  572. {
  573. pPage->PrepareToScroll();
  574. if (m_bAsPage)
  575. if (pPage->IsPullUp())
  576. return PullDownPages(nIndex);
  577. else
  578. return PullUpPages(nIndex);
  579. else
  580. {
  581. // If this is label ...
  582. Move(PtrPageToIndex(pPage),TRUE);
  583. RecalcLayout();
  584. OnActivatePage(pPage);
  585. }
  586. pPage->EndScroll();
  587. if (CWnd* pWnd = pPage->GetWindow())
  588. if (::IsWindow(pWnd->m_hWnd))
  589. pWnd->SetFocus();
  590. }
  591. return FALSE;
  592. }
  593. // Function name : CXFloorWndCtrl::ActivatePage
  594. // Description     : Activate the page with name lpszPageName
  595. // Return type : BOOL 
  596. // Argument         : LPCTSTR lpszPageName
  597. BOOL CXFloorWndCtrl::ActivatePage(LPCTSTR lpszPageName)
  598. {
  599. return ActivatePage(PtrPageToIndex(GetPage(lpszPageName)));
  600. }
  601. // Function name : CXFloorWndCtrl::PullDownPages
  602. // Description     : Pull down all pages, that follow nIndex page
  603. // Update : Version 1.01
  604. // Return type : BOOL 
  605. // Argument         : CFloorPageObject * pPage
  606. BOOL CXFloorWndCtrl::PullDownPages(int nIndex)
  607. {
  608. if (CFloorPageObject* pPage = GetPage(nIndex))
  609. if (pPage->IsPullUp())
  610. {
  611. Move(nIndex, TRUE);
  612. for (int i = nIndex + 1; i < GetCountPage() && GetPage(i)->IsPullUp() ; i++)
  613. GetPage(i)->m_bPullUp = FALSE;
  614. RecalcLayout();
  615. OnActivatePage(pPage);
  616. }
  617. return FALSE;
  618. }
  619. // Function name : CXFloorWndCtrl::PullDownPages
  620. // Description     : Pull up all pages, that ? nIndex page
  621. // Update : Version 1.01
  622. // Return type : BOOL 
  623. // Argument         : CFloorPageObject * pPage
  624. BOOL CXFloorWndCtrl::PullUpPages(int nIndex)
  625. {
  626. if (::IsWindow(m_hWnd))
  627. if (CFloorPageObject* pPage = GetPage(nIndex))
  628. if (pPage->IsPullDown())
  629. {
  630. Move(nIndex, FALSE);
  631. for (int i = nIndex; (i >= 0) && (GetPage(i)->IsPullDown()); i--)
  632. GetPage(i)->m_bPullUp = TRUE;
  633. RecalcLayout();
  634. OnActivatePage(pPage);
  635. }
  636. return FALSE;
  637. }
  638. // Function name : CXFloorWndCtrl::PtrPageToIndex
  639. // Description     : Return position from m_arPages, of pPage
  640. // Return type : int 
  641. // Argument         : CFloorPageObject * pPage
  642. int CXFloorWndCtrl::PtrPageToIndex(CFloorPageObject * pPage)
  643. {
  644. for (int i = 0; i < GetCountPage(); i++)
  645. if ((DWORD)GetPage(i) == (DWORD)pPage)
  646. return i;
  647. return -1;
  648. }
  649. // Function name : CXFloorWndCtrl::Move
  650. // Description     : Scroll window from page nIndex, down or up
  651. // Return type : void 
  652. // Argument         : int nIndex
  653. // Argument         : BOOL bDown
  654. void CXFloorWndCtrl::Move(int nIndex, BOOL bDown)
  655. {
  656. if (::IsWindow(m_hWnd))
  657. if (::IsWindowVisible(m_hWnd))
  658. if (m_bAnimation)
  659. {
  660. HANDLE hThread = ::GetCurrentThread();
  661. int tPriority = ::GetThreadPriority(hThread);
  662. ::SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
  663. // Before I tryed to set highest priority to this thread,
  664. // because follows a critical section. At the end of functions, I will retrieve
  665. // the priority of current thread.
  666. CFloorPageObject* pPage = GetPage(nIndex);
  667. ASSERT (pPage);
  668. if (pPage != m_pActivePage)
  669. {
  670. CRect rClient; GetClientRect(rClient);
  671. CRect rScroll(rClient);
  672. int dyScroll = NULL;
  673. if (bDown)
  674. {
  675. rScroll.top = GetPage(nIndex)->m_rect.bottom;
  676. rScroll.bottom = m_rectClient.bottom;
  677. dyScroll = rScroll.bottom  - rScroll.top;
  678. if (m_bAsPage)
  679. for (int i = nIndex + 1; (i < GetCountPage()) && GetPage(i)->IsPullUp(); i++)
  680. dyScroll -= GetPage(i)->m_rect.Height() + 1;
  681. }
  682. else
  683. {
  684. rScroll.top = m_rectClient.top;
  685. rScroll.bottom = GetPage(nIndex)->m_rect.bottom + 1;
  686. dyScroll = rScroll.bottom  - rScroll.top;
  687. if (m_bAsPage)
  688. for (int i = nIndex; (i >=0 ) && GetPage(i)->IsPullDown(); i--)
  689. dyScroll -= GetPage(i)->m_rect.Height() + 1;
  690. }
  691. int nStep = 5;
  692. int nWhere = bDown ? nStep : -nStep;
  693. pPage->SetRectClient(m_rectClient);
  694. CBitmap* pBitmap = Preview(pPage->GetWindow());
  695. int tScroll = 0, dy = 0;
  696. for (int s = 0; s < dyScroll ; s += nStep)
  697. {
  698. dy = bDown ? max(0,min(nWhere,dyScroll-s)) : min(nWhere,dyScroll-s);
  699. ::ScrollWindow(m_hWnd, 0, dy ,NULL,rScroll);
  700. tScroll += abs(dy);
  701. CDC* pDC = GetDC();
  702. CDC dcMem;
  703. if (dcMem.CreateCompatibleDC(pDC))
  704. {
  705. COLORREF colorBkGnd = TranslateColor(GetBackColor());
  706. CBrush brBkGnd(colorBkGnd);
  707. CBrush* pOldBrush = pDC->SelectObject(&brBkGnd);
  708. CBitmap* pOldBitmap = dcMem.SelectObject(pBitmap);
  709. if (bDown)
  710. {
  711. CRect rCS(CPoint(m_rectClient.left ,rScroll.top), CSize(m_rectClient.Width() , tScroll));
  712. pDC->PatBlt(rScroll.left,rScroll.top, rCS.left - rScroll.left, rCS.bottom - rScroll.top, PATCOPY);
  713. pDC->BitBlt(rCS.left ,rCS.top, rCS.Width() , rCS.Height(), &dcMem, 0, m_rectClient.Height() - tScroll, SRCCOPY);
  714. pDC->PatBlt(rCS.right ,rCS.top, rScroll.right - rCS.right, rCS.bottom - rScroll.top, PATCOPY);
  715. }
  716. else
  717. {
  718. CRect rCS(CPoint(m_rectClient.left ,rScroll.bottom - tScroll), CSize(m_rectClient.Width() , tScroll));
  719. pDC->PatBlt(rScroll.left,rCS.top, rCS.left - rScroll.left, rCS.Height(), PATCOPY);
  720. pDC->BitBlt(rCS.left ,rCS.top, rCS.Width() , rCS.Height(), &dcMem, 0, 0 , SRCCOPY);
  721. pDC->PatBlt(rCS.right,rCS.top, rScroll.right - rCS.right, rCS.Height(), PATCOPY);
  722. }
  723. dcMem.SelectObject(pOldBitmap);
  724. pDC->SelectObject(pOldBrush);
  725. }
  726. ReleaseDC(pDC);
  727. if (m_nSleep > 0)
  728. Sleep(m_nSleep * MulSleep);
  729. }
  730. delete pBitmap;
  731. }
  732. ::SetThreadPriority(hThread, tPriority);
  733. }
  734. }
  735. // Function name : CXFloorWndCtrl::OnLButtonDown
  736. // Description     : Call when user click the mouse
  737. // Update : Version 1.01
  738. // Return type : void 
  739. // Argument         : UINT nFlags
  740. // Argument         : CPoint point
  741. void CXFloorWndCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
  742. {
  743. SetFocus();
  744. if (CFloorPageObject* pPage = GetPageFromPoint(point))
  745. {
  746. int nIndex = PtrPageToIndex(pPage);
  747. if (pPage != GetActivePage())
  748. {
  749. if (pPage->IsPullUp())
  750. PullDownPages(nIndex);
  751. else
  752. PullUpPages(nIndex);
  753. }
  754. else
  755. FireClickOnActivePage(nIndex);
  756. }
  757. COleControl::OnLButtonDown(nFlags, point);
  758. }
  759. void CXFloorWndCtrl::OnLButtonUp(UINT nFlags, CPoint point) 
  760. {
  761. // TODO: Add your message handler code here and/or call default
  762. COleControl::OnLButtonUp(nFlags, point);
  763. }
  764. void CXFloorWndCtrl::OnMouseMove(UINT nFlags, CPoint point) 
  765. {
  766. CFloorPageObject* pPage = GetPageFromPoint(point);
  767. if (pPage)
  768. if (m_pFocusPage != pPage)
  769. if (pPage != m_pActivePage)
  770. pPage->OnFocus();
  771. if (m_pFocusPage)
  772. if (m_pFocusPage != pPage)
  773. m_pFocusPage->Invalidate(TRUE);
  774. m_pFocusPage = pPage;
  775. // Try to put a timer to erase the focused page when cursor outrun the area of this window
  776. KillTimer(IDTIMERERASEFOCUS);
  777. if (m_pFocusPage)
  778. SetTimer(IDTIMERERASEFOCUS, UPDATEIDTIMERERASEFOCUS, NULL);
  779. COleControl::OnMouseMove(nFlags, point);
  780. }
  781. // Function name : CXFloorWndCtrl::GetPageFromPoint
  782. // Description     : Return page from point
  783. // Return type : CFloorPageObject* 
  784. // Argument         : CPoint point
  785. CFloorPageObject* CXFloorWndCtrl::GetPageFromPoint(CPoint point)
  786. {
  787. for (int i = 0; i < GetCountPage(); i++)
  788. if (GetPage(i)->PtInObject(point))
  789. return GetPage(i);
  790. return NULL;
  791. }
  792. // Function name : CXFloorWndCtrl::DeletePage
  793. // Description     : Delete the page with index nIndex. Call ActivatePage after
  794. // Update : Version 1.01
  795. // Return type : BOOL 
  796. // Argument         : int nIndex
  797. BOOL CXFloorWndCtrl::DeletePage(int nIndex)
  798. {
  799. if (CFloorPageObject* pPage = GetPage(nIndex))
  800. {
  801. BOOL bDeleteActivePage = pPage == GetActivePage();
  802. delete pPage;
  803. m_pArPage->RemoveAt(nIndex);
  804. if (bDeleteActivePage)
  805. m_pActivePage = NULL;
  806. PullUpPages(nIndex);
  807. RecalcLayout();
  808. if (bDeleteActivePage)
  809. ActivatePage(max(min(nIndex, GetCountPage()-1),0));
  810. return TRUE;
  811. }
  812. return FALSE;
  813. }
  814. // Function name : CXFloorWndCtrl::DeletePage
  815. // Description     : 
  816. // Return type : BOOL 
  817. // Argument         : LPCTSTR lpszPageName
  818. BOOL CXFloorWndCtrl::DeletePage(LPCTSTR lpszPageName)
  819. {
  820. return DeletePage(PtrPageToIndex(GetPage(lpszPageName)));
  821. }
  822. // Function name : CXFloorWndCtrl::OnTimer
  823. // Description     : Put a timer to erase the focus page if mouse pointer is outside of this window
  824. // Return type : void 
  825. // Argument         : UINT nIDEvent
  826. void CXFloorWndCtrl::OnTimer(UINT nIDEvent) 
  827. {
  828. switch (nIDEvent)
  829. {
  830. case IDTIMERERASEFOCUS:
  831. {
  832. CPoint p; ::GetCursorPos(&p);
  833. if (this != CWnd::WindowFromPoint(p))
  834. {
  835. if (m_pFocusPage)
  836. m_pFocusPage->Invalidate(TRUE);
  837. m_pFocusPage = NULL;
  838. KillTimer(IDTIMERERASEFOCUS);
  839. }
  840. break;
  841. }
  842. case IDSTARTMOVELABEL:
  843. {
  844. KillTimer(IDSTARTMOVELABEL);
  845. CComboBox* pCombo = (CComboBox*)GetDlgItem(ID_LABELCOMBO);
  846. int nItem = pCombo->GetCurSel();
  847. CFloorPageObject* pPage = (CFloorPageObject*)pCombo->GetItemData(nItem);
  848. ActivatePage(PtrPageToIndex(pPage));
  849. }
  850. }
  851. COleControl::OnTimer(nIDEvent);
  852. }
  853. // Function name : CXFloorWndCtrl::OnEraseBkgnd
  854. // Description     : Do not erase bkgnd of this control
  855. // Return type : BOOL 
  856. // Argument         : CDC* pDC
  857. BOOL CXFloorWndCtrl::OnEraseBkgnd(CDC* pDC) 
  858. {
  859. return TRUE;
  860. }
  861. // Function name : CXFloorWndCtrl::AddPage
  862. // Description     : Add a new Page. Called by interface
  863. // Return type : short 
  864. // Argument         : LPCTSTR sName
  865. short CXFloorWndCtrl::_AddPage(LPCTSTR sName) 
  866. {
  867. int nIndex = NULL;
  868. AddPage(sName, &nIndex);
  869. return nIndex;
  870. }
  871. // Function name : CXFloorWndCtrl::_DeletePage
  872. // Description     : Delete page nIndex. Called by interface
  873. // Return type : BOOL 
  874. // Argument         : short nIndex
  875. BOOL CXFloorWndCtrl::_DeletePage(short nIndex) 
  876. {
  877. if (DeletePage(nIndex))
  878. {
  879. RecalcLayout();
  880. Invalidate();
  881. return TRUE;
  882. }
  883. return FALSE;
  884. }
  885. // Function name : CXFloorWndCtrl::_GetPageName
  886. // Description     : return the name of page
  887. // Return type : BSTR 
  888. // Argument         : short nIndex
  889. BSTR CXFloorWndCtrl::_GetPageName(short nIndex) 
  890. {
  891. CString strResult;
  892. if (CFloorPageObject* pPage = GetPage(nIndex))
  893. strResult = pPage->GetName();
  894. return strResult.AllocSysString();
  895. }
  896. // Function name : CXFloorWndCtrl::_GetPage
  897. // Description     : 
  898. // Return type : short 
  899. // Argument         : LPCTSTR lpszPageName
  900. short CXFloorWndCtrl::_GetPage(LPCTSTR lpszPageName) 
  901. {
  902. return PtrPageToIndex(GetPage(lpszPageName));
  903. }
  904. // Function name : CXFloorWndCtrl::_ActivatePage
  905. // Description     : 
  906. // Return type : BOOL 
  907. // Argument         : short nIndex
  908. BOOL CXFloorWndCtrl::_ActivatePage(short nIndex) 
  909. {
  910. ActivatePage(nIndex);
  911. return TRUE;
  912. }
  913. // Function name : CXFloorWndCtrl::_AttachWindow
  914. // Description     : AttachWindow
  915. // Return type : BOOL 
  916. // Argument         : short nIndex
  917. // Argument         : long hWnd
  918. BOOL CXFloorWndCtrl::_AttachWindow(short nIndex, long pWnd) 
  919. {
  920. CWnd* pWndClient = (CWnd*)pWnd;
  921. if (pWndClient)
  922. if (::IsWindow(pWndClient->m_hWnd))
  923. if (CFloorPageObject* pPage = GetPage(nIndex))
  924. {
  925. pPage->Attach(pWndClient);
  926. return TRUE;
  927. }
  928. return FALSE;
  929. }
  930. // Function name : CXFloorWndCtrl::_SetPageName
  931. // Description     : 
  932. // Return type : BOOL 
  933. // Argument         : short nIndex
  934. // Argument         : LPCTSTR lpszPageName
  935. BOOL CXFloorWndCtrl::_SetPageName(short nIndex, LPCTSTR lpszPageName) 
  936. {
  937. if (CFloorPageObject* pPage = GetPage(nIndex))
  938. {
  939. pPage->SetName(lpszPageName);
  940. return TRUE;
  941. }
  942. return FALSE;
  943. }
  944. // Function name : CXFloorWndCtrl::OnAnimationChanged
  945. // Description     : Called when something is happen eith m_bAnimation
  946. // Return type : void 
  947. void CXFloorWndCtrl::OnAnimationChanged() 
  948. {
  949. SetModifiedFlag();
  950. }
  951. void CXFloorWndCtrl::OnSleepChanged() 
  952. {
  953. // TODO: Add notification handler code
  954. SetModifiedFlag();
  955. }
  956. void CXFloorWndCtrl::OnSignChanged() 
  957. {
  958. // TODO: Add notification handler code
  959. SetModifiedFlag();
  960. }
  961. // Function name : CXFloorWndCtrl::GetHeight
  962. // Description     : Get the Height of page nIndex
  963. // Return type : short 
  964. // Argument         : short nIndex
  965. short CXFloorWndCtrl::GetHeight(short nIndex) 
  966. {
  967. if (CFloorPageObject* pPage = GetPage(nIndex))
  968. return pPage->GetHeight();
  969. return -1;
  970. }
  971. // Function name : CXFloorWndCtrl::SetHeight
  972. // Description     : Set the new height of page nIndex to nNewValue
  973. // Return type : void 
  974. // Argument         : short nIndex
  975. // Argument         : short nNewValue
  976. void CXFloorWndCtrl::SetHeight(short nIndex, short nNewValue) 
  977. {
  978. if (CFloorPageObject* pPage = GetPage(nIndex))
  979. {
  980. pPage->SetHeight(nNewValue);
  981. SetModifiedFlag();
  982. }
  983. }
  984. // Function name : CXFloorWndCtrl::GetColor
  985. // Description     : return the default color of page
  986. // Return type : OLE_COLOR 
  987. // Argument         : short nIndex
  988. OLE_COLOR CXFloorWndCtrl::GetColor(short nIndex) 
  989. {
  990. if (CFloorPageObject* pPage = GetPage(nIndex))
  991. {
  992. LOGBRUSH logBrush;
  993. pPage->m_brBkGnd.GetLogBrush(&logBrush);
  994. return logBrush.lbColor;
  995. }
  996. return RGB(0,0,0);
  997. }
  998. // Function name : CXFloorWndCtrl::SetColor
  999. // Description     : Set the new color of background's page
  1000. // Return type : void 
  1001. // Argument         : short nIndex
  1002. // Argument         : OLE_COLOR nNewValue
  1003. void CXFloorWndCtrl::SetColor(short nIndex, OLE_COLOR nNewValue) 
  1004. {
  1005. if (CFloorPageObject* pPage = GetPage(nIndex))
  1006. {
  1007. pPage->SetBkGnd(TranslateColor(nNewValue));
  1008. SetModifiedFlag();
  1009. }
  1010. }
  1011. // Function name : CXFloorWndCtrl::OnPagesChanged
  1012. // Description     : 
  1013. // Return type : void 
  1014. void CXFloorWndCtrl::OnPagesChanged()
  1015. {
  1016. if (m_hWnd)
  1017. if (::IsWindow(m_hWnd))
  1018. {
  1019. BOOL bSAnimation = m_bAnimation;
  1020. m_bAnimation = FALSE;
  1021. int i = 0;
  1022. BOOL cont = TRUE;
  1023. while (cont)
  1024. {
  1025. CString sItem, sName, sUser;
  1026. AfxExtractSubString(sItem, m_sPages, i, _cPagesSeparator);
  1027. AfxExtractSubString(sName, sItem, 0, TCHAR('\'));
  1028. AfxExtractSubString(sUser, sItem, 1, TCHAR('\'));
  1029. LPARAM lParam = atol((LPCTSTR)sUser);
  1030. if (cont = !sName.IsEmpty())
  1031. {
  1032. int nItem = i;
  1033. if (CFloorPageObject* pPage = GetPage(nItem))
  1034. pPage->SetName(sName);
  1035. else
  1036. AddPage(sName, &nItem);
  1037. SetUserData(nItem, lParam);
  1038. i++;
  1039. }
  1040. }
  1041. while (DeletePage(i));
  1042. SetModifiedFlag();
  1043. m_bAnimation = bSAnimation;
  1044. }
  1045. }
  1046. // Function name : CXFloorWndCtrl::GetUserData
  1047. // Description     : Return the user data attached to a page nIndex
  1048. // Return type : long 
  1049. // Argument         : short nIndex
  1050. long CXFloorWndCtrl::GetUserData(short nIndex) 
  1051. {
  1052. long lResult = -1;
  1053. if (CFloorPageObject* pPage = GetPage(nIndex))
  1054. lResult = pPage->GetUserData();
  1055. return lResult;
  1056. }
  1057. // Function name : CXFloorWndCtrl::SetUserData
  1058. // Description     : Set the new user data to a page nIndex
  1059. // Return type : void 
  1060. // Argument         : short nIndex
  1061. // Argument         : long nNewValue
  1062. void CXFloorWndCtrl::SetUserData(short nIndex, long nNewValue) 
  1063. {
  1064. long lResult = 0;
  1065. if (CFloorPageObject* pPage = GetPage(nIndex))
  1066. pPage->SetUserData(nNewValue);
  1067. SetModifiedFlag();
  1068. }
  1069. // Function name : CXFloorWndCtrl::_Init
  1070. // Description     : 
  1071. // Return type : void 
  1072. void CXFloorWndCtrl::_Init() 
  1073. {
  1074. RecalcLayout();
  1075. int nIndex = 0;
  1076. CFloorPageObject* pPage = NULL;
  1077. while (pPage = GetPage(nIndex++))
  1078. pPage->SetRectClient(GetRectClient());
  1079. }
  1080. // Function name : CXFloorWndCtrl::_GetActivePage
  1081. // Description     : Version 1.01
  1082. // Return type : short 
  1083. short CXFloorWndCtrl::_GetActivePage() 
  1084. {
  1085. return PtrPageToIndex(m_pActivePage);
  1086. }
  1087. // Function name : CXFloorWndCtrl::_GetPagesCount
  1088. // Description     : Version 1.01
  1089. // Return type : long 
  1090. long CXFloorWndCtrl::_GetPagesCount() 
  1091. {
  1092. return GetCountPage();
  1093. }
  1094. // Function name : CXFloorWndCtrl::_IsPage
  1095. // Description     : Version 1.01
  1096. // Return type : BOOL 
  1097. // Argument         : short nIndex
  1098. BOOL CXFloorWndCtrl::_IsPage(short nIndex) 
  1099. {
  1100. return GetPage(nIndex) != NULL;
  1101. }
  1102. // Function name : CXFloorWndCtrl::_GetLeftTopPage
  1103. // Description     : Version 1.01
  1104. // Return type : long 
  1105. // Argument         : short nIndex
  1106. long CXFloorWndCtrl::_GetLeftTopPage(short nIndex) 
  1107. {
  1108. if (CFloorPageObject* pPage = GetPage(nIndex))
  1109. return MAKELPARAM(pPage->m_rect.TopLeft().x, pPage->m_rect.TopLeft().y);
  1110. return -1;
  1111. }
  1112. // Function name : CXFloorWndCtrl::_GetBottomRightPage
  1113. // Description     : Version 1.01
  1114. // Return type : long 
  1115. // Argument         : short nIndex
  1116. long CXFloorWndCtrl::_GetBottomRightPage(short nIndex) 
  1117. {
  1118. if (CFloorPageObject* pPage = GetPage(nIndex))
  1119. return MAKELPARAM(pPage->m_rect.BottomRight().x, pPage->m_rect.BottomRight().y);
  1120. return -1;
  1121. }
  1122. // Function name : CXFloorWndCtrl::WindowProc
  1123. // Description     : Window procedure.
  1124. // This is very important for next controls that will be inserted in this control.
  1125. // To accepts some messages you need to insert here. See CReflectorWnd class
  1126. // Update : Version 1.01
  1127. // Return type : LRESULT 
  1128. // Argument         : UINT message
  1129. // Argument         : WPARAM wParam
  1130. // Argument         : LPARAM lParam
  1131. LRESULT CXFloorWndCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
  1132. {
  1133. UINT id = (UINT)wParam;
  1134. switch (message)
  1135. {
  1136. case WM_COMMAND:
  1137. {
  1138. id = LOWORD(wParam);
  1139. if ( HIWORD(wParam) == CBN_SELENDOK )
  1140. if ( id == ID_LABELCOMBO )
  1141. {
  1142. SetTimer(IDSTARTMOVELABEL, UPDATEIDSTARTMOVELABEL, NULL);
  1143. break;
  1144. }
  1145. }
  1146. case WM_NOTIFY:
  1147. case WM_DRAWITEM:
  1148. case WM_MEASUREITEM:
  1149. {
  1150. if (CWnd* pWnd = GetDlgItem((UINT)id))
  1151. if (::IsWindow(pWnd->m_hWnd))
  1152. return pWnd->SendMessage(message, wParam, lParam);
  1153. }
  1154. }
  1155. return COleControl::WindowProc(message, wParam, lParam);
  1156. }
  1157. // Function name : CXFloorWndCtrl::SetFont
  1158. // Description     : 
  1159. // Return type : void 
  1160. // Argument         : CWnd *pWindow
  1161. // Argument         : COleControl *pControlSource
  1162. void CXFloorWndCtrl::SetFont(CWnd *pWindow, COleControl *pControlSource)
  1163. {
  1164. if (pWindow)
  1165. if (::IsWindow(pWindow->m_hWnd))
  1166. if (pControlSource)
  1167. {
  1168. IFontDisp* pFontDisp = pControlSource->GetFont();
  1169. IFont* pIFont = NULL;
  1170. if (SUCCEEDED(pFontDisp->QueryInterface(IID_IFont, (void**)&pIFont)))
  1171. {
  1172. if (pIFont)
  1173. {
  1174. HFONT hFont = NULL;
  1175. if (SUCCEEDED(pIFont->get_hFont(&hFont)))
  1176. pWindow->SetFont(CFont::FromHandle(hFont));
  1177. }
  1178. pFontDisp->Release();
  1179. }
  1180. }
  1181. }
  1182. // Function name : CXFloorWndCtrl::RefreshFontLabel
  1183. // Description     : Called when something are change into font page
  1184. // Return type : void 
  1185. // Argument         : COleControl *pControl
  1186. void CXFloorWndCtrl::RefreshFontLabel(COleControl *pControl)
  1187. {
  1188. SetFont(GetComboBox(), pControl);
  1189. SetFont(GetLabelControl(), pControl);
  1190. }
  1191. // Function name : CXFloorWndCtrl::ChangeHeightLabel
  1192. // Description     : return the rect of the page
  1193. // Return type : void 
  1194. CRect CXFloorWndCtrl::ChangeHeightLabel(CSize s)
  1195. {
  1196. //This function must be called only if style of control is floor
  1197. CComboBox* pCombo = GetComboBox();
  1198. ASSERT (pCombo);
  1199. CTLabelComboBox* pLabelControl = GetLabelControl();
  1200. ASSERT (pLabelControl);
  1201. // Just do this
  1202. pCombo->MoveWindow(0,0, s.cx, m_nDYCombo);
  1203. CRect rect; pCombo->GetClientRect(rect);
  1204. m_nDYLabel = rect.Height() + 2;
  1205. CRect rResult = CRect(CPoint(0,0), CSize(s.cx, m_nDYLabel));
  1206. pLabelControl->MoveWindow(rResult);
  1207. return rResult;
  1208. }
  1209. // Function name : CXFloorWndCtrl::PrepareChangeStyle
  1210. // Description     : 
  1211. // Return type : void 
  1212. void CXFloorWndCtrl::PrepareChangeStyle()
  1213. {
  1214. if (m_bAsPage)
  1215. {
  1216. // The new style is floor
  1217. if (GetComboBox())
  1218. GetComboBox()->DestroyWindow();
  1219. if (GetLabelControl())
  1220. GetLabelControl()->DestroyWindow();
  1221. ASSERT( !GetComboBox() );
  1222. }
  1223. else
  1224. if (m_hWnd)
  1225. {
  1226. if (!GetComboBox())
  1227. {
  1228. // The new style is label
  1229. VERIFY(m_cbPage.Create(CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE, CRect(0,0,0,0), this, ID_LABELCOMBO));
  1230. m_lbPage.RegClassLabelEdit();
  1231. VERIFY(m_lbPage.Create(_T("TLabelEdit"), _T(""), WS_CHILD | WS_VISIBLE, CRect(0,0,0,0), this, ID_LABEL));
  1232. m_lbPage.Init();
  1233. m_lbPage.AttachWindow(&m_cbPage);
  1234. OnBackColorChanged();
  1235. }
  1236. else
  1237. {
  1238. m_cbPage.ResetContent();
  1239. m_lbPage.SetWindowText(NULL);
  1240. }
  1241. RefreshFontLabel(this);
  1242. ASSERT( GetComboBox() );
  1243. }
  1244. }
  1245. // Function name : CXFloorWndCtrl::OnAsPageChanged
  1246. // Description     : When user changes the style of control
  1247. // Return type : void 
  1248. void CXFloorWndCtrl::OnAsPageChanged() 
  1249. {
  1250. // Here we will remove old array of pages and will put the new one.
  1251. CArrayPage * pArPages = new CArrayPage();
  1252. BOOL bAutoDetach = CFloorPageObject::m_bAutoDetach;
  1253. CFloorPageObject::m_bAutoDetach = FALSE;
  1254. PrepareChangeStyle();
  1255. int nActivePage = -1;
  1256. for (int i = 0; i < m_pArPage->GetSize(); i++)
  1257. {
  1258. CFloorPageObject* pPage = (*m_pArPage)[i];
  1259. CFloorPageObject* pNewPage = NewPage(m_bAsPage, pPage->GetName());
  1260. pNewPage->m_pWndClient = pPage->m_pWndClient;
  1261. pArPages->Add(pNewPage);
  1262. if (pPage == m_pActivePage)
  1263. {
  1264. nActivePage = i;
  1265. m_pActivePage->OnDeactivateObject();
  1266. m_pActivePage = NULL;
  1267. }
  1268. delete pPage;
  1269. }
  1270. // Set the new one array of pages
  1271. delete m_pArPage;
  1272. m_pArPage = pArPages;
  1273. ActivatePage(nActivePage);
  1274. RecalcLayout();
  1275. CFloorPageObject::m_bAutoDetach = bAutoDetach;
  1276. SetModifiedFlag();
  1277. }
  1278. // Function name : CXFloorWndCtrl::NewPage
  1279. // Description     : Create a new kind of page
  1280. // Return type : CFloorPageObject* 
  1281. // Argument         : BOOL bAsPage
  1282. // Argument         : LPCTSTR lpszPageName
  1283. CFloorPageObject* CXFloorWndCtrl::NewPage(BOOL bAsPage, LPCTSTR lpszPageName)
  1284. {
  1285. return (bAsPage ? new CFloorPageObject(this, lpszPageName) :  new CFloorLabelObject(this, lpszPageName));
  1286. }
  1287. // Function name : CXFloorWndCtrl::OnFontChanged
  1288. // Description     : Refresh the font into CFloorLabelObject
  1289. // Return type : void 
  1290. void CXFloorWndCtrl::OnFontChanged() 
  1291. {
  1292. RefreshFontLabel(this);
  1293. RecalcLayout();
  1294. COleControl::OnFontChanged();
  1295. }
  1296. // Function name : CXFloorWndCtrl::OnCreate
  1297. // Description     : Load the pages into control
  1298. // Return type : int 
  1299. // Argument         : LPCREATESTRUCT lpCreateStruct
  1300. int CXFloorWndCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  1301. {
  1302. if (COleControl::OnCreate(lpCreateStruct) == -1)
  1303. return -1;
  1304. PrepareChangeStyle();
  1305. OnPagesChanged();
  1306. return 0;
  1307. }
  1308. // Function name : CXFloorWndCtrl::StyleAs
  1309. // Description     : 
  1310. // Return type : void 
  1311. // Argument         : BOOL bAsFloor
  1312. void CXFloorWndCtrl::StyleAs(BOOL bAsFloor) 
  1313. {
  1314. m_bAsPage = bAsFloor;
  1315. OnAsPageChanged();
  1316. }
  1317. // Function name : CXFloorWndCtrl::GetHWnd
  1318. // Description     : 
  1319. // Return type : long 
  1320. // Argument         : long nIndex
  1321. long CXFloorWndCtrl::GetHWnd(long nIndex) 
  1322. {
  1323. if (CFloorPageObject* pPage = GetPage(nIndex))
  1324. if (CWnd* pWnd = pPage->GetWindow())
  1325. return (long)pWnd->m_hWnd;
  1326. return NULL;
  1327. }
  1328. // Function name : CXFloorWndCtrl::GetComboBox
  1329. // Description     : return NULL if combobox is not created....
  1330. // Return type : CComboBox* 
  1331. CComboBox* CXFloorWndCtrl::GetComboBox()
  1332. {
  1333. if (::IsWindow(m_cbPage.m_hWnd))
  1334. return &m_cbPage;
  1335. return NULL;
  1336. }
  1337. // Function name : CXFloorWndCtrl::GetLabelControl
  1338. // Description     : return NULL if labelcontrol is not created....
  1339. // Return type : CTLabelComboBox* 
  1340. CTLabelComboBox* CXFloorWndCtrl::GetLabelControl()
  1341. {
  1342. if (::IsWindow(m_lbPage.m_hWnd))
  1343. return &m_lbPage;
  1344. return NULL;
  1345. }
  1346. // Function name : CXFloorWndCtrl::Lookup
  1347. // Description     : Look for page pLabelObject in combobox
  1348. // Return type : int 
  1349. // Argument         : CFloorLabelObject *pLabelObject
  1350. int CXFloorWndCtrl::Lookup(CFloorLabelObject *pLabelObject)
  1351. {
  1352. CComboBox* pComboBox = GetComboBox();
  1353. int i = 0, n = pComboBox->GetCount();
  1354. for (i = 0; (i < n) && (((DWORD)pComboBox->GetItemData(i)) != (DWORD)pLabelObject); i++);
  1355. return i < n ? i : -1;
  1356. }
  1357. // Function name : CXFloorWndCtrl::OnBackColorChanged
  1358. // Description     : 
  1359. // Return type : void 
  1360. void CXFloorWndCtrl::OnBackColorChanged() 
  1361. {
  1362. if (CBrush* pBrush = &CTLabelEdit::m_brBkGnd)
  1363. {
  1364. pBrush->DeleteObject();
  1365. pBrush->CreateSolidBrush(TranslateColor(GetBackColor()));
  1366. if (CWnd* pLabel = GetLabelControl())
  1367. {
  1368. ::SetClassLong(pLabel->m_hWnd, GCL_HBRBACKGROUND, (long)(HBRUSH)*pBrush);
  1369. pLabel->Invalidate();
  1370. }
  1371. }
  1372. COleControl::OnBackColorChanged();
  1373. }