Énumérer des variables locales
Lorsque Visual Studio est prêt à remplir la fenêtre de Variables locales , il appelle IDebugProperty2 : : EnumChildren sur l'objet d' IDebugProperty2 retourné d' IDebugExpressionEvaluator : : GetMethodProperty (voir l' implémenter GetMethodProperty). IDebugProperty2::EnumChildren retourne un objet d' IEnumDebugPropertyInfo2 .
cette implémentation d' IDebugProperty2::EnumChildren effectue les tâches suivantes :
Garantit cela représente une méthode.
Utilise l'argument d' guidFilter pour déterminer quelle méthode à appeler sur l'objet d' IDebugMethodField . si guidFilter égale :
guidFilterLocals, appelez IDebugMethodField : : EnumLocals pour obtenir un objet d' IEnumDebugFields .
guidFilterArgs, appelez IDebugMethodField : : EnumArguments pour obtenir un objet d' IEnumDebugFields .
guidFilterLocalsPlusArgs, synthétisent énumération qui combine les résultats d' IDebugMethodField::EnumLocals et d' IDebugMethodField::EnumArguments. cette synthèse est représentée par la classe CEnumMethodField.
Instancie une classe ( CEnumPropertyInfo appelé par exemple) qui implémente l'interface d' IEnumDebugPropertyInfo2 et contient l'objet d' IEnumDebugFields .
Retourne l'interface d' IEnumDebugProperty2Info2 de l'objet d' CEnumPropertyInfo .
Code managé
cet exemple montre une implémentation d' IDebugProperty2::EnumChildren en code managé.
namespace EEMC
{
public class CFieldProperty : IDebugProperty2
{
public HRESULT EnumChildren (
uint dwFields,
uint radix,
ref Guid guidFilter,
ulong attribFilter,
string nameFilter,
uint timeout,
out IEnumDebugPropertyInfo2 properties)
{
properties = null;
IEnumDebugFields fields = null;
// If this field is a method...
if (0 != ((uint) fieldKind & (uint) FIELD_KIND.FIELD_TYPE_METHOD))
{
IDebugMethodField methodField = (IDebugMethodField) field;
// Enumerate parameters.
if (guidFilter == FilterGuids.guidFilterArgs)
{
methodField.EnumParameters(out fields);
}
// Enumerate local variables.
else if (guidFilter == FilterGuids.guidFilterLocals)
{
methodField.EnumLocals(address, out fields);
}
// Enumerate all local variables, including invisible compiler temps.
else if (guidFilter == FilterGuids.guidFilterAllLocals)
{
methodField.EnumAllLocals(address, out fields);
}
// Enumerate "this", if any, and all parameters and local variables.
else if (guidFilter == FilterGuids.guidFilterLocalsPlusArgs)
{
IDebugClassField fieldThis = null;
IEnumDebugFields parameters = null;
IEnumDebugFields locals = null;
methodField.GetThis(out fieldThis);
methodField.EnumParameters(out parameters);
methodField.EnumLocals(address, out locals);
CEnumMethodField enumMethodField =
new CEnumMethodField(fieldThis, parameters, locals);
fields = (IEnumDebugFields) enumMethodField;
}
// Enumerate only "this".
else if (guidFilter == FilterGuids.guidFilterThis)
{
IDebugClassField fieldThis = null;
methodField.GetThis(out fieldThis);
CEnumMethodField enumMethodField =
new CEnumMethodField(fieldThis, null, null);
fields = (IEnumDebugFields) enumMethodField;
}
else throw new COMException();// E_FAIL
}
// Wrap a property enumerator around the field enumerator.
CEnumPropertyInfo propertiesInfo =
new CEnumPropertyInfo(provider, address, binder, radix, fields,
(DEBUGPROP_INFO_FLAGS) dwFields);
properties = (IEnumDebugPropertyInfo2) propertiesInfo;
return COM.S_OK;
}
}
}
Le code non managé
Cet exemple montre une implémentation d' IDebugProperty2::EnumChildren dans du code non managé.
STDMETHODIMP CFieldProperty::EnumChildren(
in DEBUGPROP_INFO_FLAGS infoFlags,
in DWORD radix,
in REFGUID guidFilter,
in DBG_ATTRIB_FLAGS attribFilter,
in LPCOLESTR pszNameFilter,
in DWORD timeout,
out IEnumDebugPropertyInfo2 ** ppchildren )
{
if (ppchildren == NULL)
return E_INVALIDARG;
else
*ppchildren = 0;
//get enumeration
HRESULT hr;
IEnumDebugFields* pfields = NULL;
if (m_fieldKind & FIELD_TYPE_METHOD)
{
//-----------------------------------------------------
// A Method
IDebugMethodField* pmethod = NULL;
//enumerate the requested properties
hr = m_field->QueryInterface( IID_IDebugMethodField,
reinterpret_cast<void**>(&pmethod) );
if (FAILED(hr))
return hr;
if (guidFilter == guidFilterArgs)
{
hr = pmethod->EnumParameters( &pfields );
}
else if (guidFilter == guidFilterLocals)
{
hr = pmethod->EnumLocals( m_address, &pfields );
}
else if (guidFilter == guidFilterAllLocals)
{
hr = pmethod->EnumAllLocals( m_address, &pfields );
}
else if (guidFilter == guidFilterLocalsPlusArgs)
{
//we create a special enumerator for this
IDebugClassField* pfieldThis = NULL;
IEnumDebugFields* pparameters = NULL;
IEnumDebugFields* plocals = NULL;
pmethod->GetThis( &pfieldThis );
pmethod->EnumParameters( &pparameters );
pmethod->EnumLocals( m_address, &plocals );
CEnumMethodField* penumMethodField =
new CEnumMethodField( pfieldThis, pparameters, plocals );
if (pfieldThis != NULL)
pfieldThis->Release();
if (pparameters != NULL)
pparameters->Release();
if (plocals != NULL)
plocals->Release();
if (!penumMethodField)
{
hr = E_OUTOFMEMORY;
}
else
{
hr = penumMethodField->QueryInterface( IID_IEnumDebugFields,
reinterpret_cast<void**>(&pfields) );
penumMethodField->Release();
}
}
else if (guidFilter == guidFilterThis )
{
IDebugClassField* pfieldThis = NULL;
hr = pmethod->GetThis( &pfieldThis );
if (SUCCEEDED(hr))
{
CEnumMethodField* penumMethodField =
new CEnumMethodField( pfieldThis, NULL, NULL );
pfieldThis->Release();
if (!penumMethodField)
{
hr = E_OUTOFMEMORY;
}
else
{
hr = penumMethodField->QueryInterface( IID_IEnumDebugFields,
reinterpret_cast<void**>(&pfields) );
penumMethodField->Release();
}
}
}
else
{
hr = E_FAIL;
}
pmethod->Release();
if (hr != S_OK)
return hr;
}
//create a property info enumeration around the field enumerator
CEnumPropertyInfo* pproperties =
new CEnumPropertyInfo( m_provider, m_address, m_binder,
radix, pfields, infoFlags );
if (pfields != NULL)
pfields->Release();
if (pproperties == NULL)
return E_OUTOFMEMORY;
hr = pproperties->QueryInterface( IID_IEnumDebugPropertyInfo2,
reinterpret_cast<void**>(ppchildren) );
pproperties->Release();
return hr;
}