home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / mfcbind / objview.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  9.7 KB  |  351 lines

  1. // ObjView.cpp : implementation file
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "stdafx.h"
  14. #include "MFCBind.h"
  15.  
  16. #include "mainfrm.h"
  17. #include "cntritem.h"
  18. #include "BindDoc.h"
  19. #include "BindView.h"
  20. #include "ObjView.h"
  21.  
  22. #ifdef _DEBUG
  23. #define new DEBUG_NEW
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27.  
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CObjListView
  30.  
  31. IMPLEMENT_DYNCREATE(CObjListView, CView)
  32.  
  33. #pragma warning(disable: 4355)  // 'this' : used in base member initializer list
  34. CObjListView::CObjListView()
  35.     : m_listbox(this), m_bFont(FALSE)
  36. {
  37. }
  38. #pragma warning(default: 4355)
  39.  
  40. CObjListView::~CObjListView()
  41. {
  42.     // if we used a stock font, don't delete it
  43.     if (!m_bFont)
  44.         m_IconFont.Detach();
  45. }
  46.  
  47.  
  48. BEGIN_MESSAGE_MAP(CObjListView, CView)
  49.     //{{AFX_MSG_MAP(CObjListView)
  50.     ON_WM_CREATE()
  51.     ON_WM_SIZE()
  52.     ON_WM_DESTROY()
  53.     //}}AFX_MSG_MAP
  54. END_MESSAGE_MAP()
  55.  
  56. /////////////////////////////////////////////////////////////////////////////
  57. // CObjListView drawing
  58.  
  59. void CObjListView::OnDraw(CDC* pDC)
  60. {
  61. }
  62.  
  63. /////////////////////////////////////////////////////////////////////////////
  64. // CObjListView diagnostics
  65.  
  66. #ifdef _DEBUG
  67. void CObjListView::AssertValid() const
  68. {
  69.     CView::AssertValid();
  70. }
  71.  
  72. void CObjListView::Dump(CDumpContext& dc) const
  73. {
  74.     CView::Dump(dc);
  75. }
  76. #endif //_DEBUG
  77.  
  78. /////////////////////////////////////////////////////////////////////////////
  79. // CObjListView message handlers
  80.  
  81. int CObjListView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  82. {
  83.     // Creates the view and creates the listbox that takes up
  84.     // the view's client area.
  85.     if (CView::OnCreate(lpCreateStruct) == -1)
  86.         return -1;
  87.  
  88.     // create a font to draw icon text with.
  89.     LOGFONT lf;
  90.     m_bFont = SystemParametersInfo(SPI_GETICONTITLELOGFONT,
  91.         sizeof(lf), &lf, FALSE);
  92.  
  93.     if (m_bFont)
  94.         m_bFont = m_IconFont.CreateFontIndirect(&lf);
  95.     if (!m_bFont)
  96.         m_IconFont.Attach(GetStockObject(ANSI_VAR_FONT));
  97.  
  98.     // create the listbox to fill our client area.
  99.     CRect rc;
  100.     GetClientRect(&rc);
  101.     if (!m_listbox.Create(WS_CHILD | WS_VISIBLE | WS_VSCROLL | LBS_NOTIFY |
  102.             LBS_HASSTRINGS | LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT,
  103.                 rc, this, ID_LISTBOX))
  104.     {
  105.         return -1;
  106.     }
  107.  
  108.     return 0;
  109. }
  110.  
  111. BOOL CObjListView::AddItem(COleClientItem *pObject, CString& name,
  112.     HICON hIcon)
  113. {
  114.     // Creates a CItemIcons data structure to hold item data and
  115.     // adds the item to the list box.
  116.  
  117.     CItemIcons *pitem = new CItemIcons;
  118.     pitem->m_Name = name;
  119.     pitem->m_hIcon = hIcon;
  120.     pitem->m_pObject = pObject;
  121.  
  122.     int itemID = m_listbox.AddString(name);
  123.     if (itemID != LB_ERR)
  124.         m_listbox.SetItemData(itemID, (DWORD) pitem);
  125.     m_listbox.SetCurSel(itemID);
  126.     return TRUE;
  127. }
  128.  
  129. BOOL CObjListView::RemoveItem(COleClientItem *pRemove)
  130. {
  131.     // Removes an item from the list box and sets focus to the previous
  132.     // item in the list, if there is one.
  133.     CItemIcons *pitem = NULL;
  134.     CMainFrame *pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
  135.  
  136.     // We'll have to walk our list control and find the item to remove;
  137.     int nItem;
  138.     for (nItem = 0; nItem < m_listbox.GetCount(); nItem++)
  139.     {
  140.         pitem = (CItemIcons*) m_listbox.GetItemData(nItem);
  141.         if (pitem && pitem->m_pObject == pRemove)
  142.         {
  143.             m_listbox.DeleteString(nItem);//delete item from listbox
  144.             delete pitem; //free up the item
  145.         }
  146.     }
  147.  
  148.     if (m_listbox.GetCount() == 0) //no items left
  149.         return TRUE;
  150.  
  151.     // set the previous item in the listbox as the current item
  152.  
  153.     pitem = (CItemIcons*) m_listbox.GetItemData( m_listbox.GetCount() - 1);
  154.     if (pitem != NULL)
  155.     {
  156.         ASSERT(pitem->m_pObject != NULL);
  157.         pitem->m_pObject->Activate(OLEIVERB_SHOW, pFrame->GetDocView());
  158.         pitem->m_pObject->GetInPlaceWindow()->SetFocus();
  159.  
  160.         pFrame->GetDocView()->m_pSelection = (CMFCBindCntrItem*) pitem->m_pObject;
  161.     }
  162.  
  163.     m_listbox.SetCurSel(m_listbox.GetCount() - 1);
  164.     return TRUE;
  165. }
  166.  
  167. void CObjListView::RemoveAllItems()
  168. {
  169.     //Clears the listbox.  This also has the efect of deleting all of the CItemIcons from
  170.     //the listbox.
  171.  
  172.     CItemIcons *pItem=0;
  173.     int nItems = m_listbox.GetCount();
  174.     for(int i=0;i<nItems;i++)
  175.     {
  176.         pItem = (CItemIcons*)m_listbox.GetItemData(i);
  177.         if (pItem)
  178.             delete pItem;
  179.     }
  180.     m_listbox.ResetContent();
  181.  
  182. }
  183.  
  184. void CObjListView::OnDestroy()
  185. {
  186.     // When we destroy the view, we need to make sure we loop
  187.     // through all the items in the listbox and delete the CItemIcon structs
  188.     // associated with each item in the listbox.
  189.  
  190.     CView::OnDestroy();
  191.  
  192.     // We can safely assume that all child windows still exist
  193.     // so, we can go through each item in the list box and delete
  194.     // the CItemIcons objects stored in item data.
  195.  
  196.     int nItem;
  197.     for (nItem = 0; nItem < m_listbox.GetCount(); nItem++)
  198.     {
  199.         CItemIcons *pitem = (CItemIcons*) m_listbox.GetItemData(nItem);
  200.         if (DWORD(pitem) != LB_ERR)
  201.             delete pitem;
  202.     }
  203. }
  204.  
  205. void CObjListView::OnSize(UINT nType, int cx, int cy)
  206. {
  207.     // re-sizes the listbox in the client area when the view gets resized.
  208.     CView::OnSize(nType, cx, cy);
  209.     m_listbox.SetWindowPos(this, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER);
  210.  
  211. }
  212.  
  213. /////////////////////////////////////////////////////////////////////////////
  214. // CCustomList
  215.  
  216. CCustomList::CCustomList()
  217. {
  218. }
  219.  
  220. CCustomList::~CCustomList()
  221. {
  222. }
  223.  
  224.  
  225. BEGIN_MESSAGE_MAP(CCustomList, CListBox)
  226.     //{{AFX_MSG_MAP(CCustomList)
  227.     ON_CONTROL_REFLECT(LBN_SELCHANGE, OnSelchange)
  228.     //}}AFX_MSG_MAP
  229. END_MESSAGE_MAP()
  230.  
  231. /////////////////////////////////////////////////////////////////////////////
  232. // CCustomList message handlers
  233.  
  234. void CCustomList::OnSelchange()
  235. {
  236.     // This function will be called when someone clicks on an item in
  237.     // the listbox. Each item's item data holds a pointer to a CItemIcons
  238.     // structure, which holds pointers to the COleDocObjectItem for the embedded
  239.     // item, pointers to the item's icon's metafile struct and a CString that
  240.     // holds the name of the item.  When someone picks a new item from the list,
  241.     // we should get the item data to get at the CItemIcon struct, check to see
  242.     // if the item clicked on is the same item that is currently activated,
  243.     // and, if it isn't, deactivate the currently activated item and
  244.     // activate the newly selected item.
  245.  
  246.     // Get a pointer to the view and document that is holding our objects
  247.     CMainFrame *pMainFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;
  248.     ASSERT(pMainFrame != NULL);
  249.  
  250.     COleDocument *pDocument = (COleDocument*) pMainFrame->GetActiveDocument();
  251.     ASSERT(pDocument != NULL);
  252.  
  253.     CView *pObjView = (CView*) pMainFrame->GetDocView();
  254.  
  255.     // get the item data
  256.     int nItem = GetCurSel();
  257.     CItemIcons* pdata = (CItemIcons*) GetItemData(nItem);
  258.     if (DWORD(pdata) == LB_ERR)
  259.         return;
  260.  
  261.     COleClientItem *pActiveItem = pDocument->GetInPlaceActiveItem(pObjView);
  262.  
  263.     // check to see if we're already active
  264.     if (pActiveItem == pdata->m_pObject)
  265.     {
  266.         pActiveItem->GetInPlaceWindow()->SetFocus();
  267.         pMainFrame->GetDocView()->m_pSelection = (CMFCBindCntrItem*) pActiveItem;
  268.         return; // already active, no work to do
  269.     }
  270.     else if (pActiveItem != NULL)
  271.         pActiveItem->Deactivate(); // deactivate the already active item
  272.  
  273.     // activate the newly selected item
  274.     pActiveItem = pdata->m_pObject;
  275.     pActiveItem->Activate(OLEIVERB_SHOW, pObjView);
  276.     CWnd *pWndEdit = pActiveItem->GetInPlaceWindow();
  277.     if (pWndEdit != NULL)
  278.         pWndEdit->SetFocus();
  279.     pMainFrame->GetDocView()->m_pSelection = (CMFCBindCntrItem*) pActiveItem;
  280. }
  281.  
  282. void CCustomList::MeasureItem(LPMEASUREITEMSTRUCT lpm)
  283. {
  284.     //specify how high each listbox item will be.
  285.     lpm->itemHeight = GetSystemMetrics(SM_CYICONSPACING);
  286. }
  287.  
  288. void CCustomList::DrawItem(LPDRAWITEMSTRUCT ldis)
  289. {
  290.     ASSERT(ldis != NULL);
  291.  
  292.     // drawing code for each item. We fill the entire rectangle
  293.     // depending on whether or not we are drawing a selected item then
  294.     // we draw the icon and the title held in the CItemIcons struct.
  295.     COLORREF oldTextColor=0;
  296.     COLORREF oldBkColor=0;
  297.     CRect rc(ldis->rcItem);
  298.     int cxIcon = GetSystemMetrics(SM_CXICON);
  299.     int cyIcon = GetSystemMetrics(SM_CYICON);
  300.  
  301.     CDC dc;
  302.     dc.Attach(ldis->hDC);
  303.  
  304.     // we stored a pointer to our CItemIcons struct in item data
  305.  
  306.     CItemIcons *pItem = (CItemIcons*) GetItemData(ldis->itemID);
  307.     CFont *pOldFont = dc.SelectObject(&m_pParent->m_IconFont);
  308.     CRect rcText;
  309.  
  310.     switch(ldis->itemAction)
  311.     {
  312.         case ODA_SELECT:
  313.         case ODA_DRAWENTIRE:
  314.             ASSERT(pItem->m_hIcon != NULL);
  315.             // draw the background with system-wide color preference
  316.             if (ldis->itemState & ODS_SELECTED)
  317.             {
  318.                 dc.FillSolidRect(rc, ::GetSysColor(COLOR_HIGHLIGHT));
  319.                 oldTextColor = dc.SetTextColor(::GetSysColor(COLOR_WINDOW) );
  320.                 oldBkColor = dc.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT) );
  321.             }
  322.             else
  323.                 dc.FillSolidRect(rc, ::GetSysColor(COLOR_WINDOW));
  324.  
  325.             // Draw the icon
  326.             dc.DrawIcon((rc.Width() / 2) - (cxIcon / 2), rc.top + 5,
  327.                 pItem->m_hIcon);
  328.  
  329.             // calculate a rect to place the text centered below
  330.             // the icon then draw the text
  331.             rcText.SetRect(rc.left, rc.top + cyIcon + 4, rc.right, rc.bottom);
  332.             dc.DrawText(pItem->m_Name, rcText, DT_CENTER | DT_TOP);
  333.             if (ldis->itemState & ODS_SELECTED)
  334.             {
  335.                 //we changed the text color in this case
  336.                 //so (being good GDI programmers) now we must change it back.
  337.                 dc.SetTextColor(oldTextColor);
  338.                 dc.SetBkColor(oldBkColor);
  339.             }
  340.  
  341.             break;
  342.  
  343.         case ODA_FOCUS:
  344.             break;
  345.     }
  346.  
  347.     // restore the DC
  348.     dc.SelectObject(pOldFont);
  349.     dc.Detach();
  350. }
  351.