12 #ifndef __ATLCTRLX_H__ 13 #define __ATLCTRLX_H__ 18 #error atlctrlx.h requires atlapp.h to be included first 21 #ifndef __ATLCTRLS_H__ 22 #error atlctrlx.h requires atlctrls.h to be included first 25 #ifndef WM_UPDATEUISTATE 26 #define WM_UPDATEUISTATE 0x0128 27 #endif // !WM_UPDATEUISTATE 60 #define BMPBTN_HOVER 0x00000001 61 #define BMPBTN_AUTO3D_SINGLE 0x00000002 62 #define BMPBTN_AUTO3D_DOUBLE 0x00000004 63 #define BMPBTN_AUTOSIZE 0x00000008 64 #define BMPBTN_SHAREIMAGELISTS 0x00000010 65 #define BMPBTN_AUTOFIRE 0x00000020 67 template <
class T,
class TBase = CButton,
class TWinTraits = ATL::CControlWinTraits>
71 DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
85 ID_TIMER_FIRST = 1000,
86 ID_TIMER_REPEAT = 1001
90 DWORD m_dwExtendedStyle;
93 int m_nImage[_nImageCount];
96 LPTSTR m_lpstrToolTipText;
99 unsigned m_fMouseOver:1;
101 unsigned m_fPressed:1;
105 CBitmapButtonImpl(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) :
106 m_ImageList(hImageList), m_dwExtendedStyle(dwExtendedStyle),
107 m_lpstrToolTipText(NULL),
108 m_fMouseOver(0), m_fFocus(0), m_fPressed(0)
110 m_nImage[_nImageNormal] = -1;
111 m_nImage[_nImagePushed] = -1;
112 m_nImage[_nImageFocusOrHover] = -1;
113 m_nImage[_nImageDisabled] = -1;
118 if((m_dwExtendedStyle & BMPBTN_SHAREIMAGELISTS) == 0)
119 m_ImageList.Destroy();
120 delete [] m_lpstrToolTipText;
124 BOOL SubclassWindow(HWND hWnd)
126 #if (_MSC_VER >= 1300) 127 BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits>::SubclassWindow(hWnd);
128 #else // !(_MSC_VER >= 1300) 129 typedef ATL::CWindowImpl< T, TBase, TWinTraits> _baseClass;
130 BOOL bRet = _baseClass::SubclassWindow(hWnd);
131 #endif // !(_MSC_VER >= 1300) 138 DWORD GetBitmapButtonExtendedStyle()
const 140 return m_dwExtendedStyle;
143 DWORD SetBitmapButtonExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
145 DWORD dwPrevStyle = m_dwExtendedStyle;
147 m_dwExtendedStyle = dwExtendedStyle;
149 m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
153 HIMAGELIST GetImageList()
const 158 HIMAGELIST SetImageList(HIMAGELIST hImageList)
160 HIMAGELIST hImageListPrev = m_ImageList;
161 m_ImageList = hImageList;
162 if((m_dwExtendedStyle & BMPBTN_AUTOSIZE) != 0 && ::IsWindow(m_hWnd))
164 return hImageListPrev;
167 int GetToolTipTextLength()
const 169 return (m_lpstrToolTipText == NULL) ? -1 : lstrlen(m_lpstrToolTipText);
172 bool GetToolTipText(LPTSTR lpstrText,
int nLength)
const 174 ATLASSERT(lpstrText != NULL);
175 if(m_lpstrToolTipText == NULL)
178 errno_t nRet = SecureHelper::strncpy_x(lpstrText, nLength, m_lpstrToolTipText, _TRUNCATE);
180 return (nRet == 0 || nRet == STRUNCATE);
183 bool SetToolTipText(LPCTSTR lpstrText)
185 if(m_lpstrToolTipText != NULL)
187 delete [] m_lpstrToolTipText;
188 m_lpstrToolTipText = NULL;
191 if(lpstrText == NULL)
194 m_tip.Activate(FALSE);
198 int cchLen = lstrlen(lpstrText) + 1;
199 ATLTRY(m_lpstrToolTipText =
new TCHAR[cchLen]);
200 if(m_lpstrToolTipText == NULL)
203 SecureHelper::strcpy_x(m_lpstrToolTipText, cchLen, lpstrText);
206 m_tip.Activate(TRUE);
207 m_tip.AddTool(m_hWnd, m_lpstrToolTipText);
214 void SetImages(
int nNormal,
int nPushed = -1,
int nFocusOrHover = -1,
int nDisabled = -1)
217 m_nImage[_nImageNormal] = nNormal;
219 m_nImage[_nImagePushed] = nPushed;
220 if(nFocusOrHover != -1)
221 m_nImage[_nImageFocusOrHover] = nFocusOrHover;
223 m_nImage[_nImageDisabled] = nDisabled;
228 ATLASSERT(::IsWindow(m_hWnd) && m_ImageList.m_hImageList != NULL);
231 if(!m_ImageList.GetIconSize(cx, cy))
233 return ResizeClient(cx, cy);
239 ATLASSERT(m_ImageList.m_hImageList != NULL);
240 ATLASSERT(m_nImage[0] != -1);
244 bool bHover = IsHoverMode();
245 if(!IsWindowEnabled())
246 nImage = m_nImage[_nImageDisabled];
247 else if(m_fPressed == 1)
248 nImage = m_nImage[_nImagePushed];
249 else if((!bHover && m_fFocus == 1) || (bHover && m_fMouseOver == 1))
250 nImage = m_nImage[_nImageFocusOrHover];
252 nImage = m_nImage[_nImageNormal];
256 if((m_fPressed == 1) && ((m_dwExtendedStyle & (BMPBTN_AUTO3D_SINGLE | BMPBTN_AUTO3D_DOUBLE)) != 0) && (m_nImage[_nImagePushed] == -1))
258 m_ImageList.Draw(dc, nImage, xyPos, xyPos, ILD_NORMAL);
261 if((m_dwExtendedStyle & (BMPBTN_AUTO3D_SINGLE | BMPBTN_AUTO3D_DOUBLE)) != 0)
264 GetClientRect(&rect);
267 dc.DrawEdge(&rect, ((m_dwExtendedStyle & BMPBTN_AUTO3D_SINGLE) != 0) ? BDR_SUNKENOUTER : EDGE_SUNKEN, BF_RECT);
268 else if(!bHover || m_fMouseOver == 1)
269 dc.DrawEdge(&rect, ((m_dwExtendedStyle & BMPBTN_AUTO3D_SINGLE) != 0) ? BDR_RAISEDINNER : EDGE_RAISED, BF_RECT);
271 if(!bHover && m_fFocus == 1)
273 ::InflateRect(&rect, -2 * ::GetSystemMetrics(SM_CXEDGE), -2 * ::GetSystemMetrics(SM_CYEDGE));
274 dc.DrawFocusRect(&rect);
281 MESSAGE_HANDLER(WM_CREATE, OnCreate)
282 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
283 MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
284 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
285 MESSAGE_HANDLER(WM_PAINT, OnPaint)
286 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
287 MESSAGE_HANDLER(WM_SETFOCUS, OnFocus)
288 MESSAGE_HANDLER(WM_KILLFOCUS, OnFocus)
289 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
290 MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk)
291 MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
292 MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
293 MESSAGE_HANDLER(WM_ENABLE, OnEnable)
294 MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
295 MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave)
296 MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
297 MESSAGE_HANDLER(WM_KEYUP, OnKeyUp)
298 MESSAGE_HANDLER(WM_TIMER, OnTimer)
299 MESSAGE_HANDLER(WM_UPDATEUISTATE, OnUpdateUiState)
302 LRESULT OnCreate(UINT , WPARAM , LPARAM , BOOL& bHandled)
309 LRESULT OnDestroy(UINT , WPARAM , LPARAM , BOOL& bHandled)
313 m_tip.DestroyWindow();
320 LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
322 MSG msg = { m_hWnd, uMsg, wParam, lParam };
324 m_tip.RelayEvent(&msg);
329 LRESULT OnEraseBackground(UINT , WPARAM , LPARAM , BOOL& )
334 LRESULT OnPaint(UINT , WPARAM wParam, LPARAM , BOOL& )
336 T* pT =
static_cast<T*
>(
this);
339 pT->DoPaint((HDC)wParam);
344 pT->DoPaint(dc.m_hDC);
349 LRESULT OnFocus(UINT uMsg, WPARAM , LPARAM , BOOL& bHandled)
351 m_fFocus = (uMsg == WM_SETFOCUS) ? 1 : 0;
358 LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& )
364 lRet = DefWindowProc(uMsg, wParam, lParam);
365 if(::GetCapture() == m_hWnd)
371 if((m_dwExtendedStyle & BMPBTN_AUTOFIRE) != 0)
375 if(::SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &nDelay, 0))
376 nElapse += nDelay * 250;
377 SetTimer(ID_TIMER_FIRST, nElapse);
382 LRESULT OnLButtonDblClk(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& )
386 lRet = DefWindowProc(uMsg, wParam, lParam);
387 if(::GetCapture() != m_hWnd)
398 LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& )
401 bool bHover = IsHoverMode();
403 lRet = DefWindowProc(uMsg, wParam, lParam);
404 if(::GetCapture() == m_hWnd)
406 if(bHover && m_fPressed == 1)
407 ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
413 LRESULT OnCaptureChanged(UINT , WPARAM , LPARAM , BOOL& bHandled)
425 LRESULT OnEnable(UINT , WPARAM , LPARAM , BOOL& bHandled)
433 LRESULT OnMouseMove(UINT , WPARAM , LPARAM lParam, BOOL& bHandled)
435 if(::GetCapture() == m_hWnd)
437 POINT ptCursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
438 ClientToScreen(&ptCursor);
440 GetWindowRect(&rect);
441 unsigned int uPressed = ::PtInRect(&rect, ptCursor) ? 1 : 0;
442 if(m_fPressed != uPressed)
444 m_fPressed = uPressed;
449 else if(IsHoverMode() && m_fMouseOver == 0)
454 StartTrackMouseLeave();
460 LRESULT OnMouseLeave(UINT , WPARAM , LPARAM , BOOL& )
462 if(m_fMouseOver == 1)
471 LRESULT OnKeyDown(UINT , WPARAM wParam, LPARAM , BOOL& bHandled)
473 if(wParam == VK_SPACE && IsHoverMode())
475 if(wParam == VK_SPACE && m_fPressed == 0)
485 LRESULT OnKeyUp(UINT , WPARAM wParam, LPARAM , BOOL& bHandled)
487 if(wParam == VK_SPACE && IsHoverMode())
489 if(wParam == VK_SPACE && m_fPressed == 1)
499 LRESULT OnTimer(UINT , WPARAM wParam, LPARAM , BOOL& )
501 ATLASSERT((m_dwExtendedStyle & BMPBTN_AUTOFIRE) != 0);
505 KillTimer(ID_TIMER_FIRST);
508 ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
511 if(::SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &nRepeat, 0))
512 nElapse = 10000 / (10 * nRepeat + 25);
513 SetTimer(ID_TIMER_REPEAT, nElapse);
516 case ID_TIMER_REPEAT:
518 ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
519 else if(::GetCapture() != m_hWnd)
520 KillTimer(ID_TIMER_REPEAT);
528 LRESULT OnUpdateUiState(UINT , WPARAM , LPARAM , BOOL& )
539 ModifyStyle(0, BS_OWNERDRAW);
542 m_tip.Create(m_hWnd);
543 ATLASSERT(m_tip.IsWindow());
544 if(m_tip.IsWindow() && m_lpstrToolTipText != NULL)
546 m_tip.Activate(TRUE);
547 m_tip.AddTool(m_hWnd, m_lpstrToolTipText);
550 if(m_ImageList.m_hImageList != NULL && (m_dwExtendedStyle & BMPBTN_AUTOSIZE) != 0)
554 BOOL StartTrackMouseLeave()
556 TRACKMOUSEEVENT tme = { 0 };
557 tme.cbSize =
sizeof(tme);
558 tme.dwFlags = TME_LEAVE;
559 tme.hwndTrack = m_hWnd;
560 return _TrackMouseEvent(&tme);
563 bool IsHoverMode()
const 565 return ((m_dwExtendedStyle & BMPBTN_HOVER) != 0);
572 DECLARE_WND_SUPERCLASS(_T(
"WTL_BitmapButton"), GetWndClassName())
574 CBitmapButton(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) :
579 #endif // !_WIN32_WCE 585 template <DWORD t_dwStyle, DWORD t_dwExStyle, DWORD t_dwExListViewStyle>
589 static DWORD GetWndStyle(DWORD dwStyle)
591 return (dwStyle == 0) ? t_dwStyle : dwStyle;
594 static DWORD GetWndExStyle(DWORD dwExStyle)
596 return (dwExStyle == 0) ? t_dwExStyle : dwExStyle;
599 static DWORD GetExtendedLVStyle()
601 return t_dwExListViewStyle;
607 template <
class T,
class TBase = CListViewCtrl,
class TWinTraits = CCheckListViewCtrlTraits>
611 DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
614 static DWORD GetExtendedLVStyle()
616 return TWinTraits::GetExtendedLVStyle();
620 BOOL SubclassWindow(HWND hWnd)
622 #if (_MSC_VER >= 1300) 623 BOOL bRet = ATL::CWindowImplBaseT< TBase, TWinTraits>::SubclassWindow(hWnd);
624 #else // !(_MSC_VER >= 1300) 625 typedef ATL::CWindowImplBaseT< TBase, TWinTraits> _baseClass;
626 BOOL bRet = _baseClass::SubclassWindow(hWnd);
627 #endif // !(_MSC_VER >= 1300) 630 T* pT =
static_cast<T*
>(
this);
632 ATLASSERT((pT->GetExtendedLVStyle() & LVS_EX_CHECKBOXES) != 0);
633 SetExtendedListViewStyle(pT->GetExtendedLVStyle());
638 void CheckSelectedItems(
int nCurrItem)
642 lvi.iItem = nCurrItem;
644 lvi.mask = LVIF_STATE;
645 lvi.stateMask = LVIS_SELECTED;
648 if(!(lvi.state & LVIS_SELECTED))
651 BOOL bCheck = !GetCheckState(nCurrItem);
654 while((nItem = GetNextItem(nOldItem, LVNI_SELECTED)) != -1)
656 if(nItem != nCurrItem)
657 SetCheckState(nItem, bCheck);
664 MESSAGE_HANDLER(WM_CREATE, OnCreate)
665 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
666 MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDown)
667 MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
670 LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& )
673 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
674 T* pT =
static_cast<T*
>(
this);
676 ATLASSERT((pT->GetExtendedLVStyle() & LVS_EX_CHECKBOXES) != 0);
677 SetExtendedListViewStyle(pT->GetExtendedLVStyle());
681 LRESULT OnLButtonDown(UINT , WPARAM , LPARAM lParam, BOOL& bHandled)
683 POINT ptMsg = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
684 LVHITTESTINFO lvh = { 0 };
686 if(HitTest(&lvh) != -1 && lvh.flags == LVHT_ONITEMSTATEICON && ::GetKeyState(VK_CONTROL) >= 0)
688 T* pT =
static_cast<T*
>(
this);
689 pT->CheckSelectedItems(lvh.iItem);
695 LRESULT OnKeyDown(UINT , WPARAM wParam, LPARAM , BOOL& bHandled)
697 if(wParam == VK_SPACE)
699 int nCurrItem = GetNextItem(-1, LVNI_FOCUSED);
700 if(nCurrItem != -1 && ::GetKeyState(VK_CONTROL) >= 0)
702 T* pT =
static_cast<T*
>(
this);
703 pT->CheckSelectedItems(nCurrItem);
714 DECLARE_WND_SUPERCLASS(_T(
"WTL_CheckListView"), GetWndClassName())
721 #if (WINVER < 0x0500) && !defined(_WIN32_WCE) 722 __declspec(selectany)
struct 724 enum { cxWidth = 32, cyHeight = 32 };
727 unsigned char arrANDPlane[cxWidth * cyHeight / 8];
728 unsigned char arrXORPlane[cxWidth * cyHeight / 8];
729 } _AtlHyperLink_CursorData =
733 0xF9, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF,
734 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF,
735 0xF0, 0x00, 0xFF, 0xFF, 0x10, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF,
736 0x80, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x7F, 0xFF,
737 0xE0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF,
738 0xF8, 0x01, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
739 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
740 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
743 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
744 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x06, 0xD8, 0x00, 0x00,
745 0x06, 0xDA, 0x00, 0x00, 0x06, 0xDB, 0x00, 0x00, 0x67, 0xFB, 0x00, 0x00, 0x77, 0xFF, 0x00, 0x00,
746 0x37, 0xFF, 0x00, 0x00, 0x17, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x00,
747 0x0F, 0xFE, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00,
748 0x03, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
749 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
750 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
753 #endif // (WINVER < 0x0500) && !defined(_WIN32_WCE) 755 #define HLINK_UNDERLINED 0x00000000 756 #define HLINK_NOTUNDERLINED 0x00000001 757 #define HLINK_UNDERLINEHOVER 0x00000002 758 #define HLINK_COMMANDBUTTON 0x00000004 759 #define HLINK_NOTIFYBUTTON 0x0000000C 760 #define HLINK_USETAGS 0x00000010 761 #define HLINK_USETAGSBOLD 0x00000030 762 #define HLINK_NOTOOLTIP 0x00000040 763 #define HLINK_AUTOCREATELINKFONT 0x00000080 764 #define HLINK_SINGLELINE 0x00000100 770 template <
class T,
class TBase = ATL::CWindow,
class TWinTraits = ATL::CControlWinTraits>
771 class ATL_NO_VTABLE
CHyperLinkImpl :
public ATL::CWindowImpl< T, TBase, TWinTraits >
775 LPTSTR m_lpstrHyperLink;
784 #endif // !_WIN32_WCE 787 COLORREF m_clrVisited;
789 DWORD m_dwExtendedStyle;
791 bool m_bPaintLabel:1;
794 bool m_bInternalLinkFont:1;
795 bool m_bInternalNormalFont:1;
800 m_lpstrLabel(NULL), m_lpstrHyperLink(NULL),
801 m_hCursor(NULL), m_hFontLink(NULL), m_hFontNormal(NULL),
802 m_clrLink(RGB(0, 0, 255)), m_clrVisited(RGB(128, 0, 128)),
803 m_dwExtendedStyle(dwExtendedStyle),
804 m_bPaintLabel(
true), m_bVisited(
false),
805 m_bHover(
false), m_bInternalLinkFont(
false), m_bInternalNormalFont(
false)
807 ::SetRectEmpty(&m_rcLink);
812 delete [] m_lpstrLabel;
813 delete [] m_lpstrHyperLink;
814 #if (WINVER < 0x0500) && !defined(_WIN32_WCE) 816 if(m_hCursor != NULL)
817 ::DestroyCursor(m_hCursor);
818 #endif // (WINVER < 0x0500) && !defined(_WIN32_WCE) 822 DWORD GetHyperLinkExtendedStyle()
const 824 return m_dwExtendedStyle;
827 DWORD SetHyperLinkExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
829 DWORD dwPrevStyle = m_dwExtendedStyle;
831 m_dwExtendedStyle = dwExtendedStyle;
833 m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
837 bool GetLabel(LPTSTR lpstrBuffer,
int nLength)
const 839 if(m_lpstrLabel == NULL)
841 ATLASSERT(lpstrBuffer != NULL);
842 if(nLength <= lstrlen(m_lpstrLabel))
845 SecureHelper::strcpy_x(lpstrBuffer, nLength, m_lpstrLabel);
850 bool SetLabel(LPCTSTR lpstrLabel)
852 delete [] m_lpstrLabel;
854 int cchLen = lstrlen(lpstrLabel) + 1;
855 ATLTRY(m_lpstrLabel =
new TCHAR[cchLen]);
856 if(m_lpstrLabel == NULL)
859 SecureHelper::strcpy_x(m_lpstrLabel, cchLen, lpstrLabel);
860 T* pT =
static_cast<T*
>(
this);
864 SetWindowText(lpstrLabel);
869 bool GetHyperLink(LPTSTR lpstrBuffer,
int nLength)
const 871 if(m_lpstrHyperLink == NULL)
873 ATLASSERT(lpstrBuffer != NULL);
874 if(nLength <= lstrlen(m_lpstrHyperLink))
877 SecureHelper::strcpy_x(lpstrBuffer, nLength, m_lpstrHyperLink);
882 bool SetHyperLink(LPCTSTR lpstrLink)
884 delete [] m_lpstrHyperLink;
885 m_lpstrHyperLink = NULL;
886 int cchLen = lstrlen(lpstrLink) + 1;
887 ATLTRY(m_lpstrHyperLink =
new TCHAR[cchLen]);
888 if(m_lpstrHyperLink == NULL)
891 SecureHelper::strcpy_x(m_lpstrHyperLink, cchLen, lpstrLink);
892 if(m_lpstrLabel == NULL)
894 T* pT =
static_cast<T*
>(
this);
900 m_tip.Activate(TRUE);
901 m_tip.AddTool(m_hWnd, m_lpstrHyperLink, &m_rcLink, 1);
903 #endif // !_WIN32_WCE 907 HFONT GetLinkFont()
const 912 void SetLinkFont(HFONT hFont)
914 if(m_bInternalLinkFont)
916 ::DeleteObject(m_hFontLink);
917 m_bInternalLinkFont =
false;
922 T* pT =
static_cast<T*
>(
this);
926 int GetIdealHeight()
const 928 ATLASSERT(::IsWindow(m_hWnd));
929 if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL)
934 UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
938 GetClientRect(&rect);
939 HFONT hFontOld = dc.SelectFont(m_hFontNormal);
941 dc.DrawText(_T(
"NS"), -1, &rcText, DT_LEFT | uFormat | DT_CALCRECT);
942 dc.SelectFont(m_hFontLink);
944 dc.DrawText(_T(
"NS"), -1, &rcLink, DT_LEFT | uFormat | DT_CALCRECT);
945 dc.SelectFont(hFontOld);
946 return max(rcText.bottom - rcText.top, rcLink.bottom - rcLink.top);
949 bool GetIdealSize(SIZE& size)
const 952 bool bRet = GetIdealSize(cx, cy);
961 bool GetIdealSize(
int& cx,
int& cy)
const 963 ATLASSERT(::IsWindow(m_hWnd));
964 if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL)
970 RECT rcClient = { 0 };
971 GetClientRect(&rcClient);
972 RECT rcAll = rcClient;
977 LPTSTR lpstrLeft = NULL;
979 LPTSTR lpstrLink = NULL;
981 LPTSTR lpstrRight = NULL;
984 const T* pT =
static_cast<const T*
>(
this);
985 pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight);
988 UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
990 HFONT hFontOld = dc.SelectFont(m_hFontNormal);
991 RECT rcLeft = rcClient;
992 dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | uFormat | DT_CALCRECT);
994 dc.SelectFont(m_hFontLink);
995 RECT rcLink = { rcLeft.right, rcLeft.top, rcClient.right, rcClient.bottom };
996 dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | uFormat | DT_CALCRECT);
998 dc.SelectFont(m_hFontNormal);
999 RECT rcRight = { rcLink.right, rcLink.top, rcClient.right, rcClient.bottom };
1000 dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | uFormat | DT_CALCRECT);
1002 dc.SelectFont(hFontOld);
1004 int cyMax = max(rcLeft.bottom, max(rcLink.bottom, rcRight.bottom));
1005 ::SetRect(&rcAll, rcLeft.left, rcLeft.top, rcRight.right, cyMax);
1009 HFONT hOldFont = NULL;
1010 if(m_hFontLink != NULL)
1011 hOldFont = dc.SelectFont(m_hFontLink);
1012 LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
1013 DWORD dwStyle = GetStyle();
1014 UINT uFormat = DT_LEFT;
1015 if (dwStyle & SS_CENTER)
1016 uFormat = DT_CENTER;
1017 else if (dwStyle & SS_RIGHT)
1019 uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
1020 dc.DrawText(lpstrText, -1, &rcAll, uFormat | DT_CALCRECT);
1021 if(m_hFontLink != NULL)
1022 dc.SelectFont(hOldFont);
1023 if (dwStyle & SS_CENTER)
1025 int dx = (rcClient.right - rcAll.right) / 2;
1026 ::OffsetRect(&rcAll, dx, 0);
1028 else if (dwStyle & SS_RIGHT)
1030 int dx = rcClient.right - rcAll.right;
1031 ::OffsetRect(&rcAll, dx, 0);
1035 cx = rcAll.right - rcAll.left;
1036 cy = rcAll.bottom - rcAll.top;
1042 bool GetToolTipText(LPTSTR lpstrBuffer,
int nLength)
const 1044 ATLASSERT(IsCommandButton());
1045 return GetHyperLink(lpstrBuffer, nLength);
1048 bool SetToolTipText(LPCTSTR lpstrToolTipText)
1050 ATLASSERT(IsCommandButton());
1051 return SetHyperLink(lpstrToolTipText);
1055 BOOL SubclassWindow(HWND hWnd)
1057 ATLASSERT(m_hWnd == NULL);
1058 ATLASSERT(::IsWindow(hWnd));
1059 if(m_hFontNormal == NULL)
1060 m_hFontNormal = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0L);
1061 #if (_MSC_VER >= 1300) 1062 BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits>::SubclassWindow(hWnd);
1063 #else // !(_MSC_VER >= 1300) 1064 typedef ATL::CWindowImpl< T, TBase, TWinTraits> _baseClass;
1065 BOOL bRet = _baseClass::SubclassWindow(hWnd);
1066 #endif // !(_MSC_VER >= 1300) 1069 T* pT =
static_cast<T*
>(
this);
1077 ATLASSERT(::IsWindow(m_hWnd));
1079 if(IsNotifyButton())
1081 NMHDR nmhdr = { m_hWnd, GetDlgCtrlID(), NM_CLICK };
1082 ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmhdr);
1084 else if(IsCommandButton())
1086 ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
1090 ATLASSERT(m_lpstrHyperLink != NULL);
1092 DWORD_PTR dwRet = (DWORD_PTR)::ShellExecute(0, _T(
"open"), m_lpstrHyperLink, 0, 0, SW_SHOWNORMAL);
1093 bRet = (dwRet > 32);
1094 #else // CE specific 1095 SHELLEXECUTEINFO shExeInfo = {
sizeof(SHELLEXECUTEINFO), 0, 0, L
"open", m_lpstrHyperLink, 0, 0, SW_SHOWNORMAL, 0, 0, 0, 0, 0, 0, 0 };
1096 ::ShellExecuteEx(&shExeInfo);
1097 DWORD_PTR dwRet = (DWORD_PTR)shExeInfo.hInstApp;
1098 bRet = (dwRet == 0) || (dwRet > 32);
1099 #endif // _WIN32_WCE 1110 void CreateLinkFontFromNormal()
1112 if(m_bInternalLinkFont)
1114 ::DeleteObject(m_hFontLink);
1115 m_bInternalLinkFont =
false;
1118 CFontHandle font = (m_hFontNormal != NULL) ? m_hFontNormal : (HFONT)::GetStockObject(SYSTEM_FONT);
1120 font.GetLogFont(&lf);
1122 if(IsUsingTagsBold())
1123 lf.lfWeight = FW_BOLD;
1124 else if(!IsNotUnderlined())
1125 lf.lfUnderline = TRUE;
1127 m_hFontLink = ::CreateFontIndirect(&lf);
1128 m_bInternalLinkFont =
true;
1129 ATLASSERT(m_hFontLink != NULL);
1134 MESSAGE_HANDLER(WM_CREATE, OnCreate)
1136 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
1137 MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
1138 #endif // !_WIN32_WCE 1139 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
1140 MESSAGE_HANDLER(WM_PAINT, OnPaint)
1142 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
1143 #endif // !_WIN32_WCE 1144 MESSAGE_HANDLER(WM_SETFOCUS, OnFocus)
1145 MESSAGE_HANDLER(WM_KILLFOCUS, OnFocus)
1146 MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
1148 MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave)
1149 #endif // !_WIN32_WCE 1150 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
1151 MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
1152 MESSAGE_HANDLER(WM_CHAR, OnChar)
1153 MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode)
1154 MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
1155 MESSAGE_HANDLER(WM_ENABLE, OnEnable)
1156 MESSAGE_HANDLER(WM_GETFONT, OnGetFont)
1157 MESSAGE_HANDLER(WM_SETFONT, OnSetFont)
1158 MESSAGE_HANDLER(WM_UPDATEUISTATE, OnUpdateUiState)
1159 MESSAGE_HANDLER(WM_SIZE, OnSize)
1162 LRESULT OnCreate(UINT , WPARAM , LPARAM , BOOL& )
1164 T* pT =
static_cast<T*
>(
this);
1170 LRESULT OnDestroy(UINT , WPARAM , LPARAM , BOOL& bHandled)
1172 if(m_tip.IsWindow())
1174 m_tip.DestroyWindow();
1175 m_tip.m_hWnd = NULL;
1178 if(m_bInternalLinkFont)
1180 ::DeleteObject(m_hFontLink);
1182 m_bInternalLinkFont =
false;
1185 if(m_bInternalNormalFont)
1187 ::DeleteObject(m_hFontNormal);
1188 m_hFontNormal = NULL;
1189 m_bInternalNormalFont =
false;
1196 LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1198 MSG msg = { m_hWnd, uMsg, wParam, lParam };
1199 if(m_tip.IsWindow() && IsUsingToolTip())
1200 m_tip.RelayEvent(&msg);
1204 #endif // !_WIN32_WCE 1206 LRESULT OnEraseBackground(UINT , WPARAM , LPARAM , BOOL& )
1211 LRESULT OnPaint(UINT , WPARAM wParam, LPARAM , BOOL& bHandled)
1219 T* pT =
static_cast<T*
>(
this);
1222 pT->DoEraseBackground((HDC)wParam);
1223 pT->DoPaint((HDC)wParam);
1228 pT->DoEraseBackground(dc.m_hDC);
1229 pT->DoPaint(dc.m_hDC);
1235 LRESULT OnFocus(UINT , WPARAM , LPARAM , BOOL& bHandled)
1244 LRESULT OnMouseMove(UINT , WPARAM , LPARAM lParam, BOOL& bHandled)
1246 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1247 if((m_lpstrHyperLink != NULL || IsCommandButton()) && ::PtInRect(&m_rcLink, pt))
1249 ::SetCursor(m_hCursor);
1250 if(IsUnderlineHover())
1255 InvalidateRect(&m_rcLink);
1258 StartTrackMouseLeave();
1259 #endif // !_WIN32_WCE 1265 if(IsUnderlineHover())
1270 InvalidateRect(&m_rcLink);
1280 LRESULT OnMouseLeave(UINT , WPARAM , LPARAM , BOOL& )
1282 if(IsUnderlineHover() && m_bHover)
1285 InvalidateRect(&m_rcLink);
1290 #endif // !_WIN32_WCE 1292 LRESULT OnLButtonDown(UINT , WPARAM , LPARAM lParam, BOOL& )
1294 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1295 if(::PtInRect(&m_rcLink, pt))
1303 LRESULT OnLButtonUp(UINT , WPARAM , LPARAM lParam, BOOL& )
1305 if(GetCapture() == m_hWnd)
1308 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1309 if(::PtInRect(&m_rcLink, pt))
1311 T* pT =
static_cast<T*
>(
this);
1318 LRESULT OnChar(UINT , WPARAM wParam, LPARAM , BOOL& )
1320 if(wParam == VK_RETURN || wParam == VK_SPACE)
1322 T* pT =
static_cast<T*
>(
this);
1328 LRESULT OnGetDlgCode(UINT , WPARAM , LPARAM , BOOL& )
1330 return DLGC_WANTCHARS;
1333 LRESULT OnSetCursor(UINT , WPARAM , LPARAM , BOOL& bHandled)
1335 POINT pt = { 0, 0 };
1337 ScreenToClient(&pt);
1338 if((m_lpstrHyperLink != NULL || IsCommandButton()) && ::PtInRect(&m_rcLink, pt))
1346 LRESULT OnEnable(UINT , WPARAM , LPARAM , BOOL& )
1353 LRESULT OnGetFont(UINT , WPARAM , LPARAM , BOOL& )
1355 return (LRESULT)m_hFontNormal;
1358 LRESULT OnSetFont(UINT , WPARAM wParam, LPARAM lParam, BOOL& )
1360 if(m_bInternalNormalFont)
1362 ::DeleteObject(m_hFontNormal);
1363 m_bInternalNormalFont =
false;
1366 bool bCreateLinkFont = m_bInternalLinkFont;
1368 m_hFontNormal = (HFONT)wParam;
1370 if(bCreateLinkFont || IsAutoCreateLinkFont())
1371 CreateLinkFontFromNormal();
1373 T* pT =
static_cast<T*
>(
this);
1374 pT->CalcLabelRect();
1385 LRESULT OnUpdateUiState(UINT , WPARAM , LPARAM , BOOL& )
1392 LRESULT OnSize(UINT , WPARAM , LPARAM , BOOL& )
1394 T* pT =
static_cast<T*
>(
this);
1395 pT->CalcLabelRect();
1403 ATLASSERT(::IsWindow(m_hWnd));
1406 const int cchBuff = 8;
1407 TCHAR szBuffer[cchBuff] = { 0 };
1408 if(::GetClassName(m_hWnd, szBuffer, cchBuff))
1410 if(lstrcmpi(szBuffer, _T(
"static")) == 0)
1412 ModifyStyle(0, SS_NOTIFY);
1413 DWORD dwStyle = GetStyle() & 0x000000FF;
1415 if(dwStyle == SS_ICON || dwStyle == SS_BLACKRECT || dwStyle == SS_GRAYRECT ||
1416 dwStyle == SS_WHITERECT || dwStyle == SS_BLACKFRAME || dwStyle == SS_GRAYFRAME ||
1417 dwStyle == SS_WHITEFRAME || dwStyle == SS_OWNERDRAW ||
1418 dwStyle == SS_BITMAP || dwStyle == SS_ENHMETAFILE)
1419 #else // CE specific 1420 if(dwStyle == SS_ICON || dwStyle == SS_BITMAP)
1421 #endif // _WIN32_WCE 1422 m_bPaintLabel =
false;
1427 #if (WINVER >= 0x0500) || defined(_WIN32_WCE) 1428 m_hCursor = ::LoadCursor(NULL, IDC_HAND);
1430 m_hCursor = ::CreateCursor(ModuleHelper::GetModuleInstance(), _AtlHyperLink_CursorData.xHotSpot, _AtlHyperLink_CursorData.yHotSpot, _AtlHyperLink_CursorData.cxWidth, _AtlHyperLink_CursorData.cyHeight, _AtlHyperLink_CursorData.arrANDPlane, _AtlHyperLink_CursorData.arrXORPlane);
1432 ATLASSERT(m_hCursor != NULL);
1437 if(m_hFontNormal == NULL)
1439 m_hFontNormal = AtlCreateControlFont();
1440 m_bInternalNormalFont =
true;
1443 if(m_hFontLink == NULL)
1444 CreateLinkFontFromNormal();
1449 m_tip.Create(m_hWnd);
1450 ATLASSERT(m_tip.IsWindow());
1451 #endif // !_WIN32_WCE 1454 if(m_lpstrLabel == NULL)
1456 int nLen = GetWindowTextLength();
1459 ATLTRY(m_lpstrLabel =
new TCHAR[nLen + 1]);
1460 if(m_lpstrLabel != NULL)
1461 ATLVERIFY(GetWindowText(m_lpstrLabel, nLen + 1) > 0);
1465 T* pT =
static_cast<T*
>(
this);
1466 pT->CalcLabelRect();
1469 if(m_lpstrHyperLink == NULL && !IsCommandButton())
1471 if(m_lpstrLabel != NULL)
1472 SetHyperLink(m_lpstrLabel);
1477 m_tip.Activate(TRUE);
1478 m_tip.AddTool(m_hWnd, m_lpstrHyperLink, &m_rcLink, 1);
1480 #endif // !_WIN32_WCE 1486 LONG lRet = rk.Open(HKEY_CURRENT_USER, _T(
"Software\\Microsoft\\Internet Explorer\\Settings"));
1487 if(lRet == ERROR_SUCCESS)
1489 const int cchValue = 12;
1490 TCHAR szValue[cchValue] = { 0 };
1491 ULONG ulCount = cchValue;
1492 lRet = rk.QueryStringValue(_T(
"Anchor Color"), szValue, &ulCount);
1493 if(lRet == ERROR_SUCCESS)
1495 COLORREF clr = pT->_ParseColorString(szValue);
1496 ATLASSERT(clr != CLR_INVALID);
1497 if(clr != CLR_INVALID)
1502 lRet = rk.QueryStringValue(_T(
"Anchor Color Visited"), szValue, &ulCount);
1503 if(lRet == ERROR_SUCCESS)
1505 COLORREF clr = pT->_ParseColorString(szValue);
1506 ATLASSERT(clr != CLR_INVALID);
1507 if(clr != CLR_INVALID)
1514 static COLORREF _ParseColorString(LPTSTR lpstr)
1516 int c[3] = { -1, -1, -1 };
1518 for(
int i = 0; i < 2; i++)
1520 for(p = lpstr; *p != _T(
'\0'); p = ::CharNext(p))
1525 c[i] = MinCrtHelper::_atoi(lpstr);
1533 if(*lpstr == _T(
'\0'))
1535 c[2] = MinCrtHelper::_atoi(lpstr);
1537 return RGB(c[0], c[1], c[2]);
1540 bool CalcLabelRect()
1542 if(!::IsWindow(m_hWnd))
1544 if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL)
1548 RECT rcClient = { 0 };
1549 GetClientRect(&rcClient);
1550 m_rcLink = rcClient;
1557 LPTSTR lpstrLeft = NULL;
1559 LPTSTR lpstrLink = NULL;
1561 LPTSTR lpstrRight = NULL;
1564 T* pT =
static_cast<T*
>(
this);
1565 pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight);
1566 ATLASSERT(lpstrLink != NULL);
1567 ATLASSERT(cchLink > 0);
1570 HFONT hFontOld = dc.SelectFont(m_hFontNormal);
1572 UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
1574 RECT rcLeft = rcClient;
1575 if(lpstrLeft != NULL)
1576 dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | uFormat | DT_CALCRECT);
1578 dc.SelectFont(m_hFontLink);
1579 RECT rcLink = rcClient;
1580 if(lpstrLeft != NULL)
1581 rcLink.left = rcLeft.right;
1582 dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | uFormat | DT_CALCRECT);
1584 dc.SelectFont(hFontOld);
1590 HFONT hOldFont = NULL;
1591 if(m_hFontLink != NULL)
1592 hOldFont = dc.SelectFont(m_hFontLink);
1593 LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
1594 DWORD dwStyle = GetStyle();
1595 UINT uFormat = DT_LEFT;
1596 if (dwStyle & SS_CENTER)
1597 uFormat = DT_CENTER;
1598 else if (dwStyle & SS_RIGHT)
1600 uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
1601 dc.DrawText(lpstrText, -1, &m_rcLink, uFormat | DT_CALCRECT);
1602 if(m_hFontLink != NULL)
1603 dc.SelectFont(hOldFont);
1604 if (dwStyle & SS_CENTER)
1606 int dx = (rcClient.right - m_rcLink.right) / 2;
1607 ::OffsetRect(&m_rcLink, dx, 0);
1609 else if (dwStyle & SS_RIGHT)
1611 int dx = rcClient.right - m_rcLink.right;
1612 ::OffsetRect(&m_rcLink, dx, 0);
1619 void CalcLabelParts(LPTSTR& lpstrLeft,
int& cchLeft, LPTSTR& lpstrLink,
int& cchLink, LPTSTR& lpstrRight,
int& cchRight)
const 1628 LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
1629 int cchText = lstrlen(lpstrText);
1630 bool bOutsideLink =
true;
1631 for(
int i = 0; i < cchText; i++)
1633 if(lpstrText[i] != _T(
'<'))
1638 if(::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, &lpstrText[i], 3, _T(
"<A>"), 3) == CSTR_EQUAL)
1642 lpstrLeft = lpstrText;
1645 lpstrLink = &lpstrText[i + 3];
1646 bOutsideLink =
false;
1651 if(::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, &lpstrText[i], 4, _T(
"</A>"), 4) == CSTR_EQUAL)
1653 cchLink = i - 3 - cchLeft;
1654 if(lpstrText[i + 4] != 0)
1656 lpstrRight = &lpstrText[i + 4];
1657 cchRight = cchText - (i + 4);
1668 HBRUSH hBrush = (HBRUSH)::SendMessage(GetParent(), WM_CTLCOLORSTATIC, (WPARAM)dc.m_hDC, (LPARAM)m_hWnd);
1672 GetClientRect(&rect);
1673 dc.FillRect(&rect, hBrush);
1682 LPTSTR lpstrLeft = NULL;
1684 LPTSTR lpstrLink = NULL;
1686 LPTSTR lpstrRight = NULL;
1689 T* pT =
static_cast<T*
>(
this);
1690 pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight);
1693 RECT rcClient = { 0 };
1694 GetClientRect(&rcClient);
1696 dc.SetBkMode(TRANSPARENT);
1697 HFONT hFontOld = dc.SelectFont(m_hFontNormal);
1699 UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
1701 if(lpstrLeft != NULL)
1702 dc.DrawText(lpstrLeft, cchLeft, &rcClient, DT_LEFT | uFormat);
1704 COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT)));
1705 if(m_hFontLink != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover)))
1706 dc.SelectFont(m_hFontLink);
1708 dc.SelectFont(m_hFontNormal);
1710 dc.DrawText(lpstrLink, cchLink, &m_rcLink, DT_LEFT | uFormat);
1712 dc.SetTextColor(clrOld);
1713 dc.SelectFont(m_hFontNormal);
1714 if(lpstrRight != NULL)
1716 RECT rcRight = { m_rcLink.right, m_rcLink.top, rcClient.right, rcClient.bottom };
1717 dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | uFormat);
1720 if(GetFocus() == m_hWnd)
1721 dc.DrawFocusRect(&m_rcLink);
1723 dc.SelectFont(hFontOld);
1727 dc.SetBkMode(TRANSPARENT);
1728 COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT)));
1730 HFONT hFontOld = NULL;
1731 if(m_hFontLink != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover)))
1732 hFontOld = dc.SelectFont(m_hFontLink);
1734 hFontOld = dc.SelectFont(m_hFontNormal);
1736 LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
1738 DWORD dwStyle = GetStyle();
1739 UINT uFormat = DT_LEFT;
1740 if (dwStyle & SS_CENTER)
1741 uFormat = DT_CENTER;
1742 else if (dwStyle & SS_RIGHT)
1744 uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
1746 dc.DrawText(lpstrText, -1, &m_rcLink, uFormat);
1748 if(GetFocus() == m_hWnd)
1749 dc.DrawFocusRect(&m_rcLink);
1751 dc.SetTextColor(clrOld);
1752 dc.SelectFont(hFontOld);
1757 BOOL StartTrackMouseLeave()
1759 TRACKMOUSEEVENT tme = { 0 };
1760 tme.cbSize =
sizeof(tme);
1761 tme.dwFlags = TME_LEAVE;
1762 tme.hwndTrack = m_hWnd;
1763 return _TrackMouseEvent(&tme);
1765 #endif // !_WIN32_WCE 1768 bool IsUnderlined()
const 1770 return ((m_dwExtendedStyle & (HLINK_NOTUNDERLINED | HLINK_UNDERLINEHOVER)) == 0);
1773 bool IsNotUnderlined()
const 1775 return ((m_dwExtendedStyle & HLINK_NOTUNDERLINED) != 0);
1778 bool IsUnderlineHover()
const 1780 return ((m_dwExtendedStyle & HLINK_UNDERLINEHOVER) != 0);
1783 bool IsCommandButton()
const 1785 return ((m_dwExtendedStyle & HLINK_COMMANDBUTTON) != 0);
1788 bool IsNotifyButton()
const 1790 return ((m_dwExtendedStyle & HLINK_NOTIFYBUTTON) == HLINK_NOTIFYBUTTON);
1793 bool IsUsingTags()
const 1795 return ((m_dwExtendedStyle & HLINK_USETAGS) != 0);
1798 bool IsUsingTagsBold()
const 1800 return ((m_dwExtendedStyle & HLINK_USETAGSBOLD) == HLINK_USETAGSBOLD);
1803 bool IsUsingToolTip()
const 1805 return ((m_dwExtendedStyle & HLINK_NOTOOLTIP) == 0);
1808 bool IsAutoCreateLinkFont()
const 1810 return ((m_dwExtendedStyle & HLINK_AUTOCREATELINKFONT) == HLINK_AUTOCREATELINKFONT);
1813 bool IsSingleLine()
const 1815 return ((m_dwExtendedStyle & HLINK_SINGLELINE) == HLINK_SINGLELINE);
1822 DECLARE_WND_CLASS(_T(
"WTL_HyperLink"))
1833 HCURSOR m_hWaitCursor;
1834 HCURSOR m_hOldCursor;
1838 CWaitCursor(
bool bSet =
true, LPCTSTR lpstrCursor = IDC_WAIT,
bool bSys =
true) : m_hOldCursor(NULL), m_bInUse(
false)
1840 HINSTANCE hInstance = bSys ? NULL : ModuleHelper::GetResourceInstance();
1841 m_hWaitCursor = ::LoadCursor(hInstance, lpstrCursor);
1842 ATLASSERT(m_hWaitCursor != NULL);
1858 m_hOldCursor = ::SetCursor(m_hWaitCursor);
1867 ::SetCursor(m_hOldCursor);
1884 if(hInstance == NULL)
1885 hInstance = ModuleHelper::GetResourceInstance();
1886 m_hWaitCursor = (HCURSOR)::LoadImage(hInstance, cursor.m_lpstr, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE);
1895 #if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) 1896 ::DestroyCursor(m_hWaitCursor);
1897 #endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) 1905 template <
class T,
class TBase = CStatusBarCtrl>
1909 DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
1912 enum { m_cxPaneMargin = 3 };
1927 HWND Create(HWND hWndParent, LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR)
1929 #if (_MSC_VER >= 1300) 1930 return ATL::CWindowImpl< T, TBase >::Create(hWndParent, rcDefault, lpstrText, dwStyle, 0, nID);
1931 #else // !(_MSC_VER >= 1300) 1932 typedef ATL::CWindowImpl< T, TBase > _baseClass;
1933 return _baseClass::Create(hWndParent, rcDefault, lpstrText, dwStyle, 0, nID);
1934 #endif // !(_MSC_VER >= 1300) 1937 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)
1939 const int cchMax = 128;
1940 TCHAR szText[cchMax] = { 0 };
1941 ::LoadString(ModuleHelper::GetResourceInstance(), nTextID, szText, cchMax);
1942 return Create(hWndParent, szText, dwStyle, nID);
1945 BOOL SetPanes(
int* pPanes,
int nPanes,
bool bSetText =
true)
1947 ATLASSERT(::IsWindow(m_hWnd));
1948 ATLASSERT(nPanes > 0);
1954 ATLTRY(m_pPane =
new int[nPanes]);
1955 ATLASSERT(m_pPane != NULL);
1960 int* pPanesPos = buff.Allocate(nPanes);
1961 ATLASSERT(pPanesPos != NULL);
1962 if(pPanesPos == NULL)
1965 SecureHelper::memcpy_x(m_pPane, nPanes *
sizeof(
int), pPanes, nPanes *
sizeof(
int));
1969 HFONT hOldFont = dc.SelectFont(GetFont());
1972 int arrBorders[3] = { 0 };
1973 GetBorders(arrBorders);
1975 const int cchBuff = 128;
1976 TCHAR szBuff[cchBuff] = { 0 };
1977 SIZE size = { 0, 0 };
1978 int cxLeft = arrBorders[0];
1981 for(
int i = 0; i < nPanes; i++)
1983 if(pPanes[i] == ID_DEFAULT_PANE)
1986 pPanesPos[i] = INT_MAX / 2;
1990 ::LoadString(ModuleHelper::GetResourceInstance(), pPanes[i], szBuff, cchBuff);
1991 dc.GetTextExtent(szBuff, lstrlen(szBuff), &size);
1992 T* pT =
static_cast<T*
>(
this);
1994 pPanesPos[i] = cxLeft + size.cx + arrBorders[2] + 2 * pT->m_cxPaneMargin;
1996 cxLeft = pPanesPos[i];
1999 BOOL bRet = SetParts(nPanes, pPanesPos);
2001 if(bRet && bSetText)
2003 for(
int i = 0; i < nPanes; i++)
2005 if(pPanes[i] != ID_DEFAULT_PANE)
2007 ::LoadString(ModuleHelper::GetResourceInstance(), pPanes[i], szBuff, cchBuff);
2008 SetPaneText(m_pPane[i], szBuff);
2013 dc.SelectFont(hOldFont);
2017 bool GetPaneTextLength(
int nPaneID,
int* pcchLength = NULL,
int* pnType = NULL)
const 2019 ATLASSERT(::IsWindow(m_hWnd));
2020 int nIndex = GetPaneIndexFromID(nPaneID);
2024 int nLength = GetTextLength(nIndex, pnType);
2025 if(pcchLength != NULL)
2026 *pcchLength = nLength;
2031 BOOL GetPaneText(
int nPaneID, LPTSTR lpstrText,
int* pcchLength = NULL,
int* pnType = NULL)
const 2033 ATLASSERT(::IsWindow(m_hWnd));
2034 int nIndex = GetPaneIndexFromID(nPaneID);
2038 int nLength = GetText(nIndex, lpstrText, pnType);
2039 if(pcchLength != NULL)
2040 *pcchLength = nLength;
2045 BOOL SetPaneText(
int nPaneID, LPCTSTR lpstrText,
int nType = 0)
2047 ATLASSERT(::IsWindow(m_hWnd));
2048 int nIndex = GetPaneIndexFromID(nPaneID);
2052 return SetText(nIndex, lpstrText, nType);
2055 BOOL GetPaneRect(
int nPaneID, LPRECT lpRect)
const 2057 ATLASSERT(::IsWindow(m_hWnd));
2058 int nIndex = GetPaneIndexFromID(nPaneID);
2062 return GetRect(nIndex, lpRect);
2065 BOOL SetPaneWidth(
int nPaneID,
int cxWidth)
2067 ATLASSERT(::IsWindow(m_hWnd));
2068 ATLASSERT(nPaneID != ID_DEFAULT_PANE);
2069 int nIndex = GetPaneIndexFromID(nPaneID);
2075 int* pPanesPos = buff.Allocate(m_nPanes);
2076 if(pPanesPos == NULL)
2078 GetParts(m_nPanes, pPanesPos);
2080 int cxPaneWidth = pPanesPos[nIndex] - ((nIndex == 0) ? 0 : pPanesPos[nIndex - 1]);
2081 int cxOff = cxWidth - cxPaneWidth;
2083 int nDef = m_nPanes;
2084 for(
int i = 0; i < m_nPanes; i++)
2086 if(m_pPane[i] == ID_DEFAULT_PANE)
2095 for(
int i = nIndex; i < nDef; i++)
2096 pPanesPos[i] += cxOff;
2101 for(
int i = nDef; i < nIndex; i++)
2102 pPanesPos[i] -= cxOff;
2105 return SetParts(m_nPanes, pPanesPos);
2108 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) 2109 BOOL GetPaneTipText(
int nPaneID, LPTSTR lpstrText,
int nSize)
const 2111 ATLASSERT(::IsWindow(m_hWnd));
2112 int nIndex = GetPaneIndexFromID(nPaneID);
2116 GetTipText(nIndex, lpstrText, nSize);
2120 BOOL SetPaneTipText(
int nPaneID, LPCTSTR lpstrText)
2122 ATLASSERT(::IsWindow(m_hWnd));
2123 int nIndex = GetPaneIndexFromID(nPaneID);
2127 SetTipText(nIndex, lpstrText);
2130 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) 2132 #if ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) 2133 BOOL GetPaneIcon(
int nPaneID, HICON& hIcon)
const 2135 ATLASSERT(::IsWindow(m_hWnd));
2136 int nIndex = GetPaneIndexFromID(nPaneID);
2140 hIcon = GetIcon(nIndex);
2144 BOOL SetPaneIcon(
int nPaneID, HICON hIcon)
2146 ATLASSERT(::IsWindow(m_hWnd));
2147 int nIndex = GetPaneIndexFromID(nPaneID);
2151 return SetIcon(nIndex, hIcon);
2153 #endif // ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) 2157 MESSAGE_HANDLER(WM_SIZE, OnSize)
2160 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& )
2162 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
2163 if(wParam != SIZE_MINIMIZED && m_nPanes > 0)
2165 T* pT =
static_cast<T*
>(
this);
2166 pT->UpdatePanesLayout();
2172 BOOL UpdatePanesLayout()
2176 int* pPanesPos = buff.Allocate(m_nPanes);
2177 ATLASSERT(pPanesPos != NULL);
2178 if(pPanesPos == NULL)
2180 int nRet = GetParts(m_nPanes, pPanesPos);
2181 ATLASSERT(nRet == m_nPanes);
2182 if(nRet != m_nPanes)
2185 RECT rcClient = { 0 };
2186 GetClientRect(&rcClient);
2187 int cxOff = rcClient.right - pPanesPos[m_nPanes - 1];
2190 if((GetStyle() & SBARS_SIZEGRIP) != 0)
2191 cxOff -= ::GetSystemMetrics(SM_CXVSCROLL) + ::GetSystemMetrics(SM_CXEDGE);
2192 #endif // !_WIN32_WCE 2195 for(i = 0; i < m_nPanes; i++)
2197 if(m_pPane[i] == ID_DEFAULT_PANE)
2201 if((i < m_nPanes) && (pPanesPos[i] + cxOff) > ((i == 0) ? 0 : pPanesPos[i - 1]))
2203 for(; i < m_nPanes; i++)
2204 pPanesPos[i] += cxOff;
2207 return SetParts(m_nPanes, pPanesPos);
2210 int GetPaneIndexFromID(
int nPaneID)
const 2212 for(
int i = 0; i < m_nPanes; i++)
2214 if(m_pPane[i] == nPaneID)
2225 DECLARE_WND_SUPERCLASS(_T(
"WTL_MultiPaneStatusBar"), GetWndClassName())
2233 #define PANECNT_NOCLOSEBUTTON 0x00000001 2234 #define PANECNT_VERTICAL 0x00000002 2235 #define PANECNT_FLATBORDER 0x00000004 2236 #define PANECNT_NOBORDER 0x00000008 2238 template <
class T,
class TBase = ATL::CWindow,
class TWinTraits = ATL::CControlWinTraits>
2242 DECLARE_WND_CLASS_EX(NULL, 0, -1)
2248 m_cxyTextOffset = 4,
2257 m_cxToolBar = m_cxImageTB + m_cxyBtnAddTB + m_cxyBorder + m_cxyBtnOffset,
2259 m_xBtnImageLeft = 6,
2261 m_xBtnImageRight = 12,
2262 m_yBtnImageBottom = 11,
2264 m_nCloseBtnID = ID_PANE_CLOSE
2269 ATL::CWindow m_wndClient;
2271 TCHAR m_szTitle[m_cchTitle];
2272 DWORD m_dwExtendedStyle;
2274 bool m_bInternalFont;
2278 CPaneContainerImpl() : m_cxyHeader(0), m_dwExtendedStyle(0), m_hFont(NULL), m_bInternalFont(
false)
2284 DWORD GetPaneContainerExtendedStyle()
const 2286 return m_dwExtendedStyle;
2289 DWORD SetPaneContainerExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
2291 DWORD dwPrevStyle = m_dwExtendedStyle;
2293 m_dwExtendedStyle = dwExtendedStyle;
2295 m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
2298 T* pT =
static_cast<T*
>(
this);
2299 bool bUpdate =
false;
2301 if(((dwPrevStyle & PANECNT_NOCLOSEBUTTON) != 0) && ((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) == 0))
2303 pT->CreateCloseButton();
2306 else if(((dwPrevStyle & PANECNT_NOCLOSEBUTTON) == 0) && ((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) != 0))
2308 pT->DestroyCloseButton();
2312 if((dwPrevStyle & PANECNT_VERTICAL) != (m_dwExtendedStyle & PANECNT_VERTICAL))
2318 if((dwPrevStyle & (PANECNT_FLATBORDER | PANECNT_NOBORDER)) !=
2319 (m_dwExtendedStyle & (PANECNT_FLATBORDER | PANECNT_NOBORDER)))
2330 HWND GetClient()
const 2335 HWND SetClient(HWND hWndClient)
2337 HWND hWndOldClient = m_wndClient;
2338 m_wndClient = hWndClient;
2341 T* pT =
static_cast<T*
>(
this);
2344 return hWndOldClient;
2347 BOOL GetTitle(LPTSTR lpstrTitle,
int cchLength)
const 2349 ATLASSERT(lpstrTitle != NULL);
2351 errno_t nRet = SecureHelper::strncpy_x(lpstrTitle, cchLength, m_szTitle, _TRUNCATE);
2353 return (nRet == 0 || nRet == STRUNCATE);
2356 BOOL SetTitle(LPCTSTR lpstrTitle)
2358 ATLASSERT(lpstrTitle != NULL);
2360 errno_t nRet = SecureHelper::strncpy_x(m_szTitle, m_cchTitle, lpstrTitle, _TRUNCATE);
2361 bool bRet = (nRet == 0 || nRet == STRUNCATE);
2362 if(bRet && m_hWnd != NULL)
2364 T* pT =
static_cast<T*
>(
this);
2371 int GetTitleLength()
const 2373 return lstrlen(m_szTitle);
2377 HWND Create(HWND hWndParent, LPCTSTR lpstrTitle = NULL, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
2378 DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL)
2380 if(lpstrTitle != NULL)
2381 SecureHelper::strncpy_x(m_szTitle, m_cchTitle, lpstrTitle, _TRUNCATE);
2382 #if (_MSC_VER >= 1300) 2383 return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam);
2384 #else // !(_MSC_VER >= 1300) 2385 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
2386 return _baseClass::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam);
2387 #endif // !(_MSC_VER >= 1300) 2390 HWND Create(HWND hWndParent, UINT uTitleID, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
2391 DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL)
2394 ::LoadString(ModuleHelper::GetResourceInstance(), uTitleID, m_szTitle, m_cchTitle);
2395 #if (_MSC_VER >= 1300) 2396 return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam);
2397 #else // !(_MSC_VER >= 1300) 2398 typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass;
2399 return _baseClass::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam);
2400 #endif // !(_MSC_VER >= 1300) 2403 BOOL EnableCloseButton(BOOL bEnable)
2405 ATLASSERT(::IsWindow(m_hWnd));
2406 T* pT =
static_cast<T*
>(
this);
2408 return (m_tb.m_hWnd != NULL) ? m_tb.EnableButton(pT->m_nCloseBtnID, bEnable) : FALSE;
2413 RECT rcClient = { 0 };
2414 GetClientRect(&rcClient);
2415 T* pT =
static_cast<T*
>(
this);
2416 pT->UpdateLayout(rcClient.right, rcClient.bottom);
2421 MESSAGE_HANDLER(WM_CREATE, OnCreate)
2422 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
2423 MESSAGE_HANDLER(WM_SIZE, OnSize)
2424 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
2425 MESSAGE_HANDLER(WM_GETFONT, OnGetFont)
2426 MESSAGE_HANDLER(WM_SETFONT, OnSetFont)
2427 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
2428 MESSAGE_HANDLER(WM_PAINT, OnPaint)
2430 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
2431 #endif // !_WIN32_WCE 2432 MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
2433 MESSAGE_HANDLER(WM_COMMAND, OnCommand)
2434 FORWARD_NOTIFICATIONS()
2437 LRESULT OnCreate(UINT , WPARAM , LPARAM , BOOL& )
2444 ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT,
sizeof(LOGFONT), &lf, 0) != FALSE);
2446 lf.lfEscapement = 900;
2447 m_hFont = ::CreateFontIndirect(&lf);
2448 #else // CE specific 2449 m_hFont = (HFONT)::GetStockObject(SYSTEM_FONT);
2453 lf.lfEscapement = 900;
2454 m_hFont = ::CreateFontIndirect(&lf);
2456 #endif // _WIN32_WCE 2457 m_bInternalFont =
true;
2460 T* pT =
static_cast<T*
>(
this);
2463 if((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) == 0)
2464 pT->CreateCloseButton();
2469 LRESULT OnDestroy(UINT , WPARAM , LPARAM , BOOL& )
2473 ::DeleteObject(m_hFont);
2475 m_bInternalFont =
false;
2481 LRESULT OnSize(UINT , WPARAM , LPARAM lParam, BOOL& )
2483 T* pT =
static_cast<T*
>(
this);
2484 pT->UpdateLayout(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
2488 LRESULT OnSetFocus(UINT , WPARAM , LPARAM , BOOL& )
2490 if(m_wndClient.m_hWnd != NULL)
2491 m_wndClient.SetFocus();
2495 LRESULT OnGetFont(UINT , WPARAM , LPARAM , BOOL& )
2497 return (LRESULT)m_hFont;
2500 LRESULT OnSetFont(UINT , WPARAM wParam, LPARAM lParam, BOOL& )
2504 ::DeleteObject(m_hFont);
2505 m_bInternalFont =
false;
2508 m_hFont = (HFONT)wParam;
2510 T* pT =
static_cast<T*
>(
this);
2513 if((BOOL)lParam != FALSE)
2519 LRESULT OnEraseBackground(UINT , WPARAM , LPARAM , BOOL& )
2524 LRESULT OnPaint(UINT , WPARAM wParam, LPARAM , BOOL& )
2526 T* pT =
static_cast<T*
>(
this);
2529 pT->DrawPaneTitle((HDC)wParam);
2531 if(m_wndClient.m_hWnd == NULL)
2532 pT->DrawPane((HDC)wParam);
2537 pT->DrawPaneTitle(dc.m_hDC);
2539 if(m_wndClient.m_hWnd == NULL)
2540 pT->DrawPane(dc.m_hDC);
2546 LRESULT OnNotify(UINT , WPARAM , LPARAM lParam, BOOL& bHandled)
2548 if(m_tb.m_hWnd == NULL)
2554 T* pT =
static_cast<T*
>(
this);
2556 LPNMHDR lpnmh = (LPNMHDR)lParam;
2560 if(lpnmh->code == NM_CUSTOMDRAW && lpnmh->hwndFrom == m_tb.m_hWnd)
2565 else if(lpnmh->code == TTN_GETDISPINFO && lpnmh->idFrom == pT->m_nCloseBtnID)
2566 bHandled = pT->GetToolTipText(lpnmh);
2567 #endif // !_WIN32_WCE 2569 else if(lpnmh->hwndFrom != m_tb.m_hWnd && lpnmh->idFrom != pT->m_nCloseBtnID)
2575 LRESULT OnCommand(UINT , WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2578 if(m_tb.m_hWnd != NULL && (HWND)lParam == m_tb.m_hWnd)
2579 return ::SendMessage(GetParent(), WM_COMMAND, wParam, (LPARAM)m_hWnd);
2586 DWORD OnPrePaint(
int , LPNMCUSTOMDRAW )
2588 return CDRF_NOTIFYITEMDRAW;
2591 DWORD OnItemPrePaint(
int , LPNMCUSTOMDRAW lpNMCustomDraw)
2594 #if (_WIN32_IE >= 0x0400) 2595 RECT& rc = lpNMCustomDraw->rc;
2596 #else // !(_WIN32_IE >= 0x0400) 2598 m_tb.GetItemRect(0, &rc);
2599 #endif // !(_WIN32_IE >= 0x0400) 2601 dc.FillRect(&rc, COLOR_3DFACE);
2603 return CDRF_NOTIFYPOSTPAINT;
2606 DWORD OnItemPostPaint(
int , LPNMCUSTOMDRAW lpNMCustomDraw)
2609 #if (_WIN32_IE >= 0x0400) 2610 RECT& rc = lpNMCustomDraw->rc;
2611 #else // !(_WIN32_IE >= 0x0400) 2613 m_tb.GetItemRect(0, &rc);
2614 #endif // !(_WIN32_IE >= 0x0400) 2616 RECT rcImage = { m_xBtnImageLeft, m_yBtnImageTop, m_xBtnImageRight + 1, m_yBtnImageBottom + 1 };
2617 ::OffsetRect(&rcImage, rc.left, rc.top);
2618 T* pT =
static_cast<T*
>(
this);
2620 if((lpNMCustomDraw->uItemState & CDIS_DISABLED) != 0)
2622 RECT rcShadow = rcImage;
2623 ::OffsetRect(&rcShadow, 1, 1);
2625 pen1.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DHILIGHT));
2626 pT->DrawButtonImage(dc, rcShadow, pen1);
2628 pen2.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DSHADOW));
2629 pT->DrawButtonImage(dc, rcImage, pen2);
2633 if((lpNMCustomDraw->uItemState & CDIS_SELECTED) != 0)
2634 ::OffsetRect(&rcImage, 1, 1);
2636 pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNTEXT));
2637 pT->DrawButtonImage(dc, rcImage, pen);
2640 return CDRF_DODEFAULT;
2644 void UpdateLayout(
int cxWidth,
int cyHeight)
2646 ATLASSERT(::IsWindow(m_hWnd));
2651 ::SetRect(&rect, 0, 0, m_cxyHeader, cyHeight);
2652 if(m_tb.m_hWnd != NULL)
2653 m_tb.SetWindowPos(NULL, m_cxyBorder, m_cxyBorder + m_cxyBtnOffset, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
2655 if(m_wndClient.m_hWnd != NULL)
2656 m_wndClient.SetWindowPos(NULL, m_cxyHeader, 0, cxWidth - m_cxyHeader, cyHeight, SWP_NOZORDER);
2658 rect.right = cxWidth;
2662 ::SetRect(&rect, 0, 0, cxWidth, m_cxyHeader);
2663 if(m_tb.m_hWnd != NULL)
2664 m_tb.SetWindowPos(NULL, rect.right - m_cxToolBar, m_cxyBorder + m_cxyBtnOffset, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
2666 if(m_wndClient.m_hWnd != NULL)
2667 m_wndClient.SetWindowPos(NULL, 0, m_cxyHeader, cxWidth, cyHeight - m_cxyHeader, SWP_NOZORDER);
2669 rect.bottom = cyHeight;
2672 InvalidateRect(&rect);
2675 void CreateCloseButton()
2677 ATLASSERT(m_tb.m_hWnd == NULL);
2679 m_tb.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NOMOVEY | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT, 0);
2680 ATLASSERT(m_tb.IsWindow());
2682 if(m_tb.m_hWnd != NULL)
2684 T* pT =
static_cast<T*
>(
this);
2687 m_tb.SetButtonStructSize();
2689 TBBUTTON tbbtn = { 0 };
2690 tbbtn.idCommand = pT->m_nCloseBtnID;
2691 tbbtn.fsState = TBSTATE_ENABLED;
2692 tbbtn.fsStyle = TBSTYLE_BUTTON;
2693 m_tb.AddButtons(1, &tbbtn);
2695 m_tb.SetBitmapSize(m_cxImageTB, m_cyImageTB);
2696 m_tb.SetButtonSize(m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB);
2699 m_tb.SetWindowPos(NULL, m_cxyBorder + m_cxyBtnOffset, m_cxyBorder + m_cxyBtnOffset, m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB, SWP_NOZORDER | SWP_NOACTIVATE);
2701 m_tb.SetWindowPos(NULL, 0, 0, m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
2705 void DestroyCloseButton()
2707 if(m_tb.m_hWnd != NULL)
2708 m_tb.DestroyWindow();
2713 T* pT =
static_cast<T*
>(
this);
2716 font = (HFONT)::GetStockObject(SYSTEM_FONT);
2718 font.GetLogFont(lf);
2721 m_cxyHeader = m_cxImageTB + m_cxyBtnAddTB + m_cxyBorder;
2725 int cyFont = abs(lf.lfHeight) + m_cxyBorder + 2 * m_cxyTextOffset;
2726 int cyBtn = m_cyImageTB + m_cxyBtnAddTB + m_cxyBorder + 2 * m_cxyBtnOffset;
2727 m_cxyHeader = max(cyFont, cyBtn);
2731 HFONT GetTitleFont()
const 2737 BOOL GetToolTipText(LPNMHDR )
2741 #endif // !_WIN32_WCE 2746 GetClientRect(&rect);
2748 UINT uBorder = BF_LEFT | BF_TOP | BF_ADJUST;
2751 rect.right = rect.left + m_cxyHeader;
2752 uBorder |= BF_BOTTOM;
2756 rect.bottom = rect.top + m_cxyHeader;
2757 uBorder |= BF_RIGHT;
2760 if((m_dwExtendedStyle & PANECNT_NOBORDER) == 0)
2762 if((m_dwExtendedStyle & PANECNT_FLATBORDER) != 0)
2764 dc.DrawEdge(&rect, EDGE_ETCHED, uBorder);
2766 dc.FillRect(&rect, COLOR_3DFACE);
2769 dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
2770 dc.SetBkMode(TRANSPARENT);
2771 T* pT =
static_cast<T*
>(
this);
2772 HFONT hFontOld = dc.SelectFont(pT->GetTitleFont());
2774 const UINT DT_END_ELLIPSIS = 0;
2775 #endif // _WIN32_WCE 2779 rect.top += m_cxyTextOffset;
2780 rect.bottom -= m_cxyTextOffset;
2781 if(m_tb.m_hWnd != NULL)
2782 rect.top += m_cxToolBar;;
2784 RECT rcCalc = { rect.left, rect.bottom, rect.right, rect.top };
2785 int cxFont = dc.DrawText(m_szTitle, -1, &rcCalc, DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS | DT_CALCRECT);
2786 RECT rcText = { 0 };
2787 rcText.left = (rect.right - rect.left - cxFont) / 2;
2788 rcText.right = rcText.left + (rect.bottom - rect.top);
2789 rcText.top = rect.bottom;
2790 rcText.bottom = rect.top;
2791 dc.DrawText(m_szTitle, -1, &rcText, DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS);
2795 rect.left += m_cxyTextOffset;
2796 rect.right -= m_cxyTextOffset;
2797 if(m_tb.m_hWnd != NULL)
2798 rect.right -= m_cxToolBar;;
2800 dc.DrawText(m_szTitle, -1, &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS);
2803 dc.SelectFont(hFontOld);
2810 GetClientRect(&rect);
2812 rect.left += m_cxyHeader;
2814 rect.top += m_cxyHeader;
2815 if((GetExStyle() & WS_EX_CLIENTEDGE) == 0)
2816 dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
2817 dc.FillRect(&rect, COLOR_APPWORKSPACE);
2821 void DrawButtonImage(
CDCHandle dc, RECT& rcImage, HPEN hPen)
2823 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) 2824 HPEN hPenOld = dc.SelectPen(hPen);
2826 dc.MoveTo(rcImage.left, rcImage.top);
2827 dc.LineTo(rcImage.right, rcImage.bottom);
2828 dc.MoveTo(rcImage.left + 1, rcImage.top);
2829 dc.LineTo(rcImage.right + 1, rcImage.bottom);
2831 dc.MoveTo(rcImage.left, rcImage.bottom - 1);
2832 dc.LineTo(rcImage.right, rcImage.top - 1);
2833 dc.MoveTo(rcImage.left + 1, rcImage.bottom - 1);
2834 dc.LineTo(rcImage.right + 1, rcImage.top - 1);
2836 dc.SelectPen(hPenOld);
2837 #else // (_WIN32_WCE < 400) 2841 #endif // (_WIN32_WCE < 400) 2844 bool IsVertical()
const 2846 return ((m_dwExtendedStyle & PANECNT_VERTICAL) != 0);
2853 DECLARE_WND_CLASS_EX(_T(
"WTL_PaneContainer"), 0, -1)
2861 #define SORTLV_USESHELLBITMAPS 0x00000001 2864 #define SLVN_SORTCHANGED LVN_LAST 2879 LVCOLSORT_TEXTNOCASE,
2887 LVCOLSORT_LAST = LVCOLSORT_CUSTOM
2897 m_cchCmpTextMax = 32,
2904 m_nShellSortUpID = 133
2911 DWORD_PTR dwItemData;
2929 bool m_bSortDescending;
2933 int m_fmtOldSortCol;
2934 HBITMAP m_hbmOldSortCol;
2935 DWORD m_dwSortLVExtendedStyle;
2936 ATL::CSimpleArray<WORD> m_arrColSortType;
2937 bool m_bUseWaitCursor;
2940 m_bSortDescending(
false),
2941 m_bCommCtrl6(
false),
2944 m_hbmOldSortCol(NULL),
2945 m_dwSortLVExtendedStyle(SORTLV_USESHELLBITMAPS),
2946 m_bUseWaitCursor(
true)
2951 HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor);
2952 m_bCommCtrl6 = SUCCEEDED(hRet) && dwMajor >= 6;
2953 #endif // !_WIN32_WCE 2957 void SetSortColumn(
int iCol)
2959 T* pT =
static_cast<T*
>(
this);
2960 ATLASSERT(::IsWindow(pT->m_hWnd));
2962 ATLASSERT(header.m_hWnd != NULL);
2963 ATLASSERT(iCol >= -1 && iCol < m_arrColSortType.GetSize());
2965 int iOldSortCol = m_iSortColumn;
2966 m_iSortColumn = iCol;
2970 const int HDF_SORTUP = 0x0400;
2971 #endif // HDF_SORTUP 2972 #ifndef HDF_SORTDOWN 2973 const int HDF_SORTDOWN = 0x0200;
2974 #endif // HDF_SORTDOWN 2975 const int nMask = HDF_SORTUP | HDF_SORTDOWN;
2976 HDITEM hditem = { HDI_FORMAT };
2977 if(iOldSortCol != iCol && iOldSortCol >= 0 && header.GetItem(iOldSortCol, &hditem))
2979 hditem.fmt &= ~nMask;
2980 header.SetItem(iOldSortCol, &hditem);
2982 if(iCol >= 0 && header.GetItem(iCol, &hditem))
2984 hditem.fmt &= ~nMask;
2985 hditem.fmt |= m_bSortDescending ? HDF_SORTDOWN : HDF_SORTUP;
2986 header.SetItem(iCol, &hditem);
2991 if(m_bmSort[m_iSortUp].IsNull())
2992 pT->CreateSortBitmaps();
2995 HDITEM hditem = { HDI_BITMAP | HDI_FORMAT };
2996 if(iOldSortCol != iCol && iOldSortCol >= 0)
2998 hditem.hbm = m_hbmOldSortCol;
2999 hditem.fmt = m_fmtOldSortCol;
3000 header.SetItem(iOldSortCol, &hditem);
3004 if(iCol >= 0 && header.GetItem(iCol, &hditem))
3006 if(iOldSortCol != iCol)
3008 m_fmtOldSortCol = hditem.fmt;
3009 m_hbmOldSortCol = hditem.hbm;
3011 hditem.fmt &= ~HDF_IMAGE;
3012 hditem.fmt |= HDF_BITMAP | HDF_BITMAP_ON_RIGHT;
3013 int i = m_bSortDescending ? m_iSortDown : m_iSortUp;
3014 hditem.hbm = m_bmSort[i];
3015 header.SetItem(iCol, &hditem);
3019 int GetSortColumn()
const 3021 return m_iSortColumn;
3024 void SetColumnSortType(
int iCol, WORD wType)
3026 ATLASSERT(iCol >= 0 && iCol < m_arrColSortType.GetSize());
3027 ATLASSERT(wType >= LVCOLSORT_NONE && wType <= LVCOLSORT_LAST);
3028 m_arrColSortType[iCol] = wType;
3031 WORD GetColumnSortType(
int iCol)
const 3033 ATLASSERT((iCol >= 0) && iCol < m_arrColSortType.GetSize());
3034 return m_arrColSortType[iCol];
3037 int GetColumnCount()
const 3039 const T* pT =
static_cast<const T*
>(
this);
3040 ATLASSERT(::IsWindow(pT->m_hWnd));
3042 return header.m_hWnd != NULL ? header.GetItemCount() : 0;
3045 bool IsSortDescending()
const 3047 return m_bSortDescending;
3050 DWORD GetSortListViewExtendedStyle()
const 3052 return m_dwSortLVExtendedStyle;
3055 DWORD SetSortListViewExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
3057 DWORD dwPrevStyle = m_dwSortLVExtendedStyle;
3059 m_dwSortLVExtendedStyle = dwExtendedStyle;
3061 m_dwSortLVExtendedStyle = (m_dwSortLVExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
3066 bool DoSortItems(
int iCol,
bool bDescending =
false)
3068 T* pT =
static_cast<T*
>(
this);
3069 ATLASSERT(::IsWindow(pT->m_hWnd));
3070 ATLASSERT(iCol >= 0 && iCol < m_arrColSortType.GetSize());
3072 WORD wType = m_arrColSortType[iCol];
3073 if(wType == LVCOLSORT_NONE)
3076 int nCount = pT->GetItemCount();
3079 m_bSortDescending = bDescending;
3080 SetSortColumn(iCol);
3085 if(m_bUseWaitCursor)
3090 PFNLVCOMPARE pFunc = NULL;
3091 TCHAR pszTemp[pT->m_cchCmpTextMax] = { 0 };
3092 bool bStrValue =
false;
3096 case LVCOLSORT_TEXT:
3097 pFunc = (PFNLVCOMPARE)pT->LVCompareText;
3098 case LVCOLSORT_TEXTNOCASE:
3100 pFunc = (PFNLVCOMPARE)pT->LVCompareTextNoCase;
3101 case LVCOLSORT_CUSTOM:
3104 pFunc = (PFNLVCOMPARE)pT->LVCompareCustom;
3106 for(
int i = 0; i < nCount; i++)
3108 pParam[i].iItem = i;
3109 pParam[i].dwItemData = pT->GetItemData(i);
3110 pParam[i].pszValue =
new TCHAR[pT->m_cchCmpTextMax];
3111 pT->GetItemText(i, iCol, (LPTSTR)pParam[i].pszValue, pT->m_cchCmpTextMax);
3112 pT->SetItemData(i, (DWORD_PTR)&pParam[i]);
3117 case LVCOLSORT_LONG:
3119 pFunc = (PFNLVCOMPARE)pT->LVCompareLong;
3120 for(
int i = 0; i < nCount; i++)
3122 pParam[i].iItem = i;
3123 pParam[i].dwItemData = pT->GetItemData(i);
3124 pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax);
3125 pParam[i].lValue = pT->StrToLong(pszTemp);
3126 pT->SetItemData(i, (DWORD_PTR)&pParam[i]);
3130 case LVCOLSORT_DOUBLE:
3132 pFunc = (PFNLVCOMPARE)pT->LVCompareDouble;
3133 for(
int i = 0; i < nCount; i++)
3135 pParam[i].iItem = i;
3136 pParam[i].dwItemData = pT->GetItemData(i);
3137 pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax);
3138 pParam[i].dblValue = pT->StrToDouble(pszTemp);
3139 pT->SetItemData(i, (DWORD_PTR)&pParam[i]);
3143 case LVCOLSORT_DECIMAL:
3145 pFunc = (PFNLVCOMPARE)pT->LVCompareDecimal;
3146 for(
int i = 0; i < nCount; i++)
3148 pParam[i].iItem = i;
3149 pParam[i].dwItemData = pT->GetItemData(i);
3150 pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax);
3151 pT->StrToDecimal(pszTemp, &pParam[i].decValue);
3152 pT->SetItemData(i, (DWORD_PTR)&pParam[i]);
3156 case LVCOLSORT_DATETIME:
3157 case LVCOLSORT_DATE:
3158 case LVCOLSORT_TIME:
3160 pFunc = (PFNLVCOMPARE)pT->LVCompareDouble;
3161 DWORD dwFlags = LOCALE_NOUSEROVERRIDE;
3162 if(wType == LVCOLSORT_DATE)
3163 dwFlags |= VAR_DATEVALUEONLY;
3164 else if(wType == LVCOLSORT_TIME)
3165 dwFlags |= VAR_TIMEVALUEONLY;
3166 for(
int i = 0; i < nCount; i++)
3168 pParam[i].iItem = i;
3169 pParam[i].dwItemData = pT->GetItemData(i);
3170 pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax);
3171 pParam[i].dblValue = pT->DateStrToDouble(pszTemp, dwFlags);
3172 pT->SetItemData(i, (DWORD_PTR)&pParam[i]);
3177 ATLTRACE2(atlTraceUI, 0, _T(
"Unknown value for sort type in CSortListViewImpl::DoSortItems()\n"));
3181 ATLASSERT(pFunc != NULL);
3183 bool bRet = ((BOOL)pT->DefWindowProc(LVM_SORTITEMS, (WPARAM)&lvsi, (LPARAM)pFunc) != FALSE);
3184 for(
int i = 0; i < nCount; i++)
3186 DWORD_PTR dwItemData = pT->GetItemData(i);
3188 ATLASSERT(p != NULL);
3190 delete [] (TCHAR*)p->pszValue;
3191 pT->SetItemData(i, p->dwItemData);
3197 m_bSortDescending = bDescending;
3198 SetSortColumn(iCol);
3201 if(m_bUseWaitCursor)
3202 waitCursor.Restore();
3207 void CreateSortBitmaps()
3209 if((m_dwSortLVExtendedStyle & SORTLV_USESHELLBITMAPS) != 0)
3212 LPCTSTR pszModule = _T(
"shell32.dll");
3213 HINSTANCE hShell = ::GetModuleHandle(pszModule);
3217 hShell = ::LoadLibrary(pszModule);
3223 bool bSuccess =
true;
3224 for(
int i = m_iSortUp; i <= m_iSortDown; i++)
3226 if(!m_bmSort[i].IsNull())
3227 m_bmSort[i].DeleteObject();
3228 m_bmSort[i] = (HBITMAP)::LoadImage(hShell, MAKEINTRESOURCE(m_nShellSortUpID + i),
3230 IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);
3231 #else // CE specific 3232 IMAGE_BITMAP, 0, 0, 0);
3233 #endif // _WIN32_WCE 3234 if(m_bmSort[i].IsNull())
3241 ::FreeLibrary(hShell);
3247 T* pT =
static_cast<T*
>(
this);
3248 for(
int i = m_iSortUp; i <= m_iSortDown; i++)
3250 if(!m_bmSort[i].IsNull())
3251 m_bmSort[i].DeleteObject();
3255 dcMem.CreateCompatibleDC(dc.m_hDC);
3256 m_bmSort[i].CreateCompatibleBitmap(dc.m_hDC, m_cxSortImage, m_cySortImage);
3257 HBITMAP hbmOld = dcMem.SelectBitmap(m_bmSort[i]);
3258 RECT rc = {0,0,m_cxSortImage, m_cySortImage};
3259 pT->DrawSortBitmap(dcMem.m_hDC, i, &rc);
3260 dcMem.SelectBitmap(hbmOld);
3265 void NotifyParentSortChanged(
int iNewSortCol,
int iOldSortCol)
3267 T* pT =
static_cast<T*
>(
this);
3268 int nID = pT->GetDlgCtrlID();
3269 NMSORTLISTVIEW nm = { { pT->m_hWnd, nID, SLVN_SORTCHANGED }, iNewSortCol, iOldSortCol };
3270 ::SendMessage(pT->GetParent(), WM_NOTIFY, (WPARAM)nID, (LPARAM)&nm);
3281 void DrawSortBitmap(
CDCHandle dc,
int iBitmap, LPRECT prc)
3283 dc.FillRect(prc, ::GetSysColorBrush(COLOR_BTNFACE));
3284 HBRUSH hbrOld = dc.SelectBrush(::GetSysColorBrush(COLOR_BTNSHADOW));
3286 pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNSHADOW));
3287 HPEN hpenOld = dc.SelectPen(pen);
3288 POINT ptOrg = { (m_cxSortImage - m_cxSortArrow) / 2, (m_cySortImage - m_cySortArrow) / 2 };
3289 if(iBitmap == m_iSortUp)
3293 { ptOrg.x + m_cxSortArrow / 2, ptOrg.y },
3294 { ptOrg.x, ptOrg.y + m_cySortArrow - 1 },
3295 { ptOrg.x + m_cxSortArrow - 1, ptOrg.y + m_cySortArrow - 1 }
3303 { ptOrg.x, ptOrg.y },
3304 { ptOrg.x + m_cxSortArrow / 2, ptOrg.y + m_cySortArrow - 1 },
3305 { ptOrg.x + m_cxSortArrow - 1, ptOrg.y }
3309 dc.SelectBrush(hbrOld);
3310 dc.SelectPen(hpenOld);
3313 double DateStrToDouble(LPCTSTR lpstr, DWORD dwFlags)
3315 ATLASSERT(lpstr != NULL);
3316 if(lpstr == NULL || lpstr[0] == _T(
'\0'))
3320 HRESULT hRet = E_FAIL;
3322 if (FAILED(hRet = ::VarDateFromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, dwFlags, &dRet)))
3324 ATLTRACE2(atlTraceUI, 0, _T(
"VarDateFromStr failed with result of 0x%8.8X\n"), hRet);
3330 long StrToLong(LPCTSTR lpstr)
3332 ATLASSERT(lpstr != NULL);
3333 if(lpstr == NULL || lpstr[0] == _T(
'\0'))
3337 HRESULT hRet = E_FAIL;
3339 if (FAILED(hRet = ::VarI4FromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, &lRet)))
3341 ATLTRACE2(atlTraceUI, 0, _T(
"VarI4FromStr failed with result of 0x%8.8X\n"), hRet);
3347 double StrToDouble(LPCTSTR lpstr)
3349 ATLASSERT(lpstr != NULL);
3350 if(lpstr == NULL || lpstr[0] == _T(
'\0'))
3354 HRESULT hRet = E_FAIL;
3356 if (FAILED(hRet = ::VarR8FromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, &dblRet)))
3358 ATLTRACE2(atlTraceUI, 0, _T(
"VarR8FromStr failed with result of 0x%8.8X\n"), hRet);
3364 bool StrToDecimal(LPCTSTR lpstr, DECIMAL* pDecimal)
3366 ATLASSERT(lpstr != NULL);
3367 ATLASSERT(pDecimal != NULL);
3368 if(lpstr == NULL || pDecimal == NULL)
3372 HRESULT hRet = E_FAIL;
3373 if (FAILED(hRet = ::VarDecFromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, pDecimal)))
3375 ATLTRACE2(atlTraceUI, 0, _T(
"VarDecFromStr failed with result of 0x%8.8X\n"), hRet);
3378 pDecimal->signscale = 0;
3385 static int CALLBACK LVCompareText(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3387 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3393 int nRet = lstrcmp(pParam1->pszValue, pParam2->pszValue);
3394 return pInfo->bDescending ? -nRet : nRet;
3397 static int CALLBACK LVCompareTextNoCase(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3399 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3405 int nRet = lstrcmpi(pParam1->pszValue, pParam2->pszValue);
3406 return pInfo->bDescending ? -nRet : nRet;
3409 static int CALLBACK LVCompareLong(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3411 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3418 if(pParam1->lValue > pParam2->lValue)
3420 else if(pParam1->lValue < pParam2->lValue)
3422 return pInfo->bDescending ? -nRet : nRet;
3425 static int CALLBACK LVCompareDouble(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3427 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3434 if(pParam1->dblValue > pParam2->dblValue)
3436 else if(pParam1->dblValue < pParam2->dblValue)
3438 return pInfo->bDescending ? -nRet : nRet;
3441 static int CALLBACK LVCompareCustom(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3443 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3449 int nRet = pInfo->pT->CompareItemsCustom(pParam1, pParam2, pInfo->iSortCol);
3450 return pInfo->bDescending ? -nRet : nRet;
3454 static int CALLBACK LVCompareDecimal(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3456 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3462 int nRet = (int)::VarDecCmp(&pParam1->decValue, &pParam2->decValue);
3464 return pInfo->bDescending ? -nRet : nRet;
3468 static int CompareMantissas(
const DECIMAL& decLeft,
const DECIMAL& decRight)
3470 if (decLeft.Hi32 < decRight.Hi32)
3474 if (decLeft.Hi32 > decRight.Hi32)
3479 if (decLeft.Lo64 < decRight.Lo64)
3483 if (decLeft.Lo64 > decRight.Lo64)
3491 static HRESULT VarDecCmp(
const DECIMAL* pdecLeft,
const DECIMAL* pdecRight)
3493 static const ULONG powersOfTen[] =
3505 static const int largestPower =
sizeof(powersOfTen) /
sizeof(powersOfTen[0]);
3506 if (!pdecLeft || !pdecRight)
3513 bool bLeftZero = (!pdecLeft->Lo64 && !pdecLeft->Hi32);
3514 bool bRightZero = (!pdecRight->Lo64 && !pdecRight->Hi32);
3515 if (bLeftZero && bRightZero)
3519 bool bLeftNeg = ((pdecLeft->sign & DECIMAL_NEG) != 0);
3520 bool bRightNeg = ((pdecRight->sign & DECIMAL_NEG) != 0);
3523 return (bRightNeg ? VARCMP_GT : VARCMP_LT);
3526 if (bRightZero || bLeftNeg != bRightNeg)
3528 return (bLeftNeg ? VARCMP_LT : VARCMP_GT);
3541 bool bInvert = bLeftNeg;
3542 if (pdecLeft->scale < pdecRight->scale)
3549 pdecRight = pdecLeft;
3556 while ((comp = CompareMantissas(temp, *pdecRight)) < 0 &&
3557 temp.scale < pdecRight->scale)
3560 int scaleDiff = pdecRight->scale - temp.scale;
3561 if (scaleDiff > largestPower)
3564 scaleDiff = largestPower;
3566 DWORDLONG power = powersOfTen[scaleDiff - 1];
3568 DWORDLONG product = temp.Lo32 * power;
3569 ULONG carry =
static_cast<ULONG
>(product >> 32);
3570 temp.Lo32 =
static_cast<ULONG
>(product);
3571 product = temp.Mid32 * power + carry;
3572 carry =
static_cast<ULONG
>(product >> 32);
3573 temp.Mid32 =
static_cast<ULONG
>(product);
3574 product = temp.Hi32 * power + carry;
3575 if (static_cast<ULONG>(product >> 32))
3580 temp.Hi32 =
static_cast<ULONG
>(product);
3581 temp.scale = (BYTE)(temp.scale + scaleDiff);
3583 if (temp.scale < pdecRight->scale)
3591 return (comp > 0 ? VARCMP_GT : comp < 0 ? VARCMP_LT : VARCMP_EQ);
3594 static int CALLBACK LVCompareDecimal(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3596 ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL);
3602 int nRet = (int)VarDecCmp(&pParam1->decValue, &pParam2->decValue);
3604 return pInfo->bDescending ? -nRet : nRet;
3606 #endif // !_WIN32_WCE 3609 MESSAGE_HANDLER(LVM_INSERTCOLUMN, OnInsertColumn)
3610 MESSAGE_HANDLER(LVM_DELETECOLUMN, OnDeleteColumn)
3611 NOTIFY_CODE_HANDLER(HDN_ITEMCLICKA, OnHeaderItemClick)
3612 NOTIFY_CODE_HANDLER(HDN_ITEMCLICKW, OnHeaderItemClick)
3613 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
3616 LRESULT OnInsertColumn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& )
3618 T* pT =
static_cast<T*
>(
this);
3619 LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam);
3624 m_arrColSortType.Add(wType);
3625 int nCount = m_arrColSortType.GetSize();
3626 ATLASSERT(nCount == GetColumnCount());
3628 for(
int i = nCount - 1; i > lRet; i--)
3629 m_arrColSortType[i] = m_arrColSortType[i - 1];
3630 m_arrColSortType[(int)lRet] = LVCOLSORT_TEXT;
3632 if(lRet <= m_iSortColumn)
3638 LRESULT OnDeleteColumn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& )
3640 T* pT =
static_cast<T*
>(
this);
3641 LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam);
3645 int iCol = (int)wParam;
3646 if(m_iSortColumn == iCol)
3648 else if(m_iSortColumn > iCol)
3650 m_arrColSortType.RemoveAt(iCol);
3655 LRESULT OnHeaderItemClick(
int , LPNMHDR pnmh, BOOL& bHandled)
3657 LPNMHEADER p = (LPNMHEADER)pnmh;
3660 int iOld = m_iSortColumn;
3661 bool bDescending = (m_iSortColumn == p->iItem) ? !m_bSortDescending :
false;
3662 if(DoSortItems(p->iItem, bDescending))
3663 NotifyParentSortChanged(p->iItem, iOld);
3669 LRESULT OnSettingChange(UINT , WPARAM wParam, LPARAM , BOOL& bHandled)
3672 if(wParam == SPI_SETNONCLIENTMETRICS)
3673 GetSystemSettings();
3674 #else // CE specific 3676 GetSystemSettings();
3677 #endif // _WIN32_WCE 3682 void GetSystemSettings()
3684 if(!m_bCommCtrl6 && !m_bmSort[m_iSortUp].IsNull())
3686 T* pT =
static_cast<T*
>(
this);
3687 pT->CreateSortBitmaps();
3688 if(m_iSortColumn != -1)
3689 SetSortColumn(m_iSortColumn);
3696 typedef ATL::CWinTraits<WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | LVS_REPORT | LVS_SHOWSELALWAYS , WS_EX_CLIENTEDGE> CSortListViewCtrlTraits;
3698 template <
class T,
class TBase = CListViewCtrl,
class TWinTraits = CSortListViewCtrlTraits>
3702 DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
3704 bool SortItems(
int iCol,
bool bDescending =
false)
3706 return DoSortItems(iCol, bDescending);
3721 DECLARE_WND_SUPERCLASS(_T(
"WTL_SortListViewCtrl"), GetWndClassName())
3729 #define TBVN_PAGEACTIVATED (0U-741) 3730 #define TBVN_CONTEXTMENU (0U-742) 3742 template <
class T,
class TBase = ATL::CWindow,
class TWinTraits = ATL::CControlWinTraits>
3743 class ATL_NO_VTABLE
CTabViewImpl :
public ATL::CWindowImpl<T, TBase, TWinTraits>
3746 DECLARE_WND_CLASS_EX(NULL, 0, COLOR_APPWORKSPACE)
3758 TCITEMHEADER tciheader;
3761 operator LPTCITEM() {
return (LPTCITEM)
this; }
3769 m_nMenuItemsMax = (ID_WINDOW_TABLAST - ID_WINDOW_TABFIRST + 1)
3773 ATL::CContainedWindowT<CTabCtrl> m_tab;
3779 POINT m_ptStartDrag;
3783 int m_cchTabTextLength;
3785 int m_nMenuItemsCount;
3787 ATL::CWindow m_wndTitleBar;
3788 LPTSTR m_lpstrTitleBarBase;
3789 int m_cchTitleBarLength;
3793 bool m_bDestroyPageOnRemove:1;
3794 bool m_bDestroyImageList:1;
3795 bool m_bActivePageMenuItem:1;
3796 bool m_bActiveAsDefaultMenuItem:1;
3797 bool m_bEmptyMenuItem:1;
3798 bool m_bWindowsMenuItem:1;
3799 bool m_bNoTabDrag:1;
3801 bool m_bTabCapture:1;
3803 bool m_bInternalFont:1;
3811 m_cchTabTextLength(30),
3812 m_nMenuItemsCount(10),
3813 m_lpstrTitleBarBase(NULL),
3814 m_cchTitleBarLength(100),
3815 m_bDestroyPageOnRemove(
true),
3816 m_bDestroyImageList(
true),
3817 m_bActivePageMenuItem(
true),
3818 m_bActiveAsDefaultMenuItem(
false),
3819 m_bEmptyMenuItem(
false),
3820 m_bWindowsMenuItem(
false),
3821 m_bNoTabDrag(
false),
3822 m_bTabCapture(
false),
3824 m_bInternalFont(
false)
3826 m_ptStartDrag.x = 0;
3827 m_ptStartDrag.y = 0;
3832 delete [] m_lpstrTitleBarBase;
3836 BOOL PreTranslateMessage(MSG* pMsg)
3838 if(IsWindow() == FALSE)
3844 int nCount = GetPageCount();
3847 bool bControl = (::GetKeyState(VK_CONTROL) < 0);
3848 if((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_TAB) && bControl)
3852 int nPage = m_nActivePage;
3853 bool bShift = (::GetKeyState(VK_SHIFT) < 0);
3855 nPage = (nPage > 0) ? (nPage - 1) : (nCount - 1);
3857 nPage = ((nPage >= 0) && (nPage < (nCount - 1))) ? (nPage + 1) : 0;
3859 SetActivePage(nPage);
3860 T* pT =
static_cast<T*
>(
this);
3861 pT->OnPageActivated(m_nActivePage);
3871 if(m_bTabCapture && pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
3881 if(m_nActivePage != -1)
3882 bRet = (BOOL)::SendMessage(GetPageHWND(m_nActivePage), WM_FORWARDMSG, 0, (LPARAM)pMsg);
3889 int GetPageCount()
const 3891 ATLASSERT(::IsWindow(m_hWnd));
3892 return m_tab.GetItemCount();
3895 int GetActivePage()
const 3897 return m_nActivePage;
3900 void SetActivePage(
int nPage)
3902 ATLASSERT(::IsWindow(m_hWnd));
3903 ATLASSERT(IsValidPageIndex(nPage));
3905 T* pT =
static_cast<T*
>(
this);
3909 if(m_nActivePage != -1)
3910 ::ShowWindow(GetPageHWND(m_nActivePage), FALSE);
3911 m_nActivePage = nPage;
3912 m_tab.SetCurSel(m_nActivePage);
3913 ::ShowWindow(GetPageHWND(m_nActivePage), TRUE);
3918 RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
3920 if(::GetFocus() != m_tab.m_hWnd)
3921 ::SetFocus(GetPageHWND(m_nActivePage));
3923 pT->UpdateTitleBar();
3927 HIMAGELIST GetImageList()
const 3929 ATLASSERT(::IsWindow(m_hWnd));
3930 return m_tab.GetImageList();
3933 HIMAGELIST SetImageList(HIMAGELIST hImageList)
3935 ATLASSERT(::IsWindow(m_hWnd));
3936 return m_tab.SetImageList(hImageList);
3939 void SetWindowMenu(HMENU hMenu)
3941 ATLASSERT(::IsWindow(m_hWnd));
3945 T* pT =
static_cast<T*
>(
this);
3949 void SetTitleBarWindow(HWND hWnd)
3951 ATLASSERT(::IsWindow(m_hWnd));
3953 delete [] m_lpstrTitleBarBase;
3954 m_lpstrTitleBarBase = NULL;
3956 m_wndTitleBar = hWnd;
3960 int cchLen = m_wndTitleBar.GetWindowTextLength() + 1;
3961 ATLTRY(m_lpstrTitleBarBase =
new TCHAR[cchLen]);
3962 if(m_lpstrTitleBarBase != NULL)
3964 m_wndTitleBar.GetWindowText(m_lpstrTitleBarBase, cchLen);
3965 T* pT =
static_cast<T*
>(
this);
3966 pT->UpdateTitleBar();
3971 HWND GetPageHWND(
int nPage)
const 3973 ATLASSERT(::IsWindow(m_hWnd));
3974 ATLASSERT(IsValidPageIndex(nPage));
3977 tcix.tciheader.mask = TCIF_PARAM;
3978 m_tab.GetItem(nPage, tcix);
3980 return tcix.tvpage.hWnd;
3983 LPCTSTR GetPageTitle(
int nPage)
const 3985 ATLASSERT(::IsWindow(m_hWnd));
3986 ATLASSERT(IsValidPageIndex(nPage));
3989 tcix.tciheader.mask = TCIF_PARAM;
3990 if(m_tab.GetItem(nPage, tcix) == FALSE)
3993 return tcix.tvpage.lpstrTitle;
3996 bool SetPageTitle(
int nPage, LPCTSTR lpstrTitle)
3998 ATLASSERT(::IsWindow(m_hWnd));
3999 ATLASSERT(IsValidPageIndex(nPage));
4001 T* pT =
static_cast<T*
>(
this);
4003 int cchBuff = lstrlen(lpstrTitle) + 1;
4004 LPTSTR lpstrBuff = NULL;
4005 ATLTRY(lpstrBuff =
new TCHAR[cchBuff]);
4006 if(lpstrBuff == NULL)
4009 SecureHelper::strcpy_x(lpstrBuff, cchBuff, lpstrTitle);
4011 tcix.tciheader.mask = TCIF_PARAM;
4012 if(m_tab.GetItem(nPage, tcix) == FALSE)
4016 LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1);
4017 if(lpstrTabText == NULL)
4020 delete [] tcix.tvpage.lpstrTitle;
4022 pT->ShortenTitle(lpstrTitle, lpstrTabText, m_cchTabTextLength + 1);
4024 tcix.tciheader.mask = TCIF_TEXT | TCIF_PARAM;
4025 tcix.tciheader.pszText = lpstrTabText;
4026 tcix.tvpage.lpstrTitle = lpstrBuff;
4027 if(m_tab.SetItem(nPage, tcix) == FALSE)
4030 pT->UpdateTitleBar();
4036 LPVOID GetPageData(
int nPage)
const 4038 ATLASSERT(::IsWindow(m_hWnd));
4039 ATLASSERT(IsValidPageIndex(nPage));
4042 tcix.tciheader.mask = TCIF_PARAM;
4043 m_tab.GetItem(nPage, tcix);
4045 return tcix.tvpage.pData;
4048 LPVOID SetPageData(
int nPage, LPVOID pData)
4050 ATLASSERT(::IsWindow(m_hWnd));
4051 ATLASSERT(IsValidPageIndex(nPage));
4054 tcix.tciheader.mask = TCIF_PARAM;
4055 m_tab.GetItem(nPage, tcix);
4056 LPVOID pDataOld = tcix.tvpage.pData;
4058 tcix.tvpage.pData = pData;
4059 m_tab.SetItem(nPage, tcix);
4064 int GetPageImage(
int nPage)
const 4066 ATLASSERT(::IsWindow(m_hWnd));
4067 ATLASSERT(IsValidPageIndex(nPage));
4070 tcix.tciheader.mask = TCIF_IMAGE;
4071 m_tab.GetItem(nPage, tcix);
4073 return tcix.tciheader.iImage;
4076 int SetPageImage(
int nPage,
int nImage)
4078 ATLASSERT(::IsWindow(m_hWnd));
4079 ATLASSERT(IsValidPageIndex(nPage));
4082 tcix.tciheader.mask = TCIF_IMAGE;
4083 m_tab.GetItem(nPage, tcix);
4084 int nImageOld = tcix.tciheader.iImage;
4086 tcix.tciheader.iImage = nImage;
4087 m_tab.SetItem(nPage, tcix);
4093 bool AddPage(HWND hWndView, LPCTSTR lpstrTitle,
int nImage = -1, LPVOID pData = NULL)
4095 return InsertPage(GetPageCount(), hWndView, lpstrTitle, nImage, pData);
4098 bool InsertPage(
int nPage, HWND hWndView, LPCTSTR lpstrTitle,
int nImage = -1, LPVOID pData = NULL)
4100 ATLASSERT(::IsWindow(m_hWnd));
4101 ATLASSERT(nPage == GetPageCount() || IsValidPageIndex(nPage));
4103 T* pT =
static_cast<T*
>(
this);
4105 int cchBuff = lstrlen(lpstrTitle) + 1;
4106 LPTSTR lpstrBuff = NULL;
4107 ATLTRY(lpstrBuff =
new TCHAR[cchBuff]);
4108 if(lpstrBuff == NULL)
4111 SecureHelper::strcpy_x(lpstrBuff, cchBuff, lpstrTitle);
4114 LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1);
4115 if(lpstrTabText == NULL)
4118 pT->ShortenTitle(lpstrTitle, lpstrTabText, m_cchTabTextLength + 1);
4123 tcix.tciheader.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM;
4124 tcix.tciheader.pszText = lpstrTabText;
4125 tcix.tciheader.iImage = nImage;
4126 tcix.tvpage.hWnd = hWndView;
4127 tcix.tvpage.lpstrTitle = lpstrBuff;
4128 tcix.tvpage.pData = pData;
4129 int nItem = m_tab.InsertItem(nPage, tcix);
4132 delete [] lpstrBuff;
4137 SetActivePage(nItem);
4138 pT->OnPageActivated(m_nActivePage);
4140 if(GetPageCount() == 1)
4141 pT->ShowTabControl(
true);
4146 RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
4151 void RemovePage(
int nPage)
4153 ATLASSERT(::IsWindow(m_hWnd));
4154 ATLASSERT(IsValidPageIndex(nPage));
4156 T* pT =
static_cast<T*
>(
this);
4160 if(GetPageCount() == 1)
4161 pT->ShowTabControl(
false);
4163 if(m_bDestroyPageOnRemove)
4164 ::DestroyWindow(GetPageHWND(nPage));
4166 ::ShowWindow(GetPageHWND(nPage), FALSE);
4167 LPTSTR lpstrTitle = (LPTSTR)GetPageTitle(nPage);
4168 delete [] lpstrTitle;
4170 ATLVERIFY(m_tab.DeleteItem(nPage) != FALSE);
4172 if(m_nActivePage == nPage)
4178 SetActivePage(nPage - 1);
4180 else if(GetPageCount() > 0)
4182 SetActivePage(nPage);
4189 pT->UpdateTitleBar();
4195 nPage = (nPage < m_nActivePage) ? (m_nActivePage - 1) : m_nActivePage;
4197 SetActivePage(nPage);
4200 pT->OnPageActivated(m_nActivePage);
4203 void RemoveAllPages()
4205 ATLASSERT(::IsWindow(m_hWnd));
4207 if(GetPageCount() == 0)
4210 T* pT =
static_cast<T*
>(
this);
4214 pT->ShowTabControl(
false);
4216 for(
int i = 0; i < GetPageCount(); i++)
4218 if(m_bDestroyPageOnRemove)
4219 ::DestroyWindow(GetPageHWND(i));
4221 ::ShowWindow(GetPageHWND(i), FALSE);
4222 LPTSTR lpstrTitle = (LPTSTR)GetPageTitle(i);
4223 delete [] lpstrTitle;
4225 m_tab.DeleteAllItems();
4228 pT->OnPageActivated(m_nActivePage);
4234 pT->UpdateTitleBar();
4238 int PageIndexFromHwnd(HWND hWnd)
const 4242 for(
int i = 0; i < GetPageCount(); i++)
4244 if(GetPageHWND(i) == hWnd)
4254 void BuildWindowMenu(HMENU hMenu,
int nMenuItemsCount = 10,
bool bEmptyMenuItem =
true,
bool bWindowsMenuItem =
true,
bool bActivePageMenuItem =
true,
bool bActiveAsDefaultMenuItem =
false)
4256 ATLASSERT(::IsWindow(m_hWnd));
4259 T* pT =
static_cast<T*
>(
this);
4265 for(nFirstPos = 0; nFirstPos < menu.GetMenuItemCount(); nFirstPos++)
4267 UINT nID = menu.GetMenuItemID(nFirstPos);
4268 if((nID >= ID_WINDOW_TABFIRST && nID <= ID_WINDOW_TABLAST) || nID == ID_WINDOW_SHOWTABLIST)
4271 #else // CE specific 4272 for(nFirstPos = 0; ; nFirstPos++)
4275 mii.fMask = MIIM_ID;
4276 BOOL bRet = menu.GetMenuItemInfo(nFirstPos, TRUE, &mii);
4279 if((mii.wID >= ID_WINDOW_TABFIRST && mii.wID <= ID_WINDOW_TABLAST) || mii.wID == ID_WINDOW_SHOWTABLIST)
4282 #endif // _WIN32_WCE 4286 while(bRet != FALSE)
4287 bRet = menu.DeleteMenu(nFirstPos, MF_BYPOSITION);
4290 int nPageCount = GetPageCount();
4291 if((bWindowsMenuItem || (nPageCount > 0)) && (nFirstPos > 0))
4294 mii.fMask = MIIM_TYPE;
4295 menu.GetMenuItemInfo(nFirstPos - 1, TRUE, &mii);
4296 if((nFirstPos <= 0) || ((mii.fType & MFT_SEPARATOR) == 0))
4298 menu.AppendMenu(MF_SEPARATOR);
4307 const int cchPrefix = 3;
4308 nMenuItemsCount = min(min(nPageCount, nMenuItemsCount), (
int)m_nMenuItemsMax);
4309 ATLASSERT(nMenuItemsCount < 100);
4310 if(nMenuItemsCount >= 100)
4311 nMenuItemsCount = 99;
4313 for(
int i = 0; i < nMenuItemsCount; i++)
4315 LPCTSTR lpstrTitle = GetPageTitle(i);
4316 int nLen = lstrlen(lpstrTitle);
4318 LPTSTR lpstrText = buff.Allocate(cchPrefix + nLen + 1);
4319 ATLASSERT(lpstrText != NULL);
4320 if(lpstrText != NULL)
4322 LPCTSTR lpstrFormat = (i < 9) ? _T(
"&%i %s") : _T(
"%i %s");
4323 SecureHelper::wsprintf_x(lpstrText, cchPrefix + nLen + 1, lpstrFormat, i + 1, lpstrTitle);
4324 menu.AppendMenu(MF_STRING, ID_WINDOW_TABFIRST + i, lpstrText);
4329 if(bActivePageMenuItem && (m_nActivePage != -1))
4332 if(bActiveAsDefaultMenuItem)
4334 menu.SetMenuDefaultItem((UINT)-1, TRUE);
4335 menu.SetMenuDefaultItem(nFirstPos + m_nActivePage, TRUE);
4338 #else // CE specific 4339 bActiveAsDefaultMenuItem;
4340 #endif // _WIN32_WCE 4342 menu.CheckMenuRadioItem(nFirstPos, nFirstPos + nMenuItemsCount, nFirstPos + m_nActivePage, MF_BYPOSITION);
4350 menu.AppendMenu(MF_BYPOSITION | MF_STRING, ID_WINDOW_TABFIRST, pT->GetEmptyListText());
4351 menu.EnableMenuItem(ID_WINDOW_TABFIRST, MF_GRAYED);
4355 if(!bEmptyMenuItem && !bWindowsMenuItem && (nFirstPos > 0))
4358 mii.fMask = MIIM_TYPE;
4359 menu.GetMenuItemInfo(nFirstPos - 1, TRUE, &mii);
4360 if((mii.fType & MFT_SEPARATOR) != 0)
4361 menu.DeleteMenu(nFirstPos - 1, MF_BYPOSITION);
4366 if(bWindowsMenuItem)
4367 menu.AppendMenu(MF_BYPOSITION | MF_STRING, ID_WINDOW_SHOWTABLIST, pT->GetWindowsMenuItemText());
4372 MESSAGE_HANDLER(WM_CREATE, OnCreate)
4373 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
4374 MESSAGE_HANDLER(WM_SIZE, OnSize)
4375 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
4376 MESSAGE_HANDLER(WM_GETFONT, OnGetFont)
4377 MESSAGE_HANDLER(WM_SETFONT, OnSetFont)
4378 NOTIFY_HANDLER(m_nTabID, TCN_SELCHANGE, OnTabChanged)
4379 NOTIFY_ID_HANDLER(m_nTabID, OnTabNotification)
4381 NOTIFY_CODE_HANDLER(TTN_GETDISPINFO, OnTabGetDispInfo)
4382 #endif // !_WIN32_WCE 4383 FORWARD_NOTIFICATIONS()
4385 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnTabLButtonDown)
4386 MESSAGE_HANDLER(WM_LBUTTONUP, OnTabLButtonUp)
4387 MESSAGE_HANDLER(WM_CAPTURECHANGED, OnTabCaptureChanged)
4388 MESSAGE_HANDLER(WM_MOUSEMOVE, OnTabMouseMove)
4389 MESSAGE_HANDLER(WM_RBUTTONUP, OnTabRButtonUp)
4390 MESSAGE_HANDLER(WM_SYSKEYDOWN, OnTabSysKeyDown)
4393 LRESULT OnCreate(UINT , WPARAM , LPARAM , BOOL& )
4395 T* pT =
static_cast<T*
>(
this);
4396 pT->CreateTabControl();
4401 LRESULT OnDestroy(UINT , WPARAM , LPARAM , BOOL& )
4405 if(m_bDestroyImageList)
4408 if(il.m_hImageList != NULL)
4414 HFONT hFont = m_tab.GetFont();
4415 m_tab.SetFont(NULL, FALSE);
4416 ::DeleteObject(hFont);
4417 m_bInternalFont =
false;
4423 LRESULT OnSize(UINT , WPARAM , LPARAM , BOOL& )
4425 T* pT =
static_cast<T*
>(
this);
4430 LRESULT OnSetFocus(UINT , WPARAM , LPARAM , BOOL& )
4432 if(m_nActivePage != -1)
4433 ::SetFocus(GetPageHWND(m_nActivePage));
4437 LRESULT OnGetFont(UINT , WPARAM , LPARAM , BOOL& )
4439 return m_tab.SendMessage(WM_GETFONT);
4442 LRESULT OnSetFont(UINT , WPARAM wParam, LPARAM lParam, BOOL& )
4446 HFONT hFont = m_tab.GetFont();
4447 m_tab.SetFont(NULL, FALSE);
4448 ::DeleteObject(hFont);
4449 m_bInternalFont =
false;
4452 m_tab.SendMessage(WM_SETFONT, wParam, lParam);
4454 T* pT =
static_cast<T*
>(
this);
4455 m_cyTabHeight = pT->CalcTabHeight();
4457 if((BOOL)lParam != FALSE)
4463 LRESULT OnTabChanged(
int , LPNMHDR , BOOL& )
4465 SetActivePage(m_tab.GetCurSel());
4466 T* pT =
static_cast<T*
>(
this);
4467 pT->OnPageActivated(m_nActivePage);
4472 LRESULT OnTabNotification(
int , LPNMHDR , BOOL& )
4480 LRESULT OnTabGetDispInfo(
int , LPNMHDR pnmh, BOOL& bHandled)
4482 LPNMTTDISPINFO pTTDI = (LPNMTTDISPINFO)pnmh;
4483 if(pTTDI->hdr.hwndFrom == m_tab.GetTooltips())
4485 T* pT =
static_cast<T*
>(
this);
4486 pT->UpdateTooltipText(pTTDI);
4495 #endif // !_WIN32_WCE 4498 LRESULT OnTabLButtonDown(UINT , WPARAM , LPARAM lParam, BOOL& bHandled)
4500 if(!m_bNoTabDrag && (m_tab.GetItemCount() > 1))
4502 m_bTabCapture =
true;
4505 m_ptStartDrag.x = GET_X_LPARAM(lParam);
4506 m_ptStartDrag.y = GET_Y_LPARAM(lParam);
4513 LRESULT OnTabLButtonUp(UINT , WPARAM , LPARAM lParam, BOOL& bHandled)
4519 TCHITTESTINFO hti = { 0 };
4520 hti.pt.x = GET_X_LPARAM(lParam);
4521 hti.pt.y = GET_Y_LPARAM(lParam);
4522 int nItem = m_tab.HitTest(&hti);
4524 MovePage(m_nActivePage, nItem);
4534 LRESULT OnTabCaptureChanged(UINT , WPARAM , LPARAM , BOOL& bHandled)
4538 m_bTabCapture =
false;
4543 T* pT =
static_cast<T*
>(
this);
4544 pT->DrawMoveMark(-1);
4547 m_ilDrag.DragLeave(GetDesktopWindow());
4548 #endif // !_WIN32_WCE 4552 m_ilDrag.m_hImageList = NULL;
4560 LRESULT OnTabMouseMove(UINT , WPARAM , LPARAM lParam, BOOL& bHandled)
4566 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
4571 if(abs(m_ptStartDrag.x - GET_X_LPARAM(lParam)) >= ::GetSystemMetrics(SM_CXDRAG) ||
4572 abs(m_ptStartDrag.y - GET_Y_LPARAM(lParam)) >= ::GetSystemMetrics(SM_CYDRAG))
4573 #else // CE specific 4574 if(abs(m_ptStartDrag.x - GET_X_LPARAM(lParam)) >= 4 ||
4575 abs(m_ptStartDrag.y - GET_Y_LPARAM(lParam)) >= 4)
4576 #endif // _WIN32_WCE 4578 T* pT =
static_cast<T*
>(
this);
4579 pT->GenerateDragImage(m_nActivePage);
4581 int cxCursor = ::GetSystemMetrics(SM_CXCURSOR);
4582 int cyCursor = ::GetSystemMetrics(SM_CYCURSOR);
4583 m_ilDrag.BeginDrag(0, -(cxCursor / 2), -(cyCursor / 2));
4585 POINT ptEnter = m_ptStartDrag;
4586 m_tab.ClientToScreen(&ptEnter);
4587 m_ilDrag.DragEnter(GetDesktopWindow(), ptEnter);
4588 #endif // !_WIN32_WCE 4596 TCHITTESTINFO hti = { 0 };
4598 int nItem = m_tab.HitTest(&hti);
4600 T* pT =
static_cast<T*
>(
this);
4601 pT->SetMoveCursor(nItem != -1);
4603 if(m_nInsertItem != nItem)
4604 pT->DrawMoveMark(nItem);
4606 m_ilDrag.DragShowNolock((nItem != -1) ? TRUE : FALSE);
4607 m_tab.ClientToScreen(&pt);
4608 m_ilDrag.DragMove(pt);
4617 LRESULT OnTabRButtonUp(UINT , WPARAM , LPARAM lParam, BOOL& )
4619 TCHITTESTINFO hti = { 0 };
4620 hti.pt.x = GET_X_LPARAM(lParam);
4621 hti.pt.y = GET_Y_LPARAM(lParam);
4622 int nItem = m_tab.HitTest(&hti);
4625 T* pT =
static_cast<T*
>(
this);
4626 pT->OnContextMenu(nItem, hti.pt);
4632 LRESULT OnTabSysKeyDown(UINT , WPARAM wParam, LPARAM , BOOL& bHandled)
4634 bool bShift = (::GetKeyState(VK_SHIFT) < 0);
4635 if(wParam == VK_F10 && bShift)
4637 if(m_nActivePage != -1)
4640 m_tab.GetItemRect(m_nActivePage, &rect);
4641 POINT pt = { rect.left, rect.bottom };
4642 T* pT =
static_cast<T*
>(
this);
4643 pT->OnContextMenu(m_nActivePage, pt);
4655 bool IsValidPageIndex(
int nPage)
const 4657 return (nPage >= 0 && nPage < GetPageCount());
4660 bool MovePage(
int nMovePage,
int nInsertBeforePage)
4662 ATLASSERT(IsValidPageIndex(nMovePage));
4663 ATLASSERT(IsValidPageIndex(nInsertBeforePage));
4665 if(!IsValidPageIndex(nMovePage) || !IsValidPageIndex(nInsertBeforePage))
4668 if(nMovePage == nInsertBeforePage)
4672 LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1);
4673 if(lpstrTabText == NULL)
4676 tcix.tciheader.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM;
4677 tcix.tciheader.pszText = lpstrTabText;
4678 tcix.tciheader.cchTextMax = m_cchTabTextLength + 1;
4679 BOOL bRet = m_tab.GetItem(nMovePage, tcix);
4680 ATLASSERT(bRet != FALSE);
4684 int nInsertItem = (nInsertBeforePage > nMovePage) ? nInsertBeforePage + 1 : nInsertBeforePage;
4685 int nNewItem = m_tab.InsertItem(nInsertItem, tcix);
4686 ATLASSERT(nNewItem == nInsertItem);
4687 if(nNewItem != nInsertItem)
4689 ATLVERIFY(m_tab.DeleteItem(nNewItem));
4693 if(nMovePage > nInsertBeforePage)
4694 ATLVERIFY(m_tab.DeleteItem(nMovePage + 1) != FALSE);
4695 else if(nMovePage < nInsertBeforePage)
4696 ATLVERIFY(m_tab.DeleteItem(nMovePage) != FALSE);
4698 SetActivePage(nInsertBeforePage);
4699 T* pT =
static_cast<T*
>(
this);
4700 pT->OnPageActivated(m_nActivePage);
4706 bool CreateTabControl()
4709 m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_TOOLTIPS, 0, m_nTabID);
4710 #else // CE specific 4711 m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, m_nTabID);
4712 #endif // _WIN32_WCE 4713 ATLASSERT(m_tab.m_hWnd != NULL);
4714 if(m_tab.m_hWnd == NULL)
4717 m_tab.SetFont(AtlCreateControlFont());
4718 m_bInternalFont =
true;
4722 T* pT =
static_cast<T*
>(
this);
4723 m_cyTabHeight = pT->CalcTabHeight();
4730 int nCount = m_tab.GetItemCount();
4732 tcix.tciheader.mask = TCIF_TEXT;
4733 tcix.tciheader.pszText = _T(
"NS");
4734 int nIndex = m_tab.InsertItem(nCount, tcix);
4736 RECT rect = { 0, 0, 1000, 1000 };
4737 m_tab.AdjustRect(FALSE, &rect);
4739 RECT rcWnd = { 0, 0, 1000, rect.top };
4740 ::AdjustWindowRectEx(&rcWnd, m_tab.GetStyle(), FALSE, m_tab.GetExStyle());
4742 int nHeight = rcWnd.bottom - rcWnd.top;
4744 m_tab.DeleteItem(nIndex);
4749 void ShowTabControl(
bool bShow)
4751 m_tab.ShowWindow(bShow ? SW_SHOWNOACTIVATE : SW_HIDE);
4757 GetClientRect(&rect);
4759 if(m_tab.IsWindow() && ((m_tab.GetStyle() & WS_VISIBLE) != 0))
4760 m_tab.SetWindowPos(NULL, 0, 0, rect.right - rect.left, m_cyTabHeight, SWP_NOZORDER);
4762 if(m_nActivePage != -1)
4763 ::SetWindowPos(GetPageHWND(m_nActivePage), NULL, 0, m_cyTabHeight, rect.right - rect.left, rect.bottom - rect.top - m_cyTabHeight, SWP_NOZORDER);
4768 if(m_menu.m_hMenu != NULL)
4769 BuildWindowMenu(m_menu, m_nMenuItemsCount, m_bEmptyMenuItem, m_bWindowsMenuItem, m_bActivePageMenuItem, m_bActiveAsDefaultMenuItem);
4772 void UpdateTitleBar()
4774 if(!m_wndTitleBar.IsWindow() || m_lpstrTitleBarBase == NULL)
4777 if(m_nActivePage != -1)
4779 T* pT =
static_cast<T*
>(
this);
4780 LPCTSTR lpstrTitle = pT->GetPageTitle(m_nActivePage);
4781 LPCTSTR lpstrDivider = pT->GetTitleDividerText();
4782 int cchBuffer = m_cchTitleBarLength + lstrlen(lpstrDivider) + lstrlen(m_lpstrTitleBarBase) + 1;
4784 LPTSTR lpstrPageTitle = buff.Allocate(cchBuffer);
4785 ATLASSERT(lpstrPageTitle != NULL);
4786 if(lpstrPageTitle != NULL)
4788 pT->ShortenTitle(lpstrTitle, lpstrPageTitle, m_cchTitleBarLength + 1);
4789 SecureHelper::strcat_x(lpstrPageTitle, cchBuffer, lpstrDivider);
4790 SecureHelper::strcat_x(lpstrPageTitle, cchBuffer, m_lpstrTitleBarBase);
4794 lpstrPageTitle = m_lpstrTitleBarBase;
4797 m_wndTitleBar.SetWindowText(lpstrPageTitle);
4801 m_wndTitleBar.SetWindowText(m_lpstrTitleBarBase);
4805 void DrawMoveMark(
int nItem)
4807 T* pT =
static_cast<T*
>(
this);
4809 if(m_nInsertItem != -1)
4812 pT->GetMoveMarkRect(rect);
4813 m_tab.InvalidateRect(&rect);
4816 m_nInsertItem = nItem;
4818 if(m_nInsertItem != -1)
4823 pT->GetMoveMarkRect(rect);
4826 pen.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_WINDOWTEXT));
4828 brush.CreateSolidBrush(::GetSysColor(COLOR_WINDOWTEXT));
4830 HPEN hPenOld = dc.SelectPen(pen);
4831 HBRUSH hBrushOld = dc.SelectBrush(brush);
4835 POINT ptsTop[3] = { { x, y }, { x + m_cxMoveMark, y }, { x + (m_cxMoveMark / 2), y + m_cyMoveMark } };
4836 dc.Polygon(ptsTop, 3);
4838 y = rect.bottom - 1;
4839 POINT ptsBottom[3] = { { x, y }, { x + m_cxMoveMark, y }, { x + (m_cxMoveMark / 2), y - m_cyMoveMark } };
4840 dc.Polygon(ptsBottom, 3);
4842 dc.SelectPen(hPenOld);
4843 dc.SelectBrush(hBrushOld);
4847 void GetMoveMarkRect(RECT& rect)
const 4849 m_tab.GetClientRect(&rect);
4851 RECT rcItem = { 0 };
4852 m_tab.GetItemRect(m_nInsertItem, &rcItem);
4854 if(m_nInsertItem <= m_nActivePage)
4856 rect.left = rcItem.left - m_cxMoveMark / 2 - 1;
4857 rect.right = rcItem.left + m_cxMoveMark / 2;
4861 rect.left = rcItem.right - m_cxMoveMark / 2 - 1;
4862 rect.right = rcItem.right + m_cxMoveMark / 2;
4866 void SetMoveCursor(
bool bCanMove)
4868 ::SetCursor(::LoadCursor(NULL, bCanMove ? IDC_ARROW : IDC_NO));
4871 void GenerateDragImage(
int nItem)
4873 ATLASSERT(IsValidPageIndex(nItem));
4876 RECT rcItem = { 0 };
4877 m_tab.GetItemRect(nItem, &rcItem);
4878 ::InflateRect(&rcItem, 2, 2);
4879 #else // CE specific 4881 RECT rcItem = { 0, 0, 40, 20 };
4882 #endif // _WIN32_WCE 4884 ATLASSERT(m_ilDrag.m_hImageList == NULL);
4885 m_ilDrag.Create(rcItem.right - rcItem.left, rcItem.bottom - rcItem.top, ILC_COLORDDB | ILC_MASK, 1, 1);
4889 dcMem.CreateCompatibleDC(dc);
4890 ATLASSERT(dcMem.m_hDC != NULL);
4891 dcMem.SetViewportOrg(-rcItem.left, -rcItem.top);
4894 bmp.CreateCompatibleBitmap(dc, rcItem.right - rcItem.left, rcItem.bottom - rcItem.top);
4895 ATLASSERT(bmp.m_hBitmap != NULL);
4897 HBITMAP hBmpOld = dcMem.SelectBitmap(bmp);
4899 m_tab.SendMessage(WM_PRINTCLIENT, (WPARAM)dcMem.m_hDC);
4900 #else // CE specific 4901 dcMem.Rectangle(&rcItem);
4902 #endif // _WIN32_WCE 4903 dcMem.SelectBitmap(hBmpOld);
4905 ATLVERIFY(m_ilDrag.Add(bmp.m_hBitmap, RGB(255, 0, 255)) != -1);
4908 void ShortenTitle(LPCTSTR lpstrTitle, LPTSTR lpstrShortTitle,
int cchShortTitle)
4910 if(lstrlen(lpstrTitle) >= cchShortTitle)
4912 LPCTSTR lpstrEllipsis = _T(
"...");
4913 int cchEllipsis = lstrlen(lpstrEllipsis);
4914 SecureHelper::strncpy_x(lpstrShortTitle, cchShortTitle, lpstrTitle, cchShortTitle - cchEllipsis - 1);
4915 SecureHelper::strcat_x(lpstrShortTitle, cchShortTitle, lpstrEllipsis);
4919 SecureHelper::strcpy_x(lpstrShortTitle, cchShortTitle, lpstrTitle);
4924 void UpdateTooltipText(LPNMTTDISPINFO pTTDI)
4926 ATLASSERT(pTTDI != NULL);
4927 pTTDI->lpszText = (LPTSTR)GetPageTitle((
int)pTTDI->hdr.idFrom);
4929 #endif // !_WIN32_WCE 4932 static LPCTSTR GetEmptyListText()
4934 return _T(
"(Empty)");
4937 static LPCTSTR GetWindowsMenuItemText()
4939 return _T(
"&Windows...");
4942 static LPCTSTR GetTitleDividerText()
4948 void OnPageActivated(
int nPage)
4950 NMHDR nmhdr = { 0 };
4951 nmhdr.hwndFrom = m_hWnd;
4952 nmhdr.idFrom = nPage;
4953 nmhdr.code = TBVN_PAGEACTIVATED;
4954 ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmhdr);
4957 void OnContextMenu(
int nPage, POINT pt)
4959 m_tab.ClientToScreen(&pt);
4962 cmi.hdr.hwndFrom = m_hWnd;
4963 cmi.hdr.idFrom = nPage;
4964 cmi.hdr.code = TBVN_CONTEXTMENU;
4966 ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&cmi);
4973 DECLARE_WND_CLASS_EX(_T(
"WTL_TabView"), 0, COLOR_APPWORKSPACE)
4978 #endif // __ATLCTRLX_H__
Definition: atlwinx.h:455
Definition: atlctrlx.h:3699
Definition: atlctrlx.h:2239
Definition: atlapp.h:1730
Definition: atlctrlx.h:2922
Definition: atlctrlx.h:1906
Definition: atlgdi.h:3388
Definition: atlctrlx.h:608
Definition: atlctrlx.h:1829
Definition: atlctrlx.h:2892
Definition: atlctrls.h:9714
Definition: atlctrls.h:1850
Definition: atlctrlx.h:3743
Definition: atlctrlx.h:2850
Definition: atlctrlx.h:586
Definition: atlctrlx.h:1877
Definition: atlapp.h:1317
Definition: atlctrlx.h:3718
Definition: atlgdi.h:1211
Definition: atlctrlx.h:1819
Definition: atlctrlx.h:2867
Definition: atlctrlx.h:711
Definition: atlctrlx.h:2908
Definition: atlgdi.h:3364
Definition: atlctrlx.h:771
Definition: atlctrlx.h:3749
Definition: atlctrlx.h:2222
Definition: atlctrlx.h:4970