winmini.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #ifdef AFX_CORE4_SEG
  12. #pragma code_seg(AFX_CORE4_SEG)
  13. #endif
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. #pragma warning(disable: 4706) // assignment within conditional
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CMiniFrameWnd global data
  21. AFX_STATIC_DATA HBITMAP _afx_hbmMiniSys = 0;
  22. AFX_STATIC_DATA HFONT _afx_hfontMiniSys = 0;
  23. AFX_STATIC_DATA SIZE _afx_sizeMiniSys = { 0, 0 };
  24. void AFX_CDECL _AfxWinminiTerm()
  25. {
  26. AfxDeleteObject((HGDIOBJ*)&_afx_hbmMiniSys);
  27. AfxDeleteObject((HGDIOBJ*)&_afx_hfontMiniSys);
  28. }
  29. int _afxWinminiTerm = atexit(_AfxWinminiTerm);
  30. /////////////////////////////////////////////////////////////////////////////
  31. // CMiniFrameWnd
  32. BEGIN_MESSAGE_MAP(CMiniFrameWnd, CFrameWnd)
  33. //{{AFX_MSG_MAP(CMiniFrameWnd)
  34. ON_WM_NCPAINT()
  35. ON_WM_NCACTIVATE()
  36. ON_WM_NCCALCSIZE()
  37. ON_WM_NCHITTEST()
  38. ON_WM_NCLBUTTONDOWN()
  39. ON_WM_MOUSEMOVE()
  40. ON_WM_LBUTTONUP()
  41. ON_WM_SYSCOMMAND()
  42. ON_WM_GETMINMAXINFO()
  43. ON_WM_NCCREATE()
  44. ON_MESSAGE(WM_GETTEXT, OnGetText)
  45. ON_MESSAGE(WM_GETTEXTLENGTH, OnGetTextLength)
  46. ON_MESSAGE(WM_SETTEXT, OnSetText)
  47. ON_MESSAGE(WM_FLOATSTATUS, OnFloatStatus)
  48. ON_MESSAGE(WM_QUERYCENTERWND, OnQueryCenterWnd)
  49. //}}AFX_MSG_MAP
  50. END_MESSAGE_MAP()
  51. #define new DEBUG_NEW
  52. /////////////////////////////////////////////////////////////////////////////
  53. // CMiniFrameWnd constructors
  54. CMiniFrameWnd::CMiniFrameWnd()
  55. {
  56. m_bActive = FALSE;
  57. Initialize();
  58. }
  59. void AFX_CDECL CMiniFrameWnd::Initialize()
  60. {
  61. // initialization not required if running latest Windows
  62. if (afxData.bSmCaption)
  63. return;
  64. AfxLockGlobals(CRIT_MINIFRAMEWND);
  65. if (_afx_hbmMiniSys == NULL)
  66. {
  67. HINSTANCE hInst = AfxFindResourceHandle(
  68. MAKEINTRESOURCE(AFX_IDB_MINIFRAME_MENU), RT_BITMAP);
  69. VERIFY(_afx_hbmMiniSys =
  70. LoadBitmap(hInst, MAKEINTRESOURCE(AFX_IDB_MINIFRAME_MENU)));
  71. BITMAP bmStruct;
  72. if (::GetObject(_afx_hbmMiniSys, sizeof(BITMAP), &bmStruct))
  73. {
  74. _afx_sizeMiniSys.cx = bmStruct.bmWidth;
  75. _afx_sizeMiniSys.cy = bmStruct.bmHeight;
  76. }
  77. }
  78. if (_afx_hfontMiniSys == NULL)
  79. {
  80. LOGFONT logFont; memset(&logFont, 0, sizeof(LOGFONT));
  81. logFont.lfHeight = -(_afx_sizeMiniSys.cy-1);
  82. logFont.lfCharSet = DEFAULT_CHARSET;
  83. logFont.lfWeight = FW_NORMAL;
  84. if (GetSystemMetrics(SM_DBCSENABLED))
  85. lstrcpy(logFont.lfFaceName, _T("Terminal"));
  86. else
  87. lstrcpy(logFont.lfFaceName, _T("Small Fonts"));
  88. if (!AfxCustomLogFont(AFX_IDS_MINI_FONT, &logFont))
  89. logFont.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
  90. _afx_hfontMiniSys = ::CreateFontIndirect(&logFont);
  91. }
  92. if (_afx_hfontMiniSys != NULL)
  93. {
  94. CClientDC dc(NULL);
  95. TEXTMETRIC tm;
  96. HFONT hFontOld = (HFONT)dc.SelectObject(_afx_hfontMiniSys);
  97. BOOL bResult = dc.GetTextMetrics(&tm);
  98. dc.SelectObject(hFontOld);
  99. if (!bResult || tm.tmHeight - tm.tmInternalLeading > _afx_sizeMiniSys.cy)
  100. AfxDeleteObject((HGDIOBJ*)&_afx_hfontMiniSys);
  101. }
  102. AfxUnlockGlobals(CRIT_MINIFRAMEWND);
  103. }
  104. CMiniFrameWnd::~CMiniFrameWnd()
  105. {
  106. DestroyWindow();
  107. }
  108. BOOL CMiniFrameWnd::Create(LPCTSTR lpClassName, LPCTSTR lpszWindowName,
  109. DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
  110. {
  111. return CMiniFrameWnd::CreateEx(0, lpClassName, lpszWindowName, dwStyle,
  112. rect, pParentWnd, nID);
  113. }
  114. BOOL CMiniFrameWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpClassName,
  115. LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect,
  116. CWnd* pParentWnd, UINT nID)
  117. {
  118. m_strCaption = lpszWindowName;
  119. return CWnd::CreateEx(dwExStyle, lpClassName ? lpClassName :
  120. AfxRegisterWndClass(CS_DBLCLKS, ::LoadCursor(NULL, IDC_ARROW)),
  121. lpszWindowName, dwStyle, rect.left, rect.top, rect.right - rect.left,
  122. rect.bottom - rect.top, pParentWnd->GetSafeHwnd(), (HMENU)nID);
  123. }
  124. /////////////////////////////////////////////////////////////////////////////
  125. // CMiniFrameWnd message handlers
  126. BOOL CMiniFrameWnd::OnNcCreate(LPCREATESTRUCT lpcs)
  127. {
  128. if (!CFrameWnd::OnNcCreate(lpcs))
  129. return FALSE;
  130. if (GetStyle() & MFS_SYNCACTIVE)
  131. {
  132. // syncronize activation state with top level parent
  133. CWnd* pParentWnd = GetTopLevelParent();
  134. ASSERT(pParentWnd != NULL);
  135. CWnd* pActiveWnd = GetForegroundWindow();
  136. BOOL bActive = (pParentWnd == pActiveWnd) ||
  137. (pParentWnd->GetLastActivePopup() == pActiveWnd &&
  138. pActiveWnd->SendMessage(WM_FLOATSTATUS, FS_SYNCACTIVE) != 0);
  139. // the WM_FLOATSTATUS does the actual work
  140. SendMessage(WM_FLOATSTATUS, bActive ? FS_ACTIVATE : FS_DEACTIVATE);
  141. }
  142. return TRUE;
  143. }
  144. BOOL CMiniFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
  145. {
  146. if (afxData.bSmCaption)
  147. {
  148. // WS_4THICKFRAME and MFS_THICKFRAME imply WS_THICKFRAME
  149. if (cs.style & (MFS_4THICKFRAME | MFS_THICKFRAME))
  150. cs.style |= WS_THICKFRAME;
  151. // WS_CAPTION implies WS_EX_TOOLWINDOW
  152. if (cs.style & WS_CAPTION)
  153. cs.dwExStyle |= WS_EX_TOOLWINDOW;
  154. }
  155. VERIFY(CFrameWnd::PreCreateWindow(cs));
  156. cs.dwExStyle &= ~(WS_EX_CLIENTEDGE);
  157. return TRUE;
  158. }
  159. void CMiniFrameWnd::OnGetMinMaxInfo(MINMAXINFO* pMMI)
  160. {
  161. // allow Windows to fill in the defaults
  162. CFrameWnd::OnGetMinMaxInfo(pMMI);
  163. // don't allow sizing smaller than the non-client area
  164. CRect rectWindow, rectClient;
  165. GetWindowRect(rectWindow);
  166. GetClientRect(rectClient);
  167. pMMI->ptMinTrackSize.x = rectWindow.Width() - rectClient.right;
  168. pMMI->ptMinTrackSize.y = rectWindow.Height() - rectClient.bottom;
  169. }
  170. BOOL CMiniFrameWnd::OnNcActivate(BOOL bActive)
  171. {
  172. if ((GetStyle() & MFS_SYNCACTIVE) == 0)
  173. {
  174. if (afxData.bSmCaption)
  175. return Default();
  176. if (m_bActive != bActive)
  177. {
  178. m_bActive = bActive;
  179. SendMessage(WM_NCPAINT);
  180. }
  181. }
  182. else if(m_nFlags & WF_KEEPMINIACTIVE)
  183. {
  184. return FALSE;
  185. }
  186. return TRUE;
  187. }
  188. void CMiniFrameWnd::OnNcCalcSize(BOOL, NCCALCSIZE_PARAMS *lpParams)
  189. {
  190. if (afxData.bSmCaption)
  191. {
  192. Default();
  193. return;
  194. }
  195. // Modify the first rectangle in rgrc.
  196. LONG dwStyle = GetStyle();
  197. if (dwStyle & (MFS_4THICKFRAME | MFS_THICKFRAME | WS_THICKFRAME))
  198. {
  199. ::InflateRect(lpParams->rgrc,
  200. -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME));
  201. }
  202. else
  203. {
  204. ::InflateRect(lpParams->rgrc,
  205. -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
  206. }
  207. if (dwStyle & WS_CAPTION)
  208. lpParams->rgrc[0].top += _afx_sizeMiniSys.cy;
  209. }
  210. UINT CMiniFrameWnd::OnNcHitTest(CPoint point)
  211. {
  212. DWORD dwStyle = GetStyle();
  213. CRect rectWindow;
  214. GetWindowRect(&rectWindow);
  215. CSize sizeFrame(GetSystemMetrics(SM_CXFRAME),
  216. GetSystemMetrics(SM_CYFRAME));
  217. if (afxData.bSmCaption)
  218. {
  219. UINT nHit = CFrameWnd::OnNcHitTest(point);
  220. // MFS_BLOCKSYSMENU translates system menu hit to caption hit
  221. if (afxData.bWin4 && (dwStyle & MFS_BLOCKSYSMENU))
  222. {
  223. if (nHit == HTSYSMENU)
  224. nHit = HTCAPTION;
  225. if (GetKeyState(VK_RBUTTON) < 0)
  226. return HTNOWHERE;
  227. }
  228. if ((nHit < HTSIZEFIRST || nHit > HTSIZELAST) && nHit != HTGROWBOX)
  229. return nHit;
  230. // MFS_MOVEFRAME translates all size requests to move requests
  231. if (dwStyle & MFS_MOVEFRAME)
  232. return HTCAPTION;
  233. // MFS_4THICKFRAME does not allow diagonal sizing
  234. rectWindow.InflateRect(-sizeFrame.cx, -sizeFrame.cy);
  235. if (dwStyle & MFS_4THICKFRAME)
  236. {
  237. switch (nHit)
  238. {
  239. case HTTOPLEFT:
  240. return point.y < rectWindow.top ? HTTOP : HTLEFT;
  241. case HTTOPRIGHT:
  242. return point.y < rectWindow.top ? HTTOP : HTRIGHT;
  243. case HTBOTTOMLEFT:
  244. return point.y > rectWindow.bottom ? HTBOTTOM : HTLEFT;
  245. case HTGROWBOX:
  246. case HTBOTTOMRIGHT:
  247. return point.y > rectWindow.bottom ? HTBOTTOM : HTRIGHT;
  248. }
  249. }
  250. return nHit; // no special translation
  251. }
  252. if (!rectWindow.PtInRect(point))
  253. return (UINT)HTNOWHERE;
  254. CSize sizeBorder(GetSystemMetrics(SM_CXBORDER),
  255. GetSystemMetrics(SM_CYBORDER));
  256. NCCALCSIZE_PARAMS Params;
  257. Params.rgrc[0].top = rectWindow.top;
  258. Params.rgrc[0].left = rectWindow.left;
  259. Params.rgrc[0].bottom = rectWindow.bottom;
  260. Params.rgrc[0].right = rectWindow.right;
  261. OnNcCalcSize(FALSE, &Params);
  262. CRect rcClient(Params.rgrc);
  263. if (rcClient.PtInRect(point))
  264. return HTCLIENT;
  265. if (dwStyle & (MFS_4THICKFRAME | MFS_THICKFRAME | WS_THICKFRAME))
  266. {
  267. UINT ht = HTNOWHERE;
  268. CSize sizeOffset(sizeFrame.cx + _afx_sizeMiniSys.cx - sizeBorder.cx * 3,
  269. sizeFrame.cy + _afx_sizeMiniSys.cy - sizeBorder.cy * 2);
  270. if (point.y < rectWindow.top + sizeFrame.cy)
  271. {
  272. if (dwStyle & MFS_4THICKFRAME)
  273. ht = HTTOP;
  274. else if (point.x <= rectWindow.left + sizeOffset.cx)
  275. ht = HTTOPLEFT;
  276. else if (point.x >= rectWindow.right - sizeOffset.cx)
  277. ht = HTTOPRIGHT;
  278. else
  279. ht = HTTOP;
  280. }
  281. else if (point.y >= rectWindow.bottom - sizeFrame.cy)
  282. {
  283. if (dwStyle & MFS_4THICKFRAME)
  284. ht = HTBOTTOM;
  285. else if (point.x <= rectWindow.left + sizeOffset.cx)
  286. ht = HTBOTTOMLEFT;
  287. else if (point.x >= rectWindow.right - sizeOffset.cx)
  288. ht = HTBOTTOMRIGHT;
  289. else
  290. ht = HTBOTTOM;
  291. }
  292. else if (point.x < rectWindow.left + sizeFrame.cx)
  293. {
  294. if (dwStyle & MFS_4THICKFRAME)
  295. ht = HTLEFT;
  296. else if (point.y <= rectWindow.top + sizeOffset.cy)
  297. ht = HTTOPLEFT;
  298. else if (point.y >= rectWindow.bottom - sizeOffset.cy)
  299. ht = HTBOTTOMLEFT;
  300. else
  301. ht = HTLEFT;
  302. }
  303. else if (point.x >= rectWindow.right - sizeFrame.cx)
  304. {
  305. if (dwStyle & MFS_4THICKFRAME)
  306. ht = HTRIGHT;
  307. else if (point.y <= rectWindow.top + sizeOffset.cy)
  308. ht = HTTOPRIGHT;
  309. else if (point.y >= rectWindow.bottom - sizeOffset.cy)
  310. ht = HTBOTTOMRIGHT;
  311. else
  312. ht = HTRIGHT;
  313. }
  314. if (ht != HTNOWHERE)
  315. return (dwStyle & MFS_MOVEFRAME) ? HTCAPTION : ht;
  316. rectWindow.InflateRect(-sizeFrame.cx, -sizeFrame.cy);
  317. }
  318. rectWindow.bottom = rectWindow.top + _afx_sizeMiniSys.cy + sizeBorder.cy;
  319. if (rectWindow.PtInRect(point))
  320. {
  321. if (point.x < rectWindow.left + (_afx_sizeMiniSys.cx - 2) &&
  322. (dwStyle & WS_SYSMENU))
  323. return HTSYSMENU;
  324. return HTCAPTION;
  325. }
  326. return (UINT)HTERROR;
  327. }
  328. void CMiniFrameWnd::OnNcLButtonDown(UINT nHitTest, CPoint pt)
  329. {
  330. if (afxData.bSmCaption || nHitTest != HTSYSMENU)
  331. {
  332. CFrameWnd::OnNcLButtonDown(nHitTest, pt);
  333. return;
  334. }
  335. m_bSysTracking = TRUE;
  336. m_bInSys = TRUE;
  337. SetCapture();
  338. InvertSysMenu();
  339. }
  340. void CMiniFrameWnd::OnMouseMove(UINT /*nFlags*/, CPoint pt)
  341. {
  342. if (!m_bSysTracking)
  343. {
  344. Default();
  345. return;
  346. }
  347. ClientToScreen(&pt);
  348. if (GetCapture() != this)
  349. {
  350. m_bSysTracking = FALSE;
  351. SendMessage(WM_NCPAINT);
  352. }
  353. else if ((OnNcHitTest(pt) == HTSYSMENU) != m_bInSys)
  354. {
  355. m_bInSys = !m_bInSys;
  356. InvertSysMenu();
  357. }
  358. }
  359. void CMiniFrameWnd::OnLButtonUp(UINT /*nFlags*/, CPoint pt)
  360. {
  361. if (!m_bSysTracking)
  362. {
  363. Default();
  364. return;
  365. }
  366. ReleaseCapture();
  367. m_bSysTracking = FALSE;
  368. ClientToScreen(&pt);
  369. if (OnNcHitTest(pt) == HTSYSMENU)
  370. {
  371. InvertSysMenu();
  372. SendMessage(WM_CLOSE);
  373. }
  374. }
  375. void CMiniFrameWnd::InvertSysMenu()
  376. {
  377. CSize sizeBorder(GetSystemMetrics(SM_CXBORDER),
  378. GetSystemMetrics(SM_CYBORDER));
  379. CSize sizeFrame(GetSystemMetrics(SM_CXFRAME),
  380. GetSystemMetrics(SM_CYFRAME));
  381. CRect rect(sizeBorder.cx, sizeBorder.cy,
  382. _afx_sizeMiniSys.cx - sizeBorder.cx, _afx_sizeMiniSys.cy);
  383. if (GetStyle() & (MFS_4THICKFRAME | MFS_THICKFRAME | WS_THICKFRAME))
  384. rect.OffsetRect(sizeFrame.cx - sizeBorder.cx, sizeFrame.cy - sizeBorder.cy);
  385. CDC* pDC = GetWindowDC();
  386. pDC->InvertRect(rect);
  387. ReleaseDC(pDC);
  388. }
  389. // _AfxDrawFrame: [static]
  390. // Draws a frame in a given brush, with a given width for the lines.
  391. // Works like the doors to a cabinet: two tall stiles up and down the sides
  392. // and two short spacers across the top and bottom. The thickness of the
  393. // lines are painted inside the rectangle.
  394. //
  395. AFX_STATIC void AFXAPI
  396. _AfxDrawFrame(CDC* dc, LPCRECT lpRect, int nWidth, int nHeight, CBrush& br)
  397. {
  398. CRect rect;
  399. // left stile
  400. rect = *lpRect;
  401. rect.right = rect.left + nWidth;
  402. dc->FillRect(rect, &br);
  403. // right stile
  404. rect.right = lpRect->right;
  405. rect.left = rect.right - nWidth;
  406. dc->FillRect(rect, &br);
  407. // top spacer
  408. rect = *lpRect;
  409. rect.bottom = rect.top + nHeight;
  410. rect.left += nWidth;
  411. rect.right -= nWidth;
  412. dc->FillRect(rect, &br);
  413. // bottom spacer
  414. rect.bottom = lpRect->bottom;
  415. rect.top = rect.bottom - nHeight;
  416. dc->FillRect(rect, &br);
  417. }
  418. void CMiniFrameWnd::OnNcPaint()
  419. {
  420. if (afxData.bSmCaption)
  421. {
  422. Default();
  423. return;
  424. }
  425. // Prepare for drawing the non-client area of the mini frame
  426. CWindowDC dc(this);
  427. CRect rect, rectCaption;
  428. LONG dwStyle = GetStyle();
  429. GetWindowRect(&rect);
  430. rect.OffsetRect(-rect.left, -rect.top);
  431. // Create brushes we might need.
  432. CBrush brFrame;
  433. brFrame.CreateSolidBrush(::GetSysColor(COLOR_WINDOWFRAME));
  434. CBrush brBorder;
  435. brBorder.CreateSolidBrush(::GetSysColor(m_bActive ?
  436. COLOR_ACTIVEBORDER : COLOR_INACTIVEBORDER));
  437. CBrush brCaption;
  438. brCaption.CreateSolidBrush(::GetSysColor(m_bActive ?
  439. COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
  440. CSize sizeBorder(GetSystemMetrics(SM_CXBORDER),
  441. GetSystemMetrics(SM_CYBORDER));
  442. CSize sizeFrame(GetSystemMetrics(SM_CXFRAME),
  443. GetSystemMetrics(SM_CYFRAME));
  444. // Draw the thickframe. Remove it from the rect.
  445. if (dwStyle & (MFS_4THICKFRAME | WS_THICKFRAME | MFS_THICKFRAME))
  446. {
  447. _AfxDrawFrame(&dc, rect, sizeBorder.cx, sizeBorder.cy, brFrame);
  448. rect.InflateRect(-sizeBorder.cx, -sizeBorder.cy);
  449. _AfxDrawFrame(&dc, rect, sizeFrame.cx - sizeBorder.cx,
  450. sizeFrame.cy - sizeBorder.cy, brBorder);
  451. CSize sizeTick(sizeFrame.cx - sizeBorder.cx * 2,
  452. sizeFrame.cy - sizeBorder.cy * 2);
  453. if (!(dwStyle & MFS_4THICKFRAME))
  454. {
  455. CSize sizeOffset(sizeFrame.cx + _afx_sizeMiniSys.cx - sizeBorder.cx * 3,
  456. sizeFrame.cy + _afx_sizeMiniSys.cy - sizeBorder.cy * 2);
  457. dc.FillSolidRect(rect.left, rect.top + sizeOffset.cy,
  458. sizeTick.cx, 1, RGB(0, 0, 0));
  459. dc.FillSolidRect(rect.left, rect.bottom - sizeOffset.cy,
  460. sizeTick.cx, 1, RGB(0, 0, 0));
  461. dc.FillSolidRect(rect.right - sizeTick.cx,
  462. rect.top + sizeOffset.cy, sizeTick.cx, 1, RGB(0, 0, 0));
  463. dc.FillSolidRect(rect.right - sizeTick.cx,
  464. rect.bottom - sizeOffset.cy, sizeTick.cx, 1, RGB(0, 0, 0));
  465. dc.FillSolidRect(rect.left + sizeOffset.cx, rect.top,
  466. 1, sizeTick.cy, RGB(0, 0, 0));
  467. dc.FillSolidRect(rect.right - sizeOffset.cx, rect.top,
  468. 1, sizeTick.cy, RGB(0, 0, 0));
  469. dc.FillSolidRect(rect.left + sizeOffset.cx,
  470. rect.bottom - sizeTick.cy, 1, sizeTick.cy, RGB(0, 0, 0));
  471. dc.FillSolidRect(rect.right - sizeOffset.cx,
  472. rect.bottom - sizeTick.cy, 1, sizeTick.cy, RGB(0, 0, 0));
  473. }
  474. rect.InflateRect(-sizeTick.cx, -sizeTick.cy);
  475. }
  476. // Draw the caption. Remove it from rect.
  477. if (dwStyle & WS_CAPTION)
  478. {
  479. rectCaption = rect;
  480. rectCaption.bottom = rectCaption.top + _afx_sizeMiniSys.cy + sizeBorder.cy;
  481. _AfxDrawFrame(&dc, rectCaption, sizeBorder.cx, sizeBorder.cy, brFrame);
  482. rectCaption.InflateRect(-sizeBorder.cx, -sizeBorder.cy);
  483. dc.FillRect(&rectCaption, &brCaption);
  484. // Draw the border around the client area.
  485. // At this point, rc==rcClient.InflateRect(cxBorder, cyBorder).
  486. //
  487. _AfxDrawFrame(&dc, rect, sizeBorder.cx, sizeBorder.cy, brFrame);
  488. if (_afx_hfontMiniSys != NULL)
  489. {
  490. HFONT hFontOld = (HFONT)dc.SelectObject(_afx_hfontMiniSys);
  491. CString strTitle;
  492. GetWindowText(strTitle);
  493. int xLeft = rectCaption.left +
  494. (dwStyle & WS_SYSMENU ? _afx_sizeMiniSys.cx : 0);
  495. CSize sizeText = dc.GetTextExtent(strTitle, strTitle.GetLength());
  496. if (sizeText.cx <= rectCaption.Width())
  497. {
  498. dc.SetTextAlign(TA_CENTER);
  499. xLeft += (rectCaption.right - xLeft) / 2;
  500. }
  501. TEXTMETRIC tm;
  502. VERIFY(dc.GetTextMetrics(&tm));
  503. int yHeight = tm.tmAscent + tm.tmDescent + tm.tmInternalLeading;
  504. rectCaption.InflateRect(0, 1);
  505. int yHeightDiff = (rectCaption.Height() - yHeight + 1) / 2;
  506. dc.SetTextColor(::GetSysColor(m_bActive ?
  507. COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT));
  508. dc.SetBkMode(TRANSPARENT);
  509. dc.ExtTextOut(xLeft, rectCaption.top + yHeightDiff, ETO_CLIPPED,
  510. rectCaption, strTitle, strTitle.GetLength(), NULL);
  511. dc.SelectObject(hFontOld);
  512. }
  513. // Draw the system menu.
  514. if (dwStyle & WS_SYSMENU)
  515. {
  516. CDC dcBitmap;
  517. HBITMAP hBitmapOld;
  518. if (!dcBitmap.CreateCompatibleDC(&dc))
  519. return;
  520. hBitmapOld = (HBITMAP)dcBitmap.SelectObject(_afx_hbmMiniSys);
  521. dc.BitBlt(rect.left, rect.top, _afx_sizeMiniSys.cx, _afx_sizeMiniSys.cy,
  522. &dcBitmap, 0, 0, SRCCOPY);
  523. dcBitmap.SelectObject(hBitmapOld);
  524. }
  525. rect.top = rectCaption.bottom;
  526. }
  527. else
  528. {
  529. // Draw the border around the client area.
  530. // At this point, rect == rcClient.InflateRect(cxBorder, cyBorder).
  531. _AfxDrawFrame(&dc, rect, sizeBorder.cx, sizeBorder.cy, brFrame);
  532. }
  533. }
  534. void CMiniFrameWnd::OnSysCommand(UINT nID, LPARAM lParam)
  535. {
  536. DWORD dwStyle = GetStyle();
  537. if ((dwStyle & WS_POPUP) &&
  538. ((nID & 0xFFF0) != SC_CLOSE ||
  539. (GetKeyState(VK_F4) < 0 && GetKeyState(VK_MENU) < 0 &&
  540. (dwStyle & MFS_SYNCACTIVE))))
  541. {
  542. if (HandleFloatingSysCommand(nID, lParam))
  543. return;
  544. }
  545. CFrameWnd::OnSysCommand(nID, lParam);
  546. }
  547. void CMiniFrameWnd::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType)
  548. {
  549. if (afxData.bSmCaption)
  550. {
  551. CFrameWnd::CalcWindowRect(lpClientRect, nAdjustType);
  552. return;
  553. }
  554. LONG dwStyle = GetStyle();
  555. if (dwStyle & (MFS_4THICKFRAME | WS_THICKFRAME | MFS_THICKFRAME))
  556. {
  557. ::InflateRect(lpClientRect,
  558. GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));
  559. }
  560. else
  561. {
  562. ::InflateRect(lpClientRect,
  563. GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
  564. }
  565. if (dwStyle & WS_CAPTION)
  566. lpClientRect->top -= _afx_sizeMiniSys.cy;
  567. }
  568. void PASCAL CMiniFrameWnd::CalcBorders(
  569. LPRECT lpClientRect, DWORD dwStyle, DWORD dwExStyle)
  570. {
  571. UNUSED_ALWAYS(dwExStyle);
  572. if (afxData.bSmCaption)
  573. {
  574. AdjustWindowRectEx(lpClientRect, dwStyle, FALSE, WS_EX_PALETTEWINDOW);
  575. return;
  576. }
  577. if (dwStyle & (MFS_4THICKFRAME | WS_THICKFRAME | MFS_THICKFRAME))
  578. {
  579. ::InflateRect(lpClientRect,
  580. GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));
  581. }
  582. else
  583. {
  584. ::InflateRect(lpClientRect,
  585. GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
  586. }
  587. if (dwStyle & WS_CAPTION)
  588. {
  589. Initialize();
  590. lpClientRect->top -= _afx_sizeMiniSys.cy;
  591. }
  592. }
  593. LRESULT CMiniFrameWnd::OnGetText(WPARAM wParam, LPARAM lParam)
  594. {
  595. if (afxData.bSmCaption)
  596. return Default();
  597. lstrcpyn((LPTSTR)lParam, (LPCTSTR)m_strCaption, wParam);
  598. if ((int)wParam > m_strCaption.GetLength())
  599. wParam = m_strCaption.GetLength();
  600. return wParam;
  601. }
  602. LRESULT CMiniFrameWnd::OnGetTextLength(WPARAM, LPARAM)
  603. {
  604. if (afxData.bSmCaption)
  605. return Default();
  606. return m_strCaption.GetLength();
  607. }
  608. // CMiniFrameWnd::OnSetText
  609. // Windows will repaint just the caption, as a thick caption, if
  610. // we don't override WM_SETTEXT. NOTE: Unfortunately, this will never
  611. // get called if you do a SetWindowText() on this window from another
  612. // task. Use SendMessage instead.
  613. LRESULT CMiniFrameWnd::OnSetText(WPARAM, LPARAM lParam)
  614. {
  615. if (afxData.bSmCaption)
  616. return Default();
  617. TRY
  618. {
  619. if (lParam == NULL)
  620. {
  621. // NULL lParam means set caption to nothing
  622. m_strCaption.Empty();
  623. }
  624. else
  625. {
  626. // non-NULL sets caption to that specified by lParam
  627. lstrcpy(m_strCaption.GetBufferSetLength(lstrlen((LPCTSTR)lParam)),
  628. (LPCTSTR)lParam);
  629. }
  630. SendMessage(WM_NCPAINT);
  631. }
  632. CATCH_ALL(e)
  633. {
  634. // Note: DELETE_EXCEPTION(e) not required
  635. return FALSE;
  636. }
  637. END_CATCH_ALL
  638. return TRUE;
  639. }
  640. LRESULT CMiniFrameWnd::OnFloatStatus(WPARAM wParam, LPARAM)
  641. {
  642. // these asserts make sure no conflicting actions are requested
  643. ASSERT(!((wParam & FS_SHOW) && (wParam & FS_HIDE)));
  644. ASSERT(!((wParam & FS_ENABLE) && (wParam & FS_DISABLE)));
  645. ASSERT(!((wParam & FS_ACTIVATE) && (wParam & FS_DEACTIVATE)));
  646. // FS_SYNCACTIVE is used to detect MFS_SYNCACTIVE windows
  647. LRESULT lResult = 0;
  648. if ((GetStyle() & MFS_SYNCACTIVE) && (wParam & FS_SYNCACTIVE))
  649. lResult = 1;
  650. if (wParam & (FS_SHOW|FS_HIDE))
  651. {
  652. SetWindowPos(NULL, 0, 0, 0, 0,
  653. ((wParam & FS_SHOW) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW) | SWP_NOZORDER |
  654. SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
  655. }
  656. if (wParam & (FS_ENABLE|FS_DISABLE))
  657. EnableWindow((wParam & FS_ENABLE) != 0);
  658. if ((wParam & (FS_ACTIVATE|FS_DEACTIVATE)) &&
  659. GetStyle() & MFS_SYNCACTIVE)
  660. {
  661. ModifyStyle(MFS_SYNCACTIVE, 0);
  662. SendMessage(WM_NCACTIVATE, (wParam & FS_ACTIVATE) != 0);
  663. ModifyStyle(0, MFS_SYNCACTIVE);
  664. }
  665. return lResult;
  666. }
  667. LRESULT CMiniFrameWnd::OnQueryCenterWnd(WPARAM, LPARAM)
  668. {
  669. // forward WM_QUERYCENTERWND to parent window
  670. HWND hWndParent = ::GetParent(m_hWnd);
  671. LRESULT lResult = ::SendMessage(hWndParent, WM_QUERYCENTERWND, 0, 0);
  672. if (lResult == 0)
  673. lResult = (LRESULT)hWndParent;
  674. return lResult;
  675. }
  676. #ifdef AFX_INIT_SEG
  677. #pragma code_seg(AFX_INIT_SEG)
  678. #endif
  679. IMPLEMENT_DYNCREATE(CMiniFrameWnd, CFrameWnd)
  680. ////////////////////////////////////////////////////////////////////////////