ppgstock.cpp 6.4 KB

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