statusbaract.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 526 行 · 第 1/2 页
CPP
526 行
////////////////////////////////////////////////////////////////////////////
// File: StatusBarACT.cpp
// Version: 3.1
// Created: 24 Jun 2004
//
// Author: Paul S. Vickery
// E-mail: paul@vickeryhome.freeserve.co.uk
//
// CStatusBar derived control to add auto-fit, tooltips and command handling
//
// You are free to use or modify this code, with no restrictions, other than
// you continue to acknowledge me as the original author in this source code,
// or any code derived from it.
//
// If you use this code, or use it as a base for your own code, it would be
// nice to hear from you simply so I know it's not been a waste of time!
//
// Copyright (c) 2003-2004 Paul S. Vickery
//
////////////////////////////////////////////////////////////////////////////
// Version History:
//
// Version 3.1 - 24 Jun 2004
// =========================
// - Updated to support Unicode builds
// - fixed bugs:
// - using ON_COMMAND macros causes assertion failure
// - updating tip text re-adds the tool, and causes old one to overlap
// - crash in GetPaneCursorIndex() if no pane cursors set and also in
// GetPaneFlagsIndex() if no pane flags set (reported by Tom Mason)
//
// Version 3.0 - 28 May 2003
// =========================
// - Can now specify a custom cursor for a pane
// - Added ability to specify a hand cursor to use instead of the default
// (the default is only available on Windows 98/ME and Windows 2000/XP)
//
// Version 2.0 - 15 Apr 2003
// =========================
// - Extended control to allow pane tool-tips to be specified as part of the
// pane's text, separated by a new line ('\n') character.
// - Added ability to show multi-line tool-tips by including carriage returns
// ('\r') and/or line breaks ('\n') in the tip text.
//
// Version 1.0 - 18 Feb 2003
// =========================
// Initial version
//
////////////////////////////////////////////////////////////////////////////
// PLEASE LEAVE THIS HEADER INTACT
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "StatusBarACT.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CStatusBarACT
IMPLEMENT_DYNAMIC(CStatusBarACT, CStatusBar)
CStatusBarACT::CStatusBarACT()
{
m_hCursorHand = NULL;
m_bTryDefaultHandCursor = FALSE;
}
CStatusBarACT::~CStatusBarACT()
{
}
BEGIN_MESSAGE_MAP(CStatusBarACT, CStatusBar)
//{{AFX_MSG_MAP(CStatusBarACT)
ON_WM_SETCURSOR()
ON_WM_CREATE()
ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CStatusBarACT message handlers
int CStatusBarACT::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CStatusBar::OnCreate(lpCreateStruct) == -1)
return -1;
// create tooltip control
m_tooltip.Create(this);
// allow '\n' chars to wrap tips
m_tooltip.SendMessage(TTM_SETMAXTIPWIDTH, 0, (UINT)(WORD)-1);
return 0;
}
BOOL CStatusBarACT::PreTranslateMessage(MSG* pMsg)
{
m_tooltip.RelayEvent(pMsg);
return CStatusBar::PreTranslateMessage(pMsg);
}
// returns index under point, where point is client co-ords
// returns -1 if no pane is under the point
int CStatusBarACT::HitTest(CPoint point)
{
CStatusBarCtrl& bar = GetStatusBarCtrl();
int nMax = bar.GetParts(0, NULL);
for (int nIndex = 0; nIndex < nMax; nIndex++)
{
CRect rc;
GetItemRect(nIndex, &rc);
if (rc.PtInRect(point))
return nIndex;
}
return -1;
}
// see what pane we're on, and send a WM_COMMAND message to the
// parent window, with the pane id as the low word of wParam,
// and the message causing the command as the lParam
void CStatusBarACT::SendPaneCommand(CPoint point, UINT message)
{
CWnd* pParent = GetParent();
if (pParent != NULL)
{
int nIndex = HitTest(point);
if (nIndex != -1)
{
UINT nID = GetItemID(nIndex);
BOOL bDblClk = message == WM_LBUTTONDBLCLK || message == WM_RBUTTONDBLCLK || message == WM_MBUTTONDBLCLK;
BOOL bLeft = message == WM_LBUTTONDOWN || message == WM_LBUTTONDBLCLK;
BOOL bRight = message == WM_RBUTTONDOWN || message == WM_RBUTTONDBLCLK;
BOOL bMiddle = message == WM_MBUTTONDOWN || message == WM_MBUTTONDBLCLK;
DWORD dwFlags = 0;
if (m_adwFlags.GetSize() > nIndex && m_adwFlags[nIndex] & SBACTF_COMMAND)
{
dwFlags = m_adwFlags[nIndex];
if (((bDblClk && (dwFlags & SBACTF_DOUBLECLICK)) ||
(! bDblClk && (dwFlags & SBACTF_SINGLECLICK))))
{
BOOL bDoCommand = FALSE;
if (((bLeft && dwFlags & SBACTF_LEFTBUTTON) ||
(bRight && dwFlags & SBACTF_RIGHTBUTTON) ||
(bMiddle && dwFlags & SBACTF_MIDDLEBUTTON)))
bDoCommand = TRUE;
if ((bLeft && !(dwFlags & SBACTF_LEFTBUTTON)) ||
(bRight && !(dwFlags & SBACTF_RIGHTBUTTON)) ||
(bMiddle && !(dwFlags & SBACTF_MIDDLEBUTTON)))
bDoCommand = FALSE;
if (bDoCommand)
pParent->SendMessage(WM_COMMAND, MAKEWPARAM(nID, message), 0L/*(LPARAM)GetSafeHwnd()*/);
}
}
}
}
}
#ifndef IDC_HAND
#define IDC_HAND MAKEINTRESOURCE(32649)
#endif // IDC_HAND
// if we're over a pane that has a custom cursor specified, then show it
// else if pane has the SBACTF_HANDCURSOR style then change it to a hand
BOOL CStatusBarACT::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (nHitTest == HTCLIENT)
{
CPoint pt;
GetCursorPos(&pt);
ScreenToClient(&pt);
int nIndex = HitTest(pt);
if (nIndex != -1)
{
HCURSOR hCursor = GetPaneCursorIndex(nIndex);
if (hCursor == NULL)
{
DWORD dwFlags = GetPaneFlagsIndex(nIndex);
if (dwFlags & SBACTF_HANDCURSOR)
{
if (m_bTryDefaultHandCursor)
hCursor = AfxGetApp()->LoadStandardCursor(IDC_HAND);
if (! m_bTryDefaultHandCursor || hCursor == NULL)
hCursor = m_hCursorHand;
}
}
if (hCursor != NULL)
{
SetCursor(hCursor);
return TRUE;
}
}
}
return CStatusBar::OnSetCursor(pWnd, nHitTest, message);
}
// sets the flags for a pane by the pane's index
BOOL CStatusBarACT::SetPaneFlagsIndex(int nIndex, DWORD dwFlags/*=SBACTF_NORMAL*/)
{
// make sure array is big enough
int nMax = GetStatusBarCtrl().GetParts(0, NULL);
if (nIndex >= nMax || nIndex < 0)
return FALSE;
if ((dwFlags & SBACTF_CLICKFLAGMASK) == 0)
dwFlags |= SBACTF_DOUBLECLICK; // default to just double-click
if ((dwFlags & SBACTF_BUTTONFLAGMASK) == 0)
dwFlags |= SBACTF_LEFTBUTTON; // default to just left button
if (dwFlags & SBACTF_STRETCHY)
{
dwFlags &= ~SBACTF_AUTOFIT;
SetPaneStyle(nIndex, GetPaneStyle(nIndex) | SBPS_STRETCH);
}
m_adwFlags.SetAtGrow(nIndex, dwFlags);
return TRUE;
}
// sets the flags for a pane by the pane's ID
BOOL CStatusBarACT::SetPaneFlags(UINT nID, DWORD dwFlags/*=SBACTF_NORMAL*/)
{
return SetPaneFlagsIndex(CommandToIndex(nID), dwFlags);
}
// gets the flags for a pane by the pane's index
DWORD CStatusBarACT::GetPaneFlagsIndex(int nIndex)
{
// make sure array is big enough
int nMax = GetStatusBarCtrl().GetParts(0, NULL);
if (nIndex >= nMax || nIndex < 0 || m_adwFlags.GetSize() <= nIndex)
return 0;
DWORD dwFlags = m_adwFlags[nIndex];
return dwFlags;
}
// gets the flags for a pane by the pane's ID
DWORD CStatusBarACT::GetPaneFlags(UINT nID)
{
return GetPaneFlagsIndex(CommandToIndex(nID));
}
// sets a pane's tool-tip text, by the pane's ID
BOOL CStatusBarACT::SetPaneTooltip(UINT nID, LPCTSTR lpszText/*=NULL*/)
{
return SetPaneTooltipIndex(CommandToIndex(nID), lpszText);
}
// sets a pane's tool-tip text, by the pane's index
BOOL CStatusBarACT::SetPaneTooltipIndex(int nIndex, LPCTSTR lpszText/*=NULL*/)
{
int nMax = GetStatusBarCtrl().GetParts(0, NULL);
if (nIndex >= nMax || nIndex < 0)
return FALSE;
CToolInfo ti;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?