TreeMenuFrame.cpp
上传用户:rxhxxy
上传日期:2007-01-02
资源大小:72k
文件大小:11k
源码类别:

TreeView控件

开发平台:

Visual C++

  1. //************************************************************************
  2. //
  3. // Filename : TreeMenuFrame.cpp
  4. // Author : Rainer Pfitzner
  5. // Date : 08.may.1998
  6. // Purpose : A class similar IE 4's left side pane (Favorites, Channels...): 
  7. // Combines a button, some bevels and a CTreeView derived class
  8. //              called CTreeMenu. Easy usage on Dialog Templates and in Views
  9. // Copyright (c) 1998 raip systems. All rights reserved
  10. //
  11. //************************************************************************
  12. #include "stdafx.h"
  13. #include "TreeMenuFrame.h"
  14. #ifdef _DEBUG
  15. #define new DEBUG_NEW
  16. #undef THIS_FILE
  17. static char THIS_FILE[] = __FILE__;
  18. #endif
  19. #include "sizecbar.h"
  20. #define BTNX 16
  21. #define BTNY 12
  22. #define BORDER  2
  23. #define IDC_TREEMENUFRAME 1119
  24. class CSizingControlBar;
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CFlatBtn
  27. CFlatBtn::CFlatBtn()
  28. {
  29. m_clrText = GetSysColor (COLOR_BTNTEXT);
  30. m_clrFace = GetSysColor (COLOR_BTNFACE);
  31. m_clrHotText = RGB(0,0,255);
  32. m_bLBtnDown = FALSE;
  33. strText = _T("x");
  34. }
  35. CFlatBtn::~CFlatBtn()
  36. {
  37. }
  38. BEGIN_MESSAGE_MAP(CFlatBtn, CButton)
  39. //{{AFX_MSG_MAP(CFlatBtn)
  40. ON_WM_MOUSEMOVE()
  41. ON_WM_LBUTTONDOWN()
  42. ON_WM_LBUTTONUP()
  43. ON_WM_TIMER()
  44. //}}AFX_MSG_MAP
  45. END_MESSAGE_MAP()
  46. /////////////////////////////////////////////////////////////////////////////
  47. // CFlatBtn message handlers
  48. void CFlatBtn::OnMouseMove(UINT nFlags, CPoint point)
  49. {
  50. SetTimer (1,10,NULL);
  51. CButton::OnMouseMove(nFlags, point);
  52. }
  53. void CFlatBtn::OnLButtonDown(UINT nFlags, CPoint point)
  54. {
  55. m_bLBtnDown= TRUE;
  56. CButton::OnLButtonDown(nFlags, point);
  57. }
  58. void CFlatBtn::OnLButtonUp(UINT nFlags, CPoint point)
  59. {
  60. m_bLBtnDown= FALSE;
  61.   CButton::OnLButtonUp(nFlags, point);
  62. }
  63. void CFlatBtn::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  64. {
  65. ASSERT(lpDIS != NULL);
  66. CDC* pDC = GetDC();
  67. m_rect.CopyRect(&lpDIS->rcItem);
  68. UINT state = lpDIS->itemState;
  69.     if ( (state & ODS_SELECTED) )
  70. pDC->Draw3dRect (m_rect,GetSysColor(COLOR_3DDKSHADOW), GetSysColor(COLOR_3DHILIGHT));
  71.     else
  72. pDC->Draw3dRect (m_rect,m_clrFace, m_clrFace);
  73. pDC->SetBkMode( TRANSPARENT );
  74. pDC->SetTextColor( m_clrText );
  75. if (state & ODS_DISABLED)
  76. {
  77. CBrush grayBrush;
  78. grayBrush.CreateSolidBrush (GetSysColor(COLOR_GRAYTEXT));
  79. pDC->GrayString (&grayBrush,NULL,(LPARAM)((LPCSTR)strText),-1,m_rect.left, m_rect.top,m_rect.Width(),m_rect.Height());
  80. }
  81. else 
  82. pDC->DrawText(strText, m_rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
  83. }
  84. void CFlatBtn::OnTimer(UINT nIDEvent)
  85. {
  86. POINT pt;
  87. static BOOL pPainted = FALSE;
  88. GetCursorPos(&pt);
  89. CRect rect;
  90. GetWindowRect (rect);
  91. CDC *pDC = GetDC ();
  92. if (m_bLBtnDown)
  93. {
  94. KillTimer (1);
  95. if (pPainted)
  96. InvalidateRect (NULL);
  97. pPainted = FALSE;
  98. return;
  99. }
  100. if (!rect.PtInRect (pt))
  101. {
  102. KillTimer (1);
  103. if (pPainted)
  104. InvalidateRect (NULL);
  105. pPainted = FALSE;
  106. return;
  107. }
  108. else
  109. {
  110. if (pPainted)
  111. return;
  112. else
  113. pPainted = TRUE;
  114. GetClientRect(rect);
  115. pDC->FillSolidRect(rect, m_clrFace);
  116. pDC->SetTextColor(m_clrHotText);
  117. pDC->DrawText(strText, m_rect, DT_LEFT|DT_CENTER|DT_VCENTER|DT_SINGLELINE);
  118. pDC->Draw3dRect(rect, GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
  119. ReleaseDC (pDC);
  120. }
  121. CButton::OnTimer(nIDEvent);
  122. }
  123. //////////////////////////////////////
  124. //  CDragCaption
  125. IMPLEMENT_DYNAMIC(CDragCaption, CStatic)
  126. BEGIN_MESSAGE_MAP(CDragCaption, CStatic)
  127. ON_WM_NCHITTEST()
  128. ON_WM_LBUTTONDOWN()
  129. ON_WM_CTLCOLOR_REFLECT()
  130. END_MESSAGE_MAP()
  131. ///////////////////
  132. //
  133. CDragCaption::CDragCaption(LPCTSTR lpText, BOOL bDeleteOnDestroy)
  134. {
  135. m_color = RGB(0,0,255); // hot color
  136. m_bDeleteOnDestroy = bDeleteOnDestroy; // delete object with window?
  137. }
  138. UINT CDragCaption::OnNcHitTest(CPoint point)
  139. {
  140. return HTCLIENT;
  141. }
  142. HBRUSH CDragCaption::CtlColor(CDC* pDC, UINT nCtlColor)
  143. {
  144. ASSERT(nCtlColor == CTLCOLOR_STATIC);
  145. DWORD dwStyle = GetStyle();
  146. HBRUSH hbr = NULL;
  147. if ((dwStyle & 0xFF) <= SS_RIGHT) {
  148. // this is a text control: set up font and colors
  149. if (!(HFONT)m_font) {
  150. // first time init: create font
  151. LOGFONT lf;
  152. GetFont()->GetObject(sizeof(lf), &lf);
  153. // lf.lfUnderline = TRUE;
  154. // lf.lfWeight = FW_BOLD;
  155. // lf.lfItalic = TRUE;
  156. m_font.CreateFontIndirect(&lf);
  157. }
  158. // use underline font and visited/unvisited colors
  159. pDC->SelectObject(&m_font);
  160. // pDC->SetTextColor(m_color);
  161. pDC->SetBkMode(TRANSPARENT);
  162. // return hollow brush to preserve parent background color
  163. hbr = (HBRUSH)::GetStockObject(HOLLOW_BRUSH);
  164. }
  165. return hbr;
  166. }
  167. /////////////////
  168. // Handle mouse click: StartTracking
  169. void CDragCaption::OnLButtonDown(UINT nFlags, CPoint point)
  170. {
  171. // send TMFN_HIDE to parent and handle there
  172. CWnd* pParent = GetParent();
  173. ASSERT_VALID(pParent);
  174. if (pParent != NULL)
  175. pParent->SendMessage(TMFN_CAPTIONDRAG);
  176. }
  177. void CDragCaption::PostNcDestroy()
  178. {
  179. if (m_bDeleteOnDestroy)
  180. delete this;
  181. }
  182. /////////////////////////////////////////////////////////////////////////////
  183. // CTreeMenuFrame
  184. IMPLEMENT_DYNCREATE(CTreeMenuFrame, CWnd)
  185. CTreeMenuFrame::CTreeMenuFrame()
  186. {
  187. RegisterClass();
  188. bSideBevels = FALSE;
  189. bFrameBevel = FALSE;
  190. }
  191. CTreeMenuFrame::~CTreeMenuFrame()
  192. {
  193. }
  194. BEGIN_MESSAGE_MAP(CTreeMenuFrame, CWnd)
  195. //{{AFX_MSG_MAP(CTreeMenuFrame)
  196. ON_WM_SIZE()
  197. ON_COMMAND(IDC_BTN_HIDE, OnButtonHide)
  198. //}}AFX_MSG_MAP
  199. ON_MESSAGE(TMFN_CAPTIONDRAG, OnCaptionDrag)
  200. END_MESSAGE_MAP()
  201. /////////////////////////////////////////////////////////////////////////////
  202. // CTreeMenuFrame message handlers
  203. void CTreeMenuFrame::RegisterClass()
  204. {
  205. WNDCLASSEX wc;
  206. HINSTANCE hInst = AfxGetInstanceHandle();
  207. if (!(::GetClassInfoEx(hInst, TREEMENUCTRL_CLASSNAME, &wc)))
  208.     {
  209. wc.cbSize = sizeof(WNDCLASSEX);
  210. wc.style = CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW|CS_CLASSDC; //CS_GLOBALCLASS|CS_BYTEALIGNCLIENT;
  211. wc.lpfnWndProc = ::DefWindowProc; // Message processing code
  212. wc.cbClsExtra = 0; // No extra bytes needed
  213. wc.cbWndExtra = 0; // No DLGWINDOWEXTRA needed
  214. wc.hInstance = hInst; // Instance handle
  215. wc.hIcon = NULL; // No icon
  216. wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); // Use Arrow cursor 
  217. wc.hbrBackground = NULL; // (HBRUSH) (COLOR_3DFACE+1);
  218. wc.lpszMenuName = NULL; // No menus
  219. wc.lpszClassName = TREEMENUCTRL_CLASSNAME; // Class name
  220. wc.hIconSm = NULL; // No Icon associated to the class
  221. }
  222. if (!::RegisterClassEx(&wc)) // If registration failed, subsequent dialogs will fail
  223. {
  224. // ASSERT(FALSE);
  225. }
  226. }
  227. BOOL CTreeMenuFrame::Create(const RECT& rect, CWnd* pParentWnd, UINT nID, DWORD dwStyle)
  228. {
  229.     ASSERT(pParentWnd->GetSafeHwnd());
  230.     if (!CWnd::Create(TREEMENUCTRL_CLASSNAME, NULL, dwStyle, rect, pParentWnd, nID)) 
  231.         return FALSE;
  232. Initialize();
  233. return TRUE;
  234. }
  235. BOOL CTreeMenuFrame::SubclassDlgItem(UINT nID, CWnd* parent)
  236. {
  237. if (!CWnd::SubclassDlgItem(nID, parent)) 
  238. return FALSE;
  239. Initialize();
  240. return TRUE;
  241. }
  242. void CTreeMenuFrame::Initialize()
  243. {
  244. // creates all the objects in frame -
  245. // caption, tree, button
  246. CRect rc;
  247. if (bSideBevels || !bFrameBevel)
  248. {
  249. if (!m_stcBevelLeft.Create("", WS_VISIBLE|SS_ETCHEDHORZ,
  250. rc, this, IDC_BEVELL ))
  251. {
  252. return;
  253. }
  254. if (!m_stcBevelRight.Create("", WS_VISIBLE|SS_ETCHEDHORZ,
  255. rc, this, IDC_BEVELR ))
  256. {
  257. return;
  258. }
  259. }
  260. if (!bSideBevels || bFrameBevel)
  261. {
  262. if (!m_stcBevel.Create("", WS_VISIBLE|SS_ETCHEDFRAME,
  263. rc, this, IDC_BEVEL ))
  264. {
  265. return;
  266. }
  267. }
  268. if (!m_stcLine.Create("", WS_VISIBLE|SS_ETCHEDHORZ,
  269. rc, this, IDC_LINE ))
  270. {
  271. return;
  272. }
  273. // create the caption
  274. if (!m_stcCaption.Create("Tree Menu", WS_VISIBLE|SS_CENTER|SS_CENTERIMAGE,
  275. rc, this, IDC_CAPTION ))
  276. {
  277. return;
  278. }
  279. // create the button
  280. if (!m_btn.Create("x", WS_VISIBLE|BS_OWNERDRAW|BS_CENTER|BS_VCENTER,
  281. rc, this, IDC_BTN_HIDE))
  282. {
  283. return;
  284. }
  285. // a nicer font
  286. NONCLIENTMETRICS ncm;
  287.     ncm.cbSize = sizeof(NONCLIENTMETRICS);
  288.     VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0));
  289.     m_captionFont.CreateFontIndirect(&(ncm.lfMessageFont));
  290. m_stcCaption.SetFont(&m_captionFont);
  291. if (!m_tree.Create(WS_VISIBLE|WS_CHILD|TVS_TRACKSELECT|TVS_FULLROWSELECT|TVS_HASBUTTONS|TVS_EDITLABELS/*TVS_NOSCROLL*/,
  292.    rc, this, IDC_TREEMENUFRAME))
  293. {
  294. return;
  295. }
  296. // and a tooltip for the hide button
  297. m_ToolTip.Create(this);
  298.     m_ToolTip.AddTool(&m_btn, _T("Hide"));
  299. m_ToolTip.AddTool(&m_stcCaption, _T("Drag caption to dock anywhere"));
  300. CalcLayout();  // Yes, we want align to parent
  301. }
  302. void CTreeMenuFrame::CalcLayout(BOOL bParent)
  303. {
  304. CRect rcWnd, rcLine, rcBtn, rcBevel, rcBevelLeft, rcBevelRight;
  305. if ( bParent)
  306. {
  307. CWnd* pwnd = GetParent();
  308. ASSERT(pwnd);
  309. pwnd->GetClientRect(&rcWnd);
  310. }
  311. else
  312. GetClientRect(&rcWnd);
  313. // rcWnd.SetRect(rcWnd.left, rcWnd.top+1, rcWnd.right, rcWnd.bottom-2);
  314. CRect rcCaption;
  315. int iCpt = ::GetSystemMetrics(SM_CYMENU);
  316. if (bSideBevels && ! bFrameBevel)
  317. {
  318. rcBevelLeft.SetRect(rcWnd.left, rcWnd.top, rcWnd.left+2, rcWnd.bottom);
  319. m_stcBevelLeft.MoveWindow(rcBevelLeft);
  320. rcBevelRight.SetRect(rcWnd.right-2, rcWnd.top, rcWnd.right, rcWnd.bottom);
  321. m_stcBevelRight.MoveWindow(rcBevelRight);
  322. }
  323. if (!bSideBevels && bFrameBevel)
  324. {
  325. rcBevel.SetRect(rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom);
  326. m_stcBevel.MoveWindow(rcBevel);
  327. }
  328. rcLine.SetRect(rcWnd.left+1, rcWnd.top+iCpt+2*BORDER, rcWnd.right, rcWnd.top+iCpt+3*BORDER);
  329. m_stcLine.MoveWindow(rcLine);
  330. rcCaption.SetRect(rcWnd.left+BORDER, rcWnd.top+BORDER, rcWnd.right-BTNX-4*BORDER, rcWnd.top+iCpt+2*BORDER);
  331. m_stcCaption.MoveWindow(rcCaption);
  332. rcBtn.SetRect(rcWnd.right-BTNX-4*BORDER, rcWnd.top+2*BORDER, rcWnd.right-2*BORDER, rcCaption.bottom-BORDER);
  333. m_btn.MoveWindow(rcBtn);
  334. CRect rcTree;
  335. rcTree.left = rcWnd.left+BORDER;
  336. rcTree.top = rcCaption.bottom+BORDER;
  337. rcTree.right = rcWnd.right-BORDER;
  338. rcTree.bottom = rcWnd.bottom-2*BORDER;
  339. m_tree.MoveWindow(rcTree);
  340. }
  341. BOOL CTreeMenuFrame::PreTranslateMessage(MSG* pMsg) 
  342. {
  343.     m_ToolTip.RelayEvent(pMsg);
  344.     return CWnd::PreTranslateMessage(pMsg);
  345. }
  346. void CTreeMenuFrame::OnButtonHide()
  347. {
  348. Hide();
  349. }
  350. void CTreeMenuFrame::OnCaptionDrag()
  351. {
  352. // send TMFN_CAPTIONDRAG to parent and handle there
  353. CWnd* pParent = GetParent();
  354. ASSERT_VALID(pParent);
  355. if (pParent != NULL)
  356. pParent->SendMessage(TMFN_CAPTIONDRAG);
  357. }
  358. void CTreeMenuFrame::OnSize(UINT nType, int cx, int cy) 
  359. {
  360. //    if (::IsWindow(GetSafeHwnd())) 
  361. //        SetFocus();
  362.     CWnd::OnSize(nType, cx, cy);
  363. }
  364. // Hide(FALSE) let show the control again
  365. void CTreeMenuFrame::Hide(BOOL hide /*TRUE*/)
  366. {
  367. // send TMFN_HIDE to parent and handle there
  368. CWnd* pParent = GetParent();
  369. ASSERT_VALID(pParent);
  370. if (pParent != NULL)
  371. pParent->SendMessage(TMFN_HIDE);
  372. }