RTSplitterWnd.cpp
上传用户:qhonly
上传日期:2013-06-10
资源大小:487k
文件大小:9k
源码类别:

界面编程

开发平台:

Visual C++

  1. // RTSplitterWnd.cpp : 实现文件
  2. //
  3. #include "stdafx.h"
  4. #include "RTSplitterWnd.h"
  5. #include "RTDraw.h"
  6. // CRTSplitterWnd
  7. IMPLEMENT_DYNAMIC(CRTSplitterWnd, CWnd)
  8. CRTSplitterWnd::CRTSplitterWnd()
  9. {
  10. m_Child[0] = NULL;
  11. m_Child[1] = NULL;
  12. m_IsVertical = FALSE;
  13. m_SplitterRect.SetRect(0,0,0,0);
  14. m_SplitterWidth = 4;
  15. m_SplitterSize.cx = 200;
  16. m_SplitterSize.cy = -1;
  17. m_IsSelSplitter = FALSE;
  18. m_ImageList = NULL;
  19. }
  20. CRTSplitterWnd::~CRTSplitterWnd()
  21. {
  22. if(m_ImageList != NULL) 
  23. {
  24. m_ImageList->DeleteImageList();
  25. delete m_ImageList;
  26. }
  27. }
  28. CBitmap* CRTSplitterWnd::m_SplitterBitmap[5] = {NULL,NULL,NULL,NULL,NULL};
  29. UINT     CRTSplitterWnd::m_SplitterBitmapDrawMode[5] = {0,0,0,0,0};
  30. BOOL     CRTSplitterWnd::m_IsEnableSkin = TRUE;
  31. HCURSOR  CRTSplitterWnd::m_VerCursor = NULL;
  32. HCURSOR  CRTSplitterWnd::m_HorCursor = NULL;
  33. BEGIN_MESSAGE_MAP(CRTSplitterWnd, CWnd)
  34. ON_WM_SIZE()
  35. ON_WM_ERASEBKGND()
  36. ON_WM_PAINT()
  37. ON_WM_MOUSEMOVE()
  38. ON_WM_LBUTTONDOWN()
  39. ON_WM_LBUTTONUP()
  40. ON_WM_LBUTTONDBLCLK()
  41. ON_WM_SETCURSOR()
  42. ON_WM_CREATE()
  43. END_MESSAGE_MAP()
  44. // CRTSplitterWnd 消息处理程序
  45. void CRTSplitterWnd::SetVertical(CWnd* pLeft, CWnd* pRight, int LeftWidth, int RightWidth)
  46. {
  47. ASSERT(pLeft != NULL);
  48. ASSERT(pRight != NULL);
  49. m_Child[0] = pLeft;
  50. m_Child[1] = pRight;
  51. pLeft->SetParent(this);
  52. pRight->SetParent(this);
  53. pLeft->ShowWindow(SW_SHOW);
  54. pRight->ShowWindow(SW_SHOW);
  55. m_IsVertical = TRUE;
  56. m_SplitterSize.cx = LeftWidth;
  57. m_SplitterSize.cy = RightWidth;
  58. RTSize();
  59. }
  60. void CRTSplitterWnd::SetHorizoncal(CWnd* pTop, CWnd* pBottom, int TopWidth, int BottomWidth)
  61. {
  62. ASSERT(pTop != NULL);
  63. ASSERT(pBottom != NULL);
  64. m_Child[0] = pTop;
  65. m_Child[1] = pBottom;
  66. pTop->SetParent(this);
  67. pBottom->SetParent(this);
  68. pTop->ShowWindow(SW_SHOW);
  69. pBottom->ShowWindow(SW_SHOW);
  70. m_IsVertical = FALSE;
  71. m_SplitterSize.cx = TopWidth;
  72. m_SplitterSize.cy = BottomWidth;
  73. RTSize();
  74. }
  75. void CRTSplitterWnd::OnSize(UINT nType, int cx, int cy)
  76. {
  77. CWnd::OnSize(nType, cx, cy);
  78. if(!IsWindow(m_hWnd))return;
  79. RTSize();
  80. }
  81. void CRTSplitterWnd::RTSize()
  82. {
  83. CRect rt;
  84. GetClientRect(&rt);
  85. if(m_IsVertical)
  86. {
  87. int left = 0;
  88. int right = 0;
  89. if(m_SplitterSize.cx == -1)
  90. {
  91. if(m_SplitterSize.cy > rt.Width() - m_SplitterWidth)
  92. right = rt.Width() - m_SplitterWidth;
  93. else
  94. right = m_SplitterSize.cy;
  95. left = rt.Width() - right - m_SplitterWidth;
  96. }
  97. else
  98. {
  99. if(rt.Width() - m_SplitterWidth < m_SplitterSize.cx)
  100. left = rt.Width() - m_SplitterWidth;
  101. else
  102. left = m_SplitterSize.cx;
  103. right = rt.Width() - m_SplitterWidth - left;
  104. }
  105. m_SplitterRect.SetRect(rt.left + left,rt.top,rt.left + left + m_SplitterWidth,rt.bottom);
  106. if(m_Child[0] != NULL)m_Child[0]->MoveWindow(rt.left,rt.top,left,rt.Height());
  107. if(m_Child[1] != NULL)m_Child[1]->MoveWindow(rt.left + left + m_SplitterWidth,rt.top,right,rt.Height());
  108. }
  109. else
  110. {
  111. int top ;
  112. int bottom;
  113. if(m_SplitterSize.cx == -1)
  114. {
  115. if(m_SplitterSize.cy > rt.Height() - m_SplitterWidth)
  116. bottom = rt.Height() - m_SplitterWidth;
  117. else
  118. bottom = m_SplitterSize.cy;
  119. top = rt.Height() - bottom - m_SplitterWidth;
  120. }
  121. else
  122. {
  123. if(rt.Height() - m_SplitterWidth < m_SplitterSize.cx)
  124. top = rt.Height() - m_SplitterWidth;
  125. else
  126. top = m_SplitterSize.cx;
  127. bottom = rt.Height() - top - m_SplitterWidth;
  128. }
  129. m_SplitterRect.SetRect(rt.left,rt.top + top,rt.right,rt.top + top + m_SplitterWidth);
  130. if(m_Child[0] != NULL)m_Child[0]->MoveWindow(rt.left,rt.top,rt.Width(),top);
  131. if(m_Child[1] != NULL)m_Child[1]->MoveWindow(rt.left,rt.top + top + m_SplitterWidth,rt.Width(),bottom);
  132. }
  133. Invalidate();
  134. }
  135. BOOL CRTSplitterWnd::PreCreateWindow(CREATESTRUCT& cs)
  136. {
  137. if(!CWnd::PreCreateWindow(cs))
  138. return FALSE;
  139. cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
  140. ::LoadCursor(NULL, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL);
  141. return TRUE;
  142. }
  143. BOOL CRTSplitterWnd::Create(DWORD dwStyle,const RECT &rect,CWnd* pParentWnd,UINT nID,CCreateContext *pContext)
  144. {
  145. return CWnd::Create(NULL,NULL,dwStyle,rect,pParentWnd,nID,pContext);
  146. }
  147. BOOL CRTSplitterWnd::OnEraseBkgnd(CDC* pDC)
  148. {
  149. if(m_Child[0] != NULL && m_Child[1] != NULL)return TRUE;
  150. return CWnd::OnEraseBkgnd(pDC);
  151. }
  152. void CRTSplitterWnd::OnPaint()
  153. {
  154. CPaintDC dc(this); // device context for painting
  155. if(m_SplitterBitmap[BMP_BACK] != NULL && m_IsEnableSkin)
  156. {
  157. CRTDraw::RTDrawBitmap(&dc,&m_SplitterRect,m_SplitterBitmap[BMP_BACK],m_SplitterBitmapDrawMode[BMP_BACK]);
  158. }
  159. else
  160. {
  161. CBrush br(GetSysColor(COLOR_3DFACE));
  162. dc.FillRect(&m_SplitterRect,&br);
  163. }
  164. }
  165. void CRTSplitterWnd::OnMouseMove(UINT nFlags, CPoint point)
  166. {
  167. if(nFlags == MK_LBUTTON)
  168. {
  169. if(m_IsSelSplitter)
  170. {
  171. CPoint MovePoint(point.x,point.y);
  172. CRect rt;
  173. GetClientRect(&rt);
  174. if(m_IsVertical)
  175. {
  176. int SPLeft = point.x - m_MouseDownPoint.x;
  177. if(SPLeft < rt.left || SPLeft + m_SplitterWidth > rt.right)
  178. return;
  179. if(m_SplitterSize.cx == -1)
  180. m_SplitterSize.cy = rt.right - SPLeft - m_SplitterWidth;
  181. else
  182. m_SplitterSize.cx = SPLeft;
  183. MovePoint.y = 0;
  184. }
  185. else
  186. {
  187. int SPTop = point.y - m_MouseDownPoint.y;
  188. if(SPTop < rt.top || SPTop + m_SplitterWidth > rt.bottom)
  189. return;
  190. if(m_SplitterSize.cx == -1)
  191. m_SplitterSize.cy = rt.bottom - SPTop - m_SplitterWidth;
  192. else
  193. m_SplitterSize.cx = SPTop;
  194. MovePoint.x = 0;
  195. }
  196. m_ImageList->DragMove(MovePoint);
  197. }
  198. else
  199. {
  200. CWnd::OnMouseMove(nFlags, point);
  201. }
  202. }
  203. else if(nFlags == 0)
  204. {
  205. if(m_SplitterRect.PtInRect(point))
  206. {
  207. if(m_IsSelSplitter == FALSE)
  208. {
  209. m_IsSelSplitter = TRUE;
  210. }
  211. }
  212. else
  213. {
  214. if(m_IsSelSplitter == TRUE)
  215. {
  216. m_IsSelSplitter = FALSE;
  217. }
  218. CWnd::OnMouseMove(nFlags, point);
  219. }
  220. }
  221. else
  222. {
  223. CWnd::OnMouseMove(nFlags, point);
  224. }
  225. }
  226. void CRTSplitterWnd::OnLButtonDown(UINT nFlags, CPoint point)
  227. {
  228. if(m_IsSelSplitter)
  229. {  
  230. if(m_ImageList == NULL)
  231. {
  232. m_ImageList = new CImageList();
  233. m_ImageList->Create(m_SplitterRect.Width(),m_SplitterRect.Height(),ILC_COLOR ,1,1);
  234. CBitmap bmp;
  235. int CxBitCount = m_SplitterRect.Width() / 16;
  236. if((m_SplitterRect.Width() % 8 ) != 0)CxBitCount++;
  237. int CyBitCount = m_SplitterRect.Height();
  238. WORD *bits = new WORD[CxBitCount * CyBitCount];
  239. WORD *ptr = bits;
  240. for(int y = 0; y < CyBitCount; y++)
  241. {
  242. if((y % 2) == 0)
  243. {
  244. for(int x = 0; x < CxBitCount; x++)
  245. {
  246. *ptr = 0x5555;
  247. ptr++;
  248. }
  249. }
  250. else
  251. {
  252. for(int x = 0; x < CxBitCount; x++)
  253. {
  254. *ptr = 0xaaaa;
  255. ptr++;
  256. }
  257. }
  258. }
  259. bmp.CreateBitmap(m_SplitterRect.Width(),m_SplitterRect.Height(),1,1,bits);
  260. m_ImageList->Add(&bmp,&bmp);
  261. delete[] bits;
  262. CPoint BeginPoint(point.x,point.y);
  263. m_MouseDownPoint.SetPoint(point.x - m_SplitterRect.left,point.y - m_SplitterRect.top);
  264. if(m_IsVertical)
  265. {
  266. BeginPoint.y  = 0;
  267. m_MouseDownPoint.y = 0;
  268. }
  269. else
  270. {
  271. BeginPoint.x = 0;
  272. m_MouseDownPoint.x = 0;
  273. }
  274. m_ImageList->BeginDrag(0,m_MouseDownPoint);
  275. m_ImageList->DragEnter(this,BeginPoint);
  276. SetCapture();
  277. }
  278. }
  279. else
  280. {
  281. CWnd::OnLButtonDown(nFlags, point);
  282. }
  283. }
  284. void CRTSplitterWnd::OnLButtonUp(UINT nFlags, CPoint point)
  285. {
  286. if(m_IsSelSplitter)
  287. {
  288. ReleaseCapture();
  289. if(m_ImageList != NULL)
  290. {
  291. m_ImageList->EndDrag();
  292. m_ImageList->DeleteImageList();
  293. delete m_ImageList;
  294. m_ImageList = NULL;
  295. }
  296. RTSize();
  297. }
  298. CWnd::OnLButtonUp(nFlags, point);
  299. }
  300. void CRTSplitterWnd::OnLButtonDblClk(UINT nFlags, CPoint point)
  301. {
  302. // TODO: 在此添加消息处理程序代码和/或调用默认值
  303. if(m_IsSelSplitter)
  304. {
  305. if(m_IsVertical)
  306. {
  307. SetCursor(LoadCursor(NULL,IDC_SIZEWE));
  308. }
  309. else
  310. {
  311. SetCursor(LoadCursor(NULL,IDC_SIZENS));
  312. }
  313. return;
  314. }
  315. CWnd::OnLButtonDblClk(nFlags, point);
  316. }
  317. void CRTSplitterWnd::SetBitmap(CBitmap* pBitmaps[], UINT DrawMode[])
  318. {
  319. for(int i = 0; i < 5; i ++)
  320. {
  321. m_SplitterBitmap[i] = pBitmaps[i];
  322. m_SplitterBitmapDrawMode[i] = DrawMode[i];
  323. }
  324. }
  325. void CRTSplitterWnd::EnableSkin(BOOL IsEnable)
  326. {
  327. m_IsEnableSkin = IsEnable;
  328. }
  329. BOOL CRTSplitterWnd::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  330. {
  331. GetParent()->SendMessage(WM_NOTIFY,wParam,lParam);
  332. return CWnd::OnNotify(wParam, lParam, pResult);
  333. }
  334. BOOL CRTSplitterWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  335. {
  336. BOOL rt = CWnd::OnSetCursor(pWnd, nHitTest, message);
  337. if(m_VerCursor == NULL)m_VerCursor = LoadCursor(NULL,IDC_SIZEWE);
  338. if(m_HorCursor == NULL)m_HorCursor = LoadCursor(NULL,IDC_SIZENS);
  339. if(m_IsSelSplitter)
  340. {
  341. if(m_IsVertical && m_VerCursor != NULL)
  342. {
  343. SetCursor(m_VerCursor);
  344. }
  345. if(!m_IsVertical && m_HorCursor != NULL)
  346. {
  347. SetCursor(m_HorCursor);
  348. }
  349. }
  350. return  rt;
  351. }
  352. int CRTSplitterWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
  353. {
  354. if (CWnd::OnCreate(lpCreateStruct) == -1)
  355. return -1;
  356. return 0;
  357. }
  358. void CRTSplitterWnd::RTSetCursor(HCURSOR hVerCursor,HCURSOR hHorCursor)
  359. {
  360. m_VerCursor = hVerCursor;
  361. m_HorCursor = hHorCursor;
  362. }