📄 atlctrlx.h
字号:
// Windows Template Library - WTL version 8.0
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// This file is a part of the Windows Template Library.
// The use and distribution terms for this software are covered by the
// Microsoft Permissive License (Ms-PL) which can be found in the file
// Ms-PL.txt at the root of this distribution.
#ifndef __ATLCTRLX_H__
#define __ATLCTRLX_H__
#pragma once
#ifndef __cplusplus
#error ATL requires C++ compilation (use a .cpp suffix)
#endif
#ifndef __ATLAPP_H__
#error atlctrlx.h requires atlapp.h to be included first
#endif
#ifndef __ATLCTRLS_H__
#error atlctrlx.h requires atlctrls.h to be included first
#endif
#ifndef WM_UPDATEUISTATE
#define WM_UPDATEUISTATE 0x0128
#endif // !WM_UPDATEUISTATE
///////////////////////////////////////////////////////////////////////////////
// Classes in this file:
//
// CBitmapButtonImpl<T, TBase, TWinTraits>
// CBitmapButton
// CCheckListViewCtrlImpl<T, TBase, TWinTraits>
// CCheckListViewCtrl
// CHyperLinkImpl<T, TBase, TWinTraits>
// CHyperLink
// CWaitCursor
// CCustomWaitCursor
// CMultiPaneStatusBarCtrlImpl<T, TBase>
// CMultiPaneStatusBarCtrl
// CPaneContainerImpl<T, TBase, TWinTraits>
// CPaneContainer
// CSortListViewImpl<T>
// CSortListViewCtrlImpl<T, TBase, TWinTraits>
// CSortListViewCtrl
// CTabViewImpl<T, TBase, TWinTraits>
// CTabView
namespace WTL
{
///////////////////////////////////////////////////////////////////////////////
// CBitmapButton - bitmap button implementation
#ifndef _WIN32_WCE
// bitmap button extended styles
#define BMPBTN_HOVER 0x00000001
#define BMPBTN_AUTO3D_SINGLE 0x00000002
#define BMPBTN_AUTO3D_DOUBLE 0x00000004
#define BMPBTN_AUTOSIZE 0x00000008
#define BMPBTN_SHAREIMAGELISTS 0x00000010
#define BMPBTN_AUTOFIRE 0x00000020
template <class T, class TBase = CButton, class TWinTraits = ATL::CControlWinTraits>
class ATL_NO_VTABLE CBitmapButtonImpl : public ATL::CWindowImpl< T, TBase, TWinTraits>
{
public:
DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
enum
{
_nImageNormal = 0,
_nImagePushed,
_nImageFocusOrHover,
_nImageDisabled,
_nImageCount = 4,
};
enum
{
ID_TIMER_FIRST = 1000,
ID_TIMER_REPEAT = 1001
};
// Bitmap button specific extended styles
DWORD m_dwExtendedStyle;
CImageList m_ImageList;
int m_nImage[_nImageCount];
CToolTipCtrl m_tip;
LPTSTR m_lpstrToolTipText;
// Internal states
unsigned m_fMouseOver:1;
unsigned m_fFocus:1;
unsigned m_fPressed:1;
// Constructor/Destructor
CBitmapButtonImpl(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) :
m_ImageList(hImageList), m_dwExtendedStyle(dwExtendedStyle),
m_lpstrToolTipText(NULL),
m_fMouseOver(0), m_fFocus(0), m_fPressed(0)
{
m_nImage[_nImageNormal] = -1;
m_nImage[_nImagePushed] = -1;
m_nImage[_nImageFocusOrHover] = -1;
m_nImage[_nImageDisabled] = -1;
}
~CBitmapButtonImpl()
{
if((m_dwExtendedStyle & BMPBTN_SHAREIMAGELISTS) == 0)
m_ImageList.Destroy();
delete [] m_lpstrToolTipText;
}
// overridden to provide proper initialization
BOOL SubclassWindow(HWND hWnd)
{
#if (_MSC_VER >= 1300)
BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits>::SubclassWindow(hWnd);
#else // !(_MSC_VER >= 1300)
typedef ATL::CWindowImpl< T, TBase, TWinTraits> _baseClass;
BOOL bRet = _baseClass::SubclassWindow(hWnd);
#endif // !(_MSC_VER >= 1300)
if(bRet)
Init();
return bRet;
}
// Attributes
DWORD GetBitmapButtonExtendedStyle() const
{
return m_dwExtendedStyle;
}
DWORD SetBitmapButtonExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
{
DWORD dwPrevStyle = m_dwExtendedStyle;
if(dwMask == 0)
m_dwExtendedStyle = dwExtendedStyle;
else
m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
return dwPrevStyle;
}
HIMAGELIST GetImageList() const
{
return m_ImageList;
}
HIMAGELIST SetImageList(HIMAGELIST hImageList)
{
HIMAGELIST hImageListPrev = m_ImageList;
m_ImageList = hImageList;
if((m_dwExtendedStyle & BMPBTN_AUTOSIZE) != 0 && ::IsWindow(m_hWnd))
SizeToImage();
return hImageListPrev;
}
int GetToolTipTextLength() const
{
return (m_lpstrToolTipText == NULL) ? -1 : lstrlen(m_lpstrToolTipText);
}
bool GetToolTipText(LPTSTR lpstrText, int nLength) const
{
ATLASSERT(lpstrText != NULL);
if(m_lpstrToolTipText == NULL)
return false;
errno_t nRet = SecureHelper::strncpy_x(lpstrText, nLength, m_lpstrToolTipText, _TRUNCATE);
return (nRet == 0 || nRet == STRUNCATE);
}
bool SetToolTipText(LPCTSTR lpstrText)
{
if(m_lpstrToolTipText != NULL)
{
delete [] m_lpstrToolTipText;
m_lpstrToolTipText = NULL;
}
if(lpstrText == NULL)
{
if(m_tip.IsWindow())
m_tip.Activate(FALSE);
return true;
}
int cchLen = lstrlen(lpstrText) + 1;
ATLTRY(m_lpstrToolTipText = new TCHAR[cchLen]);
if(m_lpstrToolTipText == NULL)
return false;
SecureHelper::strcpy_x(m_lpstrToolTipText, cchLen, lpstrText);
if(m_tip.IsWindow())
{
m_tip.Activate(TRUE);
m_tip.AddTool(m_hWnd, m_lpstrToolTipText);
}
return true;
}
// Operations
void SetImages(int nNormal, int nPushed = -1, int nFocusOrHover = -1, int nDisabled = -1)
{
if(nNormal != -1)
m_nImage[_nImageNormal] = nNormal;
if(nPushed != -1)
m_nImage[_nImagePushed] = nPushed;
if(nFocusOrHover != -1)
m_nImage[_nImageFocusOrHover] = nFocusOrHover;
if(nDisabled != -1)
m_nImage[_nImageDisabled] = nDisabled;
}
BOOL SizeToImage()
{
ATLASSERT(::IsWindow(m_hWnd) && m_ImageList.m_hImageList != NULL);
int cx = 0;
int cy = 0;
if(!m_ImageList.GetIconSize(cx, cy))
return FALSE;
return ResizeClient(cx, cy);
}
// Overrideables
void DoPaint(CDCHandle dc)
{
ATLASSERT(m_ImageList.m_hImageList != NULL); // image list must be set
ATLASSERT(m_nImage[0] != -1); // main bitmap must be set
// set bitmap according to the current button state
int nImage = -1;
bool bHover = IsHoverMode();
if(!IsWindowEnabled())
nImage = m_nImage[_nImageDisabled];
else if(m_fPressed == 1)
nImage = m_nImage[_nImagePushed];
else if((!bHover && m_fFocus == 1) || (bHover && m_fMouseOver == 1))
nImage = m_nImage[_nImageFocusOrHover];
if(nImage == -1) // not there, use default one
nImage = m_nImage[_nImageNormal];
// draw the button image
int xyPos = 0;
if((m_fPressed == 1) && ((m_dwExtendedStyle & (BMPBTN_AUTO3D_SINGLE | BMPBTN_AUTO3D_DOUBLE)) != 0) && (m_nImage[_nImagePushed] == -1))
xyPos = 1;
m_ImageList.Draw(dc, nImage, xyPos, xyPos, ILD_NORMAL);
// draw 3D border if required
if((m_dwExtendedStyle & (BMPBTN_AUTO3D_SINGLE | BMPBTN_AUTO3D_DOUBLE)) != 0)
{
RECT rect;
GetClientRect(&rect);
if(m_fPressed == 1)
dc.DrawEdge(&rect, ((m_dwExtendedStyle & BMPBTN_AUTO3D_SINGLE) != 0) ? BDR_SUNKENOUTER : EDGE_SUNKEN, BF_RECT);
else if(!bHover || m_fMouseOver == 1)
dc.DrawEdge(&rect, ((m_dwExtendedStyle & BMPBTN_AUTO3D_SINGLE) != 0) ? BDR_RAISEDINNER : EDGE_RAISED, BF_RECT);
if(!bHover && m_fFocus == 1)
{
::InflateRect(&rect, -2 * ::GetSystemMetrics(SM_CXEDGE), -2 * ::GetSystemMetrics(SM_CYEDGE));
dc.DrawFocusRect(&rect);
}
}
}
// Message map and handlers
BEGIN_MSG_MAP(CBitmapButtonImpl)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
MESSAGE_HANDLER(WM_SETFOCUS, OnFocus)
MESSAGE_HANDLER(WM_KILLFOCUS, OnFocus)
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk)
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
MESSAGE_HANDLER(WM_ENABLE, OnEnable)
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave)
MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
MESSAGE_HANDLER(WM_KEYUP, OnKeyUp)
MESSAGE_HANDLER(WM_TIMER, OnTimer)
MESSAGE_HANDLER(WM_UPDATEUISTATE, OnUpdateUiState)
END_MSG_MAP()
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
Init();
bHandled = FALSE;
return 1;
}
LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
if(m_tip.IsWindow())
{
m_tip.DestroyWindow();
m_tip.m_hWnd = NULL;
}
bHandled = FALSE;
return 1;
}
LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
MSG msg = { m_hWnd, uMsg, wParam, lParam };
if(m_tip.IsWindow())
m_tip.RelayEvent(&msg);
bHandled = FALSE;
return 1;
}
LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return 1; // no background needed
}
LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
if(wParam != NULL)
{
pT->DoPaint((HDC)wParam);
}
else
{
CPaintDC dc(m_hWnd);
pT->DoPaint(dc.m_hDC);
}
return 0;
}
LRESULT OnFocus(UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
m_fFocus = (uMsg == WM_SETFOCUS) ? 1 : 0;
Invalidate();
UpdateWindow();
bHandled = FALSE;
return 1;
}
LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
LRESULT lRet = 0;
if(IsHoverMode())
SetCapture();
else
lRet = DefWindowProc(uMsg, wParam, lParam);
if(::GetCapture() == m_hWnd)
{
m_fPressed = 1;
Invalidate();
UpdateWindow();
}
if((m_dwExtendedStyle & BMPBTN_AUTOFIRE) != 0)
{
int nElapse = 250;
int nDelay = 0;
if(::SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &nDelay, 0))
nElapse += nDelay * 250; // all milli-seconds
SetTimer(ID_TIMER_FIRST, nElapse);
}
return lRet;
}
LRESULT OnLButtonDblClk(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
LRESULT lRet = 0;
if(!IsHoverMode())
lRet = DefWindowProc(uMsg, wParam, lParam);
if(::GetCapture() != m_hWnd)
SetCapture();
if(m_fPressed == 0)
{
m_fPressed = 1;
Invalidate();
UpdateWindow();
}
return lRet;
}
LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
LRESULT lRet = 0;
bool bHover = IsHoverMode();
if(!bHover)
lRet = DefWindowProc(uMsg, wParam, lParam);
if(::GetCapture() == m_hWnd)
{
if(bHover && m_fPressed == 1)
::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
::ReleaseCapture();
}
return lRet;
}
LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
if(m_fPressed == 1)
{
m_fPressed = 0;
Invalidate();
UpdateWindow();
}
bHandled = FALSE;
return 1;
}
LRESULT OnEnable(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
Invalidate();
UpdateWindow();
bHandled = FALSE;
return 1;
}
LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
{
if(::GetCapture() == m_hWnd)
{
POINT ptCursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
ClientToScreen(&ptCursor);
RECT rect = { 0 };
GetWindowRect(&rect);
unsigned int uPressed = ::PtInRect(&rect, ptCursor) ? 1 : 0;
if(m_fPressed != uPressed)
{
m_fPressed = uPressed;
Invalidate();
UpdateWindow();
}
}
else if(IsHoverMode() && m_fMouseOver == 0)
{
m_fMouseOver = 1;
Invalidate();
UpdateWindow();
StartTrackMouseLeave();
}
bHandled = FALSE;
return 1;
}
LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
if(m_fMouseOver == 1)
{
m_fMouseOver = 0;
Invalidate();
UpdateWindow();
}
return 0;
}
LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
if(wParam == VK_SPACE && IsHoverMode())
return 0; // ignore if in hover mode
if(wParam == VK_SPACE && m_fPressed == 0)
{
m_fPressed = 1;
Invalidate();
UpdateWindow();
}
bHandled = FALSE;
return 1;
}
LRESULT OnKeyUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
if(wParam == VK_SPACE && IsHoverMode())
return 0; // ignore if in hover mode
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -