📄 atlctrlx.h
字号:
int nLen = GetWindowTextLength();
if(nLen > 0)
{
LPTSTR lpszText = (LPTSTR)_alloca((nLen+1)*sizeof(TCHAR));
if(GetWindowText(lpszText, nLen+1))
SetLabel(lpszText);
}
}
// set hyperlink (defaults to label)
if(m_lpstrHyperLink == NULL && m_lpstrLabel != NULL)
SetHyperLink(m_lpstrLabel);
T* pT = static_cast<T*>(this);
pT->CalcLabelRect();
// create a tool tip
m_tip.Create(m_hWnd);
ATLASSERT(m_tip.IsWindow());
m_tip.Activate(TRUE);
m_tip.AddTool(m_hWnd, m_lpstrHyperLink);
// set link colors
if(m_bPaintLabel)
{
CRegKey rk;
LONG lRet = rk.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Internet Explorer\\Settings"));
if(lRet == 0)
{
TCHAR szBuff[12];
#if (_ATL_VER >= 0x0700)
ULONG ulCount = 12 * sizeof(TCHAR);
lRet = rk.QueryStringValue(_T("Anchor Color"), szBuff, &ulCount);
#else
DWORD dwCount = 12 * sizeof(TCHAR);
lRet = rk.QueryValue(szBuff, _T("Anchor Color"), &dwCount);
#endif
if(lRet == 0)
{
COLORREF clr = _ParseColorString(szBuff);
ATLASSERT(clr != CLR_INVALID);
if(clr != CLR_INVALID)
m_clrLink = clr;
}
#if (_ATL_VER >= 0x0700)
ulCount = 12 * sizeof(TCHAR);
lRet = rk.QueryStringValue(_T("Anchor Color Visited"), szBuff, &ulCount);
#else
dwCount = 12 * sizeof(TCHAR);
lRet = rk.QueryValue(szBuff, _T("Anchor Color Visited"), &dwCount);
#endif
if(lRet == 0)
{
COLORREF clr = _ParseColorString(szBuff);
ATLASSERT(clr != CLR_INVALID);
if(clr != CLR_INVALID)
m_clrVisited = clr;
}
}
}
}
static COLORREF _ParseColorString(LPTSTR lpstr)
{
int c[3] = { -1, -1, -1 };
LPTSTR p;
for(int i = 0; i < 2; i++)
{
for(p = lpstr; *p != _T('\0'); p = ::CharNext(p))
{
if(*p == _T(','))
{
*p = _T('\0');
c[i] = _ttoi(lpstr);
lpstr = &p[1];
break;
}
}
if(c[i] == -1)
return CLR_INVALID;
}
if(*lpstr == _T('\0'))
return CLR_INVALID;
c[2] = _ttoi(lpstr);
return RGB(c[0], c[1], c[2]);
}
bool CalcLabelRect()
{
if(!::IsWindow(m_hWnd))
return false;
if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL)
return false;
CClientDC dc(m_hWnd);
RECT rect;
GetClientRect(&rect);
m_rcLink = rect;
if(m_bPaintLabel)
{
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 = (rect.right - m_rcLink.right) / 2;
::OffsetRect(&m_rcLink, dx, 0);
}
else if (dwStyle & SS_RIGHT)
{
int dx = rect.right - m_rcLink.right;
::OffsetRect(&m_rcLink, dx, 0);
}
}
return true;
}
void DoPaint(CDCHandle dc)
{
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(m_bVisited ? m_clrVisited : m_clrLink);
if(m_hFont != NULL)
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);
if(GetFocus() == m_hWnd)
dc.DrawFocusRect(&m_rcLink);
}
};
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)
{
HINSTANCE hInstance = bSys ? NULL : _Module.GetResourceInstance();
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;
}
};
/////////////////////////////////////////////////////////////////////////////
// CMultiPaneStatusBarCtrl - Status Bar with multiple panes
template <class T, class TBase = CStatusBarCtrl>
class ATL_NO_VTABLE CMultiPaneStatusBarCtrlImpl : public 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)
{
return CWindowImpl< T, TBase >::Create(hWndParent, rcDefault, lpstrText, dwStyle, 0, nID);
}
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)
{
TCHAR szText[128]; // max text lentgth is 127 for status bars
szText[0] = 0;
::LoadString(_Module.GetResourceInstance(), nTextID, szText, 127);
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];
GetBorders(arrBorders);
TCHAR szBuff[256];
SIZE size;
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
{
::LoadString(_Module.GetResourceInstance(), pPanes[i], szBuff, sizeof(szBuff) / sizeof(TCHAR));
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)
{
::LoadString(_Module.GetResourceInstance(), pPanes[i], szBuff, sizeof(szBuff) / sizeof(TCHAR));
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;
return true;
}
BOOL GetPaneText(int nPaneID, LPTSTR lpstrText, int* pcchLength = NULL, int* pnType = NULL) const
{
ATLASSERT(::IsWindow(m_hWnd));
int nIndex = GetPaneIndexFromID(nPaneID);
if(nIndex == -1)
return FALSE;
int nLength = GetText(nIndex, lpstrText, pnType);
if(pcchLength != NULL)
*pcchLength = nLength;
return TRUE;
}
BOOL SetPaneText(int nPaneID, LPCTSTR lpstrText, int nType = 0)
{
ATLASSERT(::IsWindow(m_hWnd));
int nIndex = GetPaneIndexFromID(nPaneID);
if(nIndex == -1)
return FALSE;
return SetText(nIndex, lpstrText, nType);
}
BOOL GetPaneRect(int nPaneID, LPRECT lpRect) const
{
ATLASSERT(::IsWindow(m_hWnd));
int nIndex = GetPaneIndexFromID(nPaneID);
if(nIndex == -1)
return FALSE;
return GetRect(nIndex, lpRect);
}
BOOL SetPaneWidth(int nPaneID, int cxWidth)
{
ATLASSERT(::IsWindow(m_hWnd));
ATLASSERT(nPaneID != ID_DEFAULT_PANE); // Can't resize this one
int nIndex = GetPaneIndexFromID(nPaneID);
if(nIndex == -1)
return FALSE;
// get pane positions
int* pPanesPos = NULL;
ATLTRY(pPanesPos = (int*)_alloca(m_nPanes * sizeof(int)));
GetParts(m_nPanes, pPanesPos);
// calculate offset
int cxPaneWidth = pPanesPos[nIndex] - ((nIndex == 0) ? 0 : pPanesPos[nIndex - 1]);
int cxOff = cxWidth - cxPaneWidth;
// find variable width pane
int nDef = m_nPanes;
for(int i = 0; i < m_nPanes; i++)
{
if(m_pPane[i] == ID_DEFAULT_PANE)
{
nDef = i;
break;
}
}
// resize
if(nIndex < nDef) // before default pane
{
for(int i = nIndex; i < nDef; i++)
pPanesPos[i] += cxOff;
}
else // after default one
{
for(int i = nDef; i < nIndex; i++)
pPanesPos[i] -= cxOff;
}
// set pane postions
return SetParts(m_nPanes, pPanesPos);
}
#if (_WIN32_IE >= 0x0400)
BOOL GetPaneTipText(int nPaneID, LPTSTR lpstrText, int nSize) const
{
ATLASSERT(::IsWindow(m_hWnd));
int nIndex = GetPaneIndexFromID(nPaneID);
if(nIndex == -1)
return FALSE;
GetTipText(nIndex, lpstrText, nSize);
return TRUE;
}
BOOL SetPaneTipText(int nPaneID, LPCTSTR lpstrText)
{
ATLASSERT(::IsWindow(m_hWnd));
int nIndex = GetPaneIndexFromID(nPaneID);
if(nIndex == -1)
return FALSE;
SetTipText(nIndex, lpstrText);
return TRUE;
}
BOOL GetPaneIcon(int nPaneID, HICON& hIcon) const
{
ATLASSERT(::IsWindow(m_hWnd));
int nIndex = GetPaneIndexFromID(nPaneID);
if(nIndex == -1)
return FALSE;
hIcon = GetIcon(nIndex);
return TRUE;
}
BOOL SetPaneIcon(int nPaneID, HICON hIcon)
{
ATLASSERT(::IsWindow(m_hWnd));
int nIndex = GetPaneIndexFromID(nPaneID);
if(nIndex == -1)
return FALSE;
return SetIcon(nIndex, hIcon);
}
#endif //(_WIN32_IE >= 0x0400)
// Message map and handlers
BEGIN_MSG_MAP(CMultiPaneStatusBarCtrlImpl< T >)
MESSAGE_HANDLER(WM_SIZE, OnSize)
END_MSG_MAP()
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
if(wParam != SIZE_MINIMIZED && m_nPanes > 0)
{
T* pT = static_cast<T*>(this);
pT->UpdatePanesLayout();
}
return lRet;
}
// Implementation
BOOL UpdatePanesLayout()
{
// get pane positions
int* pPanesPos = NULL;
ATLTRY(pPanesPos = (int*)_alloca(m_nPanes * sizeof(int)));
ATLASSERT(pPanesPos != NULL);
if(pPanesPos == NULL)
return FALSE;
int nRet = GetParts(m_nPanes, pPanesPos);
ATLASSERT(nRet == m_nPanes);
if(nRet != m_nPanes)
return FALSE;
// calculate offset
RECT rcClient;
GetClientRect(&rcClient);
int cxOff = rcClient.right - (pPanesPos[m_nPanes - 1] + ::GetSystemMetrics(SM_CXVSCROLL) + ::GetSystemMetrics(SM_CXEDGE));
// find variable width pane
int i;
for(i = 0; i < m_nPanes; i++)
{
if(m_pPane[i] == ID_DEFAULT_PANE)
break;
}
// resize all panes from the variable one to the right
if((i < m_nPanes) && (pPanesPos[i] + cxOff) > ((i == 0) ? 0 : pPanesPos[i - 1]))
{
for(; i < m_nPanes; i++)
pPanesPos[i] += cxOff;
}
// set pane postions
return SetParts(m_nPanes, pPanesPos);
}
int GetPaneIndexFromID(int nPaneID) const
{
for(int i = 0; i < m_nPanes; i++)
{
if(m_pPane[i] == nPaneID)
return i;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -