#include "stdafx.h" #include "CComponentDlg.h" #include "Common.h" #define CAPTION_HEIGHT 36 #define CAPBTN 99 IMPLEMENT_DYNAMIC(CComponentDlg, CDialogEx) CComponentDlg::CComponentDlg(UINT id, CWnd* pPage) : CDialogEx(id, pPage) { m_crBkgnd = COMPONENT_DLG_BACKGROUND; m_hbrBkgnd = nullptr; m_pContext = nullptr; m_nState = 0; m_pHotBtn = nullptr; m_pPressBtn = nullptr; } CComponentDlg::~CComponentDlg() { } BEGIN_MESSAGE_MAP(CComponentDlg, CDialogEx) ON_WM_CTLCOLOR() ON_WM_DESTROY() ON_WM_ACTIVATE() ON_WM_NCPAINT() ON_WM_MOUSEACTIVATE() ON_WM_SIZE() ON_WM_NCCALCSIZE() ON_WM_LBUTTONDOWN() ON_WM_NCHITTEST() ON_WM_NCMOUSEMOVE() ON_WM_NCLBUTTONDOWN() ON_WM_NCLBUTTONUP() END_MESSAGE_MAP() HBRUSH CComponentDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); if (nCtlColor == CTLCOLOR_STATIC) { pDC->SetBkColor(m_crBkgnd); } if (m_hbrBkgnd == nullptr) { m_hbrBkgnd = CreateSolidBrush(m_crBkgnd); } return m_hbrBkgnd; } void CComponentDlg::OnDestroy() { CDialogEx::OnDestroy(); } void CComponentDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) { CDialogEx::OnActivate(nState, pWndOther, bMinimized); if (WA_INACTIVE == nState) { OnApply(); } } void CComponentDlg::OnNcPaint() { // TODO: ÔÚ´Ë´¦Ìí¼ÓÏûÏ¢´¦Àí³ÌÐò´úÂë // ²»Îª»æÍ¼ÏûÏ¢µ÷Óà CDialogEx::OnNcPaint() RECT rect, rcClient; ::GetClientRect(m_hWnd, &rcClient); ::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.left); ::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.right); ::GetWindowRect(m_hWnd, &rect); ::OffsetRect(&rcClient, -rect.left, -rect.top); rect.right -= rect.left; rect.bottom -= rect.top; rect.left = 0; rect.top = 0; HRGN hRgnWnd = CreateRectRgnIndirect(&rect); HRGN hRgnClient = CreateRectRgnIndirect(&rcClient); HBRUSH hBrushBK, hBrushFrame; HDC hDC = ::GetWindowDC(m_hWnd); ::SelectClipRgn(hDC, hRgnWnd); ::ExtSelectClipRgn(hDC, hRgnClient, RGN_DIFF); // ±³¾° hBrushBK = CreateSolidBrush(m_crBkgnd); ::FillRect(hDC, &rect, hBrushBK); DeleteObject(hBrushBK); // ±êÌâÀ¸£¬ÎÄ×Ö£¬ºáÏß HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); ::SelectObject(hDC, hFont); RECT rcCaption, rcText; rcCaption = rect; rcCaption.bottom = rcCaption.top + CAPTION_HEIGHT; rcText = rcCaption; rcText.left += 12; char szCaption[64]; int nCaptionLen = GetWindowText(szCaption, 64); ::DrawText(hDC, szCaption, nCaptionLen, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); HPEN hPen = CreatePen(PS_SOLID, 1, RGB(222, 222, 222)); HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen); ::MoveToEx(hDC, 0, rcCaption.bottom, NULL); ::LineTo(hDC, rect.right, rcCaption.bottom); ::SelectObject(hDC, hOldPen); ::DeleteObject(hPen); // »æÖư´Å¥ int y = (rcCaption.bottom - rcCaption.top - 24) / 2; int x = rcCaption.right - 12; for (auto& item : m_toolbtns) { if (item.hIcon != nullptr) { if (!item.bEnable) { DrawIconEx(hDC, x - 24, y, item.hIcon[3], 24, 24, 0, 0, DI_NORMAL); } else if (m_pPressBtn == &item) { DrawIconEx(hDC, x - 24, y, item.hIcon[2], 24, 24, 0, 0, DI_NORMAL); } else if (m_pHotBtn == &item) { DrawIconEx(hDC, x - 24, y, item.hIcon[1], 24, 24, 0, 0, DI_NORMAL); } else { DrawIconEx(hDC, x - 24, y, item.hIcon[0], 24, 24, 0, 0, DI_NORMAL); } x -= 24; x -= 3; } } hBrushFrame = CreateSolidBrush(RGB(255, 0, 0)); // ::FrameRect(hDC, &rect, hBrushFrame); ::DeleteObject(hRgnWnd); ::DeleteObject(hRgnClient); DeleteObject(hBrushFrame); ::ReleaseDC(m_hWnd, hDC); } int CComponentDlg::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) { // TODO: ÔÚ´ËÌí¼ÓÏûÏ¢´¦Àí³ÌÐò´úÂëºÍ/»òµ÷ÓÃĬÈÏÖµ int nRet = CDialogEx::OnMouseActivate(pDesktopWnd, nHitTest, message); GetParent()->GetParent()->SendMessage(ID_MSG_VIEW_ACTIVE, (WPARAM)this, nRet); return nRet; } void CComponentDlg::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp) { lpncsp->rgrc[0].top += (CAPTION_HEIGHT); CDialogEx::OnNcCalcSize(bCalcValidRects, lpncsp); } void CComponentDlg::SetContext(void* pContext) { m_pContext = pContext; } void* CComponentDlg::GetContext() { return m_pContext; } void CComponentDlg::OnApply() { } void CComponentDlg::Show(CWnd* pParent, LPRECT lprcBtn) { RECT rcClient, rcBox; pParent->GetClientRect(&rcClient); pParent->ClientToScreen(&rcClient); GetWindowRect(&rcBox); int x = lprcBtn->left; if (x + (rcBox.right - rcBox.left) > rcClient.right) { x = rcClient.right - (rcBox.right - rcBox.left); } SetWindowPos(NULL, x, lprcBtn->bottom + 2, 0, 0, SWP_NOSIZE); ShowWindow(SW_SHOW); } void CComponentDlg::OnViewActive() { m_nState = 1; SendMessage(WM_NCPAINT, 0, 0); } void CComponentDlg::OnViewInactive() { m_nState = 0; SendMessage(WM_NCPAINT, 0, 0); } void CComponentDlg::AddToolBtn(int id, const char* pszIcon0Path, const char* pszIcon1Path, const char* pszIcon2Path, const char* pszIcon3Path, const char* pszTooltip) { TOOLBTN tb; memset(&tb, 0, sizeof(TOOLBTN)); tb.id = id; tb.hIcon[0] = (HICON)::LoadImage(GetModuleHandle(NULL), pszIcon0Path, IMAGE_ICON, 24, 24, LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); tb.hIcon[1] = (HICON)::LoadImage(GetModuleHandle(NULL), pszIcon1Path, IMAGE_ICON, 24, 24, LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); tb.hIcon[2] = (HICON)::LoadImage(GetModuleHandle(NULL), pszIcon2Path, IMAGE_ICON, 24, 24, LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); tb.hIcon[3] = (HICON)::LoadImage(GetModuleHandle(NULL), pszIcon3Path, IMAGE_ICON, 24, 24, LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); strcpy_s(tb.szTooltip, 256, pszTooltip); tb.bEnable = TRUE; m_toolbtns.push_back(tb); EnableToolTips(TRUE); } void CComponentDlg::SetToolBtnEnable(int id, BOOL bEnable) { CComponentDlg::TOOLBTN* pBtn = GetToolBtn(id); if (pBtn != nullptr) { pBtn->bEnable = bEnable; SendMessage(WM_NCPAINT); } } void CComponentDlg::SetToolBtnMenu(int id, HMENU hMenu) { CComponentDlg::TOOLBTN* pBtn = GetToolBtn(id); if (pBtn != nullptr) { pBtn->hMenu = hMenu; } } void CComponentDlg::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: ÔÚ´ËÌí¼ÓÏûÏ¢´¦Àí³ÌÐò´úÂëºÍ/»òµ÷ÓÃĬÈÏÖµ CDialogEx::OnLButtonDown(nFlags, point); } LRESULT CComponentDlg::OnNcHitTest(CPoint point) { TOOLBTN* pBtn; LRESULT hit = MyHitTest(point, pBtn); if (hit == HTCAPTION || hit == CAPBTN) { return hit; } return CDialogEx::OnNcHitTest(point); } void CComponentDlg::OnNcMouseMove(UINT nHitTest, CPoint point) { TOOLBTN* pLastHot = m_pHotBtn; int code = MyHitTest(point, m_pHotBtn); if (pLastHot != m_pHotBtn) { SendMessage(WM_NCPAINT, 0, 0); } CDialogEx::OnNcMouseMove(nHitTest, point); } void CComponentDlg::OnNcLButtonDown(UINT nHitTest, CPoint point) { int code = MyHitTest(point, m_pPressBtn); SendMessage(WM_NCPAINT, 0, 0); GetParent()->GetParent()->SendMessage(ID_MSG_VIEW_ACTIVE, (WPARAM)this, MA_ACTIVATE); CDialogEx::OnNcLButtonDown(nHitTest, point); } void CComponentDlg::OnNcLButtonUp(UINT nHitTest, CPoint point) { MyHitTest(point, m_pHotBtn); if (m_pPressBtn == m_pHotBtn && m_pPressBtn != nullptr && m_pPressBtn->bEnable) { if (m_pPressBtn->hMenu != nullptr) { int cmd = ::TrackPopupMenu(::GetSubMenu(m_pPressBtn->hMenu, 0), TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, point.x, point.y + 2, 0, m_hWnd, NULL); GetParent()->GetParent()->PostMessage(ID_MSG_BTN_MENU_ITEM, (WPARAM)this, cmd); } else { GetParent()->GetParent()->PostMessage(ID_MSG_BTN_CLICKED, (WPARAM)this, m_pPressBtn->id); } } m_pPressBtn = nullptr; SendMessage(WM_NCPAINT, 0, 0); CDialogEx::OnNcLButtonUp(nHitTest, point); } int CComponentDlg::MyHitTest(POINT& point, TOOLBTN*& pBtn) { RECT rcWnd, rcCaption; GetWindowRect(&rcWnd); LRESULT hit = HTNOWHERE; pBtn = nullptr; rcCaption.left = rcWnd.left + 2; rcCaption.right = rcWnd.right - 2; rcCaption.top = rcWnd.top += 2; rcCaption.bottom = rcCaption.top + 2 + CAPTION_HEIGHT; if (::PtInRect(&rcCaption, point)) { hit = HTCAPTION; RECT rcIcon; rcIcon.top = rcCaption.top + (rcCaption.bottom - rcCaption.top - 24) / 2; rcIcon.bottom = rcIcon.top + 24; rcIcon.right = rcCaption.right - 12; for (auto& item : m_toolbtns) { rcIcon.left = rcIcon.right - 24; if (::PtInRect(&rcIcon, point)) { pBtn = &item; hit = CAPBTN; break; } rcIcon.right = rcIcon.left - 3; } } return (int)hit; } CComponentDlg::TOOLBTN* CComponentDlg::GetToolBtn(int id) { for (auto& item : m_toolbtns) { if (item.id == id) return &item; } return nullptr; } BOOL CComponentDlg::GetBtnRect(int id, LPRECT lprcBtn) { RECT rcWnd, rcCaption; GetWindowRect(&rcWnd); ::OffsetRect(&rcWnd, -rcWnd.left, -rcWnd.top); rcCaption.left = rcWnd.left + 2; rcCaption.right = rcWnd.right - 2; rcCaption.top = rcWnd.top += 2; rcCaption.bottom = rcCaption.top + 2 + CAPTION_HEIGHT; lprcBtn->top = rcCaption.top + (rcCaption.bottom - rcCaption.top - 24) / 2; lprcBtn->bottom = lprcBtn->top + 24; lprcBtn->right = rcCaption.right - 12; for (auto& item : m_toolbtns) { lprcBtn->left = lprcBtn->right - 24; if (item.id == id) { return TRUE; } lprcBtn->right = lprcBtn->left - 3; } return FALSE; } INT_PTR CComponentDlg::OnToolHitTest(CPoint point, TOOLINFO* pTI) const { RECT rcClient, rcCaption, rcBtn; ::GetClientRect(m_hWnd, &rcClient); rcCaption.bottom = 0; rcCaption.top = rcCaption.bottom - CAPTION_HEIGHT; rcCaption.left = rcClient.left; rcCaption.right = rcClient.right; rcBtn.top = rcCaption.top + (rcCaption.bottom - rcCaption.top - 24) / 2; rcBtn.bottom = rcBtn.top + 24; rcBtn.right = rcCaption.right - 12; ::OffsetRect(&rcBtn, +5, -5); // 5Ϊ±ß¿ò´ÖµÄÐÞÕý if ((point.y <= 0)) { for (auto& item : m_toolbtns) { rcBtn.left = rcBtn.right - 24; if (::PtInRect(&rcBtn, point)) { pTI->rect = rcBtn; pTI->hwnd = m_hWnd; pTI->uId = (UINT)1020; // Tooltip should show `1020 pTI->lpszText = _tcsdup(item.szTooltip); return pTI->uId; } rcBtn.right = rcBtn.left - 3; } } return CDialogEx::OnToolHitTest(point, pTI); }