DittoWindow.cpp 26 KB

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