WinImplBase.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. #ifndef WIN_IMPL_BASE_HPP
  2. #define WIN_IMPL_BASE_HPP
  3. #include "stdafx.h"
  4. //add by Hong;
  5. #include <typeinfo>
  6. #include <atlbase.h>
  7. namespace DuiLib
  8. {
  9. //////////////////////////////////////////////////////////////////////////
  10. LPBYTE WindowImplBase::m_lpResourceZIPBuffer = NULL;
  11. DUI_BEGIN_MESSAGE_MAP (WindowImplBase, CNotifyPump)
  12. DUI_ON_MSGTYPE (DUI_MSGTYPE_CLICK, OnClick)
  13. DUI_END_MESSAGE_MAP ()
  14. WindowImplBase::WindowImplBase ()
  15. {
  16. }
  17. void WindowImplBase::OnFinalMessage (HWND hWnd)
  18. {
  19. m_PaintManager.RemovePreMessageFilter (this);
  20. m_PaintManager.RemoveNotifier (this);
  21. m_PaintManager.ReapObjects (m_PaintManager.GetRoot ());
  22. }
  23. LPCTSTR WindowImplBase::GetWindowClassName () const
  24. {
  25. static wchar_t wszWndClassName[MAX_PATH] = {0};
  26. _tcscpy (wszWndClassName, _tcsspnp (CA2W (typeid(*this).name ()), L"class "));
  27. return wszWndClassName;
  28. }
  29. UINT WindowImplBase::DoModal (HWND hParent)
  30. {
  31. Create(hParent, GetWindowClassName(), WS_POPUP, 0);
  32. CenterWindow ();
  33. return ShowModal();
  34. }
  35. LRESULT WindowImplBase::ResponseDefaultKeyEvent (WPARAM wParam)
  36. {
  37. if(wParam == VK_RETURN)
  38. {
  39. return FALSE;
  40. }
  41. else if(wParam == VK_ESCAPE)
  42. {
  43. //Close ();
  44. return TRUE;
  45. }
  46. return FALSE;
  47. }
  48. UINT WindowImplBase::GetClassStyle () const
  49. {
  50. return CS_DBLCLKS;
  51. }
  52. UILIB_RESOURCETYPE WindowImplBase::GetResourceType () const
  53. {
  54. return UILIB_FILE;
  55. }
  56. CDuiString WindowImplBase::GetZIPFileName () const
  57. {
  58. return _T ("");
  59. }
  60. LPCTSTR WindowImplBase::GetResourceID () const
  61. {
  62. return _T ("");
  63. }
  64. CControlUI* WindowImplBase::CreateControl (LPCTSTR pstrClass)
  65. {
  66. return NULL;
  67. }
  68. LRESULT WindowImplBase::MessageHandler (UINT uMsg, WPARAM wParam, LPARAM /*lParam*/, bool& /*bHandled*/)
  69. {
  70. if(uMsg == WM_KEYDOWN)
  71. {
  72. switch(wParam)
  73. {
  74. case VK_RETURN:
  75. case VK_ESCAPE:
  76. return ResponseDefaultKeyEvent (wParam);
  77. default:
  78. break;
  79. }
  80. }
  81. return FALSE;
  82. }
  83. LRESULT WindowImplBase::OnClose (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  84. {
  85. bHandled = FALSE;
  86. return 0;
  87. }
  88. LRESULT WindowImplBase::OnDestroy (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  89. {
  90. bHandled = FALSE;
  91. return 0;
  92. }
  93. #if defined(WIN32) && !defined(UNDER_CE)
  94. LRESULT WindowImplBase::OnNcActivate (UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
  95. {
  96. if(::IsIconic (*this)) bHandled = FALSE;
  97. return (wParam == 0) ? TRUE : FALSE;
  98. }
  99. LRESULT WindowImplBase::OnNcCalcSize (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  100. {
  101. LPRECT pRect = NULL;
  102. if(wParam == TRUE)
  103. {
  104. LPNCCALCSIZE_PARAMS pParam = (LPNCCALCSIZE_PARAMS)lParam;
  105. pRect = &pParam->rgrc[0];
  106. }
  107. else
  108. {
  109. pRect = (LPRECT)lParam;
  110. }
  111. if(::IsZoomed (m_hWnd))
  112. { // 最大化时,计算当前显示器最适合宽高度
  113. MONITORINFO oMonitor = {};
  114. oMonitor.cbSize = sizeof (oMonitor);
  115. ::GetMonitorInfo (::MonitorFromWindow (*this, MONITOR_DEFAULTTONEAREST), &oMonitor);
  116. CDuiRect rcWork = oMonitor.rcWork;
  117. CDuiRect rcMonitor = oMonitor.rcMonitor;
  118. rcWork.Offset (-oMonitor.rcMonitor.left, -oMonitor.rcMonitor.top);
  119. pRect->right = pRect->left + rcWork.GetWidth ();
  120. pRect->bottom = pRect->top + rcWork.GetHeight ();
  121. return WVR_REDRAW;
  122. }
  123. return 0;
  124. }
  125. LRESULT WindowImplBase::OnNcPaint (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  126. {
  127. return 0;
  128. }
  129. LRESULT WindowImplBase::OnNcHitTest (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  130. {
  131. POINT pt; pt.x = GET_X_LPARAM (lParam); pt.y = GET_Y_LPARAM (lParam);
  132. ::ScreenToClient (*this, &pt);
  133. RECT rcClient;
  134. ::GetClientRect (*this, &rcClient);
  135. if(!::IsZoomed (*this))
  136. {
  137. RECT rcSizeBox = m_PaintManager.GetSizeBox ();
  138. if(pt.y < rcClient.top + rcSizeBox.top)
  139. {
  140. if(pt.x < rcClient.left + rcSizeBox.left) return HTTOPLEFT;
  141. if(pt.x > rcClient.right - rcSizeBox.right) return HTTOPRIGHT;
  142. return HTTOP;
  143. }
  144. else if(pt.y > rcClient.bottom - rcSizeBox.bottom)
  145. {
  146. if(pt.x < rcClient.left + rcSizeBox.left) return HTBOTTOMLEFT;
  147. if(pt.x > rcClient.right - rcSizeBox.right) return HTBOTTOMRIGHT;
  148. return HTBOTTOM;
  149. }
  150. if(pt.x < rcClient.left + rcSizeBox.left) return HTLEFT;
  151. if(pt.x > rcClient.right - rcSizeBox.right) return HTRIGHT;
  152. }
  153. RECT rcCaption = m_PaintManager.GetCaptionRect ();
  154. if(pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \
  155. && pt.y >= rcCaption.top && pt.y < rcCaption.bottom)
  156. {
  157. CControlUI* pControl = static_cast<CControlUI*>(m_PaintManager.FindControl (pt));
  158. if(pControl && _tcsicmp (pControl->GetClass (), _T ("ButtonUI")) != 0 &&
  159. _tcsicmp (pControl->GetClass (), _T ("OptionUI")) != 0 &&
  160. _tcsicmp (pControl->GetClass (), _T ("TextUI")) != 0)
  161. return HTCAPTION;
  162. }
  163. return HTCLIENT;
  164. }
  165. LRESULT WindowImplBase::OnGetMinMaxInfo (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  166. {
  167. LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam;
  168. MONITORINFO oMonitor = {};
  169. oMonitor.cbSize = sizeof (oMonitor);
  170. ::GetMonitorInfo (::MonitorFromWindow (*this, MONITOR_DEFAULTTONEAREST), &oMonitor);
  171. CDuiRect rcWork = oMonitor.rcWork;
  172. CDuiRect rcMonitor = oMonitor.rcMonitor;
  173. rcWork.Offset (-oMonitor.rcMonitor.left, -oMonitor.rcMonitor.top);
  174. // 计算最大化时,正确的原点坐标
  175. lpMMI->ptMaxPosition.x = rcWork.left;
  176. lpMMI->ptMaxPosition.y = rcWork.top;
  177. lpMMI->ptMaxTrackSize.x = rcWork.GetWidth ();
  178. lpMMI->ptMaxTrackSize.y = rcWork.GetHeight ();
  179. lpMMI->ptMinTrackSize.x = m_PaintManager.GetMinInfo ().cx;
  180. lpMMI->ptMinTrackSize.y = m_PaintManager.GetMinInfo ().cy;
  181. bHandled = FALSE;
  182. return 0;
  183. }
  184. LRESULT WindowImplBase::OnMouseWheel (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  185. {
  186. bHandled = FALSE;
  187. return 0;
  188. }
  189. LRESULT WindowImplBase::OnMouseHover (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  190. {
  191. bHandled = FALSE;
  192. return 0;
  193. }
  194. #endif
  195. LRESULT WindowImplBase::OnSize (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  196. {
  197. SIZE szRoundCorner = m_PaintManager.GetRoundCorner ();
  198. #if defined(WIN32) && !defined(UNDER_CE)
  199. if(!::IsIconic (*this) && (szRoundCorner.cx != 0 || szRoundCorner.cy != 0))
  200. {
  201. CDuiRect rcWnd;
  202. ::GetWindowRect (*this, &rcWnd);
  203. rcWnd.Offset (-rcWnd.left, -rcWnd.top);
  204. rcWnd.right++; rcWnd.bottom++;
  205. HRGN hRgn = ::CreateRoundRectRgn (rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom, szRoundCorner.cx, szRoundCorner.cy);
  206. ::SetWindowRgn (*this, hRgn, TRUE);
  207. ::DeleteObject (hRgn);
  208. }
  209. #endif
  210. bHandled = FALSE;
  211. return 0;
  212. }
  213. LRESULT WindowImplBase::OnChar (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  214. {
  215. bHandled = FALSE;
  216. return 0;
  217. }
  218. LRESULT WindowImplBase::OnSysCommand (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  219. {
  220. if(wParam == SC_CLOSE)
  221. {
  222. bHandled = TRUE;
  223. PostMessage (WM_CLOSE);
  224. return 0;
  225. }
  226. #if defined(WIN32) && !defined(UNDER_CE)
  227. BOOL bZoomed = ::IsZoomed (*this);
  228. LRESULT lRes = CWindowWnd::HandleMessage (uMsg, wParam, lParam);
  229. if(::IsZoomed (*this) != bZoomed)
  230. {
  231. CControlUI* pbtnMax = static_cast<CControlUI*>(m_PaintManager.FindControl (_T ("maxbtn"))); // max button
  232. CControlUI* pbtnRestore = static_cast<CControlUI*>(m_PaintManager.FindControl (_T ("restorebtn"))); // restore button
  233. // toggle status of max and restore button
  234. if(pbtnMax && pbtnRestore)
  235. {
  236. pbtnMax->SetVisible (TRUE == bZoomed);
  237. pbtnRestore->SetVisible (FALSE == bZoomed);
  238. }
  239. }
  240. #else
  241. LRESULT lRes = CWindowWnd::HandleMessage(uMsg, wParam, lParam);
  242. #endif
  243. return lRes;
  244. }
  245. LRESULT WindowImplBase::OnCreate (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  246. {
  247. LONG styleValue = ::GetWindowLong (*this, GWL_STYLE);
  248. styleValue &= ~WS_CAPTION;
  249. ::SetWindowLong (*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
  250. RECT rcClient;
  251. ::GetClientRect (*this, &rcClient);
  252. ::SetWindowPos (*this, NULL, rcClient.left, rcClient.top, rcClient.right - rcClient.left, \
  253. rcClient.bottom - rcClient.top, SWP_FRAMECHANGED);
  254. m_PaintManager.Init (m_hWnd);
  255. m_PaintManager.AddPreMessageFilter (this);
  256. CDialogBuilder builder;
  257. CDuiString strResourcePath = m_PaintManager.GetResourcePath ();
  258. if(strResourcePath.IsEmpty ())
  259. {
  260. strResourcePath = m_PaintManager.GetInstancePath ();
  261. strResourcePath += GetSkinFolder ().GetData ();
  262. }
  263. m_PaintManager.SetResourcePath (strResourcePath.GetData ());
  264. auto ty = GetResourceType ();
  265. switch(GetResourceType ())
  266. {
  267. case UILIB_ZIP:
  268. m_PaintManager.SetResourceZip (GetZIPFileName ().GetData (), true);
  269. break;
  270. case UILIB_ZIPRESOURCE:
  271. {
  272. HRSRC hResource = ::FindResource (m_PaintManager.GetResourceDll (), GetResourceID (), _T ("ZIPRES"));
  273. if(hResource == NULL)
  274. return 0L;
  275. DWORD dwSize = 0;
  276. HGLOBAL hGlobal = ::LoadResource (m_PaintManager.GetResourceDll (), hResource);
  277. if(hGlobal == NULL)
  278. {
  279. #if defined(WIN32) && !defined(UNDER_CE)
  280. ::FreeResource (hResource);
  281. #endif
  282. return 0L;
  283. }
  284. dwSize = ::SizeofResource (m_PaintManager.GetResourceDll (), hResource);
  285. if(dwSize == 0)
  286. return 0L;
  287. m_lpResourceZIPBuffer = new BYTE[dwSize];
  288. if(m_lpResourceZIPBuffer != NULL)
  289. {
  290. ::CopyMemory (m_lpResourceZIPBuffer, (LPBYTE)::LockResource (hGlobal), dwSize);
  291. }
  292. #if defined(WIN32) && !defined(UNDER_CE)
  293. ::FreeResource (hResource);
  294. #endif
  295. m_PaintManager.SetResourceZip (m_lpResourceZIPBuffer, dwSize);
  296. }
  297. break;
  298. }
  299. CControlUI* pRoot = NULL;
  300. if(GetResourceType () == UILIB_RESOURCE)
  301. {
  302. STRINGorID xml (_ttoi (GetSkinFile ().GetData ()));
  303. pRoot = builder.Create (xml, _T ("xml"), this, &m_PaintManager);
  304. }
  305. else
  306. {
  307. auto str = GetSkinFile ().GetData ();
  308. pRoot = builder.Create (GetSkinFile ().GetData (), (UINT)0, this, &m_PaintManager);
  309. }
  310. ASSERT (pRoot);
  311. if(pRoot == NULL)
  312. {
  313. MessageBox (NULL, _T ("加载资源文件失败"), _T ("Duilib"), MB_OK | MB_ICONERROR);
  314. ExitProcess (1);
  315. return 0;
  316. }
  317. m_PaintManager.AttachDialog (pRoot);
  318. m_PaintManager.AddNotifier (this);
  319. InitWindow ();
  320. return 0;
  321. }
  322. LRESULT WindowImplBase::OnKeyDown (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  323. {
  324. bHandled = FALSE;
  325. return 0;
  326. }
  327. LRESULT WindowImplBase::OnKillFocus (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  328. {
  329. bHandled = FALSE;
  330. return 0;
  331. }
  332. LRESULT WindowImplBase::OnSetFocus (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  333. {
  334. bHandled = FALSE;
  335. return 0;
  336. }
  337. LRESULT WindowImplBase::OnLButtonDown (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  338. {
  339. bHandled = FALSE;
  340. return 0;
  341. }
  342. LRESULT WindowImplBase::OnLButtonUp (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  343. {
  344. bHandled = FALSE;
  345. return 0;
  346. }
  347. LRESULT WindowImplBase::OnMouseMove (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  348. {
  349. bHandled = FALSE;
  350. return 0;
  351. }
  352. LRESULT WindowImplBase::HandleMessage (UINT uMsg, WPARAM wParam, LPARAM lParam)
  353. {
  354. LRESULT lRes = 0;
  355. BOOL bHandled = TRUE;
  356. switch(uMsg)
  357. {
  358. case WM_CREATE: lRes = OnCreate (uMsg, wParam, lParam, bHandled); break;
  359. case WM_CLOSE: lRes = OnClose (uMsg, wParam, lParam, bHandled); break;
  360. case WM_DESTROY: lRes = OnDestroy (uMsg, wParam, lParam, bHandled); break;
  361. #if defined(WIN32) && !defined(UNDER_CE)
  362. case WM_NCACTIVATE: lRes = OnNcActivate (uMsg, wParam, lParam, bHandled); break;
  363. case WM_NCCALCSIZE: lRes = OnNcCalcSize (uMsg, wParam, lParam, bHandled); break;
  364. case WM_NCPAINT: lRes = OnNcPaint (uMsg, wParam, lParam, bHandled); break;
  365. case WM_NCHITTEST: lRes = OnNcHitTest (uMsg, wParam, lParam, bHandled); break;
  366. case WM_GETMINMAXINFO: lRes = OnGetMinMaxInfo (uMsg, wParam, lParam, bHandled); break;
  367. case WM_MOUSEWHEEL: lRes = OnMouseWheel (uMsg, wParam, lParam, bHandled); break;
  368. #endif
  369. case WM_SIZE: lRes = OnSize (uMsg, wParam, lParam, bHandled); break;
  370. case WM_CHAR: lRes = OnChar (uMsg, wParam, lParam, bHandled); break;
  371. case WM_SYSCOMMAND: lRes = OnSysCommand (uMsg, wParam, lParam, bHandled); break;
  372. case WM_KEYDOWN: lRes = OnKeyDown (uMsg, wParam, lParam, bHandled); break;
  373. case WM_KILLFOCUS: lRes = OnKillFocus (uMsg, wParam, lParam, bHandled); break;
  374. case WM_SETFOCUS: lRes = OnSetFocus (uMsg, wParam, lParam, bHandled); break;
  375. case WM_LBUTTONUP: lRes = OnLButtonUp (uMsg, wParam, lParam, bHandled); break;
  376. case WM_LBUTTONDOWN: lRes = OnLButtonDown (uMsg, wParam, lParam, bHandled); break;
  377. case WM_MOUSEMOVE: lRes = OnMouseMove (uMsg, wParam, lParam, bHandled); break;
  378. case WM_MOUSEHOVER: lRes = OnMouseHover (uMsg, wParam, lParam, bHandled); break;
  379. default: bHandled = FALSE; break;
  380. }
  381. if(bHandled) return lRes;
  382. lRes = HandleCustomMessage (uMsg, wParam, lParam, bHandled);
  383. if(bHandled) return lRes;
  384. if(m_PaintManager.MessageHandler (uMsg, wParam, lParam, lRes))
  385. return lRes;
  386. return CWindowWnd::HandleMessage (uMsg, wParam, lParam);
  387. }
  388. LRESULT WindowImplBase::HandleCustomMessage (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  389. {
  390. bHandled = FALSE;
  391. return 0;
  392. }
  393. LONG WindowImplBase::GetStyle ()
  394. {
  395. LONG styleValue = ::GetWindowLong (*this, GWL_STYLE);
  396. styleValue &= ~WS_CAPTION;
  397. return styleValue;
  398. }
  399. void WindowImplBase::OnClick (TNotifyUI& msg)
  400. {
  401. CDuiString sCtrlName = msg.pSender->GetName ();
  402. if(sCtrlName == _T ("closebtn"))
  403. {
  404. Close ();
  405. return;
  406. }
  407. else if(sCtrlName == _T ("minbtn"))
  408. {
  409. SendMessage (WM_SYSCOMMAND, SC_MINIMIZE, 0);
  410. return;
  411. }
  412. else if(sCtrlName == _T ("maxbtn"))
  413. {
  414. SendMessage (WM_SYSCOMMAND, SC_MAXIMIZE, 0);
  415. return;
  416. }
  417. else if(sCtrlName == _T ("restorebtn"))
  418. {
  419. SendMessage (WM_SYSCOMMAND, SC_RESTORE, 0);
  420. return;
  421. }
  422. return;
  423. }
  424. void WindowImplBase::Notify (TNotifyUI& msg)
  425. {
  426. return CNotifyPump::NotifyPump (msg);
  427. }
  428. }