SingleLineCaption.cpp
上传用户:zhoushen
上传日期:2022-06-15
资源大小:84k
文件大小:4k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. ////////////////////////////////////////////////////////////////
  2. //
  3. // class CSingleLineCaption
  4. //
  5. // Generic caption painter. Handles WM_NCPAINT, WM_NCACTIVATE, etc. to
  6. // handle drawing custom captions. To use it:
  7. //
  8. // - call Install from your frame's OnCreate function. 
  9. // - Set a custom CaptionBackground if desired
  10. // - Set custom TextAttributes if required
  11. //
  12. //  Derive from this class for custom caption layouts.
  13. // 
  14. //   If you are drawing custom caption buttons, you must handle WM_NCLBUTTONDOWN & co.
  15. //   yourself. CSingleLineCaption does not handle the mouse for custom caption buttons. 
  16. //
  17. // Author: Dave Lorde (dlorde@cix.compulink.co.uk)
  18. //
  19. //          Copyright 1999
  20. //
  21. // - based on a 1997 Microsoft Systems Journal
  22. //            C++ Q&A article by Paul DiLascia. 
  23. //
  24. ////////////////////////////////////////////////////////////////
  25. //
  26. #include "StdAfx.h"
  27. #include "SingleLineCaption.h"
  28. #include "SuppressStyle.h"
  29. //#include <algorithm>
  30. //using std::_cpp_max;
  31. //using std::_cpp_min;
  32. #ifdef _DEBUG
  33. #define new DEBUG_NEW
  34. #undef THIS_FILE
  35. static char THIS_FILE[] = __FILE__;
  36. #endif
  37. IMPLEMENT_DYNAMIC(CSingleLineCaption, CCaption);
  38. ////////
  39. // Default Constructor 
  40. //
  41. CSingleLineCaption::CSingleLineCaption()
  42. :m_hIcon(0)
  43. {
  44. }
  45. //////////////////
  46. // Install caption handler. 
  47. //
  48. BOOL CSingleLineCaption::Install(CWnd* pWnd)
  49. {
  50. return HookWindow(pWnd);
  51. }
  52. //////////////////
  53. // Set icon for dialogs. 
  54. //
  55. void CSingleLineCaption::SetIcon(HICON hIcon)
  56. m_hIcon = hIcon; 
  57. }
  58. //////////////////
  59. // Message handler handles caption-related messages
  60. //
  61. LRESULT CSingleLineCaption::WindowProc(UINT msg, WPARAM wp, LPARAM lp)
  62. {
  63. switch (msg) 
  64. {
  65. case WM_NCACTIVATE:
  66. return OnNcActivate(wp);
  67. }
  68. // We don't handle it: pass along
  69. return CCaption::WindowProc(msg, wp, lp);
  70. }
  71. //////////////////
  72. // Handle WM_NCACTIVATE for main window
  73. //
  74. BOOL CSingleLineCaption::OnNcActivate(BOOL bActive)
  75. {
  76. TRACE("CSingleLineCaption::OnNcActivaten");
  77. ASSERT_VALID(m_pWndHooked);
  78. CWnd& wnd = *m_pWndHooked;
  79. // Mimic MFC kludge to stay active if WF_STAYACTIVE bit is on
  80. //
  81. if (wnd.m_nFlags & WF_STAYACTIVE)
  82. bActive = TRUE;
  83. if (!wnd.IsWindowEnabled()) // but not if disabled
  84. bActive = FALSE;
  85. if (bActive == m_bActive)
  86. return TRUE; // nothing to do
  87. // In case this is a MDI app, manually activate/paint active MDI child
  88. // window, because Windows won't do it if parent frame is invisible.
  89. // Must do this BEFORE calling Default, or it will not work.
  90. //
  91. CFrameWnd* pFrame = dynamic_cast<CFrameWnd*>(m_pWndHooked);
  92. if(pFrame) 
  93. {
  94. CFrameWnd* pActiveFrame = pFrame->GetActiveFrame();
  95. if (pActiveFrame != pFrame) 
  96. {
  97. pActiveFrame->SendMessage(WM_NCACTIVATE, bActive);
  98. pActiveFrame->SendMessage(WM_NCPAINT);
  99. }
  100. }
  101. // Turn WS_VISIBLE off before calling DefWindowProc,
  102. // so DefWindowProc won't paint and thereby cause flicker.
  103. //
  104. {
  105. SuppressStyle ss(wnd.GetSafeHwnd(), WS_VISIBLE);
  106. MSG& msg = AfxGetThreadState()->m_lastSentMsg;
  107. msg.wParam = bActive;
  108. Default(); // Normal message handling
  109. }
  110. // At this point, nothing has happened (since WS_VISIBLE was off).
  111. // Now it's time to paint.
  112. //
  113. m_bActive = bActive; // update state
  114. wnd.SendMessage(WM_NCPAINT); // paint non-client area (frame too)
  115. return TRUE; // done OK
  116. }
  117. ////////////////
  118. // Draw caption icon if valid DC is provided. Returns effective width of icon.
  119. //
  120. int CSingleLineCaption::PaintIcon(CDC* pDC)
  121. {
  122. ASSERT(m_pWndHooked);
  123. CWnd& wnd = *m_pWndHooked;
  124. ////////////
  125. // If there's no icon or system menu, don't draw one
  126. //
  127. if (!(wnd.GetStyle() & WS_SYSMENU))
  128. return 0;
  129. //////////////
  130. // Within the basic button rectangle, Windows 95 uses a 1 or 2 pixel border
  131. // Icon has 2 pixel border on left, 1 pixel on top/bottom, 0 right
  132. //
  133. int cxIcon = GetSystemMetrics(SM_CXSIZE);
  134. CRect rc(0, 0, cxIcon, GetSystemMetrics(SM_CYSIZE));
  135. rc.DeflateRect(0,1);
  136. rc.left += 2;
  137. if (pDC != 0)
  138. {
  139.     HICON hic = m_hIcon ? m_hIcon : (HICON)GetClassLong(wnd.m_hWnd, GCL_HICONSM);
  140. DrawIconEx(pDC->m_hDC, rc.left, rc.top, 
  141. hic, rc.Width(), rc.Height(), 0, NULL, DI_NORMAL);
  142. }
  143. return cxIcon;
  144. }
  145. //////////////
  146. // Helper
  147. //
  148. int CSingleLineCaption::GetIconWidth()
  149. {
  150. ASSERT(m_pWndHooked);
  151. CWnd& wnd = *m_pWndHooked;
  152. ////////////
  153. // If there's no icon or system menu, don't draw one
  154. //
  155. return (wnd.GetStyle() & WS_SYSMENU) ? GetSystemMetrics(SM_CXSIZE) : 0;
  156. }