winctrl2.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #ifdef AFX_CMNCTL_SEG
  12. #pragma code_seg(AFX_CMNCTL_SEG)
  13. #endif
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. #define new DEBUG_NEW
  19. #ifndef _AFX_NO_OLE_SUPPORT
  20. extern "C"
  21. {
  22. HIMAGELIST WINAPI ImageList_Read(LPSTREAM pstm);
  23. BOOL WINAPI ImageList_Write(HIMAGELIST himl, LPSTREAM pstm);
  24. }
  25. #endif
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CDragListBox
  28. CDragListBox::~CDragListBox()
  29. {
  30. DestroyWindow();
  31. }
  32. void CDragListBox::PreSubclassWindow()
  33. {
  34. ASSERT(::IsWindow(m_hWnd));
  35. ASSERT((GetStyle() & (LBS_MULTIPLESEL|LBS_SORT)) == 0);
  36. MakeDragList(m_hWnd);
  37. }
  38. BOOL CDragListBox::BeginDrag(CPoint pt)
  39. {
  40. m_nLast = -1;
  41. DrawInsert(ItemFromPt(pt));
  42. return TRUE;
  43. }
  44. void CDragListBox::CancelDrag(CPoint)
  45. {
  46. DrawInsert(-1);
  47. }
  48. UINT CDragListBox::Dragging(CPoint pt)
  49. {
  50. int nIndex = ItemFromPt(pt, FALSE); // don't allow scrolling just yet
  51. DrawInsert(nIndex);
  52. ItemFromPt(pt);
  53. return (nIndex == LB_ERR) ? DL_STOPCURSOR : DL_MOVECURSOR;
  54. }
  55. void CDragListBox::Dropped(int nSrcIndex, CPoint pt)
  56. {
  57. ASSERT(!(GetStyle() & (LBS_OWNERDRAWFIXED|LBS_OWNERDRAWVARIABLE)) ||
  58. (GetStyle() & LBS_HASSTRINGS));
  59. DrawInsert(-1);
  60. int nDestIndex = ItemFromPt(pt);
  61. if (nSrcIndex == -1 || nDestIndex == -1)
  62. return;
  63. if (nDestIndex == nSrcIndex || nDestIndex == nSrcIndex+1)
  64. return; //didn't move
  65. CString str;
  66. DWORD dwData;
  67. GetText(nSrcIndex, str);
  68. dwData = GetItemData(nSrcIndex);
  69. DeleteString(nSrcIndex);
  70. if (nSrcIndex < nDestIndex)
  71. nDestIndex--;
  72. nDestIndex = InsertString(nDestIndex, str);
  73. SetItemData(nDestIndex, dwData);
  74. SetCurSel(nDestIndex);
  75. }
  76. void CDragListBox::DrawInsert(int nIndex)
  77. {
  78. if (m_nLast != nIndex)
  79. {
  80. DrawSingle(m_nLast);
  81. DrawSingle(nIndex);
  82. m_nLast = nIndex;
  83. }
  84. }
  85. void CDragListBox::DrawSingle(int nIndex)
  86. {
  87. if (nIndex == -1)
  88. return;
  89. CBrush* pBrush = CDC::GetHalftoneBrush();
  90. CRect rect;
  91. GetClientRect(&rect);
  92. CRgn rgn;
  93. rgn.CreateRectRgnIndirect(&rect);
  94. CDC* pDC = GetDC();
  95. // prevent drawing outside of listbox
  96. // this can happen at the top of the listbox since the listbox's DC is the
  97. // parent's DC
  98. pDC->SelectClipRgn(&rgn);
  99. GetItemRect(nIndex, &rect);
  100. rect.bottom = rect.top+2;
  101. rect.top -= 2;
  102. CBrush* pBrushOld = pDC->SelectObject(pBrush);
  103. //draw main line
  104. pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT);
  105. pDC->SelectObject(pBrushOld);
  106. ReleaseDC(pDC);
  107. }
  108. BOOL CDragListBox::OnChildNotify(UINT nMessage, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  109. {
  110. if (nMessage != m_nMsgDragList)
  111. return CListBox::OnChildNotify(nMessage, wParam, lParam, pResult);
  112. ASSERT(pResult != NULL);
  113. LPDRAGLISTINFO pInfo = (LPDRAGLISTINFO)lParam;
  114. ASSERT(pInfo != NULL);
  115. switch (pInfo->uNotification)
  116. {
  117. case DL_BEGINDRAG:
  118. *pResult = BeginDrag(pInfo->ptCursor);
  119. break;
  120. case DL_CANCELDRAG:
  121. CancelDrag(pInfo->ptCursor);
  122. break;
  123. case DL_DRAGGING:
  124. *pResult = Dragging(pInfo->ptCursor);
  125. break;
  126. case DL_DROPPED:
  127. Dropped(GetCurSel(), pInfo->ptCursor);
  128. break;
  129. }
  130. return TRUE;
  131. }
  132. /////////////////////////////////////////////////////////////////////////////
  133. // CToolBarCtrl
  134. BEGIN_MESSAGE_MAP(CToolBarCtrl, CWnd)
  135. //{{AFX_MSG_MAP(CToolBarCtrl)
  136. ON_WM_CREATE()
  137. //}}AFX_MSG_MAP
  138. END_MESSAGE_MAP()
  139. BOOL CToolBarCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  140. UINT nID)
  141. {
  142. // initialize common controls
  143. VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_BAR_REG));
  144. CWnd* pWnd = this;
  145. return pWnd->Create(TOOLBARCLASSNAME, NULL, dwStyle, rect, pParentWnd, nID);
  146. }
  147. CToolBarCtrl::~CToolBarCtrl()
  148. {
  149. DestroyWindow();
  150. }
  151. int CToolBarCtrl::AddBitmap(int nNumButtons, CBitmap* pBitmap)
  152. {
  153. ASSERT(::IsWindow(m_hWnd));
  154. TBADDBITMAP tbab;
  155. tbab.hInst = NULL;
  156. tbab.nID = (UINT)pBitmap->GetSafeHandle();
  157. return (int) ::SendMessage(m_hWnd, TB_ADDBITMAP, (WPARAM)nNumButtons,
  158. (LPARAM)&tbab);
  159. }
  160. int CToolBarCtrl::AddBitmap(int nNumButtons, UINT nBitmapID)
  161. {
  162. ASSERT(::IsWindow(m_hWnd));
  163. TBADDBITMAP tbab;
  164. tbab.hInst = AfxFindResourceHandle((LPCTSTR)nBitmapID, RT_BITMAP);
  165. ASSERT(tbab.hInst != NULL);
  166. tbab.nID = nBitmapID;
  167. return (int) ::SendMessage(m_hWnd, TB_ADDBITMAP, (WPARAM)nNumButtons,
  168. (LPARAM)&tbab);
  169. }
  170. void CToolBarCtrl::SaveState(HKEY hKeyRoot, LPCTSTR lpszSubKey,
  171. LPCTSTR lpszValueName)
  172. {
  173. ASSERT(::IsWindow(m_hWnd));
  174. TBSAVEPARAMS tbs;
  175. tbs.hkr = hKeyRoot;
  176. tbs.pszSubKey = lpszSubKey;
  177. tbs.pszValueName = lpszValueName;
  178. ::SendMessage(m_hWnd, TB_SAVERESTORE, (WPARAM)TRUE, (LPARAM)&tbs);
  179. }
  180. void CToolBarCtrl::RestoreState(HKEY hKeyRoot, LPCTSTR lpszSubKey,
  181. LPCTSTR lpszValueName)
  182. {
  183. ASSERT(::IsWindow(m_hWnd));
  184. TBSAVEPARAMS tbs;
  185. tbs.hkr = hKeyRoot;
  186. tbs.pszSubKey = lpszSubKey;
  187. tbs.pszValueName = lpszValueName;
  188. ::SendMessage(m_hWnd, TB_SAVERESTORE, (WPARAM)FALSE, (LPARAM)&tbs);
  189. }
  190. int CToolBarCtrl::AddString(UINT nStringID)
  191. {
  192. ASSERT(::IsWindow(m_hWnd));
  193. HINSTANCE hInst = AfxFindResourceHandle(MAKEINTRESOURCE((nStringID>>4)+1),
  194. RT_STRING);
  195. ASSERT(hInst != NULL);
  196. return (int)::SendMessage(m_hWnd, TB_ADDSTRING, (WPARAM)hInst, nStringID);
  197. }
  198. int CToolBarCtrl::OnCreate(LPCREATESTRUCT lpcs)
  199. {
  200. if (CWnd::OnCreate(lpcs) == -1)
  201. return -1;
  202. SetButtonStructSize(sizeof(TBBUTTON));
  203. return 0;
  204. }
  205. HRESULT CToolBarCtrl::GetDropTarget(IDropTarget** ppDropTarget) const
  206. {
  207. ASSERT(::IsWindow(m_hWnd));
  208. ASSERT(ppDropTarget);
  209. return (HRESULT) ::SendMessage(m_hWnd, TB_GETOBJECT, (WPARAM)&IID_IDropTarget, (LPARAM)ppDropTarget);
  210. }
  211. /////////////////////////////////////////////////////////////////////////////
  212. // CStatusBarCtrl
  213. BOOL CStatusBarCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  214. UINT nID)
  215. {
  216. // initialize common controls
  217. VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_BAR_REG));
  218. CWnd* pWnd = this;
  219. return pWnd->Create(STATUSCLASSNAME, NULL, dwStyle, rect, pParentWnd, nID);
  220. }
  221. CStatusBarCtrl::~CStatusBarCtrl()
  222. {
  223. DestroyWindow();
  224. }
  225. int CStatusBarCtrl::GetText(LPCTSTR lpszText, int nPane, int* pType) const
  226. {
  227. ASSERT(::IsWindow(m_hWnd));
  228. ASSERT(nPane < 256);
  229. DWORD dw = ::SendMessage(m_hWnd, SB_GETTEXT, (WPARAM)nPane,
  230. (LPARAM)lpszText);
  231. if (pType != NULL)
  232. *pType = HIWORD(dw);
  233. return LOWORD(dw);
  234. }
  235. CString CStatusBarCtrl::GetText(int nPane, int* pType) const
  236. {
  237. ASSERT(::IsWindow(m_hWnd));
  238. ASSERT(nPane < 256);
  239. int nLength = LOWORD(::SendMessage(m_hWnd, SB_GETTEXTLENGTH,
  240. (WPARAM)nPane, 0L));
  241. CString str;
  242. DWORD dw = ::SendMessage(m_hWnd, SB_GETTEXT, (WPARAM)nPane,
  243. (LPARAM)str.GetBufferSetLength(nLength+1));
  244. str.ReleaseBuffer();
  245. if (pType != NULL)
  246. *pType = HIWORD(dw);
  247. return str;
  248. }
  249. int CStatusBarCtrl::GetTextLength(int nPane, int* pType) const
  250. {
  251. ASSERT(::IsWindow(m_hWnd));
  252. ASSERT(nPane < 256);
  253. DWORD dw = ::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L);
  254. if (pType != NULL)
  255. *pType = HIWORD(dw);
  256. return LOWORD(dw);
  257. }
  258. CString CStatusBarCtrl::GetTipText(int nPane) const
  259. {
  260. ASSERT(::IsWindow(m_hWnd));
  261. ASSERT(nPane < 256);
  262. TCHAR buf[256];
  263. ::SendMessage(m_hWnd, SB_GETTIPTEXT, MAKEWPARAM(nPane, 256), (LPARAM)buf);
  264. return CString(buf);
  265. }
  266. BOOL CStatusBarCtrl::GetBorders(int& nHorz, int& nVert, int& nSpacing) const
  267. {
  268. ASSERT(::IsWindow(m_hWnd));
  269. int borders[3];
  270. BOOL bResult = (BOOL)::SendMessage(m_hWnd, SB_GETBORDERS, 0,
  271. (LPARAM)&borders);
  272. if (bResult)
  273. {
  274. nHorz = borders[0];
  275. nVert = borders[1];
  276. nSpacing = borders[2];
  277. }
  278. return bResult;
  279. }
  280. void CStatusBarCtrl::DrawItem(LPDRAWITEMSTRUCT)
  281. {
  282. ASSERT(FALSE); // must override for self draw status bars
  283. }
  284. BOOL CStatusBarCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
  285. LRESULT* pResult)
  286. {
  287. if (message != WM_DRAWITEM)
  288. return CWnd::OnChildNotify(message, wParam, lParam, pResult);
  289. ASSERT(pResult == NULL); // no return value expected
  290. UNUSED(pResult); // unused in release builds
  291. DrawItem((LPDRAWITEMSTRUCT)lParam);
  292. return TRUE;
  293. }
  294. /////////////////////////////////////////////////////////////////////////////
  295. // CListCtrl
  296. BEGIN_MESSAGE_MAP(CListCtrl, CWnd)
  297. //{{AFX_MSG_MAP(CListCtrl)
  298. ON_WM_NCDESTROY()
  299. //}}AFX_MSG_MAP
  300. END_MESSAGE_MAP()
  301. BOOL CListCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  302. UINT nID)
  303. {
  304. // initialize common controls
  305. VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_LISTVIEW_REG));
  306. CWnd* pWnd = this;
  307. return pWnd->Create(WC_LISTVIEW, NULL, dwStyle, rect, pParentWnd, nID);
  308. }
  309. CListCtrl::~CListCtrl()
  310. {
  311. DestroyWindow();
  312. }
  313. BOOL CListCtrl::GetItemRect(int nItem, LPRECT lpRect, UINT nCode) const
  314. {
  315. ASSERT(::IsWindow(m_hWnd));
  316. lpRect->left = nCode;
  317. return (BOOL) ::SendMessage(m_hWnd, LVM_GETITEMRECT, (WPARAM)nItem,
  318. (LPARAM)lpRect);
  319. }
  320. BOOL CListCtrl::SetItemCountEx(int iCount, DWORD dwFlags /* = LVSICF_NOINVALIDATEALL */)
  321. {
  322. ASSERT(::IsWindow(m_hWnd));
  323. // can't have dwFlags on a control that isn't virutal
  324. ASSERT(dwFlags == 0 || (GetStyle() & LVS_OWNERDATA));
  325. return (BOOL) ::SendMessage(m_hWnd, LVM_SETITEMCOUNT, (WPARAM) iCount,
  326. (LPARAM) dwFlags);
  327. }
  328. CSize CListCtrl::SetIconSpacing(int cx, int cy)
  329. {
  330. ASSERT(::IsWindow(m_hWnd));
  331. DWORD dwRet = (DWORD) ::SendMessage(m_hWnd, LVM_SETICONSPACING,
  332. 0, (LPARAM) MAKELONG(cx, cy));
  333. return CSize(dwRet);
  334. }
  335. CSize CListCtrl::SetIconSpacing(CSize size)
  336. {
  337. ASSERT(::IsWindow(m_hWnd));
  338. DWORD dwRet = (DWORD) ::SendMessage(m_hWnd, LVM_SETICONSPACING,
  339. 0, (LPARAM) MAKELONG(size.cx, size.cy));
  340. return CSize(dwRet);
  341. }
  342. BOOL CListCtrl::GetSubItemRect(int iItem, int iSubItem, int nArea, CRect& ref)
  343. {
  344. ASSERT(::IsWindow(m_hWnd));
  345. ASSERT(nArea == LVIR_BOUNDS || nArea == LVIR_ICON || nArea == LVIR_LABEL);
  346. RECT rect;
  347. rect.top = iSubItem;
  348. rect.left = nArea;
  349. BOOL bRet = (BOOL) ::SendMessage(m_hWnd, LVM_GETSUBITEMRECT,
  350. iItem, (LPARAM) &rect);
  351. if (bRet)
  352. ref = rect;
  353. return bRet;
  354. }
  355. int CListCtrl::InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int nFormat,
  356. int nWidth, int nSubItem)
  357. {
  358. LVCOLUMN column;
  359. column.mask = LVCF_TEXT|LVCF_FMT;
  360. column.pszText = (LPTSTR)lpszColumnHeading;
  361. column.fmt = nFormat;
  362. if (nWidth != -1)
  363. {
  364. column.mask |= LVCF_WIDTH;
  365. column.cx = nWidth;
  366. }
  367. if (nSubItem != -1)
  368. {
  369. column.mask |= LVCF_SUBITEM;
  370. column.iSubItem = nSubItem;
  371. }
  372. return CListCtrl::InsertColumn(nCol, &column);
  373. }
  374. int CListCtrl::InsertItem(UINT nMask, int nItem, LPCTSTR lpszItem, UINT nState, UINT nStateMask,
  375. int nImage, LPARAM lParam)
  376. {
  377. ASSERT(::IsWindow(m_hWnd));
  378. LVITEM item;
  379. item.mask = nMask;
  380. item.iItem = nItem;
  381. item.iSubItem = 0;
  382. item.pszText = (LPTSTR)lpszItem;
  383. item.state = nState;
  384. item.stateMask = nStateMask;
  385. item.iImage = nImage;
  386. item.lParam = lParam;
  387. return CListCtrl::InsertItem(&item);
  388. }
  389. int CListCtrl::HitTest(CPoint pt, UINT* pFlags) const
  390. {
  391. ASSERT(::IsWindow(m_hWnd));
  392. LVHITTESTINFO hti;
  393. hti.pt = pt;
  394. int nRes = (int) ::SendMessage(m_hWnd, LVM_HITTEST, 0, (LPARAM)&hti);
  395. if (pFlags != NULL)
  396. *pFlags = hti.flags;
  397. return nRes;
  398. }
  399. BOOL CListCtrl::SetItem(int nItem, int nSubItem, UINT nMask, LPCTSTR lpszItem,
  400. int nImage, UINT nState, UINT nStateMask, LPARAM lParam)
  401. {
  402. ASSERT(::IsWindow(m_hWnd));
  403. ASSERT((GetStyle() & LVS_OWNERDATA)==0);
  404. LVITEM lvi;
  405. lvi.mask = nMask;
  406. lvi.iItem = nItem;
  407. lvi.iSubItem = nSubItem;
  408. lvi.stateMask = nStateMask;
  409. lvi.state = nState;
  410. lvi.pszText = (LPTSTR) lpszItem;
  411. lvi.iImage = nImage;
  412. lvi.lParam = lParam;
  413. return (BOOL) ::SendMessage(m_hWnd, LVM_SETITEM, 0, (LPARAM)&lvi);
  414. }
  415. BOOL CListCtrl::SetItemState(int nItem, UINT nState, UINT nStateMask)
  416. {
  417. ASSERT(::IsWindow(m_hWnd));
  418. LVITEM lvi;
  419. lvi.stateMask = nStateMask;
  420. lvi.state = nState;
  421. return (BOOL) ::SendMessage(m_hWnd, LVM_SETITEMSTATE, nItem, (LPARAM)&lvi);
  422. }
  423. BOOL CListCtrl::SetItemText(int nItem, int nSubItem, LPCTSTR lpszText)
  424. {
  425. ASSERT(::IsWindow(m_hWnd));
  426. ASSERT((GetStyle() & LVS_OWNERDATA)==0);
  427. LVITEM lvi;
  428. lvi.iSubItem = nSubItem;
  429. lvi.pszText = (LPTSTR) lpszText;
  430. return (BOOL) ::SendMessage(m_hWnd, LVM_SETITEMTEXT, nItem, (LPARAM)&lvi);
  431. }
  432. CString CListCtrl::GetItemText(int nItem, int nSubItem) const
  433. {
  434. ASSERT(::IsWindow(m_hWnd));
  435. LVITEM lvi;
  436. memset(&lvi, 0, sizeof(LVITEM));
  437. lvi.iSubItem = nSubItem;
  438. CString str;
  439. int nLen = 128;
  440. int nRes;
  441. do
  442. {
  443. nLen *= 2;
  444. lvi.cchTextMax = nLen;
  445. lvi.pszText = str.GetBufferSetLength(nLen);
  446. nRes = (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem,
  447. (LPARAM)&lvi);
  448. } while (nRes == nLen-1);
  449. str.ReleaseBuffer();
  450. return str;
  451. }
  452. int CListCtrl::GetItemText(int nItem, int nSubItem, LPTSTR lpszText, int nLen) const
  453. {
  454. ASSERT(::IsWindow(m_hWnd));
  455. LVITEM lvi;
  456. memset(&lvi, 0, sizeof(LVITEM));
  457. lvi.iSubItem = nSubItem;
  458. lvi.cchTextMax = nLen;
  459. lvi.pszText = lpszText;
  460. return (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem,
  461. (LPARAM)&lvi);
  462. }
  463. DWORD CListCtrl::GetItemData(int nItem) const
  464. {
  465. ASSERT(::IsWindow(m_hWnd));
  466. LVITEM lvi;
  467. memset(&lvi, 0, sizeof(LVITEM));
  468. lvi.iItem = nItem;
  469. lvi.mask = LVIF_PARAM;
  470. VERIFY(::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)&lvi));
  471. return (DWORD)lvi.lParam;
  472. }
  473. void CListCtrl::DrawItem(LPDRAWITEMSTRUCT)
  474. {
  475. ASSERT(FALSE);
  476. }
  477. BOOL CListCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
  478. LRESULT* pResult)
  479. {
  480. if (message != WM_DRAWITEM)
  481. return CWnd::OnChildNotify(message, wParam, lParam, pResult);
  482. ASSERT(pResult == NULL); // no return value expected
  483. UNUSED(pResult); // unused in release builds
  484. DrawItem((LPDRAWITEMSTRUCT)lParam);
  485. return TRUE;
  486. }
  487. void CListCtrl::RemoveImageList(int nImageList)
  488. {
  489. HIMAGELIST h = (HIMAGELIST)SendMessage(LVM_GETIMAGELIST,
  490. (WPARAM)nImageList);
  491. if (CImageList::FromHandlePermanent(h) != NULL)
  492. SendMessage(LVM_SETIMAGELIST, (WPARAM)nImageList, NULL);
  493. }
  494. void CListCtrl::OnNcDestroy()
  495. {
  496. RemoveImageList(LVSIL_NORMAL);
  497. RemoveImageList(LVSIL_SMALL);
  498. RemoveImageList(LVSIL_STATE);
  499. CWnd::OnNcDestroy();
  500. }
  501. CImageList* CListCtrl::CreateDragImage(int nItem, LPPOINT lpPoint)
  502. {
  503. ASSERT(::IsWindow(m_hWnd));
  504. HIMAGELIST hImageList = (HIMAGELIST)::SendMessage(m_hWnd,
  505. LVM_CREATEDRAGIMAGE, nItem, (LPARAM)lpPoint);
  506. if (hImageList == NULL)
  507. return NULL;
  508. CImageList* pImageList = new CImageList;
  509. VERIFY(pImageList->Attach(hImageList));
  510. return pImageList;
  511. }
  512. /////////////////////////////////////////////////////////////////////////////
  513. // CTreeCtrl
  514. BEGIN_MESSAGE_MAP(CTreeCtrl, CWnd)
  515. //{{AFX_MSG_MAP(CTreeCtrl)
  516. ON_WM_DESTROY()
  517. //}}AFX_MSG_MAP
  518. END_MESSAGE_MAP()
  519. BOOL CTreeCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  520. UINT nID)
  521. {
  522. // initialize common controls
  523. VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_TREEVIEW_REG));
  524. CWnd* pWnd = this;
  525. return pWnd->Create(WC_TREEVIEW, NULL, dwStyle, rect, pParentWnd, nID);
  526. }
  527. CTreeCtrl::~CTreeCtrl()
  528. {
  529. DestroyWindow();
  530. }
  531. BOOL CTreeCtrl::GetItemRect(HTREEITEM hItem, LPRECT lpRect, BOOL bTextOnly) const
  532. {
  533. ASSERT(::IsWindow(m_hWnd));
  534. *(HTREEITEM*)lpRect = hItem;
  535. return (BOOL)::SendMessage(m_hWnd, TVM_GETITEMRECT, (WPARAM)bTextOnly,
  536. (LPARAM)lpRect);
  537. }
  538. CString CTreeCtrl::GetItemText(HTREEITEM hItem) const
  539. {
  540. ASSERT(::IsWindow(m_hWnd));
  541. TVITEM item;
  542. item.hItem = hItem;
  543. item.mask = TVIF_TEXT;
  544. CString str;
  545. int nLen = 128;
  546. int nRes;
  547. do
  548. {
  549. nLen *= 2;
  550. item.pszText = str.GetBufferSetLength(nLen);
  551. item.cchTextMax = nLen;
  552. ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
  553. nRes = lstrlen(item.pszText);
  554. } while (nRes == nLen-1);
  555. str.ReleaseBuffer();
  556. return str;
  557. }
  558. BOOL CTreeCtrl::GetItemImage(HTREEITEM hItem, int& nImage, int& nSelectedImage) const
  559. {
  560. ASSERT(::IsWindow(m_hWnd));
  561. TVITEM item;
  562. item.hItem = hItem;
  563. item.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE;
  564. BOOL bRes = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
  565. if (bRes)
  566. {
  567. nImage = item.iImage;
  568. nSelectedImage = item.iSelectedImage;
  569. }
  570. return bRes;
  571. }
  572. UINT CTreeCtrl::GetItemState(HTREEITEM hItem, UINT nStateMask) const
  573. {
  574. ASSERT(::IsWindow(m_hWnd));
  575. TVITEM item;
  576. item.hItem = hItem;
  577. item.mask = TVIF_STATE;
  578. item.stateMask = nStateMask;
  579. item.state = 0;
  580. VERIFY(::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item));
  581. return item.state;
  582. }
  583. DWORD CTreeCtrl::GetItemData(HTREEITEM hItem) const
  584. {
  585. ASSERT(::IsWindow(m_hWnd));
  586. TVITEM item;
  587. item.hItem = hItem;
  588. item.mask = TVIF_PARAM;
  589. VERIFY(::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item));
  590. return (DWORD)item.lParam;
  591. }
  592. BOOL CTreeCtrl::ItemHasChildren(HTREEITEM hItem) const
  593. {
  594. ASSERT(::IsWindow(m_hWnd));
  595. TVITEM item;
  596. item.hItem = hItem;
  597. item.mask = TVIF_CHILDREN;
  598. ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
  599. return item.cChildren;
  600. }
  601. BOOL CTreeCtrl::SetItem(HTREEITEM hItem, UINT nMask, LPCTSTR lpszItem, int nImage,
  602. int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam)
  603. {
  604. ASSERT(::IsWindow(m_hWnd));
  605. TVITEM item;
  606. item.hItem = hItem;
  607. item.mask = nMask;
  608. item.pszText = (LPTSTR) lpszItem;
  609. item.iImage = nImage;
  610. item.iSelectedImage = nSelectedImage;
  611. item.state = nState;
  612. item.stateMask = nStateMask;
  613. item.lParam = lParam;
  614. return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&item);
  615. }
  616. HTREEITEM CTreeCtrl::InsertItem(UINT nMask, LPCTSTR lpszItem, int nImage,
  617. int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam,
  618. HTREEITEM hParent, HTREEITEM hInsertAfter)
  619. {
  620. ASSERT(::IsWindow(m_hWnd));
  621. TVINSERTSTRUCT tvis;
  622. tvis.hParent = hParent;
  623. tvis.hInsertAfter = hInsertAfter;
  624. tvis.item.mask = nMask;
  625. tvis.item.pszText = (LPTSTR) lpszItem;
  626. tvis.item.iImage = nImage;
  627. tvis.item.iSelectedImage = nSelectedImage;
  628. tvis.item.state = nState;
  629. tvis.item.stateMask = nStateMask;
  630. tvis.item.lParam = lParam;
  631. return (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)&tvis);
  632. }
  633. HTREEITEM CTreeCtrl::HitTest(CPoint pt, UINT* pFlags) const
  634. {
  635. ASSERT(::IsWindow(m_hWnd));
  636. TVHITTESTINFO hti;
  637. hti.pt = pt;
  638. HTREEITEM h = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0,
  639. (LPARAM)&hti);
  640. if (pFlags != NULL)
  641. *pFlags = hti.flags;
  642. return h;
  643. }
  644. void CTreeCtrl::RemoveImageList(int nImageList)
  645. {
  646. HIMAGELIST h = (HIMAGELIST)SendMessage(TVM_GETIMAGELIST,
  647. (WPARAM)nImageList);
  648. if (CImageList::FromHandlePermanent(h) != NULL)
  649. SendMessage(TVM_SETIMAGELIST, (WPARAM)nImageList, NULL);
  650. }
  651. void CTreeCtrl::OnDestroy()
  652. {
  653. RemoveImageList(LVSIL_NORMAL);
  654. RemoveImageList(LVSIL_STATE);
  655. CWnd::OnDestroy();
  656. }
  657. CImageList* CTreeCtrl::CreateDragImage(HTREEITEM hItem)
  658. {
  659. ASSERT(::IsWindow(m_hWnd));
  660. HIMAGELIST hImageList = (HIMAGELIST)::SendMessage(m_hWnd,
  661. TVM_CREATEDRAGIMAGE, 0, (LPARAM)hItem);
  662. if (hImageList == NULL)
  663. return NULL;
  664. CImageList* pImageList = new CImageList;
  665. VERIFY(pImageList->Attach(hImageList));
  666. return pImageList;
  667. }
  668. BOOL CTreeCtrl::GetCheck(HTREEITEM hItem) const
  669. {
  670. ASSERT(::IsWindow(m_hWnd));
  671. TVITEM item;
  672. item.mask = TVIF_HANDLE | TVIF_STATE;
  673. item.hItem = hItem;
  674. item.stateMask = TVIS_STATEIMAGEMASK;
  675. VERIFY(::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item));
  676. // Return zero if it's not checked, or nonzero otherwise.
  677. return ((BOOL)(item.state >> 12) -1);
  678. }
  679. BOOL CTreeCtrl::SetCheck(HTREEITEM hItem, BOOL fCheck)
  680. {
  681. ASSERT(::IsWindow(m_hWnd));
  682. TVITEM item;
  683. item.mask = TVIF_HANDLE | TVIF_STATE;
  684. item.hItem = hItem;
  685. item.stateMask = TVIS_STATEIMAGEMASK;
  686. /*
  687. Since state images are one-based, 1 in this macro turns the check off, and
  688. 2 turns it on.
  689. */
  690. item.state = INDEXTOSTATEIMAGEMASK((fCheck ? 2 : 1));
  691. return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&item);
  692. }
  693. /////////////////////////////////////////////////////////////////////////////
  694. // CSpinButtonCtrl
  695. BOOL CSpinButtonCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  696. UINT nID)
  697. {
  698. // initialize common controls
  699. VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_UPDOWN_REG));
  700. CWnd* pWnd = this;
  701. return pWnd->Create(UPDOWN_CLASS, NULL, dwStyle, rect, pParentWnd, nID);
  702. }
  703. CSpinButtonCtrl::~CSpinButtonCtrl()
  704. {
  705. DestroyWindow();
  706. }
  707. void CSpinButtonCtrl::GetRange(int &lower, int& upper) const
  708. {
  709. ASSERT(::IsWindow(m_hWnd));
  710. DWORD dw = ::SendMessage(m_hWnd, UDM_GETRANGE, 0, 0l);
  711. lower = (int)(short)HIWORD(dw);
  712. upper = (int)(short)LOWORD(dw);
  713. }
  714. /////////////////////////////////////////////////////////////////////////////
  715. // CSliderCtrl
  716. BOOL CSliderCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  717. UINT nID)
  718. {
  719. // initialize common controls
  720. VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_BAR_REG));
  721. CWnd* pWnd = this;
  722. return pWnd->Create(TRACKBAR_CLASS, NULL, dwStyle, rect, pParentWnd, nID);
  723. }
  724. CSliderCtrl::~CSliderCtrl()
  725. {
  726. DestroyWindow();
  727. }
  728. void CSliderCtrl::GetRange(int& nMin, int& nMax) const
  729. {
  730. ASSERT(::IsWindow(m_hWnd));
  731. nMin = GetRangeMin();
  732. nMax = GetRangeMax();
  733. }
  734. void CSliderCtrl::SetRange(int nMin, int nMax, BOOL bRedraw)
  735. {
  736. SetRangeMin(nMin, bRedraw);
  737. SetRangeMax(nMax, bRedraw);
  738. }
  739. void CSliderCtrl::GetSelection(int& nMin, int& nMax) const
  740. {
  741. ASSERT(::IsWindow(m_hWnd));
  742. nMin = ::SendMessage(m_hWnd, TBM_GETSELSTART, 0, 0L);
  743. nMax = ::SendMessage(m_hWnd, TBM_GETSELEND, 0, 0L);
  744. }
  745. void CSliderCtrl::SetSelection(int nMin, int nMax)
  746. {
  747. ASSERT(::IsWindow(m_hWnd));
  748. ::SendMessage(m_hWnd, TBM_SETSELSTART, 0, (LPARAM)nMin);
  749. ::SendMessage(m_hWnd, TBM_SETSELEND, 0, (LPARAM)nMax);
  750. }
  751. /////////////////////////////////////////////////////////////////////////////
  752. // CProgressCtrl
  753. BOOL CProgressCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  754. UINT nID)
  755. {
  756. // initialize common controls
  757. VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_PROGRESS_REG));
  758. CWnd* pWnd = this;
  759. return pWnd->Create(PROGRESS_CLASS, NULL, dwStyle, rect, pParentWnd, nID);
  760. }
  761. CProgressCtrl::~CProgressCtrl()
  762. {
  763. DestroyWindow();
  764. }
  765. /////////////////////////////////////////////////////////////////////////////
  766. // CHeaderCtrl
  767. BOOL CHeaderCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  768. UINT nID)
  769. {
  770. // initialize common controls
  771. VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_LISTVIEW_REG));
  772. CWnd* pWnd = this;
  773. return pWnd->Create(WC_HEADER, NULL, dwStyle, rect, pParentWnd, nID);
  774. }
  775. CHeaderCtrl::~CHeaderCtrl()
  776. {
  777. DestroyWindow();
  778. }
  779. void CHeaderCtrl::DrawItem(LPDRAWITEMSTRUCT)
  780. {
  781. ASSERT(FALSE); // must override for self draw header controls
  782. }
  783. BOOL CHeaderCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
  784. LRESULT* pResult)
  785. {
  786. if (message != WM_DRAWITEM)
  787. return CWnd::OnChildNotify(message, wParam, lParam, pResult);
  788. ASSERT(pResult == NULL); // no return value expected
  789. UNUSED(pResult); // unused in release builds
  790. DrawItem((LPDRAWITEMSTRUCT)lParam);
  791. return TRUE;
  792. }
  793. /////////////////////////////////////////////////////////////////////////////
  794. // CHotKeyCtrl
  795. BOOL CHotKeyCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  796. UINT nID)
  797. {
  798. // initialize common controls
  799. VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_HOTKEY_REG));
  800. CWnd* pWnd = this;
  801. return pWnd->Create(HOTKEY_CLASS, NULL, dwStyle, rect, pParentWnd, nID);
  802. }
  803. CHotKeyCtrl::~CHotKeyCtrl()
  804. {
  805. DestroyWindow();
  806. }
  807. void CHotKeyCtrl::GetHotKey(WORD &wVirtualKeyCode, WORD &wModifiers) const
  808. {
  809. ASSERT(::IsWindow(m_hWnd));
  810. DWORD dw = ::SendMessage(m_hWnd, HKM_GETHOTKEY, 0, 0L);
  811. wVirtualKeyCode = LOBYTE(LOWORD(dw));
  812. wModifiers = HIBYTE(LOWORD(dw));
  813. }
  814. /////////////////////////////////////////////////////////////////////////////
  815. // CTabCtrl
  816. BEGIN_MESSAGE_MAP(CTabCtrl, CWnd)
  817. //{{AFX_MSG_MAP(CTabCtrl)
  818. ON_WM_DESTROY()
  819. //}}AFX_MSG_MAP
  820. END_MESSAGE_MAP()
  821. BOOL CTabCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  822. UINT nID)
  823. {
  824. // initialize common controls
  825. VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_TAB_REG));
  826. CWnd* pWnd = this;
  827. return pWnd->Create(WC_TABCONTROL, NULL, dwStyle, rect, pParentWnd, nID);
  828. }
  829. CTabCtrl::~CTabCtrl()
  830. {
  831. DestroyWindow();
  832. }
  833. void CTabCtrl::DrawItem(LPDRAWITEMSTRUCT)
  834. {
  835. ASSERT(FALSE); // must override for self draw tab controls
  836. }
  837. BOOL CTabCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
  838. LRESULT* pResult)
  839. {
  840. if (message != WM_DRAWITEM)
  841. return CWnd::OnChildNotify(message, wParam, lParam, pResult);
  842. ASSERT(pResult == NULL); // no return value expected
  843. UNUSED(pResult); // unused in release builds
  844. DrawItem((LPDRAWITEMSTRUCT)lParam);
  845. return TRUE;
  846. }
  847. void CTabCtrl::OnDestroy()
  848. {
  849. HIMAGELIST h = (HIMAGELIST)SendMessage(TCM_GETIMAGELIST);
  850. if (CImageList::FromHandlePermanent(h) != NULL)
  851. SendMessage(TCM_SETIMAGELIST, NULL, NULL);
  852. CWnd::OnDestroy();
  853. }
  854. DWORD CTabCtrl::GetItemState(int nItem, DWORD dwMask) const
  855. {
  856. ASSERT(::IsWindow(m_hWnd));
  857. TCITEM item;
  858. item.mask = TCIF_STATE;
  859. item.dwStateMask = dwMask;
  860. VERIFY(::SendMessage(m_hWnd, TCM_GETITEM, (WPARAM)nItem, (LPARAM)&item));
  861. return item.dwState;
  862. }
  863. BOOL CTabCtrl::SetItemState(int nItem, DWORD dwMask, DWORD dwState)
  864. {
  865. ASSERT(::IsWindow(m_hWnd));
  866. TCITEM item;
  867. item.mask = TCIF_STATE;
  868. item.dwState = dwState;
  869. item.dwStateMask = dwMask;
  870. return (BOOL) ::SendMessage(m_hWnd, TCM_SETITEM,
  871. (WPARAM) nItem, (LPARAM) &item);
  872. }
  873. BOOL CTabCtrl::InsertItem(UINT nMask, int nItem, LPCTSTR lpszItem,
  874. int nImage, LPARAM lParam)
  875. {
  876. ASSERT(::IsWindow(m_hWnd));
  877. TCITEM item;
  878. item.mask = nMask;
  879. item.iImage = nImage;
  880. item.lParam = lParam;
  881. item.pszText = (LPTSTR) lpszItem;
  882. return (BOOL) ::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM) &item);
  883. }
  884. BOOL CTabCtrl::InsertItem(UINT nMask, int nItem, LPCTSTR lpszItem,
  885. int nImage, LPARAM lParam, DWORD dwState, DWORD dwStateMask)
  886. {
  887. ASSERT(::IsWindow(m_hWnd));
  888. TCITEM item;
  889. item.mask = nMask;
  890. item.iImage = nImage;
  891. item.lParam = lParam;
  892. item.pszText = (LPTSTR) lpszItem;
  893. item.dwState = dwState;
  894. item.dwStateMask = dwStateMask;
  895. return (BOOL) ::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM) &item);
  896. }
  897. /////////////////////////////////////////////////////////////////////////////
  898. // CAnimateCtrl
  899. BOOL CAnimateCtrl::Create(DWORD dwStyle, const RECT& rect,
  900. CWnd* pParentWnd, UINT nID)
  901. {
  902. // initialize common controls
  903. VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_ANIMATE_REG));
  904. CWnd* pWnd = this;
  905. return pWnd->Create(ANIMATE_CLASS, NULL, dwStyle, rect, pParentWnd, nID);
  906. }
  907. CAnimateCtrl::~CAnimateCtrl()
  908. {
  909. DestroyWindow();
  910. }
  911. #ifndef _AFX_NO_RICHEDIT_SUPPORT
  912. /////////////////////////////////////////////////////////////////////////////
  913. // CRichEdit
  914. CRichEditCtrl::~CRichEditCtrl()
  915. {
  916. DestroyWindow();
  917. }
  918. #endif //!_AFX_NO_RICHEDIT_SUPPORT
  919. /////////////////////////////////////////////////////////////////////////////
  920. // CImageList
  921. #include "fixalloc.h"
  922. class CTempImageList : public CImageList
  923. {
  924. DECLARE_DYNCREATE(CTempImageList)
  925. DECLARE_FIXED_ALLOC(CTempImageList);
  926. };
  927. CHandleMap* PASCAL afxMapHIMAGELIST(BOOL bCreate)
  928. {
  929. AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  930. if (pState->m_pmapHIMAGELIST == NULL && bCreate)
  931. {
  932. BOOL bEnable = AfxEnableMemoryTracking(FALSE);
  933. #ifndef _AFX_PORTABLE
  934. _PNH pnhOldHandler = AfxSetNewHandler(&AfxCriticalNewHandler);
  935. #endif
  936. pState->m_pmapHIMAGELIST = new CHandleMap(RUNTIME_CLASS(CTempImageList),
  937. offsetof(CImageList, m_hImageList));
  938. #ifndef _AFX_PORTABLE
  939. AfxSetNewHandler(pnhOldHandler);
  940. #endif
  941. AfxEnableMemoryTracking(bEnable);
  942. }
  943. return pState->m_pmapHIMAGELIST;
  944. }
  945. CImageList::CImageList()
  946. {
  947. m_hImageList = NULL;
  948. }
  949. CImageList::~CImageList()
  950. {
  951. DeleteImageList();
  952. }
  953. HIMAGELIST CImageList::Detach()
  954. {
  955. HIMAGELIST hImageList = m_hImageList;
  956. if (hImageList != NULL)
  957. {
  958. CHandleMap* pMap = afxMapHIMAGELIST();
  959. if (pMap != NULL)
  960. pMap->RemoveHandle(m_hImageList);
  961. }
  962. m_hImageList = NULL;
  963. return hImageList;
  964. }
  965. BOOL CImageList::DeleteImageList()
  966. {
  967. if (m_hImageList == NULL)
  968. return FALSE;
  969. return ImageList_Destroy(Detach());
  970. }
  971. CImageList* PASCAL CImageList::FromHandle(HIMAGELIST h)
  972. {
  973. CHandleMap* pMap = afxMapHIMAGELIST(TRUE);
  974. ASSERT(pMap != NULL);
  975. CImageList* pImageList = (CImageList*)pMap->FromHandle(h);
  976. ASSERT(pImageList == NULL || pImageList->m_hImageList == h);
  977. return pImageList;
  978. }
  979. CImageList* PASCAL CImageList::FromHandlePermanent(HIMAGELIST h)
  980. {
  981. CHandleMap* pMap = afxMapHIMAGELIST();
  982. CImageList* pImageList = NULL;
  983. if (pMap != NULL)
  984. {
  985. // only look in the permanent map - does no allocations
  986. pImageList = (CImageList*)pMap->LookupPermanent(h);
  987. ASSERT(pImageList == NULL || pImageList->m_hImageList == h);
  988. }
  989. return pImageList;
  990. }
  991. BOOL CImageList::Create(int cx, int cy, UINT nFlags, int nInitial, int nGrow)
  992. {
  993. return Attach(ImageList_Create(cx, cy, nFlags, nInitial, nGrow));
  994. }
  995. BOOL CImageList::Create(UINT nBitmapID, int cx, int nGrow, COLORREF crMask)
  996. {
  997. ASSERT(HIWORD(nBitmapID) == 0);
  998. HINSTANCE hInst = AfxFindResourceHandle((LPCTSTR)nBitmapID, RT_BITMAP);
  999. ASSERT(hInst != NULL);
  1000. return Attach(ImageList_LoadBitmap(hInst,
  1001. (LPCTSTR)nBitmapID, cx, nGrow, crMask));
  1002. }
  1003. BOOL CImageList::Create(LPCTSTR lpszBitmapID, int cx, int nGrow,
  1004. COLORREF crMask)
  1005. {
  1006. HINSTANCE hInst = AfxFindResourceHandle(lpszBitmapID, RT_BITMAP);
  1007. ASSERT(hInst != NULL);
  1008. return Attach(ImageList_LoadBitmap(hInst, lpszBitmapID, cx, nGrow, crMask));
  1009. }
  1010. BOOL CImageList::Create(CImageList& imagelist1, int nImage1,
  1011. CImageList& imagelist2, int nImage2, int dx, int dy)
  1012. {
  1013. return Attach(ImageList_Merge(imagelist1.m_hImageList, nImage1,
  1014. imagelist2.m_hImageList, nImage2, dx, dy));
  1015. }
  1016. BOOL CImageList::Attach(HIMAGELIST hImageList)
  1017. {
  1018. ASSERT(m_hImageList == NULL); // only attach once, detach on destroy
  1019. ASSERT(FromHandlePermanent(hImageList) == NULL);
  1020. if (hImageList == NULL)
  1021. return FALSE;
  1022. CHandleMap* pMap = afxMapHIMAGELIST(TRUE);
  1023. ASSERT(pMap != NULL);
  1024. pMap->SetPermanent(m_hImageList = hImageList, this);
  1025. return TRUE;
  1026. }
  1027. #ifndef _AFX_NO_OLE_SUPPORT
  1028. BOOL CImageList::Read(CArchive* pArchive)
  1029. {
  1030. ASSERT(m_hImageList == NULL);
  1031. ASSERT(pArchive != NULL);
  1032. ASSERT(pArchive->IsLoading());
  1033. CArchiveStream arcstream(pArchive);
  1034. m_hImageList = ImageList_Read(&arcstream);
  1035. return (m_hImageList != NULL);
  1036. }
  1037. BOOL CImageList::Write(CArchive* pArchive)
  1038. {
  1039. ASSERT(m_hImageList != NULL);
  1040. ASSERT(pArchive != NULL);
  1041. ASSERT(pArchive->IsStoring());
  1042. CArchiveStream arcstream(pArchive);
  1043. return ImageList_Write(m_hImageList, &arcstream);
  1044. }
  1045. #endif //_AFX_NO_OLE_SUPPORT
  1046. #ifdef _DEBUG
  1047. void CImageList::Dump(CDumpContext& dc) const
  1048. {
  1049. CObject::Dump(dc);
  1050. dc << "m_hImageList = " << (UINT)m_hImageList;
  1051. dc << "\n";
  1052. }
  1053. void CImageList::AssertValid() const
  1054. {
  1055. CObject::AssertValid();
  1056. if (m_hImageList == NULL)
  1057. return;
  1058. // should also be in the permanent or temporary handle map
  1059. CObject* p;
  1060. CHandleMap* pMap = afxMapHIMAGELIST();
  1061. ASSERT(pMap != NULL);
  1062. ASSERT((p = pMap->LookupPermanent(m_hImageList)) != NULL ||
  1063. (p = pMap->LookupTemporary(m_hImageList)) != NULL);
  1064. ASSERT((CImageList*)p == this); // must be us
  1065. }
  1066. #endif
  1067. /////////////////////////////////////////////////////////////////////////////
  1068. #ifdef AFX_CMNCTL_SEG
  1069. #pragma code_seg(AFX_CMNCTL_SEG)
  1070. #endif
  1071. #ifndef _AFX_ENABLE_INLINES
  1072. static const char _szAfxWinInl[] = "afxcmn.inl";
  1073. #undef THIS_FILE
  1074. #define THIS_FILE _szAfxWinInl
  1075. #define _AFXCMN_INLINE
  1076. #include "afxcmn.inl"
  1077. #endif //_AFX_ENABLE_INLINES
  1078. /////////////////////////////////////////////////////////////////////////////
  1079. #ifdef AFX_INIT_SEG
  1080. #pragma code_seg(AFX_INIT_SEG)
  1081. #endif
  1082. IMPLEMENT_DYNAMIC(CDragListBox, CListBox)
  1083. IMPLEMENT_DYNAMIC(CSpinButtonCtrl, CWnd)
  1084. IMPLEMENT_DYNAMIC(CSliderCtrl, CWnd)
  1085. IMPLEMENT_DYNAMIC(CProgressCtrl, CWnd)
  1086. IMPLEMENT_DYNAMIC(CComboBoxEx, CComboBox)
  1087. IMPLEMENT_DYNAMIC(CHeaderCtrl, CWnd)
  1088. IMPLEMENT_DYNAMIC(CHotKeyCtrl, CWnd)
  1089. IMPLEMENT_DYNAMIC(CAnimateCtrl, CWnd)
  1090. IMPLEMENT_DYNAMIC(CTabCtrl, CWnd)
  1091. IMPLEMENT_DYNAMIC(CTreeCtrl, CWnd)
  1092. IMPLEMENT_DYNAMIC(CListCtrl, CWnd)
  1093. IMPLEMENT_DYNAMIC(CToolBarCtrl, CWnd)
  1094. IMPLEMENT_DYNAMIC(CStatusBarCtrl, CWnd)
  1095. IMPLEMENT_DYNCREATE(CImageList, CObject)
  1096. IMPLEMENT_DYNCREATE(CTempImageList, CImageList);
  1097. #ifndef _AFX_NO_RICHEDIT_SUPPORT
  1098. IMPLEMENT_DYNAMIC(CRichEditCtrl, CWnd)
  1099. #endif
  1100. #pragma warning(disable: 4074)
  1101. #pragma init_seg(compiler)
  1102. IMPLEMENT_FIXED_ALLOC(CTempImageList, 64);
  1103. /////////////////////////////////////////////////////////////////////////////