SplitterBar.cpp
上传用户:lds876
上传日期:2013-05-25
资源大小:567k
文件大小:9k
源码类别:

P2P编程

开发平台:

Visual C++

  1. // CSplitterBar.cpp : implementation file
  2. //
  3. /////////////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "SplitterBar.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CSplitterBar
  13. IMPLEMENT_DYNAMIC(CSplitterBar, CWnd)
  14. BEGIN_MESSAGE_MAP(CSplitterBar, CWnd)
  15. //{{AFX_MSG_MAP(CSplitterBar)
  16. ON_WM_PAINT()
  17. ON_WM_NCHITTEST()
  18. ON_WM_CREATE()
  19. ON_WM_SETCURSOR()
  20. ON_WM_MOUSEMOVE()
  21. ON_WM_LBUTTONDOWN()
  22. ON_WM_LBUTTONUP()
  23. ON_WM_NCPAINT()
  24. //}}AFX_MSG_MAP
  25. END_MESSAGE_MAP()
  26. CSplitterBar::CSplitterBar()
  27. {
  28. m_bDragging=FALSE;
  29. m_pwndLeftPane=m_pwndRightPane=NULL;
  30. }
  31. CSplitterBar::~CSplitterBar()
  32. {
  33. }
  34. BOOL CSplitterBar::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, BOOL bHorizontal)
  35. {
  36. CWnd* pWnd = this;
  37. m_bHorizontal=bHorizontal;
  38. return pWnd->Create(NULL, "", dwStyle, rect, pParentWnd, nID);
  39. }
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CSplitterBar message handlers
  42. void CSplitterBar::OnPaint() 
  43. {
  44. RECT rc;
  45. if (!GetUpdateRect(&rc)) return;
  46. PAINTSTRUCT paint;
  47. CDC *pDC = BeginPaint(&paint);
  48. CRect rect;
  49. GetWindowRect(rect);
  50. GetClientRect(rect);
  51. //*
  52. pDC->Draw3dRect(&rect,
  53.   ::GetSysColor(COLOR_BTNHIGHLIGHT),
  54.   ::GetSysColor(COLOR_BTNSHADOW));
  55.   //*/
  56. EndPaint(&paint);
  57. }
  58. void CSplitterBar::OnNcPaint() 
  59. {
  60. // PAINTSTRUCT paint;
  61. // CDC *pDC = BeginPaint(&paint);
  62. CWindowDC dc(this);
  63. CRect rect;
  64. GetWindowRect(rect);
  65. rect.OffsetRect(-rect.TopLeft());
  66. // GetClientRect(rect);
  67. //*
  68. //*
  69.     HBRUSH hbr = (HBRUSH)GetClassLong(m_hWnd, GCL_HBRBACKGROUND);
  70.     ::FillRect(dc.m_hDC, rect, ::GetSysColorBrush(COLOR_BTNFACE));
  71. /*
  72. dc.Draw3dRect(&rect,
  73.   ::GetSysColor(COLOR_BTNHIGHLIGHT),
  74.   ::GetSysColor(COLOR_BTNSHADOW));
  75.   //*/
  76. // EndPaint(&paint);
  77. }
  78. UINT CSplitterBar::OnNcHitTest(CPoint point) 
  79. {
  80. return HTCLIENT;
  81. }
  82. int CSplitterBar::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  83. {
  84. if (CWnd::OnCreate(lpCreateStruct) == -1)
  85. return -1;
  86. GetWindowRect(&m_rectSplitter);
  87. SetWindowPos(&CWnd::wndTop,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
  88. //Initialize left most and right most coordinator
  89. CRect rectParent;
  90. GetParent()->GetClientRect(rectParent);
  91. if(m_bHorizontal)
  92. {
  93. m_cxLeftMost=rectParent.top;
  94. m_cxRightMost=rectParent.bottom;
  95. }
  96. else
  97. {
  98. m_cxLeftMost=rectParent.left;
  99. m_cxRightMost=rectParent.right;
  100. }
  101. return 0;
  102. }
  103. BOOL CSplitterBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  104. {
  105. CPoint ptCursor=GetMessagePos();
  106. if(IsCursorOverSplitter(ptCursor))
  107. {
  108. /*
  109. ::SetCursor( AfxGetApp()->LoadCursor(m_bHorizontal?AFX_IDC_VSPLITBAR:AFX_IDC_HSPLITBAR));
  110. return TRUE;
  111. //*/
  112. if (m_bHorizontal)
  113. ::SetCursor( AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
  114. else
  115. ::SetCursor( AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
  116. return TRUE;
  117. }
  118. return CWnd::OnSetCursor(pWnd, nHitTest, message);
  119. }
  120. BOOL CSplitterBar::IsCursorOverSplitter( const CPoint& ptCursor )
  121. {
  122. CRect rectSplitter;
  123. GetWindowRect(rectSplitter);
  124. return rectSplitter.PtInRect( ptCursor );
  125. }
  126. void CSplitterBar::OnMouseMove(UINT nFlags, CPoint point) 
  127. {
  128. if(nFlags & MK_LBUTTON && m_bDragging)
  129. {
  130. DrawDraggingBar(point);
  131. return;
  132. }
  133. CWnd::OnMouseMove(nFlags, point);
  134. }
  135. void CSplitterBar::OnLButtonDown(UINT nFlags, CPoint point) 
  136. {
  137. ClientToScreen(&point);
  138. if(IsCursorOverSplitter(point))
  139. {
  140. SetCapture();
  141. m_bDragging=TRUE;
  142. GetWindowRect(&m_rectSplitter);
  143. ScreenToClient(&point);
  144. DrawDraggingBar(point,DRAG_ENTER);
  145. return;
  146. }
  147. CWnd::OnLButtonDown(nFlags, point);
  148. }
  149. void CSplitterBar::OnLButtonUp(UINT nFlags, CPoint point) 
  150. {
  151. if(m_bDragging)
  152. {
  153. DrawDraggingBar(point,DRAG_EXIT);
  154. //Move the splitter here
  155. ClientToScreen(&point);
  156. //with in client area?
  157. if(m_bHorizontal)
  158. {
  159. CPoint pointLeftMost;
  160. pointLeftMost.y=m_cxLeftMost;
  161. GetParent()->ClientToScreen(&pointLeftMost);
  162. CPoint pointRightMost;
  163. pointRightMost.y=m_cxRightMost;
  164. GetParent()->ClientToScreen(&pointRightMost);
  165. if(point.y < pointLeftMost.y)
  166. point.y=pointLeftMost.y;
  167. if(point.y > pointRightMost.y)
  168. point.y=pointRightMost.y;
  169. m_rectDragCurt=m_rectSplitter;
  170. m_rectDragCurt.top=point.y;
  171. m_rectDragCurt.bottom=point.y+m_rectSplitter.Height();
  172. }
  173. else
  174. {
  175. CPoint pointLeftMost;
  176. pointLeftMost.x=m_cxLeftMost;
  177. GetParent()->ClientToScreen(&pointLeftMost);
  178. CPoint pointRightMost;
  179. pointRightMost.x=m_cxRightMost;
  180. GetParent()->ClientToScreen(&pointRightMost);
  181. if(point.x < pointLeftMost.x)
  182. point.x=pointLeftMost.x;
  183. if(point.x > pointRightMost.x)
  184. point.x=pointRightMost.x;
  185. m_rectDragCurt=m_rectSplitter;
  186. m_rectDragCurt.left=point.x;
  187. m_rectDragCurt.right=point.x+m_rectSplitter.Width();
  188. }
  189. GetParent()->ScreenToClient(m_rectDragCurt);
  190. MoveWindow(m_rectDragCurt,TRUE);
  191. OnNcPaint();
  192. OnPaint();
  193. ReleaseCapture();
  194. m_bDragging=FALSE;
  195. MovePanes();
  196. GetParent()->SendMessage(WM_SPLITTER_MOVED,0,0L);
  197. }
  198. CWnd::OnLButtonUp(nFlags, point);
  199. }
  200. void CSplitterBar::DrawDraggingBar(CPoint point,DRAGFLAG df)
  201. {
  202. ClientToScreen(&point);
  203. m_rectDragCurt=m_rectSplitter;
  204. if(m_bHorizontal)
  205. {
  206. m_rectDragCurt.top=point.y;
  207. m_rectDragCurt.bottom=point.y+m_rectSplitter.Height();
  208. }
  209. else
  210. {
  211. m_rectDragCurt.left=point.x;
  212. m_rectDragCurt.right=point.x+m_rectSplitter.Width();
  213. }
  214. CSize size(m_rectDragCurt.Width(),m_rectDragCurt.Height());
  215. CWnd *pParentWnd=GetParent();
  216. ASSERT(pParentWnd);
  217. CDC *pDC=pParentWnd->GetDC();
  218. pParentWnd->ScreenToClient(m_rectDragCurt);
  219. switch(df)
  220. {
  221. case DRAG_ENTER:
  222.  pDC->DrawDragRect(m_rectDragCurt,size,NULL,size);
  223.  break;
  224. case DRAG_EXIT: //fall through
  225. default:
  226.  pDC->DrawDragRect(m_rectDragCurt,size,m_rectDragPrev,size);
  227.  break;
  228. }
  229. pParentWnd->ReleaseDC(pDC);
  230. m_rectDragPrev=m_rectDragCurt;
  231. }
  232. void CSplitterBar::SetPanes(CWnd *pwndLeftPane,CWnd *pwndRightPane)
  233. {
  234. ASSERT(pwndLeftPane);
  235. ASSERT(pwndRightPane);
  236. m_pwndLeftPane=pwndLeftPane;
  237. m_pwndRightPane=pwndRightPane;
  238. if(m_bHorizontal)
  239. {
  240. //Initialize splitter bar position & size
  241. CRect rectBar;
  242. pwndLeftPane->GetWindowRect(rectBar);
  243. GetParent()->ScreenToClient(rectBar);
  244. rectBar.top=rectBar.bottom;
  245. int nBarWidth=GetSystemMetrics(SM_CXFRAME);
  246. rectBar.top-=nBarWidth/2;
  247. rectBar.bottom+=nBarWidth/2;
  248. MoveWindow(rectBar);
  249. //repostion top & bottom panes
  250. MovePanes();
  251. //calculate top most and bottom most coordinator
  252. CRect rectLeft;
  253. m_pwndLeftPane->GetWindowRect(rectLeft);
  254. GetParent()->ScreenToClient(rectLeft);
  255. m_cxLeftMost=rectLeft.top;
  256. CRect rectRight;
  257. m_pwndRightPane->GetWindowRect(rectRight);
  258. GetParent()->ScreenToClient(rectRight);
  259. m_cxRightMost=rectRight.bottom;
  260. }
  261. else
  262. {
  263. //Initialize splitter bar position & size
  264. CRect rectBar;
  265. pwndLeftPane->GetWindowRect(rectBar);
  266. GetParent()->ScreenToClient(rectBar);
  267. rectBar.left=rectBar.right;
  268. int nBarWidth=GetSystemMetrics(SM_CYFRAME);
  269. rectBar.left-=nBarWidth/2;
  270. rectBar.right+=nBarWidth/2;
  271. MoveWindow(rectBar);
  272. //repostion left & rigth panes
  273. MovePanes();
  274. //calculate left most and right most coordinator
  275. CRect rectLeft;
  276. m_pwndLeftPane->GetWindowRect(rectLeft);
  277. GetParent()->ScreenToClient(rectLeft);
  278. m_cxLeftMost=rectLeft.left;
  279. CRect rectRight;
  280. m_pwndRightPane->GetWindowRect(rectRight);
  281. GetParent()->ScreenToClient(rectRight);
  282. m_cxRightMost=rectRight.right;
  283. }
  284. }
  285. void CSplitterBar::MovePanes()
  286. {
  287. ASSERT(m_pwndLeftPane);
  288. ASSERT(m_pwndRightPane);
  289. if(m_bHorizontal)
  290. {
  291. //Get position of the splitter bar
  292. CRect rectBar;
  293. GetWindowRect(rectBar);
  294. GetParent()->ScreenToClient(rectBar);
  295. //reposition top pane
  296. CRect rectLeft;
  297. m_pwndLeftPane->GetWindowRect(rectLeft);
  298. GetParent()->ScreenToClient(rectLeft);
  299. rectLeft.bottom=rectBar.top+GetSystemMetrics(SM_CXBORDER);
  300. m_pwndLeftPane->MoveWindow(rectLeft);
  301. //reposition bottom pane
  302. CRect rectRight;
  303. m_pwndRightPane->GetWindowRect(rectRight);
  304. GetParent()->ScreenToClient(rectRight);
  305. rectRight.top=rectBar.bottom-GetSystemMetrics(SM_CXBORDER);;
  306. m_pwndRightPane->MoveWindow(rectRight);
  307. }
  308. else
  309. {
  310. //Get position of the splitter bar
  311. CRect rectBar;
  312. GetWindowRect(rectBar);
  313. GetParent()->ScreenToClient(rectBar);
  314. //reposition left pane
  315. CRect rectLeft;
  316. m_pwndLeftPane->GetWindowRect(rectLeft);
  317. GetParent()->ScreenToClient(rectLeft);
  318. rectLeft.right=rectBar.left+GetSystemMetrics(SM_CYBORDER);
  319. m_pwndLeftPane->MoveWindow(rectLeft);
  320. //reposition right pane
  321. CRect rectRight;
  322. m_pwndRightPane->GetWindowRect(rectRight);
  323. GetParent()->ScreenToClient(rectRight);
  324. rectRight.left=rectBar.right-GetSystemMetrics(SM_CYBORDER);;
  325. m_pwndRightPane->MoveWindow(rectRight);
  326. }
  327. //repaint client area
  328. GetParent()->Invalidate();
  329. }