📄 atlctrlx.h
字号:
BOOL StartTrackMouseLeave()
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = m_hWnd;
return _TrackMouseEvent(&tme);
}
bool IsHoverMode() const
{
return ((m_dwExtendedStyle & BMPBTN_HOVER) != 0);
}
};
class CBitmapButton : public CBitmapButtonImpl<CBitmapButton>
{
public:
DECLARE_WND_SUPERCLASS(_T("WTL_BitmapButton"), GetWndClassName())
CBitmapButton(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) :
CBitmapButtonImpl<CBitmapButton>(dwExtendedStyle, hImageList)
{ }
};
/////////////////////////////////////////////////////////////////////////////
// CCheckListCtrlView - list view control with check boxes
template <DWORD t_dwStyle, DWORD t_dwExStyle, DWORD t_dwExListViewStyle>
class CCheckListViewCtrlImplTraits
{
public:
static DWORD GetWndStyle(DWORD dwStyle)
{
return (dwStyle == 0) ? t_dwStyle : dwStyle;
}
static DWORD GetWndExStyle(DWORD dwExStyle)
{
return (dwExStyle == 0) ? t_dwExStyle : dwExStyle;
}
static DWORD GetExtendedLVStyle()
{
return t_dwExListViewStyle;
}
};
typedef CCheckListViewCtrlImplTraits<WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS, WS_EX_CLIENTEDGE, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT> CCheckListViewCtrlTraits;
template <class T, class TBase = CListViewCtrl, class TWinTraits = CCheckListViewCtrlTraits>
class ATL_NO_VTABLE CCheckListViewCtrlImpl : public CWindowImpl<T, TBase, TWinTraits>
{
public:
DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
// Attributes
static DWORD GetExtendedLVStyle()
{
return TWinTraits::GetExtendedLVStyle();
}
// Operations
BOOL SubclassWindow(HWND hWnd)
{
BOOL bRet = CWindowImplBaseT< TBase, TWinTraits>::SubclassWindow(hWnd);
if(bRet)
{
T* pT = static_cast<T*>(this);
pT;
ATLASSERT((pT->GetExtendedLVStyle() & LVS_EX_CHECKBOXES) != 0);
SetExtendedListViewStyle(pT->GetExtendedLVStyle());
}
return bRet;
}
void CheckSelectedItems(int nCurrItem)
{
// first check if this item is selected
LVITEM lvi;
lvi.iItem = nCurrItem;
lvi.iSubItem = 0;
lvi.mask = LVIF_STATE;
lvi.stateMask = LVIS_SELECTED;
GetItem(&lvi);
// if item is not selected, don't do anything
if(!(lvi.state & LVIS_SELECTED))
return;
// new check state will be reverse of the current state,
BOOL bCheck = !GetCheckState(nCurrItem);
int nItem = -1;
int nOldItem = -1;
while((nItem = GetNextItem(nOldItem, LVNI_SELECTED)) != -1)
{
if(nItem != nCurrItem)
SetCheckState(nItem, bCheck);
nOldItem = nItem;
}
}
// Implementation
typedef CCheckListViewCtrlImpl< T, TBase, TWinTraits > thisClass;
BEGIN_MSG_MAP(thisClass)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDown)
MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
END_MSG_MAP()
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
// first let list view control initialize everything
LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
T* pT = static_cast<T*>(this);
pT;
ATLASSERT((pT->GetExtendedLVStyle() & LVS_EX_CHECKBOXES) != 0);
SetExtendedListViewStyle(pT->GetExtendedLVStyle());
return lRet;
}
LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
{
POINT ptMsg = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
LVHITTESTINFO lvh;
lvh.pt = ptMsg;
if(HitTest(&lvh) != -1 && lvh.flags == LVHT_ONITEMSTATEICON && ::GetKeyState(VK_CONTROL) >= 0)
CheckSelectedItems(lvh.iItem);
bHandled = FALSE;
return 1;
}
LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
if(wParam == VK_SPACE)
{
int nCurrItem = GetNextItem(-1, LVNI_FOCUSED);
if(nCurrItem != -1 && ::GetKeyState(VK_CONTROL) >= 0)
CheckSelectedItems(nCurrItem);
}
bHandled = FALSE;
return 1;
}
};
class CCheckListViewCtrl : public CCheckListViewCtrlImpl<CCheckListViewCtrl>
{
public:
DECLARE_WND_SUPERCLASS(_T("WTL_CheckListView"), GetWndClassName())
};
/////////////////////////////////////////////////////////////////////////////
// CHyperLink - hyper link control implementation
#if (WINVER < 0x0500)
__declspec(selectany) struct
{
enum { cxWidth = 32, cyHeight = 32 };
int xHotSpot;
int yHotSpot;
unsigned char arrANDPlane[cxWidth * cyHeight / 8];
unsigned char arrXORPlane[cxWidth * cyHeight / 8];
} _AtlHyperLink_CursorData =
{
5, 0,
{
0xF9, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF,
0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF,
0xF0, 0x00, 0xFF, 0xFF, 0x10, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF,
0x80, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x7F, 0xFF,
0xE0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF,
0xF8, 0x01, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
},
{
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x06, 0xD8, 0x00, 0x00,
0x06, 0xDA, 0x00, 0x00, 0x06, 0xDB, 0x00, 0x00, 0x67, 0xFB, 0x00, 0x00, 0x77, 0xFF, 0x00, 0x00,
0x37, 0xFF, 0x00, 0x00, 0x17, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x00,
0x0F, 0xFE, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00,
0x03, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
};
#endif //(WINVER < 0x0500)
template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits>
class ATL_NO_VTABLE CHyperLinkImpl : public CWindowImpl< T, TBase, TWinTraits >
{
public:
LPTSTR m_lpstrLabel;
LPTSTR m_lpstrHyperLink;
HCURSOR m_hCursor;
HFONT m_hFont;
RECT m_rcLink;
bool m_bPaintLabel;
CToolTipCtrl m_tip;
bool m_bVisited;
COLORREF m_clrLink;
COLORREF m_clrVisited;
// Constructor/Destructor
CHyperLinkImpl() : m_lpstrLabel(NULL), m_lpstrHyperLink(NULL),
m_hCursor(NULL), m_hFont(NULL), m_bPaintLabel(true), m_bVisited(false),
m_clrLink(RGB(0, 0, 255)), m_clrVisited(RGB(128, 0, 128))
{
::SetRectEmpty(&m_rcLink);
}
~CHyperLinkImpl()
{
free(m_lpstrLabel);
free(m_lpstrHyperLink);
if(m_hFont != NULL)
::DeleteObject(m_hFont);
#if (WINVER < 0x0500)
// It was created, not loaded, so we have to destroy it
if(m_hCursor != NULL)
::DestroyCursor(m_hCursor);
#endif //(WINVER < 0x0500)
}
// Attributes
bool GetLabel(LPTSTR lpstrBuffer, int nLength) const
{
if(m_lpstrLabel == NULL)
return false;
ATLASSERT(lpstrBuffer != NULL);
if(nLength > lstrlen(m_lpstrLabel) + 1)
{
lstrcpy(lpstrBuffer, m_lpstrLabel);
return true;
}
return false;
}
bool SetLabel(LPCTSTR lpstrLabel)
{
free(m_lpstrLabel);
m_lpstrLabel = NULL;
ATLTRY(m_lpstrLabel = (LPTSTR)malloc((lstrlen(lpstrLabel) + 1) * sizeof(TCHAR)));
if(m_lpstrLabel == NULL)
return false;
lstrcpy(m_lpstrLabel, lpstrLabel);
T* pT = static_cast<T*>(this);
pT->CalcLabelRect();
return true;
}
bool GetHyperLink(LPTSTR lpstrBuffer, int nLength) const
{
if(m_lpstrHyperLink == NULL)
return false;
ATLASSERT(lpstrBuffer != NULL);
if(nLength > lstrlen(m_lpstrHyperLink) + 1)
{
lstrcpy(lpstrBuffer, m_lpstrHyperLink);
return true;
}
return false;
}
bool SetHyperLink(LPCTSTR lpstrLink)
{
free(m_lpstrHyperLink);
m_lpstrHyperLink = NULL;
ATLTRY(m_lpstrHyperLink = (LPTSTR)malloc((lstrlen(lpstrLink) + 1) * sizeof(TCHAR)));
if(m_lpstrHyperLink == NULL)
return false;
lstrcpy(m_lpstrHyperLink, lpstrLink);
if(m_lpstrLabel == NULL)
{
T* pT = static_cast<T*>(this);
pT->CalcLabelRect();
}
return true;
}
// Operations
BOOL SubclassWindow(HWND hWnd)
{
ATLASSERT(m_hWnd == NULL);
ATLASSERT(::IsWindow(hWnd));
BOOL bRet = CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
if(bRet)
Init();
return bRet;
}
bool Navigate()
{
ATLASSERT(::IsWindow(m_hWnd));
ATLASSERT(m_lpstrHyperLink != NULL);
DWORD_PTR dwRet = (DWORD_PTR)::ShellExecute(0, _T("open"), m_lpstrHyperLink, 0, 0, SW_SHOWNORMAL);
ATLASSERT(dwRet > 32);
if(dwRet > 32)
{
m_bVisited = true;
Invalidate();
}
return (dwRet > 32);
}
// Message map and handlers
BEGIN_MSG_MAP(CHyperLinkImpl)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
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_MOUSEMOVE, OnMouseMove)
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
MESSAGE_HANDLER(WM_CHAR, OnChar)
MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode)
MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
END_MSG_MAP()
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
Init();
return 0;
}
LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
if(m_bPaintLabel)
{
HBRUSH hBrush = (HBRUSH)::SendMessage(GetParent(), WM_CTLCOLORSTATIC, wParam, (LPARAM)m_hWnd);
if(hBrush != NULL)
{
CDCHandle dc = (HDC)wParam;
RECT rect;
GetClientRect(&rect);
dc.FillRect(&rect, hBrush);
}
}
else
{
bHandled = FALSE;
}
return 1;
}
LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
if(!m_bPaintLabel)
{
bHandled = FALSE;
return 1;
}
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)
{
if(m_bPaintLabel)
Invalidate();
else
bHandled = FALSE;
return 0;
}
LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
if(m_lpstrHyperLink != NULL && ::PtInRect(&m_rcLink, pt))
::SetCursor(m_hCursor);
else
bHandled = FALSE;
return 0;
}
LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
if(::PtInRect(&m_rcLink, pt))
{
SetFocus();
SetCapture();
}
return 0;
}
LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
if(GetCapture() == m_hWnd)
{
ReleaseCapture();
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
if(::PtInRect(&m_rcLink, pt))
{
T* pT = static_cast<T*>(this);
pT->Navigate();
}
}
return 0;
}
LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
POINT pt;
GetCursorPos(&pt);
ScreenToClient(&pt);
if(m_lpstrHyperLink != NULL && ::PtInRect(&m_rcLink, pt))
{
return TRUE;
}
bHandled = FALSE;
return FALSE;
}
LRESULT OnChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
if(wParam == VK_RETURN || wParam == VK_SPACE)
{
T* pT = static_cast<T*>(this);
pT->Navigate();
}
return 0;
}
LRESULT OnGetDlgCode(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return DLGC_WANTCHARS;
}
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;
}
// Implementation
void Init()
{
ATLASSERT(::IsWindow(m_hWnd));
// Check if we should paint a label
TCHAR lpszBuffer[8];
if(::GetClassName(m_hWnd, lpszBuffer, 8))
{
if(lstrcmpi(lpszBuffer, _T("static")) == 0)
{
ModifyStyle(0, SS_NOTIFY); // we need this
DWORD dwStyle = GetStyle() & 0x000000FF;
if(dwStyle == SS_ICON || dwStyle == SS_BLACKRECT || dwStyle == SS_GRAYRECT ||
dwStyle == SS_WHITERECT || dwStyle == SS_BLACKFRAME || dwStyle == SS_GRAYFRAME ||
dwStyle == SS_WHITEFRAME || dwStyle == SS_OWNERDRAW ||
dwStyle == SS_BITMAP || dwStyle == SS_ENHMETAFILE)
m_bPaintLabel = false;
}
}
// create or load a cursor
#if (WINVER >= 0x0500)
m_hCursor = ::LoadCursor(NULL, IDC_HAND);
#else
m_hCursor = ::CreateCursor(_Module.GetModuleInstance(), _AtlHyperLink_CursorData.xHotSpot, _AtlHyperLink_CursorData.yHotSpot, _AtlHyperLink_CursorData.cxWidth, _AtlHyperLink_CursorData.cyHeight, _AtlHyperLink_CursorData.arrANDPlane, _AtlHyperLink_CursorData.arrXORPlane);
#endif //!(WINVER >= 0x0500)
ATLASSERT(m_hCursor != NULL);
// set font
if(m_bPaintLabel)
{
CWindow wnd = GetParent();
CFontHandle font = wnd.GetFont();
if(font.m_hFont != NULL)
{
LOGFONT lf;
font.GetLogFont(&lf);
lf.lfUnderline = TRUE;
m_hFont = ::CreateFontIndirect(&lf);
}
}
// set label (defaults to window text)
if(m_lpstrLabel == NULL)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -