#include "stdafx.h"
|
#include "CBaseView.h"
|
#include "Common.h"
|
|
|
#define CAPTION_HEIGHT 36
|
#define CAPBTN 99
|
|
|
IMPLEMENT_DYNAMIC(CBaseView, CDialogEx)
|
|
CBaseView::CBaseView(UINT id, CWnd* pPage) : CDialogEx(id, pPage)
|
{
|
m_crBkgnd = BASE_VIEW_BACKGROUND;
|
m_hbrBkgnd = nullptr;
|
m_pContext = nullptr;
|
m_nState = 0;
|
m_pHotBtn = nullptr;
|
m_pPressBtn = nullptr;
|
}
|
|
CBaseView::~CBaseView()
|
{
|
}
|
|
BEGIN_MESSAGE_MAP(CBaseView, 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 CBaseView::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 CBaseView::OnDestroy()
|
{
|
CDialogEx::OnDestroy();
|
}
|
|
void CBaseView::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
|
{
|
CDialogEx::OnActivate(nState, pWndOther, bMinimized);
|
|
if (WA_INACTIVE == nState) {
|
OnApply();
|
}
|
}
|
|
void CBaseView::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 CBaseView::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 CBaseView::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
|
{
|
lpncsp->rgrc[0].top += (CAPTION_HEIGHT);
|
CDialogEx::OnNcCalcSize(bCalcValidRects, lpncsp);
|
}
|
|
void CBaseView::SetContext(void* pContext)
|
{
|
m_pContext = pContext;
|
}
|
|
void* CBaseView::GetContext()
|
{
|
return m_pContext;
|
}
|
|
void CBaseView::OnApply()
|
{
|
|
}
|
|
void CBaseView::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 CBaseView::OnViewActive()
|
{
|
m_nState = 1;
|
SendMessage(WM_NCPAINT, 0, 0);
|
}
|
|
void CBaseView::OnViewInactive()
|
{
|
m_nState = 0;
|
SendMessage(WM_NCPAINT, 0, 0);
|
}
|
|
void CBaseView::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 CBaseView::SetToolBtnEnable(int id, BOOL bEnable)
|
{
|
CBaseView::TOOLBTN* pBtn = GetToolBtn(id);
|
if (pBtn != nullptr) {
|
pBtn->bEnable = bEnable;
|
SendMessage(WM_NCPAINT);
|
}
|
}
|
|
void CBaseView::SetToolBtnMenu(int id, HMENU hMenu)
|
{
|
CBaseView::TOOLBTN* pBtn = GetToolBtn(id);
|
if (pBtn != nullptr) {
|
pBtn->hMenu = hMenu;
|
}
|
}
|
|
void CBaseView::OnLButtonDown(UINT nFlags, CPoint point)
|
{
|
// TODO: ÔÚ´ËÌí¼ÓÏûÏ¢´¦Àí³ÌÐò´úÂëºÍ/»òµ÷ÓÃĬÈÏÖµ
|
|
CDialogEx::OnLButtonDown(nFlags, point);
|
}
|
|
|
LRESULT CBaseView::OnNcHitTest(CPoint point)
|
{
|
TOOLBTN* pBtn;
|
LRESULT hit = MyHitTest(point, pBtn);
|
if (hit == HTCAPTION || hit == CAPBTN) {
|
return hit;
|
}
|
|
return CDialogEx::OnNcHitTest(point);
|
}
|
|
void CBaseView::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 CBaseView::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 CBaseView::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 CBaseView::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;
|
}
|
|
CBaseView::TOOLBTN* CBaseView::GetToolBtn(int id)
|
{
|
for (auto& item : m_toolbtns) {
|
if (item.id == id) return &item;
|
}
|
|
return nullptr;
|
}
|
|
BOOL CBaseView::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 CBaseView::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);
|
}
|