home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / WINCTRL2.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-30  |  28.0 KB  |  1,142 lines

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