DittoWindow.cpp 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016
  1. #include "stdafx.h"
  2. #include ".\dittowindow.h"
  3. #include "CP_Main.h"
  4. #include "Options.h"
  5. CDittoWindow::CDittoWindow(void)
  6. {
  7. m_captionBorderWidth = theApp.m_metrics.ScaleX(25);
  8. m_lTopBorder = m_captionBorderWidth;
  9. m_lRightBorder = BORDER;
  10. m_lBottomBorder = BORDER;
  11. m_lLeftBorder = BORDER;
  12. m_bMouseOverChevron = false;
  13. m_bMouseDownOnChevron = false;
  14. m_bMouseDownOnClose = false;
  15. m_bMouseOverClose = false;
  16. m_bMouseDownOnMinimize = false;
  17. m_bMouseOverMinimize = false;
  18. m_bMouseDownOnMaximize = false;
  19. m_bMouseOverMaximize = false;
  20. m_bDrawClose = true;
  21. m_bDrawChevron = true;
  22. m_bDrawMaximize = true;
  23. m_bDrawMinimize = true;
  24. m_bMinimized = false;
  25. m_crCloseBT.SetRectEmpty();
  26. m_crChevronBT.SetRectEmpty();
  27. m_crMaximizeBT.SetRectEmpty();
  28. m_crMinimizeBT.SetRectEmpty();
  29. m_CaptionColorLeft = RGB(255, 255, 255);
  30. m_CaptionColorRight = RGB(204, 204, 204);
  31. m_CaptionTextColor = RGB(191, 191, 191);
  32. m_border = RGB(204, 204, 204);
  33. m_sendWMClose = true;
  34. m_customWindowTitle = _T("");
  35. m_useCustomWindowTitle = false;
  36. m_buttonDownOnCaption = false;
  37. m_crFullSizeWindow.SetRectEmpty();
  38. }
  39. CDittoWindow::~CDittoWindow(void)
  40. {
  41. }
  42. void CDittoWindow::DoCreate(CWnd *pWnd)
  43. {
  44. m_VertFont.CreateFont(theApp.m_metrics.PointsToPixels(18), 0, -900, 0, 400, FALSE, FALSE, 0, DEFAULT_CHARSET,
  45. OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
  46. DEFAULT_PITCH|FF_SWISS, _T("Segoe UI"));
  47. m_HorFont.CreateFont(theApp.m_metrics.PointsToPixels(18), 0, 0, 0, 500, FALSE, FALSE, 0, DEFAULT_CHARSET,
  48. OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
  49. DEFAULT_PITCH|FF_SWISS, _T("Segoe UI"));
  50. SetTitleTextHeight(pWnd);
  51. m_closeButton.LoadStdImageDPI(Close_Black_16_16, Close_Black_20_20, Close_Black_24_24, Close_Black_28, Close_Black_32_32, _T("PNG"));
  52. m_chevronRightButton.LoadStdImageDPI(ChevronRight_Black_16_16, ChevronRight_Black_20_20, ChevronRight_Black_24_24, ChevronRight_Black_28, ChevronRight_Black_32_32, _T("PNG"));
  53. m_chevronLeftButton.LoadStdImageDPI(ChevronLeft_Black_16_16, ChevronLeft_Black_20_20, ChevronLeft_Black_24_24, ChevronLeft_Black_28, ChevronLeft_Black_32_32, _T("PNG"));
  54. m_maximizeButton.LoadStdImageDPI(IDB_MAXIMIZE_16_16, maximize_20, maximize_24, maximize_28, maximize_32, _T("PNG"));
  55. m_minimizeButton.LoadStdImageDPI(minimize_16, minimize_20, minimize_24, minimize_28, minimize_32, _T("PNG"));
  56. //m_windowIcon.LoadStdImageDPI(NewWindowIcon_24_14, NewWindowIcon_30, NewWindowIcon_36, NewWindowIcon_48, _T("PNG"));
  57. }
  58. void CDittoWindow::DoNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
  59. {
  60. //Decrease the client area
  61. lpncsp->rgrc[0].left += m_lLeftBorder;
  62. lpncsp->rgrc[0].top += m_lTopBorder;
  63. lpncsp->rgrc[0].right -= m_lRightBorder;
  64. lpncsp->rgrc[0].bottom -= m_lBottomBorder;
  65. }
  66. UINT CDittoWindow::DoNcHitTest(CWnd *pWnd, CPoint point)
  67. {
  68. CRect crWindow;
  69. pWnd->GetWindowRect(crWindow);
  70. if(crWindow.PtInRect(point) == false)
  71. {
  72. return -1;
  73. }
  74. int x = point.x - crWindow.left;
  75. int y = point.y - crWindow.top;
  76. CPoint myLocal(x, y);
  77. //http://stackoverflow.com/questions/521147/the-curious-problem-of-the-missing-wm-nclbuttonup-message-when-a-window-isnt-ma
  78. //workaround for l button up not coming after a lbutton down
  79. if (m_crCloseBT.PtInRect(myLocal) ||
  80. m_crChevronBT.PtInRect(myLocal) ||
  81. m_crMinimizeBT.PtInRect(myLocal) ||
  82. m_crMaximizeBT.PtInRect(myLocal))
  83. {
  84. return HTBORDER;;
  85. }
  86. if(m_bMinimized == false)
  87. {
  88. if ((point.y < crWindow.top + BORDER * 4) &&
  89. (point.x < crWindow.left + BORDER * 4))
  90. return HTTOPLEFT;
  91. else if ((point.y < crWindow.top + BORDER * 4) &&
  92. (point.x > crWindow.right - BORDER * 4))
  93. return HTTOPRIGHT;
  94. else if ((point.y > crWindow.bottom - BORDER * 4) &&
  95. (point.x > crWindow.right - BORDER * 4))
  96. return HTBOTTOMRIGHT;
  97. else if ((point.y > crWindow.bottom - BORDER * 4) &&
  98. (point.x < crWindow.left + BORDER * 4))
  99. return HTBOTTOMLEFT;
  100. }
  101. if((((m_lTopBorder == m_captionBorderWidth) || (m_lBottomBorder == m_captionBorderWidth)) &&
  102. (m_bMinimized)) == false)
  103. {
  104. if (point.y < crWindow.top + BORDER * 2)
  105. return HTTOP;
  106. if (point.y > crWindow.bottom - BORDER * 2)
  107. return HTBOTTOM;
  108. }
  109. if((((m_lLeftBorder == m_captionBorderWidth) || (m_lRightBorder == m_captionBorderWidth)) &&
  110. (m_bMinimized)) == false)
  111. {
  112. if (point.x > crWindow.right - BORDER * 2)
  113. return HTRIGHT;
  114. if (point.x < crWindow.left + BORDER * 2)
  115. return HTLEFT;
  116. }
  117. if(m_lRightBorder == m_captionBorderWidth)
  118. {
  119. if (point.x > crWindow.right - m_lRightBorder)
  120. return HTCAPTION;
  121. }
  122. else if(m_lBottomBorder == m_captionBorderWidth)
  123. {
  124. if(point.y > crWindow.bottom - m_lBottomBorder)
  125. return HTCAPTION;
  126. }
  127. else if(m_lLeftBorder == m_captionBorderWidth)
  128. {
  129. if (point.x < crWindow.left + m_lLeftBorder)
  130. return HTCAPTION;
  131. }
  132. else if(m_lTopBorder == m_captionBorderWidth)
  133. {
  134. if (point.y < crWindow.top + m_lTopBorder)
  135. return HTCAPTION;
  136. }
  137. return -1;
  138. }
  139. int IndexToPos(int index, bool horizontal)
  140. {
  141. switch (index)
  142. {
  143. case 0:
  144. if (horizontal)
  145. {
  146. return theApp.m_metrics.ScaleX(24);
  147. }
  148. else
  149. {
  150. return theApp.m_metrics.ScaleY(8);
  151. }
  152. break;
  153. case 1:
  154. if (horizontal)
  155. {
  156. return theApp.m_metrics.ScaleX(48);
  157. }
  158. else
  159. {
  160. return theApp.m_metrics.ScaleY(32);
  161. }
  162. break;
  163. case 2:
  164. if (horizontal)
  165. {
  166. return theApp.m_metrics.ScaleX(72);
  167. }
  168. else
  169. {
  170. return theApp.m_metrics.ScaleY(56);
  171. }
  172. break;
  173. case 3:
  174. if (horizontal)
  175. {
  176. return theApp.m_metrics.ScaleX(96);
  177. }
  178. else
  179. {
  180. return theApp.m_metrics.ScaleY(80);
  181. }
  182. break;
  183. case 4:
  184. if (horizontal)
  185. {
  186. return theApp.m_metrics.ScaleX(104);
  187. }
  188. else
  189. {
  190. return theApp.m_metrics.ScaleY(104);
  191. }
  192. break;
  193. }
  194. return 0;
  195. }
  196. void CDittoWindow::DoNcPaint(CWnd *pWnd)
  197. {
  198. CWindowDC dc(pWnd);
  199. CRect rcFrame;
  200. pWnd->GetWindowRect(rcFrame);
  201. pWnd->ScreenToClient(rcFrame);
  202. CRect rc;
  203. pWnd->GetClientRect(rc);
  204. pWnd->ClientToScreen(rc);
  205. long lWidth = rcFrame.Width();
  206. // Draw the window border
  207. CRect rcBorder(0, 0, lWidth, rcFrame.Height());
  208. int border = theApp.m_metrics.ScaleX(2);
  209. int widthHeight = theApp.m_metrics.ScaleX(16);
  210. for (int x = 0; x < border; x++)
  211. {
  212. dc.Draw3dRect(rcBorder, m_border, m_border);
  213. rcBorder.DeflateRect(1, 1, 1, 1);
  214. }
  215. int iconArea = 0;
  216. int index = 0;
  217. int closeIndex = 0;
  218. int chevronIndex = 0;
  219. int minIndex = 0;
  220. int maxIndex = 0;
  221. if (m_bDrawClose)
  222. {
  223. iconArea += theApp.m_metrics.ScaleX(32);
  224. closeIndex = index++;
  225. }
  226. if (m_bDrawChevron)
  227. {
  228. iconArea += theApp.m_metrics.ScaleX(32);
  229. chevronIndex = index++;
  230. }
  231. if (m_bDrawMaximize)
  232. {
  233. iconArea += theApp.m_metrics.ScaleX(32);
  234. maxIndex = index++;
  235. }
  236. if (m_bDrawMinimize)
  237. {
  238. iconArea += theApp.m_metrics.ScaleX(32);
  239. minIndex = index++;
  240. }
  241. CRect leftRect;
  242. CRect rightRect;
  243. CRect textRect;
  244. BOOL bVertical = FALSE;
  245. if(m_lRightBorder == m_captionBorderWidth)
  246. {
  247. rightRect.SetRect(rcBorder.right - (m_captionBorderWidth - border), rcBorder.top, rcBorder.right, rcBorder.top + IndexToPos(index, false));
  248. leftRect.SetRect(rcBorder.right - (m_captionBorderWidth - border), rcBorder.top + IndexToPos(index, false), rcBorder.right, rcBorder.bottom);
  249. textRect.SetRect(rcBorder.right, rightRect.bottom + theApp.m_metrics.ScaleX(10), rcBorder.right - m_captionBorderWidth, rcBorder.bottom - theApp.m_metrics.ScaleX(1));
  250. int left = rightRect.left;
  251. int right = rightRect.right;
  252. int top = IndexToPos(closeIndex, false);
  253. m_crCloseBT.SetRect(left, top, right, top+ widthHeight);
  254. top = IndexToPos(chevronIndex, false);
  255. m_crChevronBT.SetRect(left, top, right, top + widthHeight);
  256. top = IndexToPos(maxIndex, false);
  257. m_crMaximizeBT.SetRect(left, top, right, top + widthHeight);
  258. top = IndexToPos(minIndex, false);
  259. m_crMinimizeBT.SetRect(left, top, right, top + widthHeight);
  260. m_crWindowIconBT.SetRect(rcBorder.right - theApp.m_metrics.ScaleX(24), rcBorder.bottom - theApp.m_metrics.ScaleX(28), rcBorder.right - theApp.m_metrics.ScaleX(2), rcBorder.bottom);
  261. bVertical = TRUE;
  262. }
  263. else if(m_lLeftBorder == m_captionBorderWidth)
  264. {
  265. rightRect.SetRect(rcBorder.left, rcBorder.top, rcBorder.left + m_captionBorderWidth - border, rcBorder.top + IndexToPos(index, false));
  266. leftRect.SetRect(rcBorder.left, rcBorder.top + IndexToPos(index, false), rcBorder.left + m_captionBorderWidth - border, rcBorder.bottom);
  267. textRect.SetRect(rcBorder.left + m_captionBorderWidth - theApp.m_metrics.ScaleX(0), rightRect.bottom + theApp.m_metrics.ScaleX(10), rcBorder.left - theApp.m_metrics.ScaleX(5), rcBorder.bottom - theApp.m_metrics.ScaleX(1));
  268. int left = rightRect.left;
  269. int right = rightRect.right;
  270. int top = IndexToPos(closeIndex, false);
  271. m_crCloseBT.SetRect(left, top, right, top + widthHeight);
  272. top = IndexToPos(chevronIndex, false);
  273. m_crChevronBT.SetRect(left, top, right, top + widthHeight);
  274. top = IndexToPos(maxIndex, false);
  275. m_crMaximizeBT.SetRect(left, top, right, top + widthHeight);
  276. top = IndexToPos(minIndex, false);
  277. m_crMinimizeBT.SetRect(left, top, right, top + widthHeight);
  278. m_crWindowIconBT.SetRect(rcBorder.left + theApp.m_metrics.ScaleX(0), rcBorder.bottom - theApp.m_metrics.ScaleX(28), rcBorder.left + theApp.m_metrics.ScaleX(25), rcBorder.bottom);
  279. bVertical = TRUE;
  280. }
  281. else if(m_lTopBorder == m_captionBorderWidth)
  282. {
  283. leftRect.SetRect(rcBorder.left, rcBorder.top, rcBorder.right - IndexToPos(index-1, true)- theApp.m_metrics.ScaleX(8), m_captionBorderWidth);
  284. rightRect.SetRect(leftRect.right, rcBorder.top, rcBorder.right, m_captionBorderWidth);
  285. textRect.SetRect(leftRect.right, leftRect.top, leftRect.right, leftRect.bottom);
  286. int top = rightRect.top;
  287. int bottom = rightRect.bottom;
  288. int left = rcBorder.right - IndexToPos(closeIndex, true);
  289. m_crCloseBT.SetRect(left, top, left + widthHeight, bottom);
  290. left = rcBorder.right - IndexToPos(chevronIndex, true);
  291. m_crChevronBT.SetRect(left, top, left + widthHeight, bottom);
  292. left = rcBorder.right - IndexToPos(maxIndex, true);
  293. m_crMaximizeBT.SetRect(left, top, left + widthHeight, bottom);
  294. left = rcBorder.right - IndexToPos(minIndex, true);
  295. m_crMinimizeBT.SetRect(left, top, left + widthHeight, bottom);
  296. left = rcBorder.left + theApp.m_metrics.ScaleX(10);
  297. m_crWindowIconBT.SetRect(left, top, left + theApp.m_metrics.ScaleX(24), bottom);
  298. bVertical = FALSE;
  299. }
  300. else if(m_lBottomBorder == m_captionBorderWidth)
  301. {
  302. leftRect.SetRect(rcBorder.left, rcBorder.bottom- m_captionBorderWidth - border, rcBorder.right - IndexToPos(index - 1, true) - theApp.m_metrics.ScaleX(8), rcBorder.bottom);
  303. rightRect.SetRect(leftRect.right, rcBorder.bottom - m_captionBorderWidth - border, rcBorder.right, rcBorder.bottom);
  304. textRect.SetRect(leftRect.right, leftRect.top, leftRect.right, leftRect.bottom);
  305. int top = rightRect.top;
  306. int bottom = rightRect.bottom;
  307. int left = rcBorder.right - IndexToPos(closeIndex, true);
  308. m_crCloseBT.SetRect(left, top, left + widthHeight, bottom);
  309. left = rcBorder.right - IndexToPos(chevronIndex, true);
  310. m_crChevronBT.SetRect(left, top, left+ widthHeight, bottom);
  311. left = rcBorder.right - IndexToPos(maxIndex, true);
  312. m_crMaximizeBT.SetRect(left, top, left + widthHeight, bottom);
  313. left = rcBorder.right - IndexToPos(minIndex, true);
  314. m_crMinimizeBT.SetRect(left, top, left + widthHeight, bottom);
  315. left = rcBorder.left + theApp.m_metrics.ScaleX(10);
  316. m_crWindowIconBT.SetRect(left, top, left + theApp.m_metrics.ScaleX(24), bottom);
  317. bVertical = FALSE;
  318. }
  319. HBRUSH leftColor = CreateSolidBrush(m_CaptionColorLeft);
  320. HBRUSH rightColor = CreateSolidBrush(m_CaptionColorRight);
  321. ::FillRect(dc, &leftRect, leftColor);
  322. ::FillRect(dc, &rightRect, rightColor);
  323. DeleteObject(leftColor);
  324. DeleteObject(rightColor);
  325. int nOldBKMode = dc.SetBkMode(TRANSPARENT);
  326. COLORREF oldColor = dc.SetTextColor(m_CaptionTextColor);
  327. CFont *pOldFont = NULL;
  328. if (bVertical)
  329. pOldFont = dc.SelectObject(&m_VertFont);
  330. else
  331. pOldFont = dc.SelectObject(&m_HorFont);
  332. CString csText = m_customWindowTitle;
  333. if (m_useCustomWindowTitle == false)
  334. {
  335. pWnd->GetWindowText(csText);
  336. }
  337. int flags = DT_SINGLELINE;
  338. if (bVertical == false)
  339. {
  340. CRect size(0, 0, 0, 0);
  341. dc.DrawText(csText, size, DT_CALCRECT);
  342. textRect.left = textRect.right - size.Width() - theApp.m_metrics.ScaleX(10);
  343. flags |= DT_VCENTER;
  344. }
  345. else
  346. {
  347. CRect size(0, 0, 0, 0);
  348. dc.DrawText(csText, size, DT_CALCRECT| DT_SINGLELINE);
  349. int rectWidth = textRect.left - textRect.right;
  350. int offset = rectWidth / 2 - m_titleTextHeight / 2;
  351. //textRect.right += 30;
  352. //I don't understand where the 4 is coming from but it's always 4 pixals from the right so adjust for this
  353. textRect.left -= (offset - theApp.m_metrics.ScaleX(4));
  354. int k = 0;
  355. }
  356. dc.DrawText(csText, textRect, flags);
  357. dc.SelectObject(pOldFont);
  358. dc.SetBkMode(nOldBKMode);
  359. DrawWindowIcon(dc, pWnd);
  360. DrawChevronBtn(dc, pWnd);
  361. DrawCloseBtn(dc, pWnd);
  362. DrawMaximizeBtn(dc, pWnd);
  363. DrawMinimizeBtn(dc, pWnd);
  364. }
  365. void CDittoWindow::DoSetRegion(CWnd *pWnd)
  366. {
  367. return;
  368. //Create the region for drawing the rounded top edge
  369. CRect rect;
  370. CRgn rgnRect, rgnRect2, rgnRound, rgnFinalA, rgnFinalB;
  371. pWnd->GetWindowRect(rect);
  372. if(rect.Width() < 0)
  373. return;
  374. CRect r;
  375. pWnd->GetClientRect(&r);
  376. int seven = theApp.m_metrics.ScaleX(7);
  377. int fifteen = theApp.m_metrics.ScaleX(15);
  378. int one = theApp.m_metrics.ScaleX(1);
  379. if((m_lRightBorder == m_captionBorderWidth) ||
  380. (m_lTopBorder == m_captionBorderWidth))
  381. {
  382. rgnRect.CreateRectRgn(0, 0, rect.Width() - seven, rect.Height());
  383. rgnRound.CreateRoundRectRgn(0, 0, rect.Width() + one, rect.Height(), fifteen, fifteen);
  384. rgnFinalB.CreateRectRgn(0, 0, 0, 0);
  385. rgnFinalB.CombineRgn(&rgnRect, &rgnRound, RGN_OR);
  386. rgnRect2.CreateRectRgn(0, seven, rect.Width(), rect.Height());
  387. rgnFinalA.CreateRectRgn(0, 0, 0, 0);
  388. rgnFinalA.CombineRgn(&rgnRect2, &rgnFinalB, RGN_OR);
  389. //Set the region
  390. pWnd->SetWindowRgn(rgnFinalA, TRUE);
  391. }
  392. else if(m_lLeftBorder == m_captionBorderWidth)
  393. {
  394. rgnRect.CreateRectRgn(0, seven, rect.Width(), rect.Height());
  395. rgnRound.CreateRoundRectRgn(0, 0, rect.Width(), rect.Height(), fifteen, fifteen);
  396. rgnFinalB.CreateRectRgn(0, 0, 0, 0);
  397. rgnFinalB.CombineRgn(&rgnRect, &rgnRound, RGN_OR);
  398. rgnRect2.CreateRectRgn(seven, 0, rect.Width(), rect.Height());
  399. rgnFinalA.CreateRectRgn(0, 0, 0, 0);
  400. rgnFinalA.CombineRgn(&rgnRect2, &rgnFinalB, RGN_OR);
  401. pWnd->SetWindowRgn(rgnFinalA, TRUE);
  402. }
  403. else if(m_lBottomBorder == m_captionBorderWidth)
  404. {
  405. rgnRect.CreateRectRgn(0, 0, rect.Width(), rect.Height() - seven);
  406. rgnRound.CreateRoundRectRgn(0, 0, rect.Width() + one, rect.Height() + one, fifteen, fifteen);
  407. rgnFinalB.CreateRectRgn(0, 0, 0, 0);
  408. rgnFinalB.CombineRgn(&rgnRect, &rgnRound, RGN_OR);
  409. rgnRect2.CreateRectRgn(0, 0, rect.Width() - fifteen, rect.Height());
  410. rgnFinalA.CreateRectRgn(0, 0, 0, 0);
  411. rgnFinalA.CombineRgn(&rgnRect2, &rgnFinalB, RGN_OR);
  412. pWnd->SetWindowRgn(rgnFinalA, TRUE);
  413. }
  414. }
  415. void CDittoWindow::DrawChevronBtn(CWindowDC &dc, CWnd *pWnd)
  416. {
  417. if(m_bDrawChevron == false)
  418. {
  419. return;
  420. }
  421. if(this->m_bMinimized)
  422. {
  423. m_chevronLeftButton.Draw(&dc, pWnd, m_crChevronBT, m_bMouseOverChevron, m_bMouseDownOnChevron);
  424. }
  425. else
  426. {
  427. m_chevronRightButton.Draw(&dc, pWnd, m_crChevronBT, m_bMouseOverChevron, m_bMouseDownOnChevron);
  428. }
  429. }
  430. void CDittoWindow::DrawWindowIcon(CWindowDC &dc, CWnd *pWnd)
  431. {
  432. //m_windowIcon.Draw(&dc, pWnd, m_crWindowIconBT.left, m_crWindowIconBT.top, false, false);
  433. }
  434. void CDittoWindow::DrawCloseBtn(CWindowDC &dc, CWnd *pWnd)
  435. {
  436. if(m_bDrawClose == false)
  437. {
  438. return;
  439. }
  440. m_closeButton.Draw(&dc, pWnd, m_crCloseBT, m_bMouseOverClose, m_bMouseDownOnClose);
  441. }
  442. void CDittoWindow::DrawMinimizeBtn(CWindowDC &dc, CWnd *pWnd)
  443. {
  444. if(m_bDrawMinimize == false)
  445. {
  446. return;
  447. }
  448. m_minimizeButton.Draw(&dc, pWnd, m_crMinimizeBT, m_bMouseOverMinimize, m_bMouseDownOnMinimize);
  449. }
  450. void CDittoWindow::DrawMaximizeBtn(CWindowDC &dc, CWnd *pWnd)
  451. {
  452. if(m_bDrawMaximize == false)
  453. {
  454. return;
  455. }
  456. m_maximizeButton.Draw(&dc, pWnd, m_crMaximizeBT, m_bMouseOverMaximize, m_bMouseDownOnMaximize);
  457. }
  458. int CDittoWindow::DoNcLButtonDown(CWnd *pWnd, UINT nHitTest, CPoint point)
  459. {
  460. switch (nHitTest)
  461. {
  462. case HTCAPTION:
  463. m_buttonDownOnCaption = true;
  464. break;
  465. default:
  466. m_buttonDownOnCaption = false;
  467. }
  468. int buttonPressed = 0;
  469. //ReleaseCapture();
  470. CPoint clPoint(point);
  471. pWnd->ScreenToClient(&clPoint);
  472. clPoint.x += m_lLeftBorder;
  473. clPoint.y += m_lTopBorder;
  474. if(m_crCloseBT.PtInRect(clPoint))
  475. {
  476. m_bMouseDownOnClose = true;
  477. //InvalidateRect(pWnd->m_hWnd, m_crCloseBT, TRUE);
  478. //pWnd->InvalidateRect(m_crCloseBT);
  479. //pWnd->UpdateWindow();
  480. //DoNcPaint(pWnd);
  481. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  482. buttonPressed = BUTTON_CLOSE;
  483. }
  484. else if(m_crChevronBT.PtInRect(clPoint))
  485. {
  486. m_bMouseDownOnChevron = true;
  487. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  488. buttonPressed = BUTTON_CHEVRON;
  489. }
  490. else if(m_crMinimizeBT.PtInRect(clPoint))
  491. {
  492. m_bMouseDownOnMinimize = true;
  493. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  494. buttonPressed = BUTTON_MINIMIZE;
  495. }
  496. else if(m_crMaximizeBT.PtInRect(clPoint))
  497. {
  498. m_bMouseDownOnMaximize = true;
  499. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  500. buttonPressed = BUTTON_MAXIMIZE;
  501. }
  502. else if(m_bMinimized)
  503. {
  504. //MinMaxWindow(FORCE_MAX);
  505. }
  506. return buttonPressed;
  507. }
  508. long CDittoWindow::DoNcLButtonUp(CWnd *pWnd, UINT nHitTest, CPoint point)
  509. {
  510. m_buttonDownOnCaption = false;
  511. CRect crWindow;
  512. pWnd->GetWindowRect(crWindow);
  513. CPoint localPoint(point.x - crWindow.left, point.y - crWindow.top);
  514. long lRet = 0;
  515. if(m_bMouseDownOnClose)
  516. {
  517. m_bMouseDownOnClose = false;
  518. m_bMouseOverClose = false;
  519. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  520. if(m_crCloseBT.PtInRect(localPoint))
  521. {
  522. if(m_sendWMClose)
  523. {
  524. pWnd->SendMessage(WM_CLOSE, 0, 0);
  525. }
  526. lRet = BUTTON_CLOSE;
  527. }
  528. }
  529. else if(m_bMouseDownOnChevron)
  530. {
  531. m_bMouseDownOnChevron = false;
  532. m_bMouseOverChevron = false;
  533. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  534. if(m_crChevronBT.PtInRect(localPoint))
  535. {
  536. lRet = BUTTON_CHEVRON;
  537. }
  538. }
  539. else if(m_bMouseDownOnMinimize)
  540. {
  541. m_bMouseDownOnMinimize = false;
  542. m_bMouseOverMinimize = false;
  543. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  544. if(m_crMinimizeBT.PtInRect(localPoint))
  545. {
  546. pWnd->ShowWindow(SW_MINIMIZE);
  547. lRet = BUTTON_MINIMIZE;
  548. }
  549. }
  550. else if(m_bMouseDownOnMaximize)
  551. {
  552. m_bMouseDownOnMaximize = false;
  553. m_bMouseOverMaximize = false;
  554. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  555. if(m_crMaximizeBT.PtInRect(localPoint))
  556. {
  557. if(pWnd->GetStyle() & WS_MAXIMIZE)
  558. pWnd->ShowWindow(SW_RESTORE);
  559. else
  560. pWnd->ShowWindow(SW_SHOWMAXIMIZED);
  561. lRet = BUTTON_MAXIMIZE;
  562. }
  563. }
  564. return lRet;
  565. }
  566. void CDittoWindow::DoNcMouseMove(CWnd *pWnd, UINT nHitTest, CPoint point)
  567. {
  568. return;
  569. CRect crWindow;
  570. pWnd->GetWindowRect(crWindow);
  571. CPoint localPoint(point.x - crWindow.left, point.y - crWindow.top);
  572. if(m_crCloseBT.PtInRect(localPoint))
  573. {
  574. m_bMouseOverClose = true;
  575. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  576. }
  577. else if(m_bMouseOverClose)
  578. {
  579. m_bMouseOverClose = false;
  580. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  581. }
  582. if(m_crChevronBT.PtInRect(localPoint))
  583. {
  584. m_bMouseOverChevron = true;
  585. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  586. }
  587. else if(m_bMouseOverChevron)
  588. {
  589. m_bMouseOverChevron = false;
  590. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  591. }
  592. if(m_crMinimizeBT.PtInRect(localPoint))
  593. {
  594. m_bMouseOverMinimize = true;
  595. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  596. }
  597. else if(m_bMouseOverMinimize)
  598. {
  599. m_bMouseOverMinimize = false;
  600. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  601. }
  602. if(m_crMaximizeBT.PtInRect(localPoint))
  603. {
  604. m_bMouseOverMaximize = true;
  605. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  606. }
  607. else if(m_bMouseOverMaximize)
  608. {
  609. m_bMouseOverMaximize = false;
  610. RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
  611. }
  612. }
  613. bool CDittoWindow::DoPreTranslateMessage(MSG* pMsg)
  614. {
  615. return true;
  616. }
  617. void CDittoWindow::SetCaptionOn(CWnd *pWnd, int nPos, bool bOnstartup, int captionSize, int captionFontSize)
  618. {
  619. m_VertFont.Detach();
  620. m_VertFont.CreateFont(theApp.m_metrics.PointsToPixels(captionFontSize), 0, -900, 0, 400, FALSE, FALSE, 0, DEFAULT_CHARSET,
  621. OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
  622. DEFAULT_PITCH | FF_SWISS, _T("Segoe UI"));
  623. m_HorFont.Detach();
  624. m_HorFont.CreateFont(theApp.m_metrics.PointsToPixels(captionFontSize), 0, 0, 0, 500, FALSE, FALSE, 0, DEFAULT_CHARSET,
  625. OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
  626. DEFAULT_PITCH | FF_SWISS, _T("Segoe UI"));
  627. SetTitleTextHeight(pWnd);
  628. m_lTopBorder = BORDER;
  629. m_lRightBorder = BORDER;
  630. m_lBottomBorder = BORDER;
  631. m_lLeftBorder = BORDER;
  632. int oldWidth = m_captionBorderWidth;
  633. m_captionBorderWidth = theApp.m_metrics.ScaleX(captionSize);
  634. if(nPos == CAPTION_RIGHT)
  635. m_lRightBorder = m_captionBorderWidth;
  636. if(nPos == CAPTION_BOTTOM)
  637. m_lBottomBorder = m_captionBorderWidth;
  638. if(nPos == CAPTION_LEFT)
  639. m_lLeftBorder = m_captionBorderWidth;
  640. if(nPos == CAPTION_TOP)
  641. m_lTopBorder = m_captionBorderWidth;
  642. DoSetRegion(pWnd);
  643. if(!bOnstartup)
  644. {
  645. pWnd->SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
  646. }
  647. pWnd->Invalidate();
  648. pWnd->RedrawWindow();
  649. if (oldWidth != m_captionBorderWidth)
  650. {
  651. ::SetWindowPos(pWnd->m_hWnd, NULL, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  652. }
  653. }
  654. void CDittoWindow::SetTitleTextHeight(CWnd *pWnd)
  655. {
  656. CWindowDC dc(pWnd);
  657. CFont *pOldFont = dc.SelectObject(&m_HorFont);
  658. CRect size(0, 0, 0, 0);
  659. dc.DrawText(_T("W"), size, DT_CALCRECT);
  660. m_titleTextHeight = size.Height();
  661. dc.SelectObject(pOldFont);
  662. }
  663. bool CDittoWindow::SetCaptionColors(COLORREF left, COLORREF right, COLORREF border)
  664. {
  665. m_CaptionColorLeft = left;
  666. m_CaptionColorRight = right;
  667. m_border = border;
  668. return true;
  669. }
  670. void CDittoWindow::SetCaptionTextColor(COLORREF color)
  671. {
  672. m_CaptionTextColor = color;
  673. }
  674. void CDittoWindow::SnapToEdge(CWnd *pWnd, WINDOWPOS* lpwndpos)
  675. {
  676. if (lpwndpos->cx == 0 &&
  677. lpwndpos->cy == 0)
  678. {
  679. return;
  680. }
  681. const char threshold = 12;
  682. RECT rect = { 0 };
  683. HMONITOR hMonitor;
  684. MONITORINFO mi;
  685. // Grab information about our monitors
  686. // For multi-monitor support, we use this instead of SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
  687. hMonitor = MonitorFromWindow(pWnd->m_hWnd, MONITOR_DEFAULTTONEAREST);
  688. mi.cbSize = sizeof(mi);
  689. GetMonitorInfo(hMonitor, &mi);
  690. rect = mi.rcWork;
  691. bool edgeMove = true;
  692. bool captionMove = false;
  693. if (m_buttonDownOnCaption)
  694. {
  695. edgeMove = false;
  696. captionMove = true;
  697. }
  698. // Snap to left
  699. if (lpwndpos->x >= (rect.left - threshold) &&
  700. lpwndpos->x <= (rect.left + threshold))
  701. {
  702. if (edgeMove)
  703. {
  704. int diff = lpwndpos->x - rect.left;
  705. lpwndpos->cx += diff;
  706. }
  707. if (edgeMove || captionMove)
  708. {
  709. lpwndpos->x = rect.left;
  710. }
  711. }
  712. // Snap to right
  713. if ((lpwndpos->x + lpwndpos->cx) >= (rect.right - threshold) &&
  714. (lpwndpos->x + lpwndpos->cx) <= (rect.right + threshold))
  715. {
  716. if (edgeMove)
  717. {
  718. int diff = rect.right - (lpwndpos->x + lpwndpos->cx);
  719. lpwndpos->cx += diff;
  720. }
  721. if (captionMove)
  722. {
  723. lpwndpos->x = (rect.right - lpwndpos->cx);
  724. }
  725. }
  726. // Snap to top
  727. if (lpwndpos->y >= (rect.top - threshold) &&
  728. lpwndpos->y <= (rect.top + threshold))
  729. {
  730. if (edgeMove)
  731. {
  732. int diff = lpwndpos->y - rect.top;
  733. lpwndpos->cy += diff;
  734. }
  735. if (edgeMove || captionMove)
  736. {
  737. lpwndpos->y = rect.top;
  738. }
  739. }
  740. // Snap to bottom
  741. if ((lpwndpos->y + lpwndpos->cy) >= (rect.bottom - threshold) &&
  742. (lpwndpos->y + lpwndpos->cy) <= (rect.bottom + threshold))
  743. {
  744. if (edgeMove)
  745. {
  746. int diff = rect.bottom - (lpwndpos->y + lpwndpos->cy);
  747. lpwndpos->cy += diff;
  748. }
  749. if (captionMove)
  750. {
  751. lpwndpos->y = (rect.bottom - lpwndpos->cy);
  752. }
  753. }
  754. }
  755. void CDittoWindow::MinMaxWindow(CWnd *pWnd, long lOption)
  756. {
  757. if ((m_bMinimized) && (lOption == FORCE_MIN))
  758. return;
  759. if ((m_bMinimized == false) && (lOption == FORCE_MAX))
  760. return;
  761. if (m_lRightBorder == m_captionBorderWidth)
  762. {
  763. if (m_bMinimized == false)
  764. {
  765. pWnd->GetWindowRect(m_crFullSizeWindow);
  766. pWnd->MoveWindow(m_crFullSizeWindow.right - m_captionBorderWidth,
  767. m_crFullSizeWindow.top, m_captionBorderWidth,
  768. m_crFullSizeWindow.Height());
  769. m_bMinimized = true;
  770. m_TimeMinimized = COleDateTime::GetCurrentTime();
  771. }
  772. else
  773. {
  774. CRect cr;
  775. pWnd->GetWindowRect(cr);
  776. pWnd->MoveWindow(cr.right - m_crFullSizeWindow.Width(),
  777. cr.top, m_crFullSizeWindow.Width(), cr.Height());
  778. m_crFullSizeWindow.SetRectEmpty();
  779. m_bMinimized = false;
  780. m_TimeMaximized = COleDateTime::GetCurrentTime();
  781. ::SetForegroundWindow(pWnd->GetSafeHwnd());
  782. }
  783. }
  784. if (m_lLeftBorder == m_captionBorderWidth)
  785. {
  786. if (m_bMinimized == false)
  787. {
  788. pWnd->GetWindowRect(m_crFullSizeWindow);
  789. pWnd->MoveWindow(m_crFullSizeWindow.left,
  790. m_crFullSizeWindow.top, m_captionBorderWidth,
  791. m_crFullSizeWindow.Height());
  792. m_bMinimized = true;
  793. m_TimeMinimized = COleDateTime::GetCurrentTime();
  794. }
  795. else
  796. {
  797. CRect cr;
  798. pWnd->GetWindowRect(cr);
  799. pWnd->MoveWindow(cr.left, cr.top,
  800. m_crFullSizeWindow.Width(), cr.Height());
  801. m_crFullSizeWindow.SetRectEmpty();
  802. m_bMinimized = false;
  803. m_TimeMaximized = COleDateTime::GetCurrentTime();
  804. ::SetForegroundWindow(pWnd->GetSafeHwnd());
  805. }
  806. }
  807. else if (m_lTopBorder == m_captionBorderWidth)
  808. {
  809. if (m_bMinimized == false)
  810. {
  811. pWnd->GetWindowRect(m_crFullSizeWindow);
  812. pWnd->MoveWindow(m_crFullSizeWindow.left,
  813. m_crFullSizeWindow.top,
  814. m_crFullSizeWindow.Width(),
  815. m_captionBorderWidth);
  816. m_bMinimized = true;
  817. m_TimeMinimized = COleDateTime::GetCurrentTime();
  818. }
  819. else
  820. {
  821. CRect cr;
  822. pWnd->GetWindowRect(cr);
  823. pWnd->MoveWindow(cr.left, cr.top,
  824. cr.Width(), m_crFullSizeWindow.Height());
  825. m_crFullSizeWindow.SetRectEmpty();
  826. m_bMinimized = false;
  827. m_TimeMaximized = COleDateTime::GetCurrentTime();
  828. ::SetForegroundWindow(pWnd->GetSafeHwnd());
  829. }
  830. }
  831. else if (m_lBottomBorder == m_captionBorderWidth)
  832. {
  833. if (m_bMinimized == false)
  834. {
  835. pWnd->GetWindowRect(m_crFullSizeWindow);
  836. pWnd->MoveWindow(m_crFullSizeWindow.left,
  837. m_crFullSizeWindow.bottom - m_captionBorderWidth,
  838. m_crFullSizeWindow.Width(),
  839. m_captionBorderWidth);
  840. m_bMinimized = true;
  841. m_TimeMinimized = COleDateTime::GetCurrentTime();
  842. }
  843. else
  844. {
  845. CRect cr;
  846. pWnd->GetWindowRect(cr);
  847. pWnd->MoveWindow(cr.left,
  848. cr.bottom - m_crFullSizeWindow.Height(),
  849. cr.Width(), m_crFullSizeWindow.Height());
  850. m_crFullSizeWindow.SetRectEmpty();
  851. m_bMinimized = false;
  852. m_TimeMaximized = COleDateTime::GetCurrentTime();
  853. ::SetForegroundWindow(pWnd->GetSafeHwnd());
  854. }
  855. }
  856. }