PageRenderTime 133ms CodeModel.GetById 21ms app.highlight 90ms RepoModel.GetById 1ms app.codeStats 3ms

/thirdparty/wtl/atlctrls.h

http://crashrpt.googlecode.com/
C++ Header | 10033 lines | 8164 code | 1548 blank | 321 comment | 431 complexity | 568a835c698d37e8daf2a4b28c1f5c17 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1// Windows Template Library - WTL version 8.1
   2// Copyright (C) Microsoft Corporation. All rights reserved.
   3//
   4// This file is a part of the Windows Template Library.
   5// The use and distribution terms for this software are covered by the
   6// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
   7// which can be found in the file CPL.TXT at the root of this distribution.
   8// By using this software in any fashion, you are agreeing to be bound by
   9// the terms of this license. You must not remove this notice, or
  10// any other, from this software.
  11
  12#ifndef __ATLCTRLS_H__
  13#define __ATLCTRLS_H__
  14
  15#pragma once
  16
  17#ifndef __ATLAPP_H__
  18	#error atlctrls.h requires atlapp.h to be included first
  19#endif
  20
  21#ifndef __ATLWIN_H__
  22	#error atlctrls.h requires atlwin.h to be included first
  23#endif
  24
  25#ifndef _WIN32_WCE
  26  #include <richedit.h>
  27  #include <richole.h>
  28#elif defined(WIN32_PLATFORM_WFSP) && !defined(_WINUSERM_H_)
  29  #include <winuserm.h>
  30#endif // !_WIN32_WCE
  31
  32// protect template members from windowsx.h macros
  33#ifdef _INC_WINDOWSX
  34  #undef GetNextSibling
  35  #undef GetPrevSibling
  36#endif // _INC_WINDOWSX
  37
  38
  39///////////////////////////////////////////////////////////////////////////////
  40// Classes in this file:
  41//
  42// CStaticT<TBase> - CStatic
  43// CButtonT<TBase> - CButton
  44// CListBoxT<TBase> - CListBox
  45// CComboBoxT<TBase> - CComboBox
  46// CEditT<TBase> - CEdit
  47// CEditCommands<T>
  48// CScrollBarT<TBase> - CScrollBar
  49//
  50// CImageList
  51// CListViewCtrlT<TBase> - CListViewCtrl
  52// CTreeViewCtrlT<TBase> - CTreeViewCtrl
  53// CTreeItemT<TBase> - CTreeItem
  54// CTreeViewCtrlExT<TBase> - CTreeViewCtrlEx
  55// CHeaderCtrlT<TBase> - CHeaderCtrl
  56// CToolBarCtrlT<TBase> - CToolBarCtrl
  57// CStatusBarCtrlT<TBase> - CStatusBarCtrl
  58// CTabCtrlT<TBase> - CTabCtrl
  59// CToolInfo
  60// CToolTipCtrlT<TBase> - CToolTipCtrl
  61// CTrackBarCtrlT<TBase> - CTrackBarCtrl
  62// CUpDownCtrlT<TBase> - CUpDownCtrl
  63// CProgressBarCtrlT<TBase> - CProgressBarCtrl
  64// CHotKeyCtrlT<TBase> - CHotKeyCtrl
  65// CAnimateCtrlT<TBase> - CAnimateCtrl
  66// CRichEditCtrlT<TBase> - CRichEditCtrl
  67// CRichEditCommands<T>
  68// CDragListBoxT<TBase> - CDragListBox
  69// CDragListNotifyImpl<T>
  70// CReBarCtrlT<TBase> - CReBarCtrl
  71// CComboBoxExT<TBase> - CComboBoxEx
  72// CDateTimePickerCtrlT<TBase> - CDateTimePickerCtrl
  73// CMonthCalendarCtrlT<TBase> - CMonthCalendarCtrl
  74// CFlatScrollBarImpl<T>
  75// CFlatScrollBarT<TBase> - CFlatScrollBar
  76// CIPAddressCtrlT<TBase> - CIPAddressCtrl
  77// CPagerCtrlT<TBase> - CPagerCtrl
  78// CLinkCtrlT<TBase> - CLinkCtrl
  79//
  80// CCustomDraw<T>
  81//
  82// CCECommandBarCtrlT<TBase> - CCECommandBarCtrl
  83// CCECommandBandsCtrlT<TBase> - CCECommandBandsCtrl
  84
  85
  86namespace WTL
  87{
  88
  89// These are wrapper classes for Windows standard and common controls.
  90// To implement a window based on a control, use following:
  91// Example: Implementing a window based on a list box
  92//
  93// class CMyListBox : CWindowImpl<CMyListBox, CListBox>
  94// {
  95// public:
  96//      BEGIN_MSG_MAP(CMyListBox)
  97//          // put your message handler entries here
  98//      END_MSG_MAP()
  99// };
 100
 101
 102
 103// --- Standard Windows controls ---
 104
 105///////////////////////////////////////////////////////////////////////////////
 106// CStatic - client side for a Windows STATIC control
 107
 108template <class TBase>
 109class CStaticT : public TBase
 110{
 111public:
 112// Constructors
 113	CStaticT(HWND hWnd = NULL) : TBase(hWnd)
 114	{ }
 115
 116	CStaticT< TBase >& operator =(HWND hWnd)
 117	{
 118		m_hWnd = hWnd;
 119		return *this;
 120	}
 121
 122	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
 123			DWORD dwStyle = 0, DWORD dwExStyle = 0,
 124			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
 125	{
 126		return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
 127	}
 128
 129// Attributes
 130	static LPCTSTR GetWndClassName()
 131	{
 132		return _T("STATIC");
 133	}
 134
 135#ifndef _WIN32_WCE
 136	HICON GetIcon() const
 137	{
 138		ATLASSERT(::IsWindow(m_hWnd));
 139		return (HICON)::SendMessage(m_hWnd, STM_GETICON, 0, 0L);
 140	}
 141
 142	HICON SetIcon(HICON hIcon)
 143	{
 144		ATLASSERT(::IsWindow(m_hWnd));
 145		return (HICON)::SendMessage(m_hWnd, STM_SETICON, (WPARAM)hIcon, 0L);
 146	}
 147
 148	HENHMETAFILE GetEnhMetaFile() const
 149	{
 150		ATLASSERT(::IsWindow(m_hWnd));
 151		return (HENHMETAFILE)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_ENHMETAFILE, 0L);
 152	}
 153
 154	HENHMETAFILE SetEnhMetaFile(HENHMETAFILE hMetaFile)
 155	{
 156		ATLASSERT(::IsWindow(m_hWnd));
 157		return (HENHMETAFILE)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_ENHMETAFILE, (LPARAM)hMetaFile);
 158	}
 159#else // CE specific
 160	HICON GetIcon() const
 161	{
 162		ATLASSERT(::IsWindow(m_hWnd));
 163		return (HICON)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_ICON, 0L);
 164	}
 165
 166	HICON SetIcon(HICON hIcon)
 167	{
 168		ATLASSERT(::IsWindow(m_hWnd));
 169		return (HICON)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
 170	}
 171#endif // _WIN32_WCE
 172
 173	CBitmapHandle GetBitmap() const
 174	{
 175		ATLASSERT(::IsWindow(m_hWnd));
 176		return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_BITMAP, 0L));
 177	}
 178
 179	CBitmapHandle SetBitmap(HBITMAP hBitmap)
 180	{
 181		ATLASSERT(::IsWindow(m_hWnd));
 182		return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap));
 183	}
 184
 185	HCURSOR GetCursor() const
 186	{
 187		ATLASSERT(::IsWindow(m_hWnd));
 188		return (HCURSOR)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_CURSOR, 0L);
 189	}
 190
 191	HCURSOR SetCursor(HCURSOR hCursor)
 192	{
 193		ATLASSERT(::IsWindow(m_hWnd));
 194		return (HCURSOR)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_CURSOR, (LPARAM)hCursor);
 195	}
 196};
 197
 198typedef CStaticT<ATL::CWindow>   CStatic;
 199
 200
 201///////////////////////////////////////////////////////////////////////////////
 202// CButton - client side for a Windows BUTTON control
 203
 204template <class TBase>
 205class CButtonT : public TBase
 206{
 207public:
 208// Constructors
 209	CButtonT(HWND hWnd = NULL) : TBase(hWnd)
 210	{ }
 211
 212	CButtonT< TBase >& operator =(HWND hWnd)
 213	{
 214		m_hWnd = hWnd;
 215		return *this;
 216	}
 217
 218	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
 219			DWORD dwStyle = 0, DWORD dwExStyle = 0,
 220			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
 221	{
 222		return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
 223	}
 224
 225// Attributes
 226	static LPCTSTR GetWndClassName()
 227	{
 228		return _T("BUTTON");
 229	}
 230
 231	UINT GetState() const
 232	{
 233		ATLASSERT(::IsWindow(m_hWnd));
 234		return (UINT)::SendMessage(m_hWnd, BM_GETSTATE, 0, 0L);
 235	}
 236
 237	void SetState(BOOL bHighlight)
 238	{
 239		ATLASSERT(::IsWindow(m_hWnd));
 240		::SendMessage(m_hWnd, BM_SETSTATE, bHighlight, 0L);
 241	}
 242
 243	int GetCheck() const
 244	{
 245		ATLASSERT(::IsWindow(m_hWnd));
 246		return (int)::SendMessage(m_hWnd, BM_GETCHECK, 0, 0L);
 247	}
 248
 249	void SetCheck(int nCheck)
 250	{
 251		ATLASSERT(::IsWindow(m_hWnd));
 252		::SendMessage(m_hWnd, BM_SETCHECK, nCheck, 0L);
 253	}
 254
 255	UINT GetButtonStyle() const
 256	{
 257		ATLASSERT(::IsWindow(m_hWnd));
 258		return (UINT)::GetWindowLong(m_hWnd, GWL_STYLE) & 0xFFFF;
 259	}
 260
 261	void SetButtonStyle(UINT nStyle, BOOL bRedraw = TRUE)
 262	{
 263		ATLASSERT(::IsWindow(m_hWnd));
 264		::SendMessage(m_hWnd, BM_SETSTYLE, nStyle, (LPARAM)bRedraw);
 265	}
 266
 267#ifndef _WIN32_WCE
 268	HICON GetIcon() const
 269	{
 270		ATLASSERT(::IsWindow(m_hWnd));
 271		return (HICON)::SendMessage(m_hWnd, BM_GETIMAGE, IMAGE_ICON, 0L);
 272	}
 273
 274	HICON SetIcon(HICON hIcon)
 275	{
 276		ATLASSERT(::IsWindow(m_hWnd));
 277		return (HICON)::SendMessage(m_hWnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
 278	}
 279
 280	CBitmapHandle GetBitmap() const
 281	{
 282		ATLASSERT(::IsWindow(m_hWnd));
 283		return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, BM_GETIMAGE, IMAGE_BITMAP, 0L));
 284	}
 285
 286	CBitmapHandle SetBitmap(HBITMAP hBitmap)
 287	{
 288		ATLASSERT(::IsWindow(m_hWnd));
 289		return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap));
 290	}
 291#endif // !_WIN32_WCE
 292
 293#if (_WIN32_WINNT >= 0x0501)
 294	BOOL GetIdealSize(LPSIZE lpSize) const
 295	{
 296		ATLASSERT(::IsWindow(m_hWnd));
 297		return (BOOL)::SendMessage(m_hWnd, BCM_GETIDEALSIZE, 0, (LPARAM)lpSize);
 298	}
 299
 300	BOOL GetImageList(PBUTTON_IMAGELIST pButtonImagelist) const
 301	{
 302		ATLASSERT(::IsWindow(m_hWnd));
 303		return (BOOL)::SendMessage(m_hWnd, BCM_GETIMAGELIST, 0, (LPARAM)pButtonImagelist);
 304	}
 305
 306	BOOL SetImageList(PBUTTON_IMAGELIST pButtonImagelist)
 307	{
 308		ATLASSERT(::IsWindow(m_hWnd));
 309		return (BOOL)::SendMessage(m_hWnd, BCM_SETIMAGELIST, 0, (LPARAM)pButtonImagelist);
 310	}
 311
 312	BOOL GetTextMargin(LPRECT lpRect) const
 313	{
 314		ATLASSERT(::IsWindow(m_hWnd));
 315		return (BOOL)::SendMessage(m_hWnd, BCM_GETTEXTMARGIN, 0, (LPARAM)lpRect);
 316	}
 317
 318	BOOL SetTextMargin(LPRECT lpRect)
 319	{
 320		ATLASSERT(::IsWindow(m_hWnd));
 321		return (BOOL)::SendMessage(m_hWnd, BCM_SETTEXTMARGIN, 0, (LPARAM)lpRect);
 322	}
 323#endif // (_WIN32_WINNT >= 0x0501)
 324
 325#if (WINVER >= 0x0600)
 326	void SetDontClick(BOOL bDontClick)
 327	{
 328		ATLASSERT(::IsWindow(m_hWnd));
 329		::SendMessage(m_hWnd, BM_SETDONTCLICK, (WPARAM)bDontClick, 0L);
 330	}
 331#endif // (WINVER >= 0x0600)
 332
 333#if (_WIN32_WINNT >= 0x0600)
 334	BOOL SetDropDownState(BOOL bDropDown)
 335	{
 336		ATLASSERT(::IsWindow(m_hWnd));
 337		ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0);
 338		return (BOOL)::SendMessage(m_hWnd, BCM_SETDROPDOWNSTATE, (WPARAM)bDropDown, 0L);
 339	}
 340
 341	BOOL GetSplitInfo(PBUTTON_SPLITINFO pSplitInfo) const
 342	{
 343		ATLASSERT(::IsWindow(m_hWnd));
 344		ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0);
 345		return (BOOL)::SendMessage(m_hWnd, BCM_GETSPLITINFO, 0, (LPARAM)pSplitInfo);
 346	}
 347
 348	BOOL SetSplitInfo(PBUTTON_SPLITINFO pSplitInfo)
 349	{
 350		ATLASSERT(::IsWindow(m_hWnd));
 351		ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0);
 352		return (BOOL)::SendMessage(m_hWnd, BCM_SETSPLITINFO, 0, (LPARAM)pSplitInfo);
 353	}
 354
 355	int GetNoteLength() const
 356	{
 357		ATLASSERT(::IsWindow(m_hWnd));
 358		ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0);
 359		return (int)::SendMessage(m_hWnd, BCM_GETNOTELENGTH, 0, 0L);
 360	}
 361
 362	BOOL GetNote(LPWSTR lpstrNoteText, int cchNoteText) const
 363	{
 364		ATLASSERT(::IsWindow(m_hWnd));
 365		ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0);
 366		return (BOOL)::SendMessage(m_hWnd, BCM_GETNOTE, cchNoteText, (LPARAM)lpstrNoteText);
 367	}
 368
 369	BOOL SetNote(LPCWSTR lpstrNoteText)
 370	{
 371		ATLASSERT(::IsWindow(m_hWnd));
 372		ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0);
 373		return (BOOL)::SendMessage(m_hWnd, BCM_SETNOTE, 0, (LPARAM)lpstrNoteText);
 374	}
 375
 376	LRESULT SetElevationRequiredState(BOOL bSet)
 377	{
 378		ATLASSERT(::IsWindow(m_hWnd));
 379		return ::SendMessage(m_hWnd, BCM_SETSHIELD, 0, (LPARAM)bSet);
 380	}
 381#endif // (_WIN32_WINNT >= 0x0600)
 382
 383// Operations
 384	void Click()
 385	{
 386		ATLASSERT(::IsWindow(m_hWnd));
 387		::SendMessage(m_hWnd, BM_CLICK, 0, 0L);
 388	}
 389};
 390
 391typedef CButtonT<ATL::CWindow>   CButton;
 392
 393
 394///////////////////////////////////////////////////////////////////////////////
 395// CListBox - client side for a Windows LISTBOX control
 396
 397template <class TBase>
 398class CListBoxT : public TBase
 399{
 400public:
 401// Constructors
 402	CListBoxT(HWND hWnd = NULL) : TBase(hWnd)
 403	{ }
 404
 405	CListBoxT< TBase >& operator =(HWND hWnd)
 406	{
 407		m_hWnd = hWnd;
 408		return *this;
 409	}
 410
 411	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
 412			DWORD dwStyle = 0, DWORD dwExStyle = 0,
 413			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
 414	{
 415		return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
 416	}
 417
 418// Attributes
 419	static LPCTSTR GetWndClassName()
 420	{
 421		return _T("LISTBOX");
 422	}
 423
 424	// for entire listbox
 425	int GetCount() const
 426	{
 427		ATLASSERT(::IsWindow(m_hWnd));
 428		return (int)::SendMessage(m_hWnd, LB_GETCOUNT, 0, 0L);
 429	}
 430
 431#ifndef _WIN32_WCE
 432	int SetCount(int cItems)
 433	{
 434		ATLASSERT(::IsWindow(m_hWnd));
 435		ATLASSERT(((GetStyle() & LBS_NODATA) != 0) && ((GetStyle() & LBS_HASSTRINGS) == 0));
 436		return (int)::SendMessage(m_hWnd, LB_SETCOUNT, cItems, 0L);
 437	}
 438#endif // !_WIN32_WCE
 439
 440	int GetHorizontalExtent() const
 441	{
 442		ATLASSERT(::IsWindow(m_hWnd));
 443		return (int)::SendMessage(m_hWnd, LB_GETHORIZONTALEXTENT, 0, 0L);
 444	}
 445
 446	void SetHorizontalExtent(int cxExtent)
 447	{
 448		ATLASSERT(::IsWindow(m_hWnd));
 449		::SendMessage(m_hWnd, LB_SETHORIZONTALEXTENT, cxExtent, 0L);
 450	}
 451
 452	int GetTopIndex() const
 453	{
 454		ATLASSERT(::IsWindow(m_hWnd));
 455		return (int)::SendMessage(m_hWnd, LB_GETTOPINDEX, 0, 0L);
 456	}
 457
 458	int SetTopIndex(int nIndex)
 459	{
 460		ATLASSERT(::IsWindow(m_hWnd));
 461		return (int)::SendMessage(m_hWnd, LB_SETTOPINDEX, nIndex, 0L);
 462	}
 463
 464	LCID GetLocale() const
 465	{
 466		ATLASSERT(::IsWindow(m_hWnd));
 467		return (LCID)::SendMessage(m_hWnd, LB_GETLOCALE, 0, 0L);
 468	}
 469
 470	LCID SetLocale(LCID nNewLocale)
 471	{
 472		ATLASSERT(::IsWindow(m_hWnd));
 473		return (LCID)::SendMessage(m_hWnd, LB_SETLOCALE, (WPARAM)nNewLocale, 0L);
 474	}
 475
 476#if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
 477	DWORD GetListBoxInfo() const
 478	{
 479		ATLASSERT(::IsWindow(m_hWnd));
 480#if (_WIN32_WINNT >= 0x0501)
 481		return (DWORD)::SendMessage(m_hWnd, LB_GETLISTBOXINFO, 0, 0L);
 482#else // !(_WIN32_WINNT >= 0x0501)
 483		return ::GetListBoxInfo(m_hWnd);
 484#endif // !(_WIN32_WINNT >= 0x0501)
 485	}
 486#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
 487
 488	// for single-selection listboxes
 489	int GetCurSel() const
 490	{
 491		ATLASSERT(::IsWindow(m_hWnd));
 492		ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0);
 493		return (int)::SendMessage(m_hWnd, LB_GETCURSEL, 0, 0L);
 494	}
 495
 496	int SetCurSel(int nSelect)
 497	{
 498		ATLASSERT(::IsWindow(m_hWnd));
 499		ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0);
 500		return (int)::SendMessage(m_hWnd, LB_SETCURSEL, nSelect, 0L);
 501	}
 502
 503	// for multiple-selection listboxes
 504	int GetSel(int nIndex) const           // also works for single-selection
 505	{
 506		ATLASSERT(::IsWindow(m_hWnd));
 507		return (int)::SendMessage(m_hWnd, LB_GETSEL, nIndex, 0L);
 508	}
 509
 510	int SetSel(int nIndex, BOOL bSelect = TRUE)
 511	{
 512		ATLASSERT(::IsWindow(m_hWnd));
 513		ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0);
 514		return (int)::SendMessage(m_hWnd, LB_SETSEL, bSelect, nIndex);
 515	}
 516
 517	int GetSelCount() const
 518	{
 519		ATLASSERT(::IsWindow(m_hWnd));
 520		ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0);
 521		return (int)::SendMessage(m_hWnd, LB_GETSELCOUNT, 0, 0L);
 522	}
 523
 524	int GetSelItems(int nMaxItems, LPINT rgIndex) const
 525	{
 526		ATLASSERT(::IsWindow(m_hWnd));
 527		ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0);
 528		return (int)::SendMessage(m_hWnd, LB_GETSELITEMS, nMaxItems, (LPARAM)rgIndex);
 529	}
 530
 531	int GetAnchorIndex() const
 532	{
 533		ATLASSERT(::IsWindow(m_hWnd));
 534		ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0);
 535		return (int)::SendMessage(m_hWnd, LB_GETANCHORINDEX, 0, 0L);
 536	}
 537
 538	void SetAnchorIndex(int nIndex)
 539	{
 540		ATLASSERT(::IsWindow(m_hWnd));
 541		ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0);
 542		::SendMessage(m_hWnd, LB_SETANCHORINDEX, nIndex, 0L);
 543	}
 544
 545	int GetCaretIndex() const
 546	{
 547		ATLASSERT(::IsWindow(m_hWnd));
 548		return (int)::SendMessage(m_hWnd, LB_GETCARETINDEX, 0, 0);
 549	}
 550
 551	int SetCaretIndex(int nIndex, BOOL bScroll = TRUE)
 552	{
 553		ATLASSERT(::IsWindow(m_hWnd));
 554		return (int)::SendMessage(m_hWnd, LB_SETCARETINDEX, nIndex, MAKELONG(bScroll, 0));
 555	}
 556
 557	// for listbox items
 558	DWORD_PTR GetItemData(int nIndex) const
 559	{
 560		ATLASSERT(::IsWindow(m_hWnd));
 561		return (DWORD_PTR)::SendMessage(m_hWnd, LB_GETITEMDATA, nIndex, 0L);
 562	}
 563
 564	int SetItemData(int nIndex, DWORD_PTR dwItemData)
 565	{
 566		ATLASSERT(::IsWindow(m_hWnd));
 567		return (int)::SendMessage(m_hWnd, LB_SETITEMDATA, nIndex, (LPARAM)dwItemData);
 568	}
 569
 570	void* GetItemDataPtr(int nIndex) const
 571	{
 572		ATLASSERT(::IsWindow(m_hWnd));
 573		return (void*)::SendMessage(m_hWnd, LB_GETITEMDATA, nIndex, 0L);
 574	}
 575
 576	int SetItemDataPtr(int nIndex, void* pData)
 577	{
 578		ATLASSERT(::IsWindow(m_hWnd));
 579		return SetItemData(nIndex, (DWORD_PTR)pData);
 580	}
 581
 582	int GetItemRect(int nIndex, LPRECT lpRect) const
 583	{
 584		ATLASSERT(::IsWindow(m_hWnd));
 585		return (int)::SendMessage(m_hWnd, LB_GETITEMRECT, nIndex, (LPARAM)lpRect);
 586	}
 587
 588	int GetText(int nIndex, LPTSTR lpszBuffer) const
 589	{
 590		ATLASSERT(::IsWindow(m_hWnd));
 591		return (int)::SendMessage(m_hWnd, LB_GETTEXT, nIndex, (LPARAM)lpszBuffer);
 592	}
 593
 594#ifndef _ATL_NO_COM
 595#ifdef _OLEAUTO_H_
 596	BOOL GetTextBSTR(int nIndex, BSTR& bstrText) const
 597	{
 598		USES_CONVERSION;
 599		ATLASSERT(::IsWindow(m_hWnd));
 600		ATLASSERT(bstrText == NULL);
 601
 602		int nLen = GetTextLen(nIndex);
 603		if(nLen == LB_ERR)
 604			return FALSE;
 605
 606		CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
 607		LPTSTR lpstrText = buff.Allocate(nLen + 1);
 608		if(lpstrText == NULL)
 609			return FALSE;
 610
 611		if(GetText(nIndex, lpstrText) == LB_ERR)
 612			return FALSE;
 613
 614		bstrText = ::SysAllocString(T2OLE(lpstrText));
 615		return (bstrText != NULL) ? TRUE : FALSE;
 616	}
 617#endif // _OLEAUTO_H_
 618#endif // !_ATL_NO_COM
 619
 620#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
 621	int GetText(int nIndex, _CSTRING_NS::CString& strText) const
 622	{
 623		ATLASSERT(::IsWindow(m_hWnd));
 624		int cchLen = GetTextLen(nIndex);
 625		if(cchLen == LB_ERR)
 626			return LB_ERR;
 627		int nRet = LB_ERR;
 628		LPTSTR lpstr = strText.GetBufferSetLength(cchLen);
 629		if(lpstr != NULL)
 630		{
 631			nRet = GetText(nIndex, lpstr);
 632			strText.ReleaseBuffer();
 633		}
 634		return nRet;
 635	}
 636#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
 637
 638	int GetTextLen(int nIndex) const
 639	{
 640		ATLASSERT(::IsWindow(m_hWnd));
 641		return (int)::SendMessage(m_hWnd, LB_GETTEXTLEN, nIndex, 0L);
 642	}
 643
 644	int GetItemHeight(int nIndex) const
 645	{
 646		ATLASSERT(::IsWindow(m_hWnd));
 647		return (int)::SendMessage(m_hWnd, LB_GETITEMHEIGHT, nIndex, 0L);
 648	}
 649
 650	int SetItemHeight(int nIndex, UINT cyItemHeight)
 651	{
 652		ATLASSERT(::IsWindow(m_hWnd));
 653		return (int)::SendMessage(m_hWnd, LB_SETITEMHEIGHT, nIndex, MAKELONG(cyItemHeight, 0));
 654	}
 655
 656	// Settable only attributes
 657	void SetColumnWidth(int cxWidth)
 658	{
 659		ATLASSERT(::IsWindow(m_hWnd));
 660		::SendMessage(m_hWnd, LB_SETCOLUMNWIDTH, cxWidth, 0L);
 661	}
 662
 663	BOOL SetTabStops(int nTabStops, LPINT rgTabStops)
 664	{
 665		ATLASSERT(::IsWindow(m_hWnd));
 666		ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0);
 667		return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops);
 668	}
 669
 670	BOOL SetTabStops()
 671	{
 672		ATLASSERT(::IsWindow(m_hWnd));
 673		ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0);
 674		return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, 0, 0L);
 675	}
 676
 677	BOOL SetTabStops(const int& cxEachStop)    // takes an 'int'
 678	{
 679		ATLASSERT(::IsWindow(m_hWnd));
 680		ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0);
 681		return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop);
 682	}
 683
 684// Operations
 685	int InitStorage(int nItems, UINT nBytes)
 686	{
 687		ATLASSERT(::IsWindow(m_hWnd));
 688		return (int)::SendMessage(m_hWnd, LB_INITSTORAGE, (WPARAM)nItems, nBytes);
 689	}
 690
 691	void ResetContent()
 692	{
 693		ATLASSERT(::IsWindow(m_hWnd));
 694		::SendMessage(m_hWnd, LB_RESETCONTENT, 0, 0L);
 695	}
 696
 697	UINT ItemFromPoint(POINT pt, BOOL& bOutside) const
 698	{
 699		ATLASSERT(::IsWindow(m_hWnd));
 700		DWORD dw = (DWORD)::SendMessage(m_hWnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(pt.x, pt.y));
 701		bOutside = (BOOL)HIWORD(dw);
 702		return (UINT)LOWORD(dw);
 703	}
 704
 705	// manipulating listbox items
 706	int AddString(LPCTSTR lpszItem)
 707	{
 708		ATLASSERT(::IsWindow(m_hWnd));
 709		return (int)::SendMessage(m_hWnd, LB_ADDSTRING, 0, (LPARAM)lpszItem);
 710	}
 711
 712	int DeleteString(UINT nIndex)
 713	{
 714		ATLASSERT(::IsWindow(m_hWnd));
 715		return (int)::SendMessage(m_hWnd, LB_DELETESTRING, nIndex, 0L);
 716	}
 717
 718	int InsertString(int nIndex, LPCTSTR lpszItem)
 719	{
 720		ATLASSERT(::IsWindow(m_hWnd));
 721		return (int)::SendMessage(m_hWnd, LB_INSERTSTRING, nIndex, (LPARAM)lpszItem);
 722	}
 723
 724#ifndef _WIN32_WCE
 725	int Dir(UINT attr, LPCTSTR lpszWildCard)
 726	{
 727		ATLASSERT(::IsWindow(m_hWnd));
 728		return (int)::SendMessage(m_hWnd, LB_DIR, attr, (LPARAM)lpszWildCard);
 729	}
 730
 731	int AddFile(LPCTSTR lpstrFileName)
 732	{
 733		ATLASSERT(::IsWindow(m_hWnd));
 734		return (int)::SendMessage(m_hWnd, LB_ADDFILE, 0, (LPARAM)lpstrFileName);
 735	}
 736#endif // !_WIN32_WCE
 737
 738	// selection helpers
 739	int FindString(int nStartAfter, LPCTSTR lpszItem) const
 740	{
 741		ATLASSERT(::IsWindow(m_hWnd));
 742		return (int)::SendMessage(m_hWnd, LB_FINDSTRING, nStartAfter, (LPARAM)lpszItem);
 743	}
 744
 745	int FindStringExact(int nIndexStart, LPCTSTR lpszFind) const
 746	{
 747		ATLASSERT(::IsWindow(m_hWnd));
 748		return (int)::SendMessage(m_hWnd, LB_FINDSTRINGEXACT, nIndexStart, (LPARAM)lpszFind);
 749	}
 750
 751	int SelectString(int nStartAfter, LPCTSTR lpszItem)
 752	{
 753		ATLASSERT(::IsWindow(m_hWnd));
 754		return (int)::SendMessage(m_hWnd, LB_SELECTSTRING, nStartAfter, (LPARAM)lpszItem);
 755	}
 756
 757	int SelItemRange(BOOL bSelect, int nFirstItem, int nLastItem)
 758	{
 759		ATLASSERT(::IsWindow(m_hWnd));
 760		ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0);
 761		ATLASSERT(nFirstItem <= nLastItem);
 762		return bSelect ? (int)::SendMessage(m_hWnd, LB_SELITEMRANGEEX, nFirstItem, nLastItem) : (int)::SendMessage(m_hWnd, LB_SELITEMRANGEEX, nLastItem, nFirstItem);
 763	}
 764
 765#ifdef WIN32_PLATFORM_WFSP   // SmartPhone only messages
 766	DWORD GetInputMode(BOOL bCurrentMode = TRUE)
 767	{
 768		return SendMessage(LB_GETINPUTMODE, 0, (LPARAM)bCurrentMode);
 769	}
 770
 771	BOOL SetInputMode(DWORD dwMode)
 772	{
 773		return SendMessage(LB_SETINPUTMODE, 0, (LPARAM)dwMode);
 774	}
 775#endif // WIN32_PLATFORM_WFSP
 776};
 777
 778typedef CListBoxT<ATL::CWindow>   CListBox;
 779
 780
 781///////////////////////////////////////////////////////////////////////////////
 782// CComboBox - client side for a Windows COMBOBOX control
 783
 784#ifndef WIN32_PLATFORM_WFSP   // No COMBOBOX on SmartPhones
 785
 786template <class TBase>
 787class CComboBoxT : public TBase
 788{
 789public:
 790// Constructors
 791	CComboBoxT(HWND hWnd = NULL) : TBase(hWnd)
 792	{ }
 793
 794	CComboBoxT< TBase >& operator =(HWND hWnd)
 795	{
 796		m_hWnd = hWnd;
 797		return *this;
 798	}
 799
 800	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
 801			DWORD dwStyle = 0, DWORD dwExStyle = 0,
 802			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
 803	{
 804		return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
 805	}
 806
 807// Attributes
 808	static LPCTSTR GetWndClassName()
 809	{
 810		return _T("COMBOBOX");
 811	}
 812
 813	// for entire combo box
 814	int GetCount() const
 815	{
 816		ATLASSERT(::IsWindow(m_hWnd));
 817		return (int)::SendMessage(m_hWnd, CB_GETCOUNT, 0, 0L);
 818	}
 819
 820	int GetCurSel() const
 821	{
 822		ATLASSERT(::IsWindow(m_hWnd));
 823		return (int)::SendMessage(m_hWnd, CB_GETCURSEL, 0, 0L);
 824	}
 825
 826	int SetCurSel(int nSelect)
 827	{
 828		ATLASSERT(::IsWindow(m_hWnd));
 829		return (int)::SendMessage(m_hWnd, CB_SETCURSEL, nSelect, 0L);
 830	}
 831
 832	LCID GetLocale() const
 833	{
 834		ATLASSERT(::IsWindow(m_hWnd));
 835		return (LCID)::SendMessage(m_hWnd, CB_GETLOCALE, 0, 0L);
 836	}
 837
 838	LCID SetLocale(LCID nNewLocale)
 839	{
 840		ATLASSERT(::IsWindow(m_hWnd));
 841		return (LCID)::SendMessage(m_hWnd, CB_SETLOCALE, (WPARAM)nNewLocale, 0L);
 842	}
 843
 844	int GetTopIndex() const
 845	{
 846		ATLASSERT(::IsWindow(m_hWnd));
 847		return (int)::SendMessage(m_hWnd, CB_GETTOPINDEX, 0, 0L);
 848	}
 849
 850	int SetTopIndex(int nIndex)
 851	{
 852		ATLASSERT(::IsWindow(m_hWnd));
 853		return (int)::SendMessage(m_hWnd, CB_SETTOPINDEX, nIndex, 0L);
 854	}
 855
 856	UINT GetHorizontalExtent() const
 857	{
 858		ATLASSERT(::IsWindow(m_hWnd));
 859		return (UINT)::SendMessage(m_hWnd, CB_GETHORIZONTALEXTENT, 0, 0L);
 860	}
 861
 862	void SetHorizontalExtent(UINT nExtent)
 863	{
 864		ATLASSERT(::IsWindow(m_hWnd));
 865		::SendMessage(m_hWnd, CB_SETHORIZONTALEXTENT, nExtent, 0L);
 866	}
 867
 868	int GetDroppedWidth() const
 869	{
 870		ATLASSERT(::IsWindow(m_hWnd));
 871		return (int)::SendMessage(m_hWnd, CB_GETDROPPEDWIDTH, 0, 0L);
 872	}
 873
 874	int SetDroppedWidth(UINT nWidth)
 875	{
 876		ATLASSERT(::IsWindow(m_hWnd));
 877		return (int)::SendMessage(m_hWnd, CB_SETDROPPEDWIDTH, nWidth, 0L);
 878	}
 879
 880#if ((WINVER >= 0x0500) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420))
 881	BOOL GetComboBoxInfo(PCOMBOBOXINFO pComboBoxInfo) const
 882	{
 883		ATLASSERT(::IsWindow(m_hWnd));
 884#if ((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420))
 885		return (BOOL)::SendMessage(m_hWnd, CB_GETCOMBOBOXINFO, 0, (LPARAM)pComboBoxInfo);
 886#else // !((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420))
 887		return ::GetComboBoxInfo(m_hWnd, pComboBoxInfo);
 888#endif // !((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420))
 889	}
 890#endif // ((WINVER >= 0x0500) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420))
 891
 892	// for edit control
 893	DWORD GetEditSel() const
 894	{
 895		ATLASSERT(::IsWindow(m_hWnd));
 896		return (DWORD)::SendMessage(m_hWnd, CB_GETEDITSEL, 0, 0L);
 897	}
 898
 899	BOOL SetEditSel(int nStartChar, int nEndChar)
 900	{
 901		ATLASSERT(::IsWindow(m_hWnd));
 902		return (BOOL)::SendMessage(m_hWnd, CB_SETEDITSEL, 0, MAKELONG(nStartChar, nEndChar));
 903	}
 904
 905	// for combobox item
 906	DWORD_PTR GetItemData(int nIndex) const
 907	{
 908		ATLASSERT(::IsWindow(m_hWnd));
 909		return (DWORD_PTR)::SendMessage(m_hWnd, CB_GETITEMDATA, nIndex, 0L);
 910	}
 911
 912	int SetItemData(int nIndex, DWORD_PTR dwItemData)
 913	{
 914		ATLASSERT(::IsWindow(m_hWnd));
 915		return (int)::SendMessage(m_hWnd, CB_SETITEMDATA, nIndex, (LPARAM)dwItemData);
 916	}
 917
 918	void* GetItemDataPtr(int nIndex) const
 919	{
 920		ATLASSERT(::IsWindow(m_hWnd));
 921		return (void*)GetItemData(nIndex);
 922	}
 923
 924	int SetItemDataPtr(int nIndex, void* pData)
 925	{
 926		ATLASSERT(::IsWindow(m_hWnd));
 927		return SetItemData(nIndex, (DWORD_PTR)pData);
 928	}
 929
 930	int GetLBText(int nIndex, LPTSTR lpszText) const
 931	{
 932		ATLASSERT(::IsWindow(m_hWnd));
 933		return (int)::SendMessage(m_hWnd, CB_GETLBTEXT, nIndex, (LPARAM)lpszText);
 934	}
 935
 936#ifndef _ATL_NO_COM
 937	BOOL GetLBTextBSTR(int nIndex, BSTR& bstrText) const
 938	{
 939		USES_CONVERSION;
 940		ATLASSERT(::IsWindow(m_hWnd));
 941		ATLASSERT(bstrText == NULL);
 942
 943		int nLen = GetLBTextLen(nIndex);
 944		if(nLen == CB_ERR)
 945			return FALSE;
 946
 947		CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
 948		LPTSTR lpstrText = buff.Allocate(nLen + 1);
 949		if(lpstrText == NULL)
 950			return FALSE;
 951
 952		if(GetLBText(nIndex, lpstrText) == CB_ERR)
 953			return FALSE;
 954
 955		bstrText = ::SysAllocString(T2OLE(lpstrText));
 956		return (bstrText != NULL) ? TRUE : FALSE;
 957	}
 958#endif // !_ATL_NO_COM
 959
 960#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
 961	int GetLBText(int nIndex, _CSTRING_NS::CString& strText) const
 962	{
 963		ATLASSERT(::IsWindow(m_hWnd));
 964		int cchLen = GetLBTextLen(nIndex);
 965		if(cchLen == CB_ERR)
 966			return CB_ERR;
 967		int nRet = CB_ERR;
 968		LPTSTR lpstr = strText.GetBufferSetLength(cchLen);
 969		if(lpstr != NULL)
 970		{
 971			nRet = GetLBText(nIndex, lpstr);
 972			strText.ReleaseBuffer();
 973		}
 974		return nRet;
 975	}
 976#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
 977
 978	int GetLBTextLen(int nIndex) const
 979	{
 980		ATLASSERT(::IsWindow(m_hWnd));
 981		return (int)::SendMessage(m_hWnd, CB_GETLBTEXTLEN, nIndex, 0L);
 982	}
 983
 984	int GetItemHeight(int nIndex) const
 985	{
 986		ATLASSERT(::IsWindow(m_hWnd));
 987		return (int)::SendMessage(m_hWnd, CB_GETITEMHEIGHT, nIndex, 0L);
 988	}
 989
 990	int SetItemHeight(int nIndex, UINT cyItemHeight)
 991	{
 992		ATLASSERT(::IsWindow(m_hWnd));
 993		return (int)::SendMessage(m_hWnd, CB_SETITEMHEIGHT, nIndex, MAKELONG(cyItemHeight, 0));
 994	}
 995
 996	BOOL GetExtendedUI() const
 997	{
 998		ATLASSERT(::IsWindow(m_hWnd));
 999		return (BOOL)::SendMessage(m_hWnd, CB_GETEXTENDEDUI, 0, 0L);
1000	}
1001
1002	int SetExtendedUI(BOOL bExtended = TRUE)
1003	{
1004		ATLASSERT(::IsWindow(m_hWnd));
1005		return (int)::SendMessage(m_hWnd, CB_SETEXTENDEDUI, bExtended, 0L);
1006	}
1007
1008	void GetDroppedControlRect(LPRECT lprect) const
1009	{
1010		ATLASSERT(::IsWindow(m_hWnd));
1011		::SendMessage(m_hWnd, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)lprect);
1012	}
1013
1014	BOOL GetDroppedState() const
1015	{
1016		ATLASSERT(::IsWindow(m_hWnd));
1017		return (BOOL)::SendMessage(m_hWnd, CB_GETDROPPEDSTATE, 0, 0L);
1018	}
1019
1020#if (_WIN32_WINNT >= 0x0501)
1021	int GetMinVisible() const
1022	{
1023		ATLASSERT(::IsWindow(m_hWnd));
1024		return (int)::SendMessage(m_hWnd, CB_GETMINVISIBLE, 0, 0L);
1025	}
1026
1027	BOOL SetMinVisible(int nMinVisible)
1028	{
1029		ATLASSERT(::IsWindow(m_hWnd));
1030		return (BOOL)::SendMessage(m_hWnd, CB_SETMINVISIBLE, nMinVisible, 0L);
1031	}
1032
1033	// Vista only
1034	BOOL GetCueBannerText(LPWSTR lpwText, int cchText) const
1035	{
1036#ifndef CB_GETCUEBANNER
1037		const UINT CB_GETCUEBANNER = (CBM_FIRST + 4);
1038#endif
1039		ATLASSERT(::IsWindow(m_hWnd));
1040		return (BOOL)::SendMessage(m_hWnd, CB_GETCUEBANNER, (WPARAM)lpwText, cchText);
1041	}
1042
1043	// Vista only
1044	BOOL SetCueBannerText(LPCWSTR lpcwText)
1045	{
1046#ifndef CB_SETCUEBANNER
1047		const UINT CB_SETCUEBANNER = (CBM_FIRST + 3);
1048#endif
1049		ATLASSERT(::IsWindow(m_hWnd));
1050		return (BOOL)::SendMessage(m_hWnd, CB_SETCUEBANNER, 0, (LPARAM)lpcwText);
1051	}
1052#endif // (_WIN32_WINNT >= 0x0501)
1053
1054// Operations
1055	int InitStorage(int nItems, UINT nBytes)
1056	{
1057		ATLASSERT(::IsWindow(m_hWnd));
1058		return (int)::SendMessage(m_hWnd, CB_INITSTORAGE, (WPARAM)nItems, nBytes);
1059	}
1060
1061	void ResetContent()
1062	{
1063		ATLASSERT(::IsWindow(m_hWnd));
1064		::SendMessage(m_hWnd, CB_RESETCONTENT, 0, 0L);
1065	}
1066
1067	// for edit control
1068	BOOL LimitText(int nMaxChars)
1069	{
1070		ATLASSERT(::IsWindow(m_hWnd));
1071		return (BOOL)::SendMessage(m_hWnd, CB_LIMITTEXT, nMaxChars, 0L);
1072	}
1073
1074	// for drop-down combo boxes
1075	void ShowDropDown(BOOL bShowIt = TRUE)
1076	{
1077		ATLASSERT(::IsWindow(m_hWnd));
1078		::SendMessage(m_hWnd, CB_SHOWDROPDOWN, bShowIt, 0L);
1079	}
1080
1081	// manipulating listbox items
1082	int AddString(LPCTSTR lpszString)
1083	{
1084		ATLASSERT(::IsWindow(m_hWnd));
1085		return (int)::SendMessage(m_hWnd, CB_ADDSTRING, 0, (LPARAM)lpszString);
1086	}
1087
1088	int DeleteString(UINT nIndex)
1089	{
1090		ATLASSERT(::IsWindow(m_hWnd));
1091		return (int)::SendMessage(m_hWnd, CB_DELETESTRING, nIndex, 0L);
1092	}
1093
1094	int InsertString(int nIndex, LPCTSTR lpszString)
1095	{
1096		ATLASSERT(::IsWindow(m_hWnd));
1097		return (int)::SendMessage(m_hWnd, CB_INSERTSTRING, nIndex, (LPARAM)lpszString);
1098	}
1099
1100#ifndef _WIN32_WCE
1101	int Dir(UINT attr, LPCTSTR lpszWildCard)
1102	{
1103		ATLASSERT(::IsWindow(m_hWnd));
1104		return (int)::SendMessage(m_hWnd, CB_DIR, attr, (LPARAM)lpszWildCard);
1105	}
1106#endif // !_WIN32_WCE
1107
1108	// selection helpers
1109	int FindString(int nStartAfter, LPCTSTR lpszString) const
1110	{
1111		ATLASSERT(::IsWindow(m_hWnd));
1112		return (int)::SendMessage(m_hWnd, CB_FINDSTRING, nStartAfter, (LPARAM)lpszString);
1113	}
1114
1115	int FindStringExact(int nIndexStart, LPCTSTR lpszFind) const
1116	{
1117		ATLASSERT(::IsWindow(m_hWnd));
1118		return (int)::SendMessage(m_hWnd, CB_FINDSTRINGEXACT, nIndexStart, (LPARAM)lpszFind);
1119	}
1120
1121	int SelectString(int nStartAfter, LPCTSTR lpszString)
1122	{
1123		ATLASSERT(::IsWindow(m_hWnd));
1124		return (int)::SendMessage(m_hWnd, CB_SELECTSTRING, nStartAfter, (LPARAM)lpszString);
1125	}
1126
1127	// Clipboard operations
1128	void Clear()
1129	{
1130		ATLASSERT(::IsWindow(m_hWnd));
1131		::SendMessage(m_hWnd, WM_CLEAR, 0, 0L);
1132	}
1133
1134	void Copy()
1135	{
1136		ATLASSERT(::IsWindow(m_hWnd));
1137		::SendMessage(m_hWnd, WM_COPY, 0, 0L);
1138	}
1139
1140	void Cut()
1141	{
1142		ATLASSERT(::IsWindow(m_hWnd));
1143		::SendMessage(m_hWnd, WM_CUT, 0, 0L);
1144	}
1145
1146	void Paste()
1147	{
1148		ATLASSERT(::IsWindow(m_hWnd));
1149		::SendMessage(m_hWnd, WM_PASTE, 0, 0L);
1150	}
1151};
1152
1153typedef CComboBoxT<ATL::CWindow>   CComboBox;
1154
1155#endif // !WIN32_PLATFORM_WFSP
1156
1157///////////////////////////////////////////////////////////////////////////////
1158// CEdit - client side for a Windows EDIT control
1159
1160template <class TBase>
1161class CEditT : public TBase
1162{
1163public:
1164// Constructors
1165	CEditT(HWND hWnd = NULL) : TBase(hWnd)
1166	{ }
1167
1168	CEditT< TBase >& operator =(HWND hWnd)
1169	{
1170		m_hWnd = hWnd;
1171		return *this;
1172	}
1173
1174	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
1175			DWORD dwStyle = 0, DWORD dwExStyle = 0,
1176			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
1177	{
1178		return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
1179	}
1180
1181// Attributes
1182	static LPCTSTR GetWndClassName()
1183	{
1184		return _T("EDIT");
1185	}
1186
1187	BOOL CanUndo() const
1188	{
1189		ATLASSERT(::IsWindow(m_hWnd));
1190		return (BOOL)::SendMessage(m_hWnd, EM_CANUNDO, 0, 0L);
1191	}
1192
1193	int GetLineCount() const
1194	{
1195		ATLASSERT(::IsWindow(m_hWnd));
1196		return (int)::SendMessage(m_hWnd, EM_GETLINECOUNT, 0, 0L);
1197	}
1198
1199	BOOL GetModify() const
1200	{
1201		ATLASSERT(::IsWindow(m_hWnd));
1202		return (BOOL)::SendMessage(m_hWnd, EM_GETMODIFY, 0, 0L);
1203	}
1204
1205	void SetModify(BOOL bModified = TRUE)
1206	{
1207		ATLASSERT(::IsWindow(m_hWnd));
1208		::SendMessage(m_hWnd, EM_SETMODIFY, bModified, 0L);
1209	}
1210
1211	void GetRect(LPRECT lpRect) const
1212	{
1213		ATLASSERT(::IsWindow(m_hWnd));
1214		::SendMessage(m_hWnd, EM_GETRECT, 0, (LPARAM)lpRect);
1215	}
1216
1217	DWORD GetSel() const
1218	{
1219		ATLASSERT(::IsWindow(m_hWnd));
1220		return (DWORD)::SendMessage(m_hWnd, EM_GETSEL, 0, 0L);
1221	}
1222
1223	void GetSel(int& nStartChar, int& nEndChar) const
1224	{
1225		ATLASSERT(::IsWindow(m_hWnd));
1226		::SendMessage(m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar);
1227	}
1228
1229#ifndef _WIN32_WCE
1230	HLOCAL GetHandle() const
1231	{
1232		ATLASSERT(::IsWindow(m_hWnd));
1233		return (HLOCAL)::SendMessage(m_hWnd, EM_GETHANDLE, 0, 0L);
1234	}
1235
1236	void SetHandle(HLOCAL hBuffer)
1237	{
1238		ATLASSERT(::IsWindow(m_hWnd));
1239		::SendMessage(m_hWnd, EM_SETHANDLE, (WPARAM)hBuffer, 0L);
1240	}
1241#endif // !_WIN32_WCE
1242
1243	DWORD GetMargins() const
1244	{
1245		ATLASSERT(::IsWindow(m_hWnd));
1246		return (DWORD)::SendMessage(m_hWnd, EM_GETMARGINS, 0, 0L);
1247	}
1248
1249	void SetMargins(UINT nLeft, UINT nRight)
1250	{
1251		ATLASSERT(::IsWindow(m_hWnd));
1252		::SendMessage(m_hWnd, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(nLeft, nRight));
1253	}
1254
1255	UINT GetLimitText() const
1256	{
1257		ATLASSERT(::IsWindow(m_hWnd));
1258		return (UINT)::SendMessage(m_hWnd, EM_GETLIMITTEXT, 0, 0L);
1259	}
1260
1261	void SetLimitText(UINT nMax)
1262	{
1263		ATLASSERT(::IsWindow(m_hWnd));
1264		::SendMessage(m_hWnd, EM_SETLIMITTEXT, nMax, 0L);
1265	}
1266
1267	POINT PosFromChar(UINT nChar) const
1268	{
1269		ATLASSERT(::IsWindow(m_hWnd));
1270		DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_POSFROMCHAR, nChar, 0);
1271		POINT point = { GET_X_LPARAM(dwRet), GET_Y_LPARAM(dwRet) };
1272		return point;
1273	}
1274
1275	int CharFromPos(POINT pt, int* pLine = NULL) const
1276	{
1277		ATLASSERT(::IsWindow(m_hWnd));
1278		DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_CHARFROMPOS, 0, MAKELPARAM(pt.x, pt.y));
1279		if(pLine != NULL)
1280			*pLine = (int)(short)HIWORD(dwRet);
1281		return (int)(short)LOWORD(dwRet);
1282	}
1283
1284	// NOTE: first word in lpszBuffer must contain the size of the buffer!
1285	int GetLine(int nIndex, LPTSTR lpszBuffer) const
1286	{
1287		ATLASSERT(::IsWindow(m_hWnd));
1288		return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer);
1289	}
1290
1291	int GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const
1292	{
1293		ATLASSERT(::IsWindow(m_hWnd));
1294		*(LPWORD)lpszBuffer = (WORD)nMaxLength;
1295		return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer);
1296	}
1297
1298	TCHAR GetPasswordChar() const
1299	{
1300		ATLASSERT(::IsWindow(m_hWnd));
1301		return (TCHAR)::SendMessage(m_hWnd, EM_GETPASSWORDCHAR, 0, 0L);
1302	}
1303
1304	void SetPasswordChar(TCHAR ch)
1305	{
1306		ATLASSERT(::IsWindow(m_hWnd));
1307		::SendMessage(m_hWnd, EM_SETPASSWORDCHAR, ch, 0L);
1308	}
1309
1310#ifndef _WIN32_WCE
1311	EDITWORDBREAKPROC GetWordBreakProc() const
1312	{
1313		ATLASSERT(::IsWindow(m_hWnd));
1314		return (EDITWORDBREAKPROC)::SendMessage(m_hWnd, EM_GETWORDBREAKPROC, 0, 0L);
1315	}
1316
1317	void SetWordBreakProc(EDITWORDBREAKPROC ewbprc)
1318	{
1319		ATLASSERT(::IsWindow(m_hWnd));
1320		::SendMessage(m_hWnd, EM_SETWORDBREAKPROC, 0, (LPARAM)ewbprc);
1321	}
1322#endif // !_WIN32_WCE
1323
1324	int GetFirstVisibleLine() const
1325	{
1326		ATLASSERT(::IsWindow(m_hWnd));
1327		return (int)::SendMessage(m_hWnd, EM_GETFIRSTVISIBLELINE, 0, 0L);
1328	}
1329
1330#ifndef _WIN32_WCE
1331	int GetThumb() const
1332	{
1333		ATLASSERT(::IsWindow(m_hWnd));
1334		ATLASSERT((GetStyle() & ES_MULTILINE) != 0);
1335		return (int)::SendMessage(m_hWnd, EM_GETTHUMB, 0, 0L);
1336	}
1337#endif // !_WIN32_WCE
1338
1339	BOOL SetReadOnly(BOOL bReadOnly = TRUE)
1340	{
1341		ATLASSERT(::IsWindow(m_hWnd));
1342		return (BOOL)::SendMessage(m_hWnd, EM_SETREADONLY, bReadOnly, 0L);
1343	}
1344
1345#if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
1346	UINT GetImeStatus(UINT uStatus) const
1347	{
1348		ATLASSERT(::IsWindow(m_hWnd));
1349		return (UINT)::SendMessage(m_hWnd, EM_GETIMESTATUS, uStatus, 0L);
1350	}
1351
1352	UINT SetImeStatus(UINT uStatus, UINT uData)
1353	{
1354		ATLASSERT(::IsWindow(m_hWnd));
1355		return (UINT)::SendMessage(m_hWnd, EM_SETIMESTATUS, uStatus, uData);
1356	}
1357#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
1358
1359#if (_WIN32_WINNT >= 0x0501)
1360	BOOL GetCueBannerText(LPCWSTR lpstrText, int cchText) const
1361	{
1362		ATLASSERT(::IsWindow(m_hWnd));
1363		return (BOOL)::SendMessage(m_hWnd, EM_GETCUEBANNER, (WPARAM)lpstrText, cchText);
1364	}
1365
1366	// bKeepWithFocus - Vista only
1367	BOOL SetCueBannerText(LPCWSTR lpstrText, BOOL bKeepWithFocus = FALSE)
1368	{
1369		ATLASSERT(::IsWindow(m_hWnd));
1370		return (BOOL)::SendMessage(m_hWnd, EM_SETCUEBANNER, (WPARAM)bKeepWithFocus, (LPARAM)(lpstrText));
1371	}
1372#endif // (_WIN32_WINNT >= 0x0501)
1373
1374// Operations
1375	void EmptyUndoBuffer()
1376	{
1377		ATLASSERT(::IsWindow(m_hWnd));
1378		::SendMessage(m_hWnd, EM_EMPTYUNDOBUFFER, 0, 0L);
1379	}
1380
1381	BOOL FmtLines(BOOL bAddEOL)
1382	{
1383		ATLASSERT(::IsWindow(m_hWnd));
1384		return (BOOL)::SendMessage(m_hWnd, EM_FMTLINES, bAddEOL, 0L);
1385	}
1386
1387	void LimitText(int nChars = 0)
1388	{
1389		ATLASSERT(::IsWindow(m_hWnd));
1390		::SendMessage(m_hWnd, EM_LIMITTEXT, nChars, 0L);
1391	}
1392
1393	int LineFromChar(int nIndex = -1) const
1394	{
1395		ATLASSERT(::IsWindow(m_hWnd));
1396		return (int)::SendMessage(m_hWnd, EM_LINEFROMCHAR, nIndex, 0L);
1397	}
1398
1399	int LineIndex(int nLine = -1) const
1400	{
1401		ATLASSERT(::IsWindow(m_hWnd));
1402		return (int)::SendMessage(m_hWnd, EM_LINEINDEX, nLine, 0L);
1403	}
1404
1405	int LineLength(int nLine = -1) const
1406	{
1407		ATLASSERT(::IsWindow(m_hWnd));
1408		return (int)::SendMessage(m_hWnd, EM_LINELENGTH, nLine, 0L);
1409	}
1410
1411	void LineScroll(int nLines, int nChars = 0)
1412	{
1413		ATLASSERT(::IsWindow(m_hWnd));
1414		::SendMessage(m_hWnd, EM_LINESCROLL, nChars, nLines);
1415	}
1416
1417	void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE)
1418	{
1419		ATLASSERT(::IsWindow(m_hWnd));
1420		::SendMessage(m_hWnd, EM_REPLACESEL, (WPARAM) bCanUndo, (LPARAM)lpszNewText);
1421	}
1422
1423	void SetRect(LPCRECT lpRect)
1424	{
1425		ATLASSERT(::IsWindow(m_hWnd));
1426		::SendMessage(m_hWnd, EM_SETRECT, 0, (LPARAM)lpRect);
1427	}
1428
1429	void SetRectNP(LPCRECT lpRect)
1430	{
1431		ATLASSERT(::IsWindow(m_hWnd));
1432		::SendMessage(m_hWnd, EM_SETRECTNP, 0, (LPARAM)lpRect);
1433	}
1434
1435	void SetSel(DWORD dwSelection, BOOL bNoScroll = FALSE)
1436	{
1437		ATLASSERT(::IsWindow(m_hWnd));
1438		::SendMessage(m_hWnd, EM_SETSEL, LOWORD(dwSelection), HIWORD(dwSelection));
1439		if(!bNoScroll)
1440			::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L);
1441	}
1442
1443	void SetSel(int nStartChar, int nEndChar, BOOL bNoScroll = FALSE)
1444	{
1445		ATLASSERT(::IsWindow(m_hWnd));
1446		::SendMessage(m_hWnd, EM_SETSEL, nStartChar, nEndChar);
1447		if(!bNoScroll)
1448			::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L);
1449	}
1450
1451	void SetSelAll(BOOL bNoScroll = FALSE)
1452	{
1453		SetSel(0, -1, bNoScroll);
1454	}
1455
1456	void SetSelNone(BOOL bNoScroll = FALSE)
1457	{
1458		SetSel(-1, 0, bNoScroll);
1459	}
1460
1461	BOOL SetTabStops(int nTabStops, LPINT rgTabStops)
1462	{
1463		ATLASSERT(::IsWindow(m_hWnd));
1464		return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops);
1465	}
1466
1467	BOOL SetTabStops()
1468	{
1469		ATLASSERT(::IsWindow(m_hWnd));
1470		return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 0, 0L);
1471	}
1472
1473	BOOL SetTabStops(const int& cxEachStop)    // takes an 'int'
1474	{
1475		ATLASSERT(::IsWindow(m_hWnd));
1476		return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop);
1477	}
1478
1479	void ScrollCaret()
1480	{
1481		ATLASSERT(::IsWindow(m_hWnd));
1482		::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L);
1483	}
1484
1485	int Scroll(int nScrollAction)
1486	{
1487		ATLASSERT(::IsWindow(m_hWnd));
1488		ATLASSERT((GetStyle() & ES_MULTILINE) != 0);
1489		LRESULT lRet = ::SendMessage(m_hWnd, EM_SCROLL, nScrollAction, 0L);
1490		if(!(BOOL)HIWORD(lRet))
1491			return -1;   // failed
1492		return (int)(short)LOWORD(lRet);
1493		
1494	}
1495
1496	void InsertText(int nInsertAfterChar, LPCTSTR lpstrText, BOOL bNoScroll = FALSE, BOOL bCanUndo = FALSE)
1497	{
1498		SetSel(nInsertAfterChar, nInsertAfterChar, bNoScroll);
1499		ReplaceSel(lpstrText, bCanUndo);
1500	}
1501
1502	void AppendText(LPCTSTR lpstrText, BOOL bNoScroll = FALSE, BOOL bCanUndo = FALSE)
1503	{
1504		InsertText(GetWindowTextLength(), lpstrText, bNoScroll, bCanUndo);
1505	}
1506
1507#if (_WIN32_WINNT >= 0x0501)
1508	BOOL ShowBalloonTip(PEDITBALLOONTIP pEditBaloonTip)
1509	{
1510		ATLASSERT(::IsWindow(m_hWnd));
1511		return (BOOL)::SendMessage(m_hWnd, EM_SHOWBALLOONTIP, 0, (LPARAM)pEditBaloonTip);
1512	}
1513
1514	BOOL HideBalloonTip()
1515	{
1516		ATLASSERT(::IsWindow(m_hWnd));
1517		return (BOOL)::SendMessage(m_hWnd, EM_HIDEBALLOONTIP, 0, 0L);
1518	}
1519#endif // (_WIN32_WINNT >= 0x0501)
1520
1521#if (_WIN32_WINNT >= 0x0600)
1522	DWORD GetHilite() const
1523	{
1524		ATLASSERT(::IsWindow(m_hWnd));
1525		return (DWORD)::SendMessage(m_hWnd, EM_GETHILITE, 0, 0L);
1526	}
1527
1528	void GetHilite(int& nStartChar, int& nEndChar) const
1529	{
1530		ATLASSERT(::IsWindow(m_hWnd));
1531		DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_GETHILITE, 0, 0L);
1532		nStartChar = (int)(short)LOWORD(dwRet);
1533		nEndChar = (int)(short)HIWORD(dwRet);
1534	}
1535
1536	void SetHilite(int nStartChar, int nEndChar)
1537	{
1538		ATLASSERT(::IsWindow(m_hWnd));
1539		::SendMessage(m_hWnd, EM_SETHILITE, nStartChar, nEndChar);
1540	}
1541#endif // (_WIN32_WINNT >= 0x0600)
1542
1543	// Clipboard operations
1544	BOOL Undo()
1545	{
1546		ATLASSERT(::IsWindow(m_hWnd));
1547		return (BOOL)::SendMessage(m_hWnd, EM_UNDO, 0, 0L);
1548	}
1549
1550	void Clear()
1551	{
1552		ATLASSERT(::IsWindow(m_hWnd));
1553		::SendMessage(m_hWnd, WM_CLEAR, 0, 0L);
1554	}
1555
1556	void Copy()
1557	{
1558		ATLASSERT(::IsWindow(m_hWnd));
1559		::SendMessage(m_hWnd, WM_COPY, 0, 0L);
1560	}
1561
1562	void Cut()
1563	{
1564		ATLASSERT(::IsWindow(m_hWnd));
1565		::SendMessage(m_hWnd, WM_CUT, 0, 0L);
1566	}
1567
1568	void Paste()
1569	{
1570		ATLASSERT(::IsWindow(m_hWnd));
1571		::SendMessage(m_hWnd, WM_PASTE, 0, 0L);
1572	}
1573
1574#ifdef WIN32_PLATFORM_WFSP   // SmartPhone only messages
1575	DWORD GetExtendedStyle()
1576	{
1577		return SendMessage(EM_GETEXTENDEDSTYLE);
1578	}
1579
1580	DWORD SetExtendedStyle(DWORD dwMask, DWORD dwExStyle)
1581	{
1582		return SendMessage(EM_SETEXTENDEDSTYLE, (WPARAM)dwMask, (LPARAM)dwExStyle);
1583	}
1584
1585	DWORD GetInputMode(BOOL bCurrentMode = TRUE)
1586	{
1587		return SendMessage(EM_GETINPUTMODE, 0, (LPARAM)bCurrentMode);
1588	}
1589
1590	BOOL SetInputMode(DWORD dwMode)
1591	{
1592		return SendMessage(EM_SETINPUTMODE, 0, (LPARAM)dwMode);
1593	}
1594
1595	BOOL SetSymbols(LPCTSTR szSymbols)
1596	{
1597		return SendMessage(EM_SETSYMBOLS, 0, (LPARAM)szSymbols);
1598	}
1599
1600	BOOL ResetSymbols()
1601	{
1602		return SendMessage(EM_SETSYMBOLS);
1603	}
1604#endif // WIN32_PLATFORM_WFSP
1605};
1606
1607typedef CEditT<ATL::CWindow>   CEdit;
1608
1609
1610///////////////////////////////////////////////////////////////////////////////
1611// CEditCommands - message handlers for standard EDIT commands
1612
1613// Chain to CEditCommands message map. Your class must also derive from CEdit.
1614// Example:
1615// class CMyEdit : public CWindowImpl<CMyEdit, CEdit>,
1616//                 public CEditCommands<CMyEdit>
1617// {
1618// public:
1619//      BEGIN_MSG_MAP(CMyEdit)
1620//              // your handlers...
1621//              CHAIN_MSG_MAP_ALT(CEditCommands<CMyEdit>, 1)
1622//      END_MSG_MAP()
1623//      // other stuff...
1624// };
1625
1626template <class T>
1627class CEditCommands
1628{
1629public:
1630	BEGIN_MSG_MAP(CEditCommands< T >)
1631	ALT_MSG_MAP(1)
1632		COMMAND_ID_HANDLER(ID_EDIT_CLEAR, OnEditClear)
1633		COMMAND_ID_HANDLER(ID_EDIT_CLEAR_ALL, OnEditClearAll)
1634		COMMAND_ID_HANDLER(ID_EDIT_COPY, OnEditCopy)
1635		COMMAND_ID_HANDLER(ID_EDIT_CUT, OnEditCut)
1636		COMMAND_ID_HANDLER(ID_EDIT_PASTE, OnEditPaste)
1637		COMMAND_ID_HANDLER(ID_EDIT_SELECT_ALL, OnEditSelectAll)
1638		COMMAND_ID_HANDLER(ID_EDIT_UNDO, OnEditUndo)
1639	END_MSG_MAP()
1640
1641	LRESULT OnEditClear(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1642	{
1643		T* pT = static_cast<T*>(this);
1644		pT->Clear();
1645		return 0;
1646	}
1647
1648	LRESULT OnEditClearAll(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1649	{
1650		T* pT = static_cast<T*>(this);
1651		pT->SetSel(0, -1);
1652		pT->Clear();
1653		return 0;
1654	}
1655
1656	LRESULT OnEditCopy(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1657	{
1658		T* pT = static_cast<T*>(this);
1659		pT->Copy();
1660		return 0;
1661	}
1662
1663	LRESULT OnEditCut(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1664	{
1665		T* pT = static_cast<T*>(this);
1666		pT->Cut();
1667		return 0;
1668	}
1669
1670	LRESULT OnEditPaste(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1671	{
1672		T* pT = static_cast<T*>(this);
1673		pT->Paste();
1674		return 0;
1675	}
1676
1677	LRESULT OnEditSelectAll(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1678	{
1679		T* pT = static_cast<T*>(this);
1680		pT->SetSel(0, -1);
1681		return 0;
1682	}
1683
1684	LRESULT OnEditUndo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
1685	{
1686		T* pT = static_cast<T*>(this);
1687		pT->Undo();
1688		return 0;
1689	}
1690
1691// State (update UI) helpers
1692	BOOL CanCut() const
1693	{ return HasSelection(); }
1694
1695	BOOL CanCopy() const
1696	{ return HasSelection(); }
1697
1698	BOOL CanClear() const
1699	{ return HasSelection(); }
1700
1701	BOOL CanSelectAll() const
1702	{ return HasText(); }
1703
1704	BOOL CanFind() const
1705	{ return HasText(); }
1706
1707	BOOL CanRepeat() const
1708	{ return HasText(); }
1709
1710	BOOL CanReplace() const
1711	{ return HasText(); }
1712
1713	BOOL CanClearAll() const
1714	{ return HasText(); }
1715
1716// Implementation
1717	BOOL HasSelection() const
1718	{
1719		const T* pT = static_cast<const T*>(this);
1720		int nMin, nMax;
1721		::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nMin, (LPARAM)&nMax);
1722		return (nMin != nMax);
1723	}
1724
1725	BOOL HasText() const
1726	{
1727		const T* pT = static_cast<const T*>(this);
1728		return (pT->GetWindowTextLength() > 0);
1729	}
1730};
1731
1732
1733///////////////////////////////////////////////////////////////////////////////
1734// CScrollBar - client side for a Windows SCROLLBAR control
1735
1736template <class TBase>
1737class CScrollBarT : public TBase
1738{
1739public:
1740// Constructors
1741	CScrollBarT(HWND hWnd = NULL) : TBase(hWnd)
1742	{ }
1743
1744	CScrollBarT< TBase >& operator =(HWND hWnd)
1745	{
1746		m_hWnd = hWnd;
1747		return *this;
1748	}
1749
1750	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
1751			DWORD dwStyle = 0, DWORD dwExStyle = 0,
1752			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
1753	{
1754		return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
1755	}
1756
1757// Attributes
1758	static LPCTSTR GetWndClassName()
1759	{
1760		return _T("SCROLLBAR");
1761	}
1762
1763#ifndef _WIN32_WCE
1764	int GetScrollPos() const
1765	{
1766		ATLASSERT(::IsWindow(m_hWnd));
1767		return ::GetScrollPos(m_hWnd, SB_CTL);
1768	}
1769#endif // !_WIN32_WCE
1770
1771	int SetScrollPos(int nPos, BOOL bRedraw = TRUE)
1772	{
1773		ATLASSERT(::IsWindow(m_hWnd));
1774		return ::SetScrollPos(m_hWnd, SB_CTL, nPos, bRedraw);
1775	}
1776
1777#ifndef _WIN32_WCE
1778	void GetScrollRange(LPINT lpMinPos, LPINT lpMaxPos) const
1779	{
1780		ATLASSERT(::IsWindow(m_hWnd));
1781		::GetScrollRange(m_hWnd, SB_CTL, lpMinPos, lpMaxPos);
1782	}
1783#endif // !_WIN32_WCE
1784
1785	void SetScrollRange(int nMinPos, int nMaxPos, BOOL bRedraw = TRUE)
1786	{
1787		ATLASSERT(::IsWindow(m_hWnd));
1788		::SetScrollRange(m_hWnd, SB_CTL, nMinPos, nMaxPos, bRedraw);
1789	}
1790
1791	BOOL GetScrollInfo(LPSCROLLINFO lpScrollInfo) const
1792	{
1793		ATLASSERT(::IsWindow(m_hWnd));
1794		return ::GetScrollInfo(m_hWnd, SB_CTL, lpScrollInfo);
1795	}
1796
1797	int SetScrollInfo(LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE)
1798	{
1799		ATLASSERT(::IsWindow(m_hWnd));
1800		return ::SetScrollInfo(m_hWnd, SB_CTL, lpScrollInfo, bRedraw);
1801	}
1802
1803#ifndef _WIN32_WCE
1804	int GetScrollLimit() const
1805	{
1806		int nMin = 0, nMax = 0;
1807		::GetScrollRange(m_hWnd, SB_CTL, &nMin, &nMax);
1808		SCROLLINFO info = { sizeof(SCROLLINFO), SIF_PAGE };
1809		if(::GetScrollInfo(m_hWnd, SB_CTL, &info))
1810			nMax -= ((info.nPage - 1) > 0) ? (info.nPage - 1) : 0;
1811
1812		return nMax;
1813	}
1814
1815#if (WINVER >= 0x0500)
1816	BOOL GetScrollBarInfo(PSCROLLBARINFO pScrollBarInfo) const
1817	{
1818		ATLASSERT(::IsWindow(m_hWnd));
1819#if (_WIN32_WINNT >= 0x0501)
1820		return (BOOL)::SendMessage(m_hWnd, SBM_GETSCROLLBARINFO, 0, (LPARAM)pScrollBarInfo);
1821#else // !(_WIN32_WINNT >= 0x0501)
1822		return ::GetScrollBarInfo(m_hWnd, OBJID_CLIENT, pScrollBarInfo);
1823#endif // !(_WIN32_WINNT >= 0x0501)
1824	}
1825#endif // (WINVER >= 0x0500)
1826
1827// Operations
1828	void ShowScrollBar(BOOL bShow = TRUE)
1829	{
1830		ATLASSERT(::IsWindow(m_hWnd));
1831		::ShowScrollBar(m_hWnd, SB_CTL, bShow);
1832	}
1833
1834	BOOL EnableScrollBar(UINT nArrowFlags = ESB_ENABLE_BOTH)
1835	{
1836		ATLASSERT(::IsWindow(m_hWnd));
1837		return ::EnableScrollBar(m_hWnd, SB_CTL, nArrowFlags);
1838	}
1839#endif // !_WIN32_WCE
1840};
1841
1842typedef CScrollBarT<ATL::CWindow>   CScrollBar;
1843
1844
1845// --- Windows Common Controls ---
1846
1847///////////////////////////////////////////////////////////////////////////////
1848// CImageList
1849
1850class CImageList
1851{
1852public:
1853	HIMAGELIST m_hImageList;
1854
1855// Constructor
1856	CImageList(HIMAGELIST hImageList = NULL) : m_hImageList(hImageList)
1857	{ }
1858
1859// Operators, etc.
1860	CImageList& operator =(HIMAGELIST hImageList)
1861	{
1862		m_hImageList = hImageList;
1863		return *this;
1864	}
1865
1866	operator HIMAGELIST() const { return m_hImageList; }
1867
1868	void Attach(HIMAGELIST hImageList)
1869	{
1870		ATLASSERT(m_hImageList == NULL);
1871		ATLASSERT(hImageList != NULL);
1872		m_hImageList = hImageList;
1873	}
1874
1875	HIMAGELIST Detach()
1876	{
1877		HIMAGELIST hImageList = m_hImageList;
1878		m_hImageList = NULL;
1879		return hImageList;
1880	}
1881
1882	bool IsNull() const { return (m_hImageList == NULL); }
1883
1884// Attributes
1885	int GetImageCount() const
1886	{
1887		ATLASSERT(m_hImageList != NULL);
1888		return ImageList_GetImageCount(m_hImageList);
1889	}
1890
1891	COLORREF GetBkColor() const
1892	{
1893		ATLASSERT(m_hImageList != NULL);
1894		return ImageList_GetBkColor(m_hImageList);
1895	}
1896
1897	COLORREF SetBkColor(COLORREF cr)
1898	{
1899		ATLASSERT(m_hImageList != NULL);
1900		return ImageList_SetBkColor(m_hImageList, cr);
1901	}
1902
1903	BOOL GetImageInfo(int nImage, IMAGEINFO* p

Large files files are truncated, but you can click here to view the full file