home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / ppgstock.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  7KB  |  260 lines

  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.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFXCTL_PAGE_SEG
  14. #pragma code_seg(AFXCTL_PAGE_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. /////////////////////////////////////////////////////////////////////////////
  25. // CStockPropPage implementation
  26.  
  27. BEGIN_MESSAGE_MAP(CStockPropPage, COlePropertyPage)
  28. END_MESSAGE_MAP()
  29.  
  30. void _AfxSizeComboToContent(CComboBox* pCombo)
  31. {
  32.     ASSERT_VALID(pCombo);
  33.     int cyEdit = (int)(pCombo->SendMessage(CB_GETITEMHEIGHT, (WPARAM)-1, 0L));
  34.     int cyItem = (int)(pCombo->SendMessage(CB_GETITEMHEIGHT, (WPARAM)0, 0L));
  35.  
  36.     CRect rcCombo;
  37.     pCombo->GetWindowRect(&rcCombo);
  38.     pCombo->SetWindowPos(NULL, 0, 0, rcCombo.Width(), cyEdit +
  39.         pCombo->GetCount() * cyItem + GetSystemMetrics(SM_CYBORDER) * 8,
  40.         SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
  41. }
  42.  
  43. CStockPropPage::CStockPropPage(UINT idDlg, UINT idCaption) :
  44.     COlePropertyPage(idDlg, idCaption)
  45. {
  46.     m_lcid = 0;
  47. }
  48.  
  49. void CStockPropPage::FillPropnameList(REFGUID guid, int nIndirect, CComboBox& combo)
  50. {
  51.     USES_CONVERSION;
  52.  
  53.     combo.ResetContent();
  54.     UINT cProps = 0;
  55.  
  56.     ULONG nObjects;
  57.     LPDISPATCH* ppDisp = GetObjectArray(&nObjects);
  58.  
  59.     if (ppDisp != NULL)
  60.     {
  61.         LPTYPEINFO pTypeInfo;
  62.         LPTYPEATTR pTypeAttr;
  63.         LPVARDESC pVarDesc;
  64.         ULONG iObj;
  65.         WORD iProp;
  66.         BSTR rgbstr[1];
  67.         UINT cName;
  68.  
  69.         // Get the property sheet locale
  70.         LPPROPERTYPAGESITE pPageSite;
  71.         if ((pPageSite = GetPageSite()) != NULL)
  72.             if (FAILED(pPageSite->GetLocaleID(&m_lcid)))
  73.                 m_lcid = 0;
  74.  
  75.         // Iterate through all objects.
  76.  
  77.         for (iObj = 0; iObj < nObjects; iObj++)
  78.         {
  79.             pTypeInfo = NULL;
  80.             if ((ppDisp[iObj] != NULL) &&
  81.                 SUCCEEDED(ppDisp[iObj]->GetTypeInfo(0, m_lcid, &pTypeInfo)))
  82.             {
  83.                 ASSERT(pTypeInfo != NULL);
  84.                 pTypeAttr = NULL;
  85.                 if (SUCCEEDED(pTypeInfo->GetTypeAttr(&pTypeAttr)))
  86.                 {
  87.                     ASSERT(pTypeAttr != NULL);
  88.  
  89.                     // Iterate through all properties of object.
  90.  
  91.                     for (iProp = 0; iProp < pTypeAttr->cVars; iProp++)
  92.                     {
  93.                         pVarDesc = NULL;
  94.                         if (SUCCEEDED(pTypeInfo->GetVarDesc(iProp, &pVarDesc)))
  95.                         {
  96.                             // Check whether property has desired type
  97.  
  98.                             if (!(pVarDesc->wVarFlags & VARFLAG_FHIDDEN) &&
  99.                                 AfxOleTypeMatchGuid(pTypeInfo,
  100.                                     &pVarDesc->elemdescVar.tdesc, guid,
  101.                                     nIndirect))
  102.                             {
  103.                                 // Get property name and insert into list.
  104.  
  105.                                 if (SUCCEEDED(pTypeInfo->GetNames(
  106.                                         pVarDesc->memid, rgbstr, 1, &cName)))
  107.                                 {
  108.                                     // Don't insert duplicates.
  109.  
  110.                                     LPCTSTR lpstr = OLE2CT(rgbstr[0]);
  111.                                     if (combo.FindString(-1, lpstr)
  112.                                             == CB_ERR)
  113.                                     {
  114.                                         int iItem = combo.AddString(lpstr);
  115.                                         if (iItem >= 0)
  116.                                         {
  117.                                             combo.SetItemData(iItem, (DWORD)pVarDesc->memid);
  118.                                             ++cProps;
  119.                                         }
  120.                                     }
  121.  
  122.                                     SysFreeString(rgbstr[0]);
  123.                                 }
  124.                             }
  125.                             pTypeInfo->ReleaseVarDesc(pVarDesc);
  126.                         }
  127.                     }
  128.  
  129.                     pTypeInfo->ReleaseTypeAttr(pTypeAttr);
  130.                 }
  131.                 pTypeInfo->Release();
  132.             }
  133.         }
  134.     }
  135.  
  136.     // Select the first one
  137.     m_iPropName = 0;            // Prevents save from happening
  138.     if (combo.SetCurSel(0) != CB_ERR)
  139.         combo.GetLBText(0, m_strPropName);
  140.  
  141.     // Disable or set the size of the combo, as appropriate
  142.     if (cProps <= 1)
  143.         combo.EnableWindow(FALSE);
  144.     else
  145.         _AfxSizeComboToContent(&combo);
  146.  
  147.     UpdateData(FALSE);
  148.     SetModifiedFlag(FALSE);
  149. }
  150.  
  151. void CStockPropPage::OnSelchangePropname(CComboBox& combo)
  152. {
  153.     int iPropNameNew = combo.GetCurSel();
  154.  
  155.     if (iPropNameNew != m_iPropName)
  156.     {
  157.         UpdateData(TRUE);
  158.  
  159.         if (iPropNameNew != CB_ERR)
  160.             combo.GetLBText(iPropNameNew, m_strPropName);
  161.         else
  162.             m_strPropName = _T("");
  163.  
  164.         m_iPropName = iPropNameNew;
  165.         UpdateData(FALSE);
  166.         SetModifiedFlag(FALSE);
  167.     }
  168. }
  169.  
  170. BOOL CStockPropPage::OnEditProperty(DISPID dispid, CComboBox& combo)
  171. {
  172.     int cItems = combo.GetCount();
  173.     int i;
  174.  
  175.     for (i = 0; i < cItems; i++)
  176.     {
  177.         if ((DISPID)(combo.GetItemData(i)) == dispid)
  178.         {
  179.             combo.SetCurSel(i);
  180.             OnSelchangePropname(combo);
  181.             return TRUE;
  182.         }
  183.     }
  184.  
  185.     return FALSE;
  186. }
  187.  
  188. /////////////////////////////////////////////////////////////////////////////
  189. // AfxOleTypeMatchGuid:  Tests whether a given TYPEDESC matches a type with a
  190. // given GUID, when all aliases have been expanded.
  191.  
  192. BOOL AFXAPI AfxOleTypeMatchGuid(
  193.         LPTYPEINFO pTypeInfo,
  194.         TYPEDESC* pTypeDesc,
  195.         REFGUID guidType,
  196.         ULONG cIndirectionLevels)
  197. {
  198.     ASSERT(pTypeInfo != NULL);
  199.     ASSERT(pTypeDesc != NULL);
  200.     ASSERT(cIndirectionLevels >= 0);
  201.  
  202.     LPTYPEINFO pTypeInfoRef = NULL;
  203.  
  204.     BOOL bMatch = FALSE;
  205.  
  206.     switch (pTypeDesc->vt)
  207.     {
  208.     case VT_USERDEFINED:
  209.         // It's an alias: Expand the alias and try to match.
  210.         if (SUCCEEDED(pTypeInfo->GetRefTypeInfo(
  211.                                     pTypeDesc->hreftype,
  212.                                     &pTypeInfoRef)))
  213.         {
  214.             ASSERT(pTypeInfoRef != NULL);
  215.             LPTYPEATTR pTypeAttr = NULL;
  216.             if (SUCCEEDED(pTypeInfoRef->GetTypeAttr(&pTypeAttr)))
  217.             {
  218.                 ASSERT(pTypeAttr != NULL);
  219.  
  220.                 // If we've dereferenced the correct number of times,
  221.                 // test the GUIDs for equality.
  222.                 if (cIndirectionLevels == 0)
  223.                     bMatch = IsEqualGUID(pTypeAttr->guid, guidType);
  224.  
  225.                 if (!bMatch && pTypeAttr->typekind == TKIND_ALIAS)
  226.                 {
  227.                     // GUIDs didn't match, but type expanded to another alias!
  228.                     bMatch = AfxOleTypeMatchGuid(pTypeInfoRef,
  229.                                     &pTypeAttr->tdescAlias, guidType,
  230.                                     cIndirectionLevels);
  231.                 }
  232.  
  233.                 pTypeInfoRef->ReleaseTypeAttr(pTypeAttr);
  234.             }
  235.  
  236.             pTypeInfoRef->Release();
  237.         }
  238.         break;
  239.  
  240.     case VT_PTR:
  241.         // It's a pointer: Dereference and try to match with one less level
  242.         // of indirection.
  243.         ASSERT(pTypeDesc->lptdesc != NULL);
  244.         bMatch = AfxOleTypeMatchGuid(pTypeInfo, pTypeDesc->lptdesc, guidType,
  245.                         cIndirectionLevels - 1);
  246.         break;
  247.     }
  248.  
  249.     return bMatch;
  250. }
  251.  
  252. /////////////////////////////////////////////////////////////////////////////
  253. // Force any extra compiler-generated code into AFX_INIT_SEG
  254.  
  255. #ifdef AFX_INIT_SEG
  256. #pragma code_seg(AFX_INIT_SEG)
  257. #endif
  258.  
  259. IMPLEMENT_DYNAMIC(CStockPropPage, COlePropertyPage)
  260.