UICoolBar.cpp
上传用户:yatsl7111
上传日期:2007-01-08
资源大小:1433k
文件大小:6k
源码类别:

图形图象

开发平台:

Visual C++

  1. ////////////////////////////////////////////////////////////////
  2. // Copyright 1998 Paul DiLascia
  3. // If this code works, it was written by Paul DiLascia.
  4. // If not, I don't know who wrote it.
  5. //
  6. // CCoolBar implements coolbars for MFC.
  7. //
  8. #include "StdAfx.h"
  9. #include "UICoolBar.h"
  10. #include "UIModulVer.h"
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. // if you want to see extra TRACE diagnostics, set below to TRUE
  17. BOOL CCoolBar::bTRACE = FALSE;
  18. #ifdef _DEBUG
  19. #define CBTRACEFN
  20. CTraceFn __fooble;
  21. if (bTRACE)
  22. TRACE
  23. #define CBTRACE
  24. if (bTRACE)
  25. TRACE
  26. #else
  27. #define CBTRACEFN TRACE
  28. #define CBTRACE   TRACE
  29. #endif
  30. IMPLEMENT_DYNAMIC(CCoolBar, CControlBar)
  31. BEGIN_MESSAGE_MAP(CCoolBar, CControlBar)
  32. //{{AFX_MSG_MAP(CCoolBar)
  33. ON_WM_CREATE()
  34. ON_WM_PAINT()
  35. ON_WM_ERASEBKGND()
  36. ON_NOTIFY_REFLECT(RBN_HEIGHTCHANGE, OnHeightChange)
  37. //}}AFX_MSG_MAP
  38. END_MESSAGE_MAP()
  39. CCoolBar::CCoolBar()
  40. {
  41. }
  42. CCoolBar::~CCoolBar()
  43. {
  44. }
  45. //////////////////
  46. // Create coolbar
  47. //
  48. BOOL CCoolBar::Create(CWnd* pParentWnd, DWORD dwStyle,
  49. DWORD dwAfxBarStyle, UINT nID)
  50. {
  51. ASSERT_VALID(pParentWnd);   // must have a parent
  52. // dynamic coolbar not supported
  53. dwStyle &= ~CBRS_SIZE_DYNAMIC;
  54. // save the style (this code copied from MFC--probably unecessary)
  55. m_dwStyle = dwAfxBarStyle;
  56. if (nID == AFX_IDW_TOOLBAR)
  57. m_dwStyle |= CBRS_HIDE_INPLACE;
  58. // MFC requires these:
  59. dwStyle |= CCS_NODIVIDER|CCS_NOPARENTALIGN;
  60. // initialize cool common controls
  61. static BOOL bInit = FALSE;
  62. if (!bInit) {
  63. HMODULE h = ::GetModuleHandle(_T("ComCtl32"));
  64. ASSERT(h);
  65. typedef BOOL (CALLBACK* INITCC)(INITCOMMONCONTROLSEX*);
  66. INITCC pfn = (INITCC)GetProcAddress(h, "InitCommonControlsEx");
  67. if (pfn) {
  68. INITCOMMONCONTROLSEX sex;
  69. sex.dwSize = sizeof(INITCOMMONCONTROLSEX);
  70. sex.dwICC = ICC_COOL_CLASSES;
  71. (*pfn)(&sex);
  72. }
  73. bInit = TRUE;
  74. }
  75. // Finally create the cool bar using given style and parent.
  76. CRect rc;
  77. rc.SetRectEmpty();
  78. return CWnd::CreateEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL,
  79. dwStyle, rc, pParentWnd, nID);
  80. }
  81. //////////////////
  82. // Invalidate coolbar: invalidate children too
  83. //
  84. void CCoolBar::Invalidate(BOOL bErase)
  85. {
  86. HWND hWndChild = ::GetWindow(m_hWnd, GW_CHILD);
  87. while (hWndChild != NULL) {
  88. ::InvalidateRect(hWndChild, NULL, bErase);
  89. hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT);
  90. }
  91. CControlBar::Invalidate(bErase);
  92. }
  93. //////////////////
  94. // Set the background bitmap. This sets the background for all bands and
  95. // sets the RBBS_FIXEDBMP style so it looks like one background.
  96. //
  97. void CCoolBar::SetBackgroundBitmap(CBitmap* pBitmap)
  98. {
  99. HBITMAP hbm = (HBITMAP)pBitmap->GetSafeHandle();
  100. CRebarBandInfo rbbi;
  101. int n = GetBandCount();
  102. for (int i=0; i< n; i++) {
  103. rbbi.fMask  = RBBIM_STYLE;
  104. GetBandInfo(i, &rbbi);
  105. rbbi.fMask  |= RBBIM_BACKGROUND;
  106. rbbi.fStyle |= RBBS_FIXEDBMP;
  107. rbbi.hbmBack = hbm;
  108. SetBandInfo(i, &rbbi);
  109. }
  110. }
  111. //////////////////
  112. // Set background/foreground colors for all bands
  113. //
  114. void CCoolBar::SetColors(COLORREF clrFG, COLORREF clrBG)
  115. {
  116. CRebarBandInfo rbbi;
  117. rbbi.fMask = RBBIM_COLORS;
  118. rbbi.clrFore = clrFG;
  119. rbbi.clrBack = clrBG;
  120. int n = GetBandCount();
  121. for (int i=0; i< n; i++)
  122. SetBandInfo(i, &rbbi);
  123. }
  124. //////////////////
  125. // Insert band. This overloaded version lets you create a child window band.
  126. //
  127. BOOL CCoolBar::InsertBand(CWnd* pWnd, CSize szMin, int cx,
  128. LPCTSTR lpText, int iPos, BOOL bNewRow)
  129. {
  130. CRebarBandInfo rbbi;
  131. rbbi.fMask = RBBIM_CHILD|RBBIM_CHILDSIZE|RBBIM_TEXT;
  132. if (cx>0) {
  133. rbbi.fMask |= RBBIM_SIZE;
  134. rbbi.cx = cx;
  135. }
  136. if (bNewRow) {
  137. rbbi.fMask  |= RBBIM_STYLE;
  138. rbbi.fStyle |= RBBS_BREAK;
  139. }
  140. rbbi.hwndChild =  pWnd->GetSafeHwnd();
  141. rbbi.cxMinChild = szMin.cx;
  142. rbbi.cyMinChild = szMin.cy;
  143. rbbi.lpText = (LPTSTR)lpText;
  144. return InsertBand(iPos, &rbbi);
  145. }
  146. //////////////////
  147. // Handle WM_CREATE: call virtual fn so derived class can create bands.
  148. //
  149. int CCoolBar::OnCreate(LPCREATESTRUCT lpcs)
  150. {
  151. return (CControlBar::OnCreate(lpcs)==-1 || !OnCreateBands()) ? -1 : 0;
  152. }
  153. //////////////////
  154. // Standard UI handler updates any controls in the coolbar.
  155. //
  156. void CCoolBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
  157. {
  158. UpdateDialogControls(pTarget, bDisableIfNoHndler);
  159. }
  160. /////////////////
  161. // These two functions are called by MFC to calculate the layout of
  162. // the main frame. Since CCoolBar is not designed to be dynamic, the
  163. // size is always fixed, and the same as the window size. 
  164. //
  165. CSize CCoolBar::CalcDynamicLayout(int nLength, DWORD dwMode)
  166. {
  167. return CalcFixedLayout(dwMode & LM_STRETCH, dwMode & LM_HORZ);
  168. }
  169. CSize CCoolBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
  170. {
  171. CRect rc;
  172. GetWindowRect(&rc);
  173. CSize sz(bHorz && bStretch ? 0x7FFF : rc.Width(),
  174. !bHorz && bStretch ? 0x7FFF : rc.Height());
  175. return sz;
  176. }
  177. //////////////////
  178. // Handle RBN_HEIGHTCHANGE notification: pass to virtual fn w/nicer args.
  179. //
  180. void CCoolBar::OnHeightChange(NMHDR* pNMHDR, LRESULT* pRes)
  181. {
  182. CRect rc;
  183. GetWindowRect(&rc);
  184. OnHeightChange(rc);
  185. *pRes = 0; // why not?
  186. }
  187. //////////////////
  188. // Height changed: Default implementation does the right thing for MFC
  189. // doc/view: notify parent frame by posting a WM_SIZE message. This will
  190. // cause the frame to do RecalcLayout. The message must be posted, not sent,
  191. // because the coolbar could send RBN_HEIGHTCHANGE while the user is sizing,
  192. // which would be in the middle of a CFrame::RecalcLayout, and RecalcLayout
  193. // doesn't let you re-enter it. Posting guarantees that CFrameWnd can finish
  194. // any recalc it may be in the middle of *before* handling my posted WM_SIZE.
  195. // Very confusing, but that's MFC for you.
  196. //
  197. void CCoolBar::OnHeightChange(const CRect& rcNew)
  198. {
  199. CWnd* pParent = GetParent();
  200. CRect rc;
  201. pParent->GetWindowRect(&rc);
  202. pParent->PostMessage(WM_SIZE, 0, MAKELONG(rc.Width(),rc.Height()));
  203. }
  204. void CCoolBar::OnPaint()
  205. {
  206. Default(); // bypass CControlBar
  207. }
  208. BOOL CCoolBar::OnEraseBkgnd(CDC* pDC)
  209. {
  210. return (BOOL)Default();  // bypass CControlBar
  211. }