CGameFrameWnd.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. #pragma once
  2. #include "pch/pch.h"
  3. class CGameFrameWnd : public CWindowWnd, public INotifyUI, public IListCallbackUI
  4. {
  5. public:
  6. CGameFrameWnd() { };
  7. LPCTSTR GetWindowClassName() const { return _T("UIMainFrame"); };
  8. UINT GetClassStyle() const { return CS_DBLCLKS; };
  9. void OnFinalMessage(HWND /*hWnd*/) { delete this; };
  10. void Init() {
  11. m_pCloseBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("closebtn")));
  12. m_pMaxBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("maxbtn")));
  13. m_pRestoreBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("restorebtn")));
  14. m_pMinBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("minbtn")));
  15. CActiveXUI* pActiveXUI = static_cast<CActiveXUI*>(m_pm.FindControl(_T("ie")));
  16. if (pActiveXUI) {
  17. IWebBrowser2* pWebBrowser = NULL;
  18. pActiveXUI->GetControl(IID_IWebBrowser2, (void**)&pWebBrowser);
  19. if (pWebBrowser != NULL) {
  20. pWebBrowser->Navigate(::SysAllocString(L"https://github.com/duilib/duilib"), NULL, NULL, NULL, NULL);
  21. //pWebBrowser->Navigate(L"about:blank",NULL,NULL,NULL,NULL);
  22. pWebBrowser->Release();
  23. }
  24. }
  25. }
  26. void OnPrepare() {
  27. GameListUI* pGameList = static_cast<GameListUI*>(m_pm.FindControl(_T("gamelist")));
  28. GameListUI::Node* pCategoryNode = NULL;
  29. GameListUI::Node* pGameNode = NULL;
  30. GameListUI::Node* pServerNode = NULL;
  31. GameListUI::Node* pRoomNode = NULL;
  32. pCategoryNode = pGameList->AddNode(_T("{x 4}{i gameicons.png 18 3}{x 4}推荐游戏"));
  33. for (int i = 0; i < 4; ++i)
  34. {
  35. pGameNode = pGameList->AddNode(_T("{x 4}{i gameicons.png 18 10}{x 4}四人斗地主"), pCategoryNode);
  36. for (int i = 0; i < 3; ++i)
  37. {
  38. pServerNode = pGameList->AddNode(_T("{x 4}{i gameicons.png 18 10}{x 4}测试服务器"), pGameNode);
  39. for (int i = 0; i < 3; ++i)
  40. {
  41. pRoomNode = pGameList->AddNode(_T("{x 4}{i gameicons.png 18 10}{x 4}测试房间"), pServerNode);
  42. }
  43. }
  44. }
  45. pCategoryNode = pGameList->AddNode(_T("{x 4}{i gameicons.png 18 3}{x 4}最近玩过的游戏"));
  46. for (int i = 0; i < 2; ++i)
  47. {
  48. pGameList->AddNode(_T("三缺一"), pCategoryNode);
  49. }
  50. pCategoryNode = pGameList->AddNode(_T("{x 4}{i gameicons.png 18 3}{x 4}棋牌游戏"));
  51. for (int i = 0; i < 8; ++i)
  52. {
  53. pGameList->AddNode(_T("双扣"), pCategoryNode);
  54. }
  55. pCategoryNode = pGameList->AddNode(_T("{x 4}{i gameicons.png 18 3}{x 4}休闲游戏"));
  56. for (int i = 0; i < 8; ++i)
  57. {
  58. pGameList->AddNode(_T("飞行棋"), pCategoryNode);
  59. }
  60. CListUI* pUserList = static_cast<CListUI*>(m_pm.FindControl(_T("userlist")));
  61. pUserList->SetTextCallback(this);
  62. for (int i = 0; i < 400; i++) {
  63. CListTextElementUI* pListElement = new CListTextElementUI;
  64. pUserList->Add(pListElement);
  65. }
  66. }
  67. void SendChatMessage() {
  68. CEditUI* pChatEdit = static_cast<CEditUI*>(m_pm.FindControl(_T("chatEdit")));
  69. if (pChatEdit == NULL) return;
  70. pChatEdit->SetFocus();
  71. if (pChatEdit->GetText().IsEmpty()) return;
  72. CRichEditUI* pRichEdit = static_cast<CRichEditUI*>(m_pm.FindControl(_T("chatmsglist")));
  73. if (pRichEdit == NULL) return;
  74. long lSelBegin = 0, lSelEnd = 0;
  75. CHARFORMAT2 cf;
  76. ZeroMemory(&cf, sizeof(CHARFORMAT2));
  77. cf.cbSize = sizeof(cf);
  78. cf.dwReserved = 0;
  79. cf.dwMask = CFM_COLOR;
  80. cf.crTextColor = RGB(220, 0, 0);
  81. lSelEnd = lSelBegin = pRichEdit->GetTextLength();
  82. pRichEdit->SetSel(lSelEnd, lSelEnd);
  83. pRichEdit->ReplaceSel(_T("某人"), false);
  84. lSelEnd = pRichEdit->GetTextLength();
  85. pRichEdit->SetSel(lSelBegin, lSelEnd);
  86. pRichEdit->SetSelectionCharFormat(cf);
  87. lSelBegin = lSelEnd;
  88. pRichEdit->SetSel(-1, -1);
  89. pRichEdit->ReplaceSel(_T("说:"), false);
  90. pRichEdit->SetSel(-1, -1);
  91. pRichEdit->ReplaceSel(pChatEdit->GetText(), false);
  92. pChatEdit->SetText(_T(""));
  93. pRichEdit->SetSel(-1, -1);
  94. pRichEdit->ReplaceSel(_T("\n"), false);
  95. cf.crTextColor = RGB(0, 0, 0);
  96. lSelEnd = pRichEdit->GetTextLength();
  97. pRichEdit->SetSel(lSelBegin, lSelEnd);
  98. pRichEdit->SetSelectionCharFormat(cf);
  99. pRichEdit->EndDown();
  100. }
  101. void Notify(TNotifyUI& msg)
  102. {
  103. if (msg.sType == _T("windowinit")) OnPrepare();
  104. else if (msg.sType == _T("click")) {
  105. if (msg.pSender == m_pCloseBtn) {
  106. COptionUI* pControl = static_cast<COptionUI*>(m_pm.FindControl(_T("hallswitch")));
  107. if (pControl && pControl->IsSelected() == false) {
  108. CControlUI* pFadeControl = m_pm.FindControl(_T("fadeEffect"));
  109. if (pFadeControl) pFadeControl->SetVisible(true);
  110. }
  111. else {
  112. /*Close()*/PostQuitMessage(0); // 因为activex的原因,使用close可能会出现错误
  113. }
  114. return;
  115. }
  116. else if (msg.pSender == m_pMinBtn) { SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0); return; }
  117. else if (msg.pSender == m_pMaxBtn) { SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0); return; }
  118. else if (msg.pSender == m_pRestoreBtn) { SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0); return; }
  119. CDuiString name = msg.pSender->GetName();
  120. if (name == _T("quitbtn")) {
  121. /*Close()*/PostQuitMessage(0); // 因为activex的原因,使用close可能会出现错误
  122. }
  123. else if (name == _T("returnhallbtn")) {
  124. CControlUI* pFadeControl = m_pm.FindControl(_T("fadeEffect"));
  125. if (pFadeControl) pFadeControl->SetVisible(false);
  126. COptionUI* pControl = static_cast<COptionUI*>(m_pm.FindControl(_T("hallswitch")));
  127. pControl->Activate();
  128. pControl = static_cast<COptionUI*>(m_pm.FindControl(_T("roomswitch")));
  129. if (pControl) pControl->SetVisible(false);
  130. }
  131. else if (name == _T("fontswitch")) {
  132. TFontInfo* pFontInfo = m_pm.GetDefaultFontInfo();
  133. if (pFontInfo->iSize < 18) {
  134. TFontInfo* pFontInfo = m_pm.GetFontInfo(0);
  135. if (pFontInfo)m_pm.SetDefaultFont(pFontInfo->sFontName, pFontInfo->iSize, pFontInfo->bBold,
  136. pFontInfo->bUnderline, pFontInfo->bItalic);
  137. }
  138. else {
  139. TFontInfo* pFontInfo = m_pm.GetFontInfo(1);
  140. if (pFontInfo)m_pm.SetDefaultFont(pFontInfo->sFontName, pFontInfo->iSize, pFontInfo->bBold,
  141. pFontInfo->bUnderline, pFontInfo->bItalic);
  142. }
  143. m_pm.GetRoot()->NeedUpdate();
  144. }
  145. else if (name == _T("leaveBtn") || name == _T("roomclosebtn")) {
  146. COptionUI* pControl = static_cast<COptionUI*>(m_pm.FindControl(_T("hallswitch")));
  147. if (pControl) {
  148. pControl->Activate();
  149. pControl = static_cast<COptionUI*>(m_pm.FindControl(_T("roomswitch")));
  150. if (pControl) pControl->SetVisible(false);
  151. }
  152. }
  153. else if (name == _T("sendbtn")) {
  154. SendChatMessage();
  155. }
  156. }
  157. else if (msg.sType == _T("selectchanged")) {
  158. CDuiString name = msg.pSender->GetName();
  159. if (name == _T("hallswitch")) {
  160. CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(m_pm.FindControl(_T("switch")));
  161. if (pControl && pControl->GetCurSel() != 0) pControl->SelectItem(0);
  162. }
  163. else if (name == _T("roomswitch")) {
  164. CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(m_pm.FindControl(_T("switch")));
  165. if (pControl && pControl->GetCurSel() != 1) {
  166. pControl->SelectItem(1);
  167. DeskListUI* pDeskList = static_cast<DeskListUI*>(m_pm.FindControl(_T("destlist")));
  168. pDeskList->SetFocus();
  169. CRichEditUI* pRichEdit = static_cast<CRichEditUI*>(m_pm.FindControl(_T("chatmsglist")));
  170. if (pRichEdit) {
  171. pRichEdit->SetText(_T("欢迎进入XXX游戏,祝游戏愉快!\n\n"));
  172. long lSelBegin = 0, lSelEnd = 0;
  173. CHARFORMAT2 cf;
  174. ZeroMemory(&cf, sizeof(CHARFORMAT2));
  175. cf.cbSize = sizeof(cf);
  176. cf.dwReserved = 0;
  177. cf.dwMask = CFM_COLOR;
  178. cf.crTextColor = RGB(255, 0, 0);
  179. lSelEnd = pRichEdit->GetTextLength();
  180. pRichEdit->SetSel(lSelBegin, lSelEnd);
  181. pRichEdit->SetSelectionCharFormat(cf);
  182. }
  183. }
  184. }
  185. }
  186. else if (msg.sType == _T("itemclick")) {
  187. GameListUI* pGameList = static_cast<GameListUI*>(m_pm.FindControl(_T("gamelist")));
  188. if (pGameList->GetItemIndex(msg.pSender) != -1)
  189. {
  190. if (_tcscmp(msg.pSender->GetClass(), DUI_CTR_LISTLABELELEMENT) == 0) {
  191. GameListUI::Node* node = (GameListUI::Node*)msg.pSender->GetTag();
  192. POINT pt = { 0 };
  193. ::GetCursorPos(&pt);
  194. ::ScreenToClient(m_pm.GetPaintWindow(), &pt);
  195. pt.x -= msg.pSender->GetX();
  196. SIZE sz = pGameList->GetExpanderSizeX(node);
  197. if (pt.x >= sz.cx && pt.x < sz.cy)
  198. pGameList->ExpandNode(node, !node->data()._expand);
  199. }
  200. }
  201. }
  202. else if (msg.sType == _T("itemactivate")) {
  203. GameListUI* pGameList = static_cast<GameListUI*>(m_pm.FindControl(_T("gamelist")));
  204. if (pGameList->GetItemIndex(msg.pSender) != -1)
  205. {
  206. if (_tcscmp(msg.pSender->GetClass(), DUI_CTR_LISTLABELELEMENT) == 0) {
  207. GameListUI::Node* node = (GameListUI::Node*)msg.pSender->GetTag();
  208. pGameList->ExpandNode(node, !node->data()._expand);
  209. if (node->data()._level == 3) {
  210. COptionUI* pControl = static_cast<COptionUI*>(m_pm.FindControl(_T("roomswitch")));
  211. if (pControl) {
  212. pControl->SetVisible(true);
  213. pControl->SetText(node->parent()->parent()->data()._text);
  214. pControl->Activate();
  215. }
  216. }
  217. }
  218. }
  219. }
  220. else if (msg.sType == _T("itemselect")) {
  221. if (msg.pSender->GetName() == _T("chatCombo")) {
  222. CEditUI* pChatEdit = static_cast<CEditUI*>(m_pm.FindControl(_T("chatEdit")));
  223. if (pChatEdit) pChatEdit->SetText(msg.pSender->GetText());
  224. static_cast<CComboUI*>(msg.pSender)->SelectItem(-1);
  225. }
  226. }
  227. else if (msg.sType == _T("return")) {
  228. if (msg.pSender->GetName() == _T("chatEdit")) {
  229. SendChatMessage();
  230. }
  231. }
  232. }
  233. LPCTSTR GetItemText(CControlUI* pControl, int iIndex, int iSubItem)
  234. {
  235. if (pControl->GetParent()->GetParent()->GetName() == _T("userlist")) {
  236. if (iSubItem == 0) return _T("<i vip.png>");
  237. if (iSubItem == 1) return _T("<i vip.png>");
  238. if (iSubItem == 2) return _T("此人昵称");
  239. if (iSubItem == 3) return _T("5");
  240. if (iSubItem == 4) return _T("50%");
  241. if (iSubItem == 5) return _T("0%");
  242. if (iSubItem == 6) return _T("100");
  243. }
  244. return _T("");
  245. }
  246. LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  247. {
  248. LONG styleValue = ::GetWindowLong(*this, GWL_STYLE);
  249. styleValue &= ~WS_CAPTION;
  250. ::SetWindowLong(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
  251. m_pm.Init(m_hWnd);
  252. CDialogBuilder builder;
  253. CDialogBuilderCallbackEx cb;
  254. CControlUI* pRoot = builder.Create(_T("hall.xml"), (UINT)0, &cb, &m_pm);
  255. ASSERT(pRoot && "Failed to parse XML");
  256. m_pm.AttachDialog(pRoot);
  257. m_pm.AddNotifier(this);
  258. Init();
  259. return 0;
  260. }
  261. LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  262. {
  263. bHandled = FALSE;
  264. return 0;
  265. }
  266. LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  267. {
  268. ::PostQuitMessage(0L);
  269. bHandled = FALSE;
  270. return 0;
  271. }
  272. LRESULT OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  273. {
  274. if (::IsIconic(*this)) bHandled = FALSE;
  275. return (wParam == 0) ? TRUE : FALSE;
  276. }
  277. LRESULT OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  278. {
  279. return 0;
  280. }
  281. LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  282. {
  283. return 0;
  284. }
  285. LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  286. {
  287. POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam);
  288. ::ScreenToClient(*this, &pt);
  289. RECT rcClient;
  290. ::GetClientRect(*this, &rcClient);
  291. if (!::IsZoomed(*this)) {
  292. RECT rcSizeBox = m_pm.GetSizeBox();
  293. if (pt.y < rcClient.top + rcSizeBox.top) {
  294. if (pt.x < rcClient.left + rcSizeBox.left) return HTTOPLEFT;
  295. if (pt.x > rcClient.right - rcSizeBox.right) return HTTOPRIGHT;
  296. return HTTOP;
  297. }
  298. else if (pt.y > rcClient.bottom - rcSizeBox.bottom) {
  299. if (pt.x < rcClient.left + rcSizeBox.left) return HTBOTTOMLEFT;
  300. if (pt.x > rcClient.right - rcSizeBox.right) return HTBOTTOMRIGHT;
  301. return HTBOTTOM;
  302. }
  303. if (pt.x < rcClient.left + rcSizeBox.left) return HTLEFT;
  304. if (pt.x > rcClient.right - rcSizeBox.right) return HTRIGHT;
  305. }
  306. RECT rcCaption = m_pm.GetCaptionRect();
  307. if (pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \
  308. && pt.y >= rcCaption.top && pt.y < rcCaption.bottom) {
  309. CControlUI* pControl = static_cast<CControlUI*>(m_pm.FindControl(pt));
  310. if (pControl && _tcscmp(pControl->GetClass(), DUI_CTR_BUTTON) != 0 &&
  311. _tcscmp(pControl->GetClass(), DUI_CTR_OPTION) != 0 &&
  312. _tcscmp(pControl->GetClass(), DUI_CTR_TEXT) != 0)
  313. return HTCAPTION;
  314. }
  315. return HTCLIENT;
  316. }
  317. LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  318. {
  319. SIZE szRoundCorner = m_pm.GetRoundCorner();
  320. if (!::IsIconic(*this) && (szRoundCorner.cx != 0 || szRoundCorner.cy != 0)) {
  321. CDuiRect rcWnd;
  322. ::GetWindowRect(*this, &rcWnd);
  323. rcWnd.Offset(-rcWnd.left, -rcWnd.top);
  324. rcWnd.right++; rcWnd.bottom++;
  325. HRGN hRgn = ::CreateRoundRectRgn(rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom, szRoundCorner.cx, szRoundCorner.cy);
  326. ::SetWindowRgn(*this, hRgn, TRUE);
  327. ::DeleteObject(hRgn);
  328. }
  329. bHandled = FALSE;
  330. return 0;
  331. }
  332. LRESULT OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  333. {
  334. int primaryMonitorWidth = ::GetSystemMetrics(SM_CXSCREEN);
  335. int primaryMonitorHeight = ::GetSystemMetrics(SM_CYSCREEN);
  336. MONITORINFO oMonitor = {};
  337. oMonitor.cbSize = sizeof(oMonitor);
  338. ::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor);
  339. CDuiRect rcWork = oMonitor.rcWork;
  340. rcWork.Offset(-oMonitor.rcMonitor.left, -oMonitor.rcMonitor.top);
  341. if (rcWork.right > primaryMonitorWidth) rcWork.right = primaryMonitorWidth;
  342. if (rcWork.bottom > primaryMonitorHeight) rcWork.right = primaryMonitorHeight;
  343. LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam;
  344. lpMMI->ptMaxPosition.x = rcWork.left;
  345. lpMMI->ptMaxPosition.y = rcWork.top;
  346. lpMMI->ptMaxSize.x = rcWork.right;
  347. lpMMI->ptMaxSize.y = rcWork.bottom;
  348. bHandled = FALSE;
  349. return 0;
  350. }
  351. LRESULT OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  352. {
  353. // 有时会在收到WM_NCDESTROY后收到wParam为SC_CLOSE的WM_SYSCOMMAND
  354. if (wParam == SC_CLOSE) {
  355. ::PostQuitMessage(0L);
  356. bHandled = TRUE;
  357. return 0;
  358. }
  359. BOOL bZoomed = ::IsZoomed(*this);
  360. LRESULT lRes = CWindowWnd::HandleMessage(uMsg, wParam, lParam);
  361. if (::IsZoomed(*this) != bZoomed) {
  362. if (!bZoomed) {
  363. CControlUI* pControl = static_cast<CControlUI*>(m_pm.FindControl(_T("maxbtn")));
  364. if (pControl) pControl->SetVisible(false);
  365. pControl = static_cast<CControlUI*>(m_pm.FindControl(_T("restorebtn")));
  366. if (pControl) pControl->SetVisible(true);
  367. }
  368. else {
  369. CControlUI* pControl = static_cast<CControlUI*>(m_pm.FindControl(_T("maxbtn")));
  370. if (pControl) pControl->SetVisible(true);
  371. pControl = static_cast<CControlUI*>(m_pm.FindControl(_T("restorebtn")));
  372. if (pControl) pControl->SetVisible(false);
  373. }
  374. }
  375. return lRes;
  376. }
  377. LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
  378. {
  379. LRESULT lRes = 0;
  380. BOOL bHandled = TRUE;
  381. switch (uMsg) {
  382. case WM_CREATE: lRes = OnCreate(uMsg, wParam, lParam, bHandled); break;
  383. case WM_CLOSE: lRes = OnClose(uMsg, wParam, lParam, bHandled); break;
  384. case WM_DESTROY: lRes = OnDestroy(uMsg, wParam, lParam, bHandled); break;
  385. case WM_NCACTIVATE: lRes = OnNcActivate(uMsg, wParam, lParam, bHandled); break;
  386. case WM_NCCALCSIZE: lRes = OnNcCalcSize(uMsg, wParam, lParam, bHandled); break;
  387. case WM_NCPAINT: lRes = OnNcPaint(uMsg, wParam, lParam, bHandled); break;
  388. case WM_NCHITTEST: lRes = OnNcHitTest(uMsg, wParam, lParam, bHandled); break;
  389. case WM_SIZE: lRes = OnSize(uMsg, wParam, lParam, bHandled); break;
  390. case WM_GETMINMAXINFO: lRes = OnGetMinMaxInfo(uMsg, wParam, lParam, bHandled); break;
  391. case WM_SYSCOMMAND: lRes = OnSysCommand(uMsg, wParam, lParam, bHandled); break;
  392. default:
  393. bHandled = FALSE;
  394. }
  395. if (bHandled) return lRes;
  396. if (m_pm.MessageHandler(uMsg, wParam, lParam, lRes)) return lRes;
  397. return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
  398. }
  399. public:
  400. CPaintManagerUI m_pm;
  401. private:
  402. CButtonUI* m_pCloseBtn;
  403. CButtonUI* m_pMaxBtn;
  404. CButtonUI* m_pRestoreBtn;
  405. CButtonUI* m_pMinBtn;
  406. //...
  407. };