QRCodeViewer.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. // QRCodeViewer.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "CP_Main.h"
  5. #include "QRCodeViewer.h"
  6. #include "MainTableFunctions.h"
  7. #define TIMER_BUTTON_UP 1
  8. // QRCodeViewer
  9. IMPLEMENT_DYNAMIC(QRCodeViewer, CWnd)
  10. QRCodeViewer::QRCodeViewer()
  11. {
  12. m_descBackground = NULL;
  13. }
  14. QRCodeViewer::~QRCodeViewer()
  15. {
  16. if(m_descBackground != NULL)
  17. {
  18. DeleteObject(m_descBackground);
  19. }
  20. }
  21. BEGIN_MESSAGE_MAP(QRCodeViewer, CWnd)
  22. ON_WM_CREATE()
  23. ON_WM_PAINT()
  24. ON_WM_SIZE()
  25. ON_WM_NCHITTEST()
  26. ON_WM_NCPAINT()
  27. ON_WM_NCCALCSIZE()
  28. ON_WM_NCLBUTTONDOWN()
  29. ON_WM_NCMOUSEMOVE()
  30. ON_WM_NCLBUTTONUP()
  31. ON_WM_ERASEBKGND()
  32. ON_WM_CTLCOLOR()
  33. ON_WM_WINDOWPOSCHANGING()
  34. ON_WM_TIMER()
  35. ON_MESSAGE(WM_DPICHANGED, OnDpiChanged)
  36. ON_WM_MOVING()
  37. ON_WM_ENTERSIZEMOVE()
  38. END_MESSAGE_MAP()
  39. BOOL QRCodeViewer::CreateEx(CWnd *pParentWnd, unsigned char* bitmapData, int imageSize, CString desc, int rowHeight, LOGFONT logFont)
  40. {
  41. // Get the class name and create the window
  42. CString szClassName = AfxRegisterWndClass(CS_CLASSDC | CS_SAVEBITS, LoadCursor(NULL, IDC_ARROW));
  43. m_bitmapData = bitmapData;
  44. m_imageSize = imageSize;
  45. m_descRowHeight = rowHeight;
  46. m_descBackground = CreateSolidBrush(RGB(255, 255, 255));
  47. m_logFont = logFont;
  48. m_originalFontHeight = logFont.lfHeight;
  49. if(CWnd::CreateEx(0, szClassName, _T(""), WS_POPUP, 0, 0, 0, 0, NULL, 0, NULL))
  50. {
  51. BOOL r = m_desc.Create(CMainTableFunctions::GetDisplayText(g_Opt.m_nLinesPerRow, desc), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, 2);
  52. m_font.CreateFontIndirect(&logFont);
  53. m_desc.SetFont(&m_font);
  54. m_DittoWindow.DoCreate(this);
  55. m_DittoWindow.SetCaptionColors(g_Opt.m_Theme.CaptionLeft(), g_Opt.m_Theme.CaptionRight(), g_Opt.m_Theme.Border());
  56. m_DittoWindow.SetCaptionOn(this, CGetSetOptions::GetCaptionPos(), true, g_Opt.m_Theme.GetCaptionSize(), g_Opt.m_Theme.GetCaptionFontSize());
  57. m_DittoWindow.m_bDrawMinimize = false;
  58. m_DittoWindow.m_bDrawMaximize = true;
  59. m_DittoWindow.m_bDrawChevron = false;
  60. m_DittoWindow.m_sendWMClose = false;
  61. m_qrCodeDrawer.LoadRaw(m_bitmapData, m_imageSize);
  62. delete[] m_bitmapData;
  63. CRect parentRect;
  64. pParentWnd->GetWindowRect(&parentRect);
  65. CRect rect;
  66. rect.left = parentRect.left;
  67. rect.top = parentRect.top;
  68. rect.right = rect.left + m_DittoWindow.m_borderSize + m_DittoWindow.m_borderSize + m_qrCodeDrawer.ImageWidth() + (CGetSetOptions::GetQRCodeBorderPixels() * 2);
  69. if (m_DittoWindow.m_captionPosition == CAPTION_LEFT ||
  70. m_DittoWindow.m_captionPosition == CAPTION_RIGHT)
  71. {
  72. rect.right += m_DittoWindow.m_captionBorderWidth;
  73. }
  74. rect.bottom = rect.top + m_DittoWindow.m_borderSize + m_DittoWindow.m_borderSize + rowHeight + 5 + m_qrCodeDrawer.ImageHeight() + (CGetSetOptions::GetQRCodeBorderPixels() * 2);
  75. CRect center = CenterRect(rect);
  76. EnsureWindowVisible(&center);
  77. ::MoveWindow(m_hWnd, center.left, center.top, center.Width(), center.Height(), TRUE);
  78. MoveControls();
  79. SetFocus();
  80. }
  81. else
  82. {
  83. delete[] m_bitmapData;
  84. }
  85. return TRUE;
  86. }
  87. void QRCodeViewer::OnSize(UINT nType, int cx, int cy)
  88. {
  89. CWnd::OnSize(nType, cx, cy);
  90. this->Invalidate();
  91. MoveControls();
  92. }
  93. void QRCodeViewer::MoveControls()
  94. {
  95. CRect crRect;
  96. GetClientRect(crRect);
  97. int cx = crRect.Width();
  98. int cy = crRect.Height();
  99. if(m_desc.m_hWnd != NULL)
  100. {
  101. m_desc.MoveWindow(m_DittoWindow.m_dpi.ScaleX(5), cy - m_DittoWindow.m_dpi.ScaleX(m_descRowHeight) - m_DittoWindow.m_dpi.ScaleX(5), cx - m_DittoWindow.m_dpi.ScaleX(10), m_DittoWindow.m_dpi.ScaleX(m_descRowHeight));
  102. }
  103. }
  104. void QRCodeViewer::OnPaint()
  105. {
  106. CPaintDC dc(this);
  107. CRect thisRect;
  108. GetClientRect(thisRect);
  109. thisRect.bottom -= m_DittoWindow.m_dpi.ScaleX(m_descRowHeight) - m_DittoWindow.m_dpi.ScaleX(5);
  110. int width = thisRect.Width() - (CGetSetOptions::GetQRCodeBorderPixels() * 2);
  111. int height = min(width, (thisRect.Height() - (CGetSetOptions::GetQRCodeBorderPixels() * 2)));
  112. width = min(width, height);
  113. CRect imageRect(0, 0, width, height);
  114. CRect centerRect = CenterRectFromRect(imageRect, thisRect);
  115. m_qrCodeDrawer.Draw(&dc, m_DittoWindow.m_dpi, this, centerRect.left, centerRect.top, false, false, width, height);
  116. }
  117. BOOL QRCodeViewer::PreTranslateMessage(MSG *pMsg)
  118. {
  119. m_DittoWindow.DoPreTranslateMessage(pMsg);
  120. switch(pMsg->message)
  121. {
  122. case WM_KEYDOWN:
  123. switch(pMsg->wParam)
  124. {
  125. case VK_ESCAPE:
  126. ::SendMessage(m_hWnd, WM_CLOSE, 0, 0);
  127. return TRUE;
  128. }
  129. }
  130. return CWnd::PreTranslateMessage(pMsg);
  131. }
  132. void QRCodeViewer::PostNcDestroy()
  133. {
  134. CWnd::PostNcDestroy();
  135. delete this;
  136. }
  137. void QRCodeViewer::OnNcPaint()
  138. {
  139. m_DittoWindow.DoNcPaint(this);
  140. }
  141. void QRCodeViewer::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
  142. {
  143. CWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
  144. m_DittoWindow.DoNcCalcSize(bCalcValidRects, lpncsp);
  145. }
  146. HITTEST_RET QRCodeViewer::OnNcHitTest(CPoint point)
  147. {
  148. UINT Ret = m_DittoWindow.DoNcHitTest(this, point);
  149. if(Ret == -1)
  150. return CWnd::OnNcHitTest(point);
  151. return Ret;
  152. }
  153. BOOL QRCodeViewer::OnEraseBkgnd(CDC* pDC)
  154. {
  155. CRect rect;
  156. GetClientRect(&rect);
  157. CBrush myBrush(RGB(255, 255, 255));
  158. CBrush *pOld = pDC->SelectObject(&myBrush);
  159. BOOL bRes = pDC->PatBlt(0, 0, rect.Width(), rect.Height(), PATCOPY);
  160. pDC->SelectObject(pOld);
  161. return TRUE;
  162. }
  163. void QRCodeViewer::OnNcLButtonDown(UINT nHitTest, CPoint point)
  164. {
  165. int buttonPressed = m_DittoWindow.DoNcLButtonDown(this, nHitTest, point);
  166. if (buttonPressed != 0)
  167. {
  168. SetTimer(TIMER_BUTTON_UP, 100, NULL);
  169. }
  170. CWnd::OnNcLButtonDown(nHitTest, point);
  171. }
  172. void QRCodeViewer::OnNcLButtonUp(UINT nHitTest, CPoint point)
  173. {
  174. long lRet = m_DittoWindow.DoNcLButtonUp(this, nHitTest, point);
  175. switch(lRet)
  176. {
  177. case BUTTON_CLOSE:
  178. ::PostMessage(m_hWnd, WM_CLOSE, 0, 0);
  179. break;
  180. }
  181. KillTimer(TIMER_BUTTON_UP);
  182. CWnd::OnNcLButtonUp(nHitTest, point);
  183. }
  184. void QRCodeViewer::OnNcMouseMove(UINT nHitTest, CPoint point)
  185. {
  186. m_DittoWindow.DoNcMouseMove(this, nHitTest, point);
  187. CWnd::OnNcMouseMove(nHitTest, point);
  188. }
  189. HBRUSH QRCodeViewer::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
  190. {
  191. HBRUSH hbr = CWnd::OnCtlColor(pDC, pWnd, nCtlColor);
  192. if(pWnd->GetDlgCtrlID() == 2)
  193. {
  194. pDC->SetBkColor(RGB(255,255,255));
  195. return m_descBackground;
  196. }
  197. // TODO: Return a different brush if the default is not desired
  198. return hbr;
  199. }
  200. void QRCodeViewer::OnWindowPosChanging(WINDOWPOS* lpwndpos)
  201. {
  202. CWnd::OnWindowPosChanging(lpwndpos);
  203. }
  204. void QRCodeViewer::OnTimer(UINT_PTR nIDEvent)
  205. {
  206. switch (nIDEvent)
  207. {
  208. case TIMER_BUTTON_UP:
  209. {
  210. if ((GetKeyState(VK_LBUTTON) & 0x100) == 0)
  211. {
  212. m_DittoWindow.DoNcLButtonUp(this, 0, CPoint(0, 0));
  213. KillTimer(TIMER_BUTTON_UP);
  214. }
  215. break;
  216. }
  217. }
  218. CWnd::OnTimer(nIDEvent);
  219. }
  220. LRESULT QRCodeViewer::OnDpiChanged(WPARAM wParam, LPARAM lParam)
  221. {
  222. int dpi = HIWORD(wParam);
  223. m_DittoWindow.OnDpiChanged(this, dpi);
  224. RECT* const prcNewWindow = (RECT*)lParam;
  225. SetWindowPos(NULL,
  226. prcNewWindow->left,
  227. prcNewWindow->top,
  228. prcNewWindow->right - prcNewWindow->left,
  229. prcNewWindow->bottom - prcNewWindow->top,
  230. SWP_NOZORDER | SWP_NOACTIVATE);
  231. MoveControls();
  232. m_logFont.lfHeight = m_DittoWindow.m_dpi.PointsToPixels(m_originalFontHeight);
  233. m_font.Detach();
  234. m_font.CreateFontIndirect(&m_logFont);
  235. m_desc.SetFont(&m_font);
  236. return TRUE;
  237. }
  238. void QRCodeViewer::OnMoving(UINT fwSide, LPRECT pRect)
  239. {
  240. CWnd::OnMoving(fwSide, pRect);
  241. m_snap.OnSnapMoving(m_hWnd, pRect);
  242. }
  243. void QRCodeViewer::OnEnterSizeMove()
  244. {
  245. m_snap.OnSnapEnterSizeMove(m_hWnd);
  246. CWnd::OnEnterSizeMove();
  247. }