From e1296858bab49a5609411293114e9c8c0714f7ed Mon Sep 17 00:00:00 2001 From: sdottaka Date: Tue, 24 Sep 2024 08:18:56 +0900 Subject: [PATCH] WIP --- Src/BasicFlatStatusBar.h | 6 +- Src/Common/MDITabBar.cpp | 94 +++++++++++------- Src/Common/MDITabBar.h | 19 ++-- Src/MainFrm.cpp | 20 +++- Src/MainFrm.h | 3 + Src/TitleBarHelper.cpp | 199 ++++++++++++++++++++++++++++++++++----- Src/TitleBarHelper.h | 25 +++-- 7 files changed, 291 insertions(+), 75 deletions(-) diff --git a/Src/BasicFlatStatusBar.h b/Src/BasicFlatStatusBar.h index 53fa65e55c2..ccbbe7df57d 100644 --- a/Src/BasicFlatStatusBar.h +++ b/Src/BasicFlatStatusBar.h @@ -15,19 +15,19 @@ class CBasicFlatStatusBar : public CStatusBar { DECLARE_DYNAMIC(CBasicFlatStatusBar) public: - CBasicFlatStatusBar(); + CBasicFlatStatusBar(); protected: CPoint CBasicFlatStatusBar::GetClientCursorPos() const; int GetIndexFromPoint(const CPoint& pt) const; static COLORREF LightenColor(COLORREF color, double amount); - afx_msg void OnPaint(); + afx_msg void OnPaint(); afx_msg BOOL OnEraseBkgnd(CDC *pDC); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnMouseLeave(); afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); - DECLARE_MESSAGE_MAP() + DECLARE_MESSAGE_MAP() bool m_bMouseTracking; int m_nTrackingPane; diff --git a/Src/Common/MDITabBar.cpp b/Src/Common/MDITabBar.cpp index aed632e052a..87663af07f4 100644 --- a/Src/Common/MDITabBar.cpp +++ b/Src/Common/MDITabBar.cpp @@ -45,9 +45,11 @@ BEGIN_MESSAGE_MAP(CMDITabBar, CControlBar) ON_WM_NCHITTEST() ON_WM_ERASEBKGND() ON_WM_PAINT() - ON_MESSAGE(WM_NCLBUTTONDBLCLK, OnNcForward) - ON_MESSAGE(WM_NCLBUTTONDOWN, OnNcForward) - ON_MESSAGE(WM_NCLBUTTONUP, OnNcForward) + ON_WM_NCMOUSEMOVE() + ON_WM_NCMOUSELEAVE() + ON_WM_NCLBUTTONDBLCLK() + ON_WM_NCLBUTTONDOWN() + ON_WM_NCLBUTTONUP() //}}AFX_MSG_MAP END_MESSAGE_MAP() @@ -469,26 +471,6 @@ void CMyTabCtrl::OnLButtonUp(UINT nFlags, CPoint point) CWnd::OnLButtonUp(nFlags, point); } -void CMDITabBar::OnSize(UINT nType, int cx, int cy) -{ - __super::OnSize(nType, cx, cy); - Invalidate(); - m_titleBar.OnSize(this, m_bMaximized, cx, cy); - if (m_tabCtrl.m_hWnd) - { - CClientDC dc(this); - const int lpx = dc.GetDeviceCaps(LOGPIXELSX); - auto pointToPixel = [lpx](float point) { return static_cast(point * lpx / 72); }; - const int leftMargin = m_bOnTitleBar ? pointToPixel(m_leftMarginPoint) : 0; - const int rightMargin = m_bOnTitleBar ? pointToPixel(m_rightMarginPoint) : 0; - int topMargin = ((m_bMaximized && m_bOnTitleBar) ? 8 : 0) + (m_bOnTitleBar ? 1 : 0); - int bottomMargin = m_bOnTitleBar ? 1 : 0; - CSize size{ 0, cy - topMargin - bottomMargin }; - m_tabCtrl.MoveWindow(leftMargin, topMargin, cx - leftMargin - rightMargin, cy - topMargin - bottomMargin, true); - m_tabCtrl.SetItemSize(size); - } -} - CRect CMyTabCtrl::GetCloseButtonRect(int nItem) { CClientDC dc(this); @@ -610,12 +592,14 @@ void CMyTabCtrl::UpdateToolTips(int nTabItemIndex) } } -BOOL CMDITabBar::Update(bool bOnTitleBar, bool bMaximized, float leftMarginPoint, float rightMarginPoint) +BOOL CMDITabBar::Update(bool bOnTitleBar, bool bMaximized) { m_bOnTitleBar = bOnTitleBar; m_bMaximized = bMaximized; - m_leftMarginPoint = leftMarginPoint; - m_rightMarginPoint = rightMarginPoint; + CRect rc; + if (m_bMaximized) + AfxGetMainWnd()->GetWindowRect(&rc); + m_top = rc.top; return true; } @@ -627,7 +611,9 @@ BOOL CMDITabBar::Create(CMDIFrameWnd* pMainFrame) { m_dwStyle = CBRS_TOP; - CWnd::Create(WC_STATIC, nullptr, WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), pMainFrame, AFX_IDW_CONTROLBAR_FIRST + 30); + m_titleBar.Init(this); + + CWnd::Create(nullptr, nullptr, WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), pMainFrame, AFX_IDW_CONTROLBAR_FIRST + 30); if (!m_tabCtrl.Create(pMainFrame, this)) return FALSE; @@ -665,8 +651,7 @@ CSize CMDITabBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz) auto pointToPixel = [lpx](int point) { return MulDiv(point, lpx, 72); }; const int r = pointToPixel(RR_RADIUS); const int sw = pointToPixel(RR_SHADOWWIDTH); - - int my = m_bOnTitleBar ? (m_bMaximized ? (8 + 6) : 6) : 0; + int my = m_bOnTitleBar ? (m_bMaximized ? (-m_top + 2) : 2) : 0; CSize size(SHRT_MAX, my + tm.tmHeight + (sw + r) * 2); return size; } @@ -676,6 +661,48 @@ LRESULT CMDITabBar::OnNcHitTest(CPoint point) return m_titleBar.HitTest(point); } +void CMDITabBar::OnNcMouseMove(UINT nHitTest, CPoint point) +{ + m_titleBar.OnNcMouseMove(nHitTest, point); +} + +void CMDITabBar::OnNcMouseLeave() +{ + m_titleBar.OnNcMouseLeave(); +} + +void CMDITabBar::OnNcLButtonDblClk(UINT nHitTest, CPoint point) +{ + m_titleBar.OnNcLButtonDblClk(nHitTest, point); +} + +void CMDITabBar::OnNcLButtonDown(UINT nHitTest, CPoint point) +{ + m_titleBar.OnNcLButtonDown(nHitTest, point); +} + +void CMDITabBar::OnNcLButtonUp(UINT nHitTest, CPoint point) +{ + m_titleBar.OnNcLButtonUp(nHitTest, point); +} + +void CMDITabBar::OnSize(UINT nType, int cx, int cy) +{ + __super::OnSize(nType, cx, cy); + Invalidate(); + m_titleBar.OnSize(m_bMaximized, cx, cy); + if (m_tabCtrl.m_hWnd) + { + const int leftMargin = m_bOnTitleBar ? m_titleBar.GetLeftMargin() : 0; + const int rightMargin = m_bOnTitleBar ? m_titleBar.GetRightMargin() : 0; + const int topMargin = ((m_bMaximized && m_bOnTitleBar) ? -m_top : 0) + (m_bOnTitleBar ? 1 : 0); + const int bottomMargin = m_bOnTitleBar ? 1 : 0; + CSize size{ 0, cy - topMargin - bottomMargin }; + m_tabCtrl.MoveWindow(leftMargin, topMargin, cx - leftMargin - rightMargin, cy - topMargin - bottomMargin, true); + m_tabCtrl.SetItemSize(size); + } +} + BOOL CMDITabBar::OnEraseBkgnd(CDC* pDC) { CRect rClient; @@ -686,12 +713,11 @@ BOOL CMDITabBar::OnEraseBkgnd(CDC* pDC) void CMDITabBar::OnPaint() { - CPaintDC dc(this); if (!m_bOnTitleBar) - return; + return __super::OnPaint(); + CPaintDC dc(this); CRect rcClient; GetClientRect(&rcClient); - const int lpx = dc.GetDeviceCaps(LOGPIXELSX); - auto pointToPixel = [lpx](float point) -> int { return static_cast(point * lpx / 72); }; - m_titleBar.DrawIcon(AfxGetMainWnd(), dc, pointToPixel(m_leftMarginPoint)); + m_titleBar.DrawIcon(AfxGetMainWnd(), dc); + m_titleBar.DrawButtons(dc); } diff --git a/Src/Common/MDITabBar.h b/Src/Common/MDITabBar.h index be5b1c086d4..9e0408bc1a3 100644 --- a/Src/Common/MDITabBar.h +++ b/Src/Common/MDITabBar.h @@ -86,8 +86,7 @@ class CMDITabBar : public CControlBar bool m_bOnTitleBar; bool m_bMaximized; - float m_leftMarginPoint; - float m_rightMarginPoint; + int m_top; CMyTabCtrl m_tabCtrl; CFont m_font; CTitleBarHelper m_titleBar; @@ -96,11 +95,10 @@ class CMDITabBar : public CControlBar CMDITabBar() : m_bOnTitleBar(true) , m_bMaximized(false) - , m_leftMarginPoint(0) - , m_rightMarginPoint(0) + , m_top(0) {} virtual ~CMDITabBar() {} - BOOL Update(bool bOnTitleBar, bool bMaxmized, float iconWidthPoint, float buttonsWidthPoint); + BOOL Update(bool bOnTitleBar, bool bMaxmized); BOOL Create(CMDIFrameWnd* pParentWnd); void UpdateTabs() { m_tabCtrl.UpdateTabs(); } bool GetAutoMaxWidth() const { return m_tabCtrl.GetAutoMaxWidth(); } @@ -113,12 +111,15 @@ class CMDITabBar : public CControlBar protected: //{{AFX_MSG(CMDITabBar) - afx_msg BOOL OnEraseBkgnd(CDC* pDC); - afx_msg void OnPaint(); afx_msg LRESULT OnNcHitTest(CPoint point); - template - afx_msg LRESULT OnNcForward(WPARAM wParam, LPARAM lParam) { return AfxGetMainWnd()->SendMessage(message, wParam, lParam); } + afx_msg void OnNcMouseMove(UINT nHitTest, CPoint point); + afx_msg void OnNcMouseLeave(); + afx_msg void OnNcLButtonDblClk(UINT nHitTest, CPoint point); + afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point); + afx_msg void OnNcLButtonUp(UINT nHitTest, CPoint point); afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg BOOL OnEraseBkgnd(CDC* pDC); + afx_msg void OnPaint(); //}}AFX_MSG DECLARE_MESSAGE_MAP() diff --git a/Src/MainFrm.cpp b/Src/MainFrm.cpp index c4e388446ab..717eb3fff0b 100644 --- a/Src/MainFrm.cpp +++ b/Src/MainFrm.cpp @@ -224,6 +224,10 @@ BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) ON_WM_ACTIVATEAPP() ON_WM_NCCALCSIZE() ON_WM_SIZE() + ON_WM_MOUSEMOVE() + ON_WM_MOUSELEAVE() + ON_WM_NCMOUSEMOVE() + ON_WM_NCMOUSELEAVE() ON_UPDATE_COMMAND_UI_RANGE(CMenuBar::FIRST_MENUID, CMenuBar::FIRST_MENUID + 10, OnUpdateMenuBarMenuItem) // [File] menu ON_COMMAND(ID_FILE_NEW, (OnFileNew<2, ID_MERGE_COMPARE_TEXT>)) @@ -413,7 +417,7 @@ int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) if (IsWin10_OrGreater()) m_bTabsOnTitleBar = GetOptionsMgr()->GetBool(OPT_TABBAR_ON_TITLEBAR); - m_wndTabBar.Update(m_bTabsOnTitleBar.value_or(false), false, 32.f, 18.f * 3); + m_wndTabBar.Update(m_bTabsOnTitleBar.value_or(false), false); if (m_bTabsOnTitleBar.value_or(false) && !m_wndTabBar.Create(this)) { @@ -2543,10 +2547,22 @@ void CMainFrame::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncs void CMainFrame::OnSize(UINT nType, int cx, int cy) { - m_wndTabBar.Update(m_bTabsOnTitleBar.value_or(false), (nType == SIZE_MAXIMIZED), 32.f, 18.f * 3); + m_wndTabBar.Update(m_bTabsOnTitleBar.value_or(false), (nType == SIZE_MAXIMIZED)); __super::OnSize(nType, cx, cy); } +void CMainFrame::OnMouseMove(UINT nFlags, CPoint point) +{ +} + +void CMainFrame::OnMouseLeave() +{ +} + +void CMainFrame::OnNcMouseMove(UINT nHitTest, CPoint point) +{ +} + BOOL CMainFrame::CreateToolbar() { if (!m_wndMenuBar.Create(this)) diff --git a/Src/MainFrm.h b/Src/MainFrm.h index 39ddafe2a6a..fbe7a03858c 100644 --- a/Src/MainFrm.h +++ b/Src/MainFrm.h @@ -387,6 +387,9 @@ class CMainFrame : public CMDIFrameWnd afx_msg void OnActivateApp(BOOL bActive, DWORD dwThreadID); afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp); afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnMouseLeave(); + afx_msg void OnNcMouseMove(UINT nHitTest, CPoint point); afx_msg void OnToolbarSize(UINT id); afx_msg void OnUpdateToolbarSize(CCmdUI* pCmdUI); afx_msg BOOL OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult); diff --git a/Src/TitleBarHelper.cpp b/Src/TitleBarHelper.cpp index 172497459ad..df7e126c13b 100644 --- a/Src/TitleBarHelper.cpp +++ b/Src/TitleBarHelper.cpp @@ -10,45 +10,201 @@ #include "TitleBarHelper.h" #include "RoundedRectWithShadow.h" -void CTitleBarHelper::DrawIcon(CWnd* pWnd, CDC& dc, int leftMarginWidth) +CTitleBarHelper::CTitleBarHelper() + : m_pWnd(nullptr) + , m_maximized(false) + , m_iconSize(0) + , m_dpi(96) + , m_leftMargin(32.f) + , m_rightMargin(35.f * 3) + , m_bMouseTracking(false) + , m_nTrackingButton(-1) + , m_nHitTest(-1) +{ +} + +void CTitleBarHelper::Init(CWnd *pWnd) +{ + m_pWnd = pWnd; +} + +void CTitleBarHelper::DrawIcon(CWnd* pWnd, CDC& dc) { HICON hIcon = (HICON)pWnd->SendMessage(WM_GETICON, ICON_SMALL2, 0); if (hIcon == nullptr) hIcon = (HICON)GetClassLongPtr(pWnd->m_hWnd, GCLP_HICONSM); if (hIcon != nullptr) { - const int my = (m_maximized ? 8 : 0); - const int height = m_size.cy - my; - const int cx = PointToPixel(12.f); - const int cy = PointToPixel(12.f); - const int x = (leftMarginWidth - cx) / 2; - const int y = (height - cy) / 2 + my; + const int topMargin = (m_maximized ? -m_rc.top : 0); + const int height = m_size.cy - topMargin; + const int cx = static_cast(PointToPixel(12.f)); + const int cy = static_cast(PointToPixel(12.f)); + const int x = static_cast((PointToPixel(m_leftMargin) - cx) / 2); + const int y = static_cast((height - cy) / 2 + topMargin); DrawIconEx(dc.m_hDC, x, y, hIcon, cx, cy, 0, nullptr, DI_NORMAL); } } -void CTitleBarHelper::DrawButtons(CDC& dc) +static void DrawTopRightEdgeWithCurve(Gdiplus::Graphics& graphics, Gdiplus::Pen& pen, Gdiplus::Rect rect, int cornerRadius) { + Gdiplus::GraphicsPath path; + path.AddLine(rect.X, rect.Y, rect.X + rect.Width - cornerRadius, rect.Y); + path.AddArc(rect.X + rect.Width - cornerRadius, rect.Y, cornerRadius, cornerRadius, 270, 90); + path.AddLine(rect.X + rect.Width, rect.Y + cornerRadius, rect.X + rect.Width, rect.Y + rect.Height); + graphics.DrawPath(&pen, &path); } -CRect CTitleBarHelper::GetIconRect() +static void DrawRoundedRectangle(Gdiplus::Graphics& graphics, Gdiplus::Pen& pen, Gdiplus::Rect rect, int cornerRadius) { - return CRect{}; + Gdiplus::GraphicsPath path; + path.AddArc(rect.X, rect.Y, cornerRadius, cornerRadius, 180, 90); + path.AddArc(rect.X + rect.Width - cornerRadius, rect.Y, cornerRadius, cornerRadius, 270, 90); + path.AddArc(rect.X + rect.Width - cornerRadius, rect.Y + rect.Height - cornerRadius, cornerRadius, cornerRadius, 0, 90); + path.AddArc(rect.X, rect.Y + rect.Height - cornerRadius, cornerRadius, cornerRadius, 90, 90); + path.CloseFigure(); + graphics.DrawPath(&pen, &path); } -CRect CTitleBarHelper::GetButtonsRect() +void CTitleBarHelper::DrawButtons(CDC& dc) { - return CRect{}; + Gdiplus::Graphics graphics(dc.m_hDC); + CRect rcIcons[3], rcButtons[3]; + const float buttonWidth = PointToPixel(m_rightMargin) / 3.f; + const float iconSize = PointToPixel(6.75); + for (int i = 0; i < 3; i++) + { + rcButtons[i] = GetButtonRect(i); + rcIcons[i] = rcButtons[i]; + rcIcons[i].left = static_cast(rcIcons[i].left + (buttonWidth - iconSize) / 2); + rcIcons[i].right = static_cast(rcIcons[i].left + iconSize); + rcIcons[i].top = static_cast(rcIcons[i].top + (rcButtons[i].Height() - iconSize) / 2); + rcIcons[i].bottom = static_cast(rcIcons[i].top + iconSize); + + Gdiplus::Color color; + color.SetFromCOLORREF((m_nTrackingButton == i) ? GetSysColor(COLOR_WINDOW) : GetSysColor(COLOR_3DFACE)); + Gdiplus::SolidBrush brush(color); + graphics.FillRectangle(&brush, rcButtons[i].left, rcButtons[i].top, rcButtons[i].Width(), rcButtons[i].Height()); + } + + graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + Gdiplus::Pen pen(Gdiplus::Color(255, 0, 0, 0), PointToPixel(0.75)); + graphics.DrawLine(&pen, Gdiplus::Point(rcIcons[2].left, rcIcons[2].top), Gdiplus::Point(rcIcons[2].right, rcIcons[2].bottom)); + graphics.DrawLine(&pen, Gdiplus::Point(rcIcons[2].left, rcIcons[2].bottom), Gdiplus::Point(rcIcons[2].right, rcIcons[2].top)); + + const int r = static_cast(PointToPixel(0.75)); + if (m_maximized) + { + DrawTopRightEdgeWithCurve(graphics, pen, Gdiplus::Rect(rcIcons[1].left + r, rcIcons[1].top - r, rcIcons[1].Width() - 2 * r, rcIcons[1].Height() - 2 * r), r); + DrawRoundedRectangle(graphics, pen, Gdiplus::Rect(rcIcons[1].left - r, rcIcons[1].top + r, rcIcons[1].Width() - 2 * r, rcIcons[1].Height() - 2 * r), r); + } + else + { + DrawRoundedRectangle(graphics, pen, Gdiplus::Rect(rcIcons[1].left, rcIcons[1].top, rcIcons[1].Width(), rcIcons[1].Height()), r); + } + + const int y = (rcIcons[0].top + rcIcons[0].bottom) / 2; + graphics.DrawLine(&pen, Gdiplus::Point(rcIcons[0].left, y), Gdiplus::Point(rcIcons[0].right, y)); +} + +CRect CTitleBarHelper::GetButtonRect(int button) const +{ + const float w1 = PointToPixel(m_rightMargin) / 3.f; + CRect rcPart; + const int topMargin = (m_maximized ? -m_rc.top : 0); + rcPart.top = topMargin; + rcPart.bottom = m_size.cy; + rcPart.left = static_cast(m_size.cx - (3 - button) * w1); + rcPart.right = static_cast(rcPart.left + w1); + return rcPart; } -void CTitleBarHelper::OnSize(CWnd* pWnd, bool maximized, int cx, int cy) +void CTitleBarHelper::OnSize(bool maximized, int cx, int cy) { m_size = CSize(cx, cy); m_maximized = maximized; - m_pWnd = pWnd; - CClientDC dc(pWnd); + CClientDC dc(m_pWnd); m_dpi = dc.GetDeviceCaps(LOGPIXELSX); + m_pWnd->GetWindowRect(&m_rc); +} + +void CTitleBarHelper::OnNcMouseMove(UINT nHitTest, CPoint point) +{ + if (!m_bMouseTracking) + { + TRACKMOUSEEVENT tme = { sizeof TRACKMOUSEEVENT, TME_LEAVE | TME_NONCLIENT, m_pWnd->m_hWnd }; + TrackMouseEvent(&tme); + m_bMouseTracking = true; + } + int i = HitTest(point); + if (i == HTMINBUTTON) + i = 0; + else if (i == HTMAXBUTTON) + i = 1; + else if (i == HTCLOSE) + i = 2; + else + i = -1; + for (int button : {i, m_nTrackingButton}) + { + if (button != -1) + { + CRect rcPart = GetButtonRect(button); + m_pWnd->InvalidateRect(&rcPart, false); + } + } + m_nTrackingButton = i; +} + +void CTitleBarHelper::OnNcMouseLeave() +{ + TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT), TME_LEAVE | TME_CANCEL, m_pWnd->m_hWnd }; + TrackMouseEvent(&tme); + m_bMouseTracking = false; + if (m_nTrackingButton >= 0) + { + CRect rcPart = GetButtonRect(m_nTrackingButton); + m_pWnd->InvalidateRect(&rcPart, false); + } + m_nTrackingButton = -1; +} + +void CTitleBarHelper::OnNcLButtonDblClk(UINT nHitTest, CPoint point) +{ + if (nHitTest == HTCAPTION || nHitTest == HTSYSMENU) + { + AfxGetMainWnd()->SendMessage(WM_NCLBUTTONDBLCLK, nHitTest, MAKELPARAM(point.x, point.y)); + } +} + +void CTitleBarHelper::OnNcLButtonDown(UINT nHitTest, CPoint point) +{ + if (nHitTest == HTCAPTION || nHitTest == HTSYSMENU) + { + AfxGetMainWnd()->SendMessage(WM_NCLBUTTONDOWN, nHitTest, MAKELPARAM(point.x, point.y)); + } + else if (nHitTest == HTMINBUTTON || nHitTest == HTMAXBUTTON || nHitTest == HTCLOSE) + { + m_nHitTest = nHitTest; + } +} + +void CTitleBarHelper::OnNcLButtonUp(UINT nHitTest, CPoint point) +{ + if (nHitTest == HTCAPTION || nHitTest == HTSYSMENU) + { + AfxGetMainWnd()->SendMessage(WM_NCLBUTTONUP, nHitTest, MAKELPARAM(point.x, point.y)); + } + else if (m_nHitTest != -1 && m_nHitTest == nHitTest) + { + if (nHitTest == HTMINBUTTON) + AfxGetMainWnd()->ShowWindow(SW_MINIMIZE); + else if (nHitTest == HTMAXBUTTON) + AfxGetMainWnd()->ShowWindow(m_maximized ? SW_RESTORE : SW_MAXIMIZE); + else if (nHitTest == HTCLOSE) + AfxGetMainWnd()->PostMessage(WM_CLOSE); + } + m_nHitTest = -1; } int CTitleBarHelper::HitTest(CPoint pt) @@ -56,10 +212,11 @@ int CTitleBarHelper::HitTest(CPoint pt) if (!m_pWnd) return HTNOWHERE; CClientDC dc(m_pWnd); - const int height = PointToPixel(24); - const int buttonWidth = PointToPixel(24); + const int height = m_size.cy; + const int leftMargin = static_cast(PointToPixel(m_leftMargin)); + const int rightMargin = static_cast(PointToPixel(m_rightMargin)); CRect rc; - const int bw = buttonWidth; + const int bw = rightMargin / 3; const int m = 8; m_pWnd->GetWindowRect(&rc); if (pt.y < rc.top + 4) @@ -74,7 +231,7 @@ int CTitleBarHelper::HitTest(CPoint pt) return HTLEFT; if (rc.right - m <= pt.x) return HTRIGHT; - if (pt.x < rc.left + bw) + if (pt.x < rc.left + leftMargin) return HTSYSMENU; if (rc.right - bw * 3 <= pt.x && pt.x < rc.right - bw * 2) { @@ -91,7 +248,7 @@ int CTitleBarHelper::HitTest(CPoint pt) return HTCAPTION; } -int CTitleBarHelper::PointToPixel(float point) +float CTitleBarHelper::PointToPixel(float point) const { - return static_cast(point * m_dpi / 72.f); + return point * m_dpi / 72.f; }; diff --git a/Src/TitleBarHelper.h b/Src/TitleBarHelper.h index 27a6fbc74ea..b421ac24873 100644 --- a/Src/TitleBarHelper.h +++ b/Src/TitleBarHelper.h @@ -12,20 +12,33 @@ class CTitleBarHelper { public: - CTitleBarHelper() {} - void DrawIcon(CWnd* pWnd, CDC& dc, int leftMarginWidth); + CTitleBarHelper(); + void Init(CWnd* pWnd); + void DrawIcon(CWnd* pWnd, CDC& dc); void DrawButtons(CDC& dc); - CRect GetIconRect(); - CRect GetButtonsRect(); - void OnSize(CWnd* pWnd, bool maximized, int cx, int cy); + int GetLeftMargin() const { return static_cast(PointToPixel(m_leftMargin)); } + int GetRightMargin() const { return static_cast(PointToPixel(m_rightMargin)); } + CRect GetButtonRect(int button) const; + void OnSize(bool maximized, int cx, int cy); + void OnNcMouseMove(UINT nHitTest, CPoint point); + void OnNcMouseLeave(); + void OnNcLButtonDblClk(UINT nHitTest, CPoint point); + void OnNcLButtonDown(UINT nHitTest, CPoint point); + void OnNcLButtonUp(UINT nHitTest, CPoint point); int HitTest(CPoint pt); private: - int PointToPixel(float point); + float PointToPixel(float point) const; CWnd* m_pWnd; CSize m_size; + CRect m_rc; bool m_maximized; + bool m_bMouseTracking; + int m_nTrackingButton; + int m_nHitTest; int m_iconSize; int m_dpi; + float m_leftMargin; + float m_rightMargin; };