📄 atlctrlx.h
字号:
GetClientRect(&rcClient);
m_rcLink = rcClient;
if(!m_bPaintLabel)
return true;
if(IsUsingTags())
{
// find tags and label parts
LPTSTR lpstrLeft = NULL;
int cchLeft = 0;
LPTSTR lpstrLink = NULL;
int cchLink = 0;
LPTSTR lpstrRight = NULL;
int cchRight = 0;
T* pT = static_cast<T*>(this);
pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight);
ATLASSERT(lpstrLink != NULL);
ATLASSERT(cchLink > 0);
// get label part rects
HFONT hFontOld = dc.SelectFont(m_hFontNormal);
RECT rcLeft = rcClient;
if(lpstrLeft != NULL)
dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | DT_WORDBREAK | DT_CALCRECT);
dc.SelectFont(m_hFont);
RECT rcLink = rcClient;
if(lpstrLeft != NULL)
rcLink.left = rcLeft.right;
dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | DT_WORDBREAK | DT_CALCRECT);
dc.SelectFont(hFontOld);
m_rcLink = rcLink;
}
else
{
HFONT hOldFont = NULL;
if(m_hFont != NULL)
hOldFont = dc.SelectFont(m_hFont);
LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
DWORD dwStyle = GetStyle();
int nDrawStyle = DT_LEFT;
if (dwStyle & SS_CENTER)
nDrawStyle = DT_CENTER;
else if (dwStyle & SS_RIGHT)
nDrawStyle = DT_RIGHT;
dc.DrawText(lpstrText, -1, &m_rcLink, nDrawStyle | DT_WORDBREAK | DT_CALCRECT);
if(m_hFont != NULL)
dc.SelectFont(hOldFont);
if (dwStyle & SS_CENTER)
{
int dx = (rcClient.right - m_rcLink.right) / 2;
::OffsetRect(&m_rcLink, dx, 0);
}
else if (dwStyle & SS_RIGHT)
{
int dx = rcClient.right - m_rcLink.right;
::OffsetRect(&m_rcLink, dx, 0);
}
}
return true;
}
void CalcLabelParts(LPTSTR& lpstrLeft, int& cchLeft, LPTSTR& lpstrLink, int& cchLink, LPTSTR& lpstrRight, int& cchRight) const
{
lpstrLeft = NULL;
cchLeft = 0;
lpstrLink = NULL;
cchLink = 0;
lpstrRight = NULL;
cchRight = 0;
LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
int cchText = lstrlen(lpstrText);
bool bOutsideLink = true;
for(int i = 0; i < cchText; i++)
{
if(lpstrText[i] != _T('<'))
continue;
if(bOutsideLink)
{
if(::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, &lpstrText[i], 3, _T("<A>"), 3) == CSTR_EQUAL)
{
if(i > 0)
{
lpstrLeft = lpstrText;
cchLeft = i;
}
lpstrLink = &lpstrText[i + 3];
bOutsideLink = false;
}
}
else
{
if(::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, &lpstrText[i], 4, _T("</A>"), 4) == CSTR_EQUAL)
{
cchLink = i - 3 - cchLeft;
if(lpstrText[i + 4] != 0)
{
lpstrRight = &lpstrText[i + 4];
cchRight = cchText - (i + 4);
break;
}
}
}
}
}
void DoEraseBackground(CDCHandle dc)
{
HBRUSH hBrush = (HBRUSH)::SendMessage(GetParent(), WM_CTLCOLORSTATIC, (WPARAM)dc.m_hDC, (LPARAM)m_hWnd);
if(hBrush != NULL)
{
RECT rect = { 0 };
GetClientRect(&rect);
dc.FillRect(&rect, hBrush);
}
}
void DoPaint(CDCHandle dc)
{
if(IsUsingTags())
{
// find tags and label parts
LPTSTR lpstrLeft = NULL;
int cchLeft = 0;
LPTSTR lpstrLink = NULL;
int cchLink = 0;
LPTSTR lpstrRight = NULL;
int cchRight = 0;
T* pT = static_cast<T*>(this);
pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight);
// get label part rects
RECT rcClient = { 0 };
GetClientRect(&rcClient);
dc.SetBkMode(TRANSPARENT);
HFONT hFontOld = dc.SelectFont(m_hFontNormal);
if(lpstrLeft != NULL)
dc.DrawText(lpstrLeft, cchLeft, &rcClient, DT_LEFT | DT_WORDBREAK);
COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT)));
if(m_hFont != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover)))
dc.SelectFont(m_hFont);
else
dc.SelectFont(m_hFontNormal);
dc.DrawText(lpstrLink, cchLink, &m_rcLink, DT_LEFT | DT_WORDBREAK);
dc.SetTextColor(clrOld);
dc.SelectFont(m_hFontNormal);
if(lpstrRight != NULL)
{
RECT rcRight = { m_rcLink.right, m_rcLink.top, rcClient.right, rcClient.bottom };
dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | DT_WORDBREAK);
}
if(GetFocus() == m_hWnd)
dc.DrawFocusRect(&m_rcLink);
dc.SelectFont(hFontOld);
}
else
{
dc.SetBkMode(TRANSPARENT);
COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT)));
HFONT hFontOld = NULL;
if(m_hFont != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover)))
hFontOld = dc.SelectFont(m_hFont);
else
hFontOld = dc.SelectFont(m_hFontNormal);
LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
DWORD dwStyle = GetStyle();
int nDrawStyle = DT_LEFT;
if (dwStyle & SS_CENTER)
nDrawStyle = DT_CENTER;
else if (dwStyle & SS_RIGHT)
nDrawStyle = DT_RIGHT;
dc.DrawText(lpstrText, -1, &m_rcLink, nDrawStyle | DT_WORDBREAK);
if(GetFocus() == m_hWnd)
dc.DrawFocusRect(&m_rcLink);
dc.SetTextColor(clrOld);
dc.SelectFont(hFontOld);
}
}
#ifndef _WIN32_WCE
BOOL StartTrackMouseLeave()
{
TRACKMOUSEEVENT tme = { 0 };
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = m_hWnd;
return _TrackMouseEvent(&tme);
}
#endif //!_WIN32_WCE
// Implementation helpers
bool IsUnderlined() const
{
return ((m_dwExtendedStyle & (HLINK_NOTUNDERLINED | HLINK_UNDERLINEHOVER)) == 0);
}
bool IsNotUnderlined() const
{
return ((m_dwExtendedStyle & HLINK_NOTUNDERLINED) != 0);
}
bool IsUnderlineHover() const
{
return ((m_dwExtendedStyle & HLINK_UNDERLINEHOVER) != 0);
}
bool IsCommandButton() const
{
return ((m_dwExtendedStyle & HLINK_COMMANDBUTTON) != 0);
}
bool IsNotifyButton() const
{
return ((m_dwExtendedStyle & HLINK_NOTIFYBUTTON) == HLINK_NOTIFYBUTTON);
}
bool IsUsingTags() const
{
return ((m_dwExtendedStyle & HLINK_USETAGS) != 0);
}
bool IsUsingTagsBold() const
{
return ((m_dwExtendedStyle & HLINK_USETAGSBOLD) == HLINK_USETAGSBOLD);
}
bool IsUsingToolTip() const
{
return ((m_dwExtendedStyle & HLINK_NOTOOLTIP) == 0);
}
};
class CHyperLink : public CHyperLinkImpl<CHyperLink>
{
public:
DECLARE_WND_CLASS(_T("WTL_HyperLink"))
};
///////////////////////////////////////////////////////////////////////////////
// CWaitCursor - displays a wait cursor
class CWaitCursor
{
public:
// Data
HCURSOR m_hWaitCursor;
HCURSOR m_hOldCursor;
bool m_bInUse;
// Constructor/destructor
CWaitCursor(bool bSet = true, LPCTSTR lpstrCursor = IDC_WAIT, bool bSys = true) : m_hOldCursor(NULL), m_bInUse(false)
{
#if (_ATL_VER >= 0x0700)
HINSTANCE hInstance = bSys ? NULL : ATL::_AtlBaseModule.GetResourceInstance();
#else //!(_ATL_VER >= 0x0700)
HINSTANCE hInstance = bSys ? NULL : _Module.GetResourceInstance();
#endif //!(_ATL_VER >= 0x0700)
m_hWaitCursor = ::LoadCursor(hInstance, lpstrCursor);
ATLASSERT(m_hWaitCursor != NULL);
if(bSet)
Set();
}
~CWaitCursor()
{
Restore();
}
// Methods
bool Set()
{
if(m_bInUse)
return false;
m_hOldCursor = ::SetCursor(m_hWaitCursor);
m_bInUse = true;
return true;
}
bool Restore()
{
if(!m_bInUse)
return false;
::SetCursor(m_hOldCursor);
m_bInUse = false;
return true;
}
};
///////////////////////////////////////////////////////////////////////////////
// CCustomWaitCursor - for custom and animated cursors
class CCustomWaitCursor : public CWaitCursor
{
public:
// Constructor/destructor
CCustomWaitCursor(ATL::_U_STRINGorID cursor, bool bSet = true, HINSTANCE hInstance = NULL) :
CWaitCursor(false, IDC_WAIT, true)
{
if(hInstance == NULL)
{
#if (_ATL_VER >= 0x0700)
hInstance = ATL::_AtlBaseModule.GetResourceInstance();
#else //!(_ATL_VER >= 0x0700)
hInstance = _Module.GetResourceInstance();
#endif //!(_ATL_VER >= 0x0700)
}
m_hWaitCursor = (HCURSOR)::LoadImage(hInstance, cursor.m_lpstr, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE);
if(bSet)
Set();
}
~CCustomWaitCursor()
{
Restore();
#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)))
::DestroyCursor(m_hWaitCursor);
#endif //!defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)))
}
};
///////////////////////////////////////////////////////////////////////////////
// CMultiPaneStatusBarCtrl - Status Bar with multiple panes
template <class T, class TBase = CStatusBarCtrl>
class ATL_NO_VTABLE CMultiPaneStatusBarCtrlImpl : public ATL::CWindowImpl< T, TBase >
{
public:
DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
// Data
enum { m_cxPaneMargin = 3 };
int m_nPanes;
int* m_pPane;
// Constructor/destructor
CMultiPaneStatusBarCtrlImpl() : m_nPanes(0), m_pPane(NULL)
{ }
~CMultiPaneStatusBarCtrlImpl()
{
delete [] m_pPane;
}
// Methods
HWND Create(HWND hWndParent, LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR)
{
#if (_MSC_VER >= 1300)
return ATL::CWindowImpl< T, TBase >::Create(hWndParent, rcDefault, lpstrText, dwStyle, 0, nID);
#else //!(_MSC_VER >= 1300)
typedef ATL::CWindowImpl< T, TBase > _baseClass;
return _baseClass::Create(hWndParent, rcDefault, lpstrText, dwStyle, 0, nID);
#endif //!(_MSC_VER >= 1300)
}
HWND Create(HWND hWndParent, UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR)
{
const int cchMax = 128; // max text length is 127 for status bars (+1 for null)
TCHAR szText[cchMax];
szText[0] = 0;
#if (_ATL_VER >= 0x0700)
::LoadString(ATL::_AtlBaseModule.GetResourceInstance(), nTextID, szText, cchMax);
#else //!(_ATL_VER >= 0x0700)
::LoadString(_Module.GetResourceInstance(), nTextID, szText, cchMax);
#endif //!(_ATL_VER >= 0x0700)
return Create(hWndParent, szText, dwStyle, nID);
}
BOOL SetPanes(int* pPanes, int nPanes, bool bSetText = true)
{
ATLASSERT(::IsWindow(m_hWnd));
ATLASSERT(nPanes > 0);
m_nPanes = nPanes;
delete [] m_pPane;
m_pPane = NULL;
ATLTRY(m_pPane = new int[nPanes]);
ATLASSERT(m_pPane != NULL);
if(m_pPane == NULL)
return FALSE;
memcpy(m_pPane, pPanes, nPanes * sizeof(int));
int* pPanesPos = NULL;
ATLTRY(pPanesPos = (int*)_alloca(nPanes * sizeof(int)));
ATLASSERT(pPanesPos != NULL);
// get status bar DC and set font
CClientDC dc(m_hWnd);
HFONT hOldFont = dc.SelectFont(GetFont());
// get status bar borders
int arrBorders[3] = { 0 };
GetBorders(arrBorders);
const int cchBuff = 128;
TCHAR szBuff[cchBuff] = { 0 };
SIZE size = { 0, 0 };
int cxLeft = arrBorders[0];
// calculate right edge of each part
for(int i = 0; i < nPanes; i++)
{
if(pPanes[i] == ID_DEFAULT_PANE)
{
// will be resized later
pPanesPos[i] = 100 + cxLeft + arrBorders[2];
}
else
{
#if (_ATL_VER >= 0x0700)
::LoadString(ATL::_AtlBaseModule.GetResourceInstance(), pPanes[i], szBuff, cchBuff);
#else //!(_ATL_VER >= 0x0700)
::LoadString(_Module.GetResourceInstance(), pPanes[i], szBuff, cchBuff);
#endif //!(_ATL_VER >= 0x0700)
dc.GetTextExtent(szBuff, lstrlen(szBuff), &size);
T* pT = static_cast<T*>(this);
pT;
pPanesPos[i] = cxLeft + size.cx + arrBorders[2] + 2 * pT->m_cxPaneMargin;
}
cxLeft = pPanesPos[i];
}
BOOL bRet = SetParts(nPanes, pPanesPos);
if(bRet && bSetText)
{
for(int i = 0; i < nPanes; i++)
{
if(pPanes[i] != ID_DEFAULT_PANE)
{
#if (_ATL_VER >= 0x0700)
::LoadString(ATL::_AtlBaseModule.GetResourceInstance(), pPanes[i], szBuff, cchBuff);
#else //!(_ATL_VER >= 0x0700)
::LoadString(_Module.GetResourceInstance(), pPanes[i], szBuff, cchBuff);
#endif //!(_ATL_VER >= 0x0700)
SetPaneText(m_pPane[i], szBuff);
}
}
}
dc.SelectFont(hOldFont);
return bRet;
}
bool GetPaneTextLength(int nPaneID, int* pcchLength = NULL, int* pnType = NULL) const
{
ATLASSERT(::IsWindow(m_hWnd));
int nIndex = GetPaneIndexFromID(nPaneID);
if(nIndex == -1)
return false;
int nLength = GetTextLength(nIndex, pnType);
if(pcchLength != NULL)
*pcchLength = nLength;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -