SingleLineCaption.cpp
上传用户:zhoushen
上传日期:2022-06-15
资源大小:84k
文件大小:4k
- ////////////////////////////////////////////////////////////////
- //
- // class CSingleLineCaption
- //
- // Generic caption painter. Handles WM_NCPAINT, WM_NCACTIVATE, etc. to
- // handle drawing custom captions. To use it:
- //
- // - call Install from your frame's OnCreate function.
- // - Set a custom CaptionBackground if desired
- // - Set custom TextAttributes if required
- //
- // Derive from this class for custom caption layouts.
- //
- // If you are drawing custom caption buttons, you must handle WM_NCLBUTTONDOWN & co.
- // yourself. CSingleLineCaption does not handle the mouse for custom caption buttons.
- //
- // Author: Dave Lorde (dlorde@cix.compulink.co.uk)
- //
- // Copyright 1999
- //
- // - based on a 1997 Microsoft Systems Journal
- // C++ Q&A article by Paul DiLascia.
- //
- ////////////////////////////////////////////////////////////////
- //
- #include "StdAfx.h"
- #include "SingleLineCaption.h"
- #include "SuppressStyle.h"
- //#include <algorithm>
- //using std::_cpp_max;
- //using std::_cpp_min;
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- IMPLEMENT_DYNAMIC(CSingleLineCaption, CCaption);
- ////////
- // Default Constructor
- //
- CSingleLineCaption::CSingleLineCaption()
- :m_hIcon(0)
- {
- }
- //////////////////
- // Install caption handler.
- //
- BOOL CSingleLineCaption::Install(CWnd* pWnd)
- {
- return HookWindow(pWnd);
- }
- //////////////////
- // Set icon for dialogs.
- //
- void CSingleLineCaption::SetIcon(HICON hIcon)
- {
- m_hIcon = hIcon;
- }
- //////////////////
- // Message handler handles caption-related messages
- //
- LRESULT CSingleLineCaption::WindowProc(UINT msg, WPARAM wp, LPARAM lp)
- {
- switch (msg)
- {
- case WM_NCACTIVATE:
- return OnNcActivate(wp);
- }
- // We don't handle it: pass along
- return CCaption::WindowProc(msg, wp, lp);
- }
- //////////////////
- // Handle WM_NCACTIVATE for main window
- //
- BOOL CSingleLineCaption::OnNcActivate(BOOL bActive)
- {
- TRACE("CSingleLineCaption::OnNcActivaten");
- ASSERT_VALID(m_pWndHooked);
- CWnd& wnd = *m_pWndHooked;
- // Mimic MFC kludge to stay active if WF_STAYACTIVE bit is on
- //
- if (wnd.m_nFlags & WF_STAYACTIVE)
- bActive = TRUE;
- if (!wnd.IsWindowEnabled()) // but not if disabled
- bActive = FALSE;
- if (bActive == m_bActive)
- return TRUE; // nothing to do
- // In case this is a MDI app, manually activate/paint active MDI child
- // window, because Windows won't do it if parent frame is invisible.
- // Must do this BEFORE calling Default, or it will not work.
- //
- CFrameWnd* pFrame = dynamic_cast<CFrameWnd*>(m_pWndHooked);
- if(pFrame)
- {
- CFrameWnd* pActiveFrame = pFrame->GetActiveFrame();
- if (pActiveFrame != pFrame)
- {
- pActiveFrame->SendMessage(WM_NCACTIVATE, bActive);
- pActiveFrame->SendMessage(WM_NCPAINT);
- }
- }
- // Turn WS_VISIBLE off before calling DefWindowProc,
- // so DefWindowProc won't paint and thereby cause flicker.
- //
- {
- SuppressStyle ss(wnd.GetSafeHwnd(), WS_VISIBLE);
- MSG& msg = AfxGetThreadState()->m_lastSentMsg;
- msg.wParam = bActive;
- Default(); // Normal message handling
- }
- // At this point, nothing has happened (since WS_VISIBLE was off).
- // Now it's time to paint.
- //
- m_bActive = bActive; // update state
- wnd.SendMessage(WM_NCPAINT); // paint non-client area (frame too)
- return TRUE; // done OK
- }
- ////////////////
- // Draw caption icon if valid DC is provided. Returns effective width of icon.
- //
- int CSingleLineCaption::PaintIcon(CDC* pDC)
- {
- ASSERT(m_pWndHooked);
- CWnd& wnd = *m_pWndHooked;
- ////////////
- // If there's no icon or system menu, don't draw one
- //
- if (!(wnd.GetStyle() & WS_SYSMENU))
- return 0;
- //////////////
- // Within the basic button rectangle, Windows 95 uses a 1 or 2 pixel border
- // Icon has 2 pixel border on left, 1 pixel on top/bottom, 0 right
- //
- int cxIcon = GetSystemMetrics(SM_CXSIZE);
- CRect rc(0, 0, cxIcon, GetSystemMetrics(SM_CYSIZE));
- rc.DeflateRect(0,1);
- rc.left += 2;
- if (pDC != 0)
- {
- HICON hic = m_hIcon ? m_hIcon : (HICON)GetClassLong(wnd.m_hWnd, GCL_HICONSM);
- DrawIconEx(pDC->m_hDC, rc.left, rc.top,
- hic, rc.Width(), rc.Height(), 0, NULL, DI_NORMAL);
- }
- return cxIcon;
- }
- //////////////
- // Helper
- //
- int CSingleLineCaption::GetIconWidth()
- {
- ASSERT(m_pWndHooked);
- CWnd& wnd = *m_pWndHooked;
- ////////////
- // If there's no icon or system menu, don't draw one
- //
- return (wnd.GetStyle() & WS_SYSMENU) ? GetSystemMetrics(SM_CXSIZE) : 0;
- }