Enumerar locais
Importante
No Visual Studio 2015, essa maneira de implementar avaliadores de expressão foi preterida. Para obter informações sobre como implementar avaliadores de expressão CLR, consulte Avaliadores de expressão CLR e Exemplo de avaliador de expressão gerenciada.
Quando o Visual Studio está pronto para preencher a janela Locals , ele chama EnumChildren no objeto IDebugProperty2 retornado de GetMethodProperty (consulte Implementando GetMethodProperty). IDebugProperty2::EnumChildren
retorna um objeto IEnumDebugPropertyInfo2 .
A implementação IDebugProperty2::EnumChildren
executa as seguintes tarefas:
Garante que isso esteja representando um método.
Usa o
guidFilter
argumento para determinar qual método chamar no objeto IDebugMethodField . SeguidFilter
for igual:guidFilterLocals
, chame EnumLocals para obter um objeto IEnumDebugFields .guidFilterArgs
, chame EnumArguments para obter umIEnumDebugFields
objeto.guidFilterLocalsPlusArgs
, sintetizam uma enumeração que combina os resultados deIDebugMethodField::EnumLocals
eIDebugMethodField::EnumArguments
. Essa síntese é representada pela classeCEnumMethodField
.
Instancia uma classe (chamada
CEnumPropertyInfo
neste exemplo) que implementa aIEnumDebugPropertyInfo2
interface e contém oIEnumDebugFields
objeto.Retorna a
IEnumDebugProperty2Info2
interface doCEnumPropertyInfo
objeto.
Código gerenciado
Este exemplo mostra uma implementação de IDebugProperty2::EnumChildren
no código gerenciado.
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;
}
}
}
Código não gerenciado
Este exemplo mostra uma implementação de IDebugProperty2::EnumChildren
em código não gerenciado.
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;
}