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 >
Wrap
C/C++ Source or Header
|
1998-06-16
|
7KB
|
260 lines
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#ifdef AFXCTL_PAGE_SEG
#pragma code_seg(AFXCTL_PAGE_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
/////////////////////////////////////////////////////////////////////////////
// CStockPropPage implementation
BEGIN_MESSAGE_MAP(CStockPropPage, COlePropertyPage)
END_MESSAGE_MAP()
void _AfxSizeComboToContent(CComboBox* pCombo)
{
ASSERT_VALID(pCombo);
int cyEdit = (int)(pCombo->SendMessage(CB_GETITEMHEIGHT, (WPARAM)-1, 0L));
int cyItem = (int)(pCombo->SendMessage(CB_GETITEMHEIGHT, (WPARAM)0, 0L));
CRect rcCombo;
pCombo->GetWindowRect(&rcCombo);
pCombo->SetWindowPos(NULL, 0, 0, rcCombo.Width(), cyEdit +
pCombo->GetCount() * cyItem + GetSystemMetrics(SM_CYBORDER) * 8,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
}
CStockPropPage::CStockPropPage(UINT idDlg, UINT idCaption) :
COlePropertyPage(idDlg, idCaption)
{
m_lcid = 0;
}
void CStockPropPage::FillPropnameList(REFGUID guid, int nIndirect, CComboBox& combo)
{
USES_CONVERSION;
combo.ResetContent();
UINT cProps = 0;
ULONG nObjects;
LPDISPATCH* ppDisp = GetObjectArray(&nObjects);
if (ppDisp != NULL)
{
LPTYPEINFO pTypeInfo;
LPTYPEATTR pTypeAttr;
LPVARDESC pVarDesc;
ULONG iObj;
WORD iProp;
BSTR rgbstr[1];
UINT cName;
// Get the property sheet locale
LPPROPERTYPAGESITE pPageSite;
if ((pPageSite = GetPageSite()) != NULL)
if (FAILED(pPageSite->GetLocaleID(&m_lcid)))
m_lcid = 0;
// Iterate through all objects.
for (iObj = 0; iObj < nObjects; iObj++)
{
pTypeInfo = NULL;
if ((ppDisp[iObj] != NULL) &&
SUCCEEDED(ppDisp[iObj]->GetTypeInfo(0, m_lcid, &pTypeInfo)))
{
ASSERT(pTypeInfo != NULL);
pTypeAttr = NULL;
if (SUCCEEDED(pTypeInfo->GetTypeAttr(&pTypeAttr)))
{
ASSERT(pTypeAttr != NULL);
// Iterate through all properties of object.
for (iProp = 0; iProp < pTypeAttr->cVars; iProp++)
{
pVarDesc = NULL;
if (SUCCEEDED(pTypeInfo->GetVarDesc(iProp, &pVarDesc)))
{
// Check whether property has desired type
if (!(pVarDesc->wVarFlags & VARFLAG_FHIDDEN) &&
AfxOleTypeMatchGuid(pTypeInfo,
&pVarDesc->elemdescVar.tdesc, guid,
nIndirect))
{
// Get property name and insert into list.
if (SUCCEEDED(pTypeInfo->GetNames(
pVarDesc->memid, rgbstr, 1, &cName)))
{
// Don't insert duplicates.
LPCTSTR lpstr = OLE2CT(rgbstr[0]);
if (combo.FindString(-1, lpstr)
== CB_ERR)
{
int iItem = combo.AddString(lpstr);
if (iItem >= 0)
{
combo.SetItemData(iItem, (DWORD)pVarDesc->memid);
++cProps;
}
}
SysFreeString(rgbstr[0]);
}
}
pTypeInfo->ReleaseVarDesc(pVarDesc);
}
}
pTypeInfo->ReleaseTypeAttr(pTypeAttr);
}
pTypeInfo->Release();
}
}
}
// Select the first one
m_iPropName = 0; // Prevents save from happening
if (combo.SetCurSel(0) != CB_ERR)
combo.GetLBText(0, m_strPropName);
// Disable or set the size of the combo, as appropriate
if (cProps <= 1)
combo.EnableWindow(FALSE);
else
_AfxSizeComboToContent(&combo);
UpdateData(FALSE);
SetModifiedFlag(FALSE);
}
void CStockPropPage::OnSelchangePropname(CComboBox& combo)
{
int iPropNameNew = combo.GetCurSel();
if (iPropNameNew != m_iPropName)
{
UpdateData(TRUE);
if (iPropNameNew != CB_ERR)
combo.GetLBText(iPropNameNew, m_strPropName);
else
m_strPropName = _T("");
m_iPropName = iPropNameNew;
UpdateData(FALSE);
SetModifiedFlag(FALSE);
}
}
BOOL CStockPropPage::OnEditProperty(DISPID dispid, CComboBox& combo)
{
int cItems = combo.GetCount();
int i;
for (i = 0; i < cItems; i++)
{
if ((DISPID)(combo.GetItemData(i)) == dispid)
{
combo.SetCurSel(i);
OnSelchangePropname(combo);
return TRUE;
}
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// AfxOleTypeMatchGuid: Tests whether a given TYPEDESC matches a type with a
// given GUID, when all aliases have been expanded.
BOOL AFXAPI AfxOleTypeMatchGuid(
LPTYPEINFO pTypeInfo,
TYPEDESC* pTypeDesc,
REFGUID guidType,
ULONG cIndirectionLevels)
{
ASSERT(pTypeInfo != NULL);
ASSERT(pTypeDesc != NULL);
ASSERT(cIndirectionLevels >= 0);
LPTYPEINFO pTypeInfoRef = NULL;
BOOL bMatch = FALSE;
switch (pTypeDesc->vt)
{
case VT_USERDEFINED:
// It's an alias: Expand the alias and try to match.
if (SUCCEEDED(pTypeInfo->GetRefTypeInfo(
pTypeDesc->hreftype,
&pTypeInfoRef)))
{
ASSERT(pTypeInfoRef != NULL);
LPTYPEATTR pTypeAttr = NULL;
if (SUCCEEDED(pTypeInfoRef->GetTypeAttr(&pTypeAttr)))
{
ASSERT(pTypeAttr != NULL);
// If we've dereferenced the correct number of times,
// test the GUIDs for equality.
if (cIndirectionLevels == 0)
bMatch = IsEqualGUID(pTypeAttr->guid, guidType);
if (!bMatch && pTypeAttr->typekind == TKIND_ALIAS)
{
// GUIDs didn't match, but type expanded to another alias!
bMatch = AfxOleTypeMatchGuid(pTypeInfoRef,
&pTypeAttr->tdescAlias, guidType,
cIndirectionLevels);
}
pTypeInfoRef->ReleaseTypeAttr(pTypeAttr);
}
pTypeInfoRef->Release();
}
break;
case VT_PTR:
// It's a pointer: Dereference and try to match with one less level
// of indirection.
ASSERT(pTypeDesc->lptdesc != NULL);
bMatch = AfxOleTypeMatchGuid(pTypeInfo, pTypeDesc->lptdesc, guidType,
cIndirectionLevels - 1);
break;
}
return bMatch;
}
/////////////////////////////////////////////////////////////////////////////
// Force any extra compiler-generated code into AFX_INIT_SEG
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
IMPLEMENT_DYNAMIC(CStockPropPage, COlePropertyPage)