|
2 | 2 | title: "Getting Local Properties | Microsoft Docs"
|
3 | 3 | ms.date: "11/04/2016"
|
4 | 4 | ms.topic: "conceptual"
|
5 |
| -helpviewer_keywords: |
| 5 | +helpviewer_keywords: |
6 | 6 | - "expression evaluation, getting local properties"
|
7 | 7 | - "debugging [Debugging SDK], local properties"
|
8 | 8 | - "expression evaluation, local properties"
|
9 | 9 | ms.assetid: 6c3a79e8-1ba1-4863-97c3-0216c3d9f092
|
10 | 10 | author: "gregvanl"
|
11 | 11 | ms.author: "gregvanl"
|
12 | 12 | manager: jillfra
|
13 |
| -ms.workload: |
| 13 | +ms.workload: |
14 | 14 | - "vssdk"
|
15 | 15 | ---
|
16 | 16 | # Get local properties
|
17 | 17 | > [!IMPORTANT]
|
18 |
| -> In Visual Studio 2015, this way of implementing expression evaluators is deprecated. For information about implementing CLR expression evaluators, see [CLR expression evaluators](https://github.com/Microsoft/ConcordExtensibilitySamples/wiki/CLR-Expression-Evaluators) and [Managed expression evaluator sample](https://github.com/Microsoft/ConcordExtensibilitySamples/wiki/Managed-Expression-Evaluator-Sample). |
19 |
| - |
20 |
| - Visual Studio calls [EnumChildren](../../extensibility/debugger/reference/idebugproperty2-enumchildren.md) to obtain an [IEnumDebugPropertyInfo2](../../extensibility/debugger/reference/ienumdebugpropertyinfo2.md) object that provides access to all the locals to be displayed in the **Locals** window. Visual Studio then calls [Next](../../extensibility/debugger/reference/ienumdebugpropertyinfo2-next.md) to get the information to be displayed for each local. In this example, the class `CEnumPropertyInfo` implements the `IEnumDebugPropertyInfo2` interface. |
21 |
| - |
22 |
| - This implementation of `IEnumDebugPropertyInfo2::Next` performs the following tasks: |
23 |
| - |
24 |
| -1. Clears the array where the information is to be stored. |
25 |
| - |
26 |
| -2. Calls [Next](../../extensibility/debugger/reference/ienumdebugfields-next.md) for each local, storing the returned [DEBUG_PROPERTY_INFO](../../extensibility/debugger/reference/debug-property-info.md) in the array to be returned. The [IEnumDebugFields](../../extensibility/debugger/reference/ienumdebugfields.md) object was supplied when this `CEnumPropertyInfo` class was instantiated. |
27 |
| - |
28 |
| -## Managed code |
29 |
| - This example shows an implementation of `IEnumDebugPropertyInfo2::EnumChildren` for a method's locals in managed code. |
30 |
| - |
31 |
| -```csharp |
32 |
| -namespace EEMC |
33 |
| -{ |
34 |
| - public class CEnumMethodField : IEnumDebugFields |
35 |
| - { |
36 |
| - public HRESULT Next( |
37 |
| - uint count, |
38 |
| - DEBUG_PROPERTY_INFO[] properties, |
39 |
| - out uint fetched) |
40 |
| - { |
41 |
| - if (count > properties.Length) |
42 |
| - throw new COMException(); |
43 |
| - |
44 |
| - // Zero out the array. |
45 |
| - for (int i= 0; i < count; i++) |
46 |
| - { |
47 |
| - properties[i].bstrFullName = ""; |
48 |
| - properties[i].bstrName = ""; |
49 |
| - properties[i].bstrType = ""; |
50 |
| - properties[i].bstrValue = ""; |
51 |
| - properties[i].dwAttrib = 0; |
52 |
| - properties[i].dwFields = 0; |
53 |
| - properties[i].pProperty = null; |
54 |
| - } |
55 |
| - fetched = 0; |
56 |
| - |
57 |
| - // COM interop. |
58 |
| - HRESULT hr; |
59 |
| - uint innerFetched; |
60 |
| - IDebugField[] field = new IDebugField[1]; |
61 |
| - |
62 |
| - while (fetched < count) |
63 |
| - { |
64 |
| - field[0] = null; |
65 |
| - innerFetched = 0; |
66 |
| - |
67 |
| - // Get next field. |
68 |
| - if (fetched < fieldCount) |
69 |
| - hr = fields.Next(1, field, ref innerFetched); |
70 |
| - // No more fields. |
71 |
| - else return COM.S_FALSE; |
72 |
| - |
73 |
| - if (hr != COM.S_OK || innerFetched != 1 || field[0] == null) |
74 |
| - throw new COMException("CEnumPropertyInfo.Next"); |
75 |
| - |
76 |
| - // Get property from field. |
77 |
| - CFieldProperty fieldProperty = |
78 |
| - new CFieldProperty(provider, address, binder, field[0]); |
79 |
| - |
80 |
| - DEBUG_PROPERTY_INFO[] property = |
81 |
| - new DEBUG_PROPERTY_INFO[1]; |
82 |
| - fieldProperty.GetPropertyInfo((uint) infoFlags, radix, 0, null, 0, property); |
83 |
| - properties[fetched++] = property[0]; |
84 |
| - } |
85 |
| - return COM.S_OK; |
86 |
| - } |
87 |
| - } |
88 |
| -} |
89 |
| -``` |
90 |
| - |
91 |
| -## Unmanaged code |
92 |
| - This example shows an implementation of `IEnumDebugPropertyInfo2::EnumChildren` for a method's locals in unmanaged code. |
93 |
| - |
94 |
| -```cpp |
95 |
| -STDMETHODIMP CEnumPropertyInfo::Next( |
96 |
| - in ULONG count, |
97 |
| - out DEBUG_PROPERTY_INFO* pelements, |
98 |
| - out ULONG* pfetched ) |
99 |
| -{ |
100 |
| - if (pfetched) |
101 |
| - *pfetched = 0; |
102 |
| - if (!pelements) |
103 |
| - return E_INVALIDARG; |
104 |
| - else |
105 |
| - memset( pelements, 0, count * sizeof(DEBUG_PROPERTY_INFO)); |
106 |
| - |
107 |
| - HRESULT hr = S_OK; |
108 |
| - ULONG idx = 0; |
109 |
| - while (idx < count) |
110 |
| - { |
111 |
| - ULONG fetchedFields; |
112 |
| - IDebugField* pfield; |
113 |
| - |
114 |
| - //get the next field |
115 |
| - hr = m_fields->Next( 1, &pfield, &fetchedFields ); |
116 |
| - if (FAILED(hr)) |
117 |
| - return hr; |
118 |
| - if (fetchedFields != 1) |
119 |
| - return E_FAIL; |
120 |
| - idx++; |
121 |
| - |
122 |
| - //create a CFieldProperty to retrieve the DEBUG_PROPERTY_INFO |
123 |
| - CFieldProperty* pproperty = |
124 |
| - new CFieldProperty( m_provider, m_address, m_binder, pfield ); |
125 |
| - pfield->Release(); |
126 |
| - if (!pproperty) |
127 |
| - return E_OUTOFMEMORY; |
128 |
| - |
129 |
| - hr = pproperty->Init(); |
130 |
| - if (FAILED(hr)) |
131 |
| - { |
132 |
| - pproperty->Release(); |
133 |
| - return hr; |
134 |
| - } |
135 |
| - |
136 |
| - hr = pproperty->GetPropertyInfo( m_infoFlags, |
137 |
| - m_radix, |
138 |
| - 0, |
139 |
| - NULL, |
140 |
| - 0, |
141 |
| - pelements + idx - 1); |
142 |
| - pproperty->Release(); |
143 |
| - if (FAILED(hr)) |
144 |
| - return hr; |
145 |
| - } |
146 |
| - |
147 |
| - if (pfetched) |
148 |
| - *pfetched = idx; |
149 |
| - return hr; |
150 |
| -} |
151 |
| -``` |
152 |
| - |
153 |
| -## See also |
154 |
| - [Sample implementation of locals](../../extensibility/debugger/sample-implementation-of-locals.md) |
155 |
| - [Enumerating locals](../../extensibility/debugger/enumerating-locals.md) |
| 18 | +> In Visual Studio 2015, this way of implementing expression evaluators is deprecated. For information about implementing CLR expression evaluators, see [CLR expression evaluators](https://github.com/Microsoft/ConcordExtensibilitySamples/wiki/CLR-Expression-Evaluators) and [Managed expression evaluator sample](https://github.com/Microsoft/ConcordExtensibilitySamples/wiki/Managed-Expression-Evaluator-Sample). |
| 19 | +
|
| 20 | +Visual Studio calls [EnumChildren](../../extensibility/debugger/reference/idebugproperty2-enumchildren.md) to obtain an [IEnumDebugPropertyInfo2](../../extensibility/debugger/reference/ienumdebugpropertyinfo2.md) object that provides access to all the locals to be displayed in the **Locals** window. Visual Studio then calls [Next](../../extensibility/debugger/reference/ienumdebugpropertyinfo2-next.md) to get the information to be displayed for each local. In this example, the class `CEnumPropertyInfo` implements the `IEnumDebugPropertyInfo2` interface. |
| 21 | + |
| 22 | +This implementation of `IEnumDebugPropertyInfo2::Next` performs the following tasks: |
| 23 | + |
| 24 | +1. Clears the array where the information is to be stored. |
| 25 | + |
| 26 | +2. Calls [Next](../../extensibility/debugger/reference/ienumdebugfields-next.md) for each local, storing the returned [DEBUG_PROPERTY_INFO](../../extensibility/debugger/reference/debug-property-info.md) in the array to be returned. The [IEnumDebugFields](../../extensibility/debugger/reference/ienumdebugfields.md) object was supplied when this `CEnumPropertyInfo` class was instantiated. |
| 27 | + |
| 28 | +## Managed code |
| 29 | +This example shows an implementation of `IEnumDebugPropertyInfo2::EnumChildren` for a method's locals in managed code. |
| 30 | + |
| 31 | +```csharp |
| 32 | +namespace EEMC |
| 33 | +{ |
| 34 | + public class CEnumMethodField : IEnumDebugFields |
| 35 | + { |
| 36 | + public HRESULT Next( |
| 37 | + uint count, |
| 38 | + DEBUG_PROPERTY_INFO[] properties, |
| 39 | + out uint fetched) |
| 40 | + { |
| 41 | + if (count > properties.Length) |
| 42 | + throw new COMException(); |
| 43 | + |
| 44 | + // Zero out the array. |
| 45 | + for (int i= 0; i < count; i++) |
| 46 | + { |
| 47 | + properties[i].bstrFullName = ""; |
| 48 | + properties[i].bstrName = ""; |
| 49 | + properties[i].bstrType = ""; |
| 50 | + properties[i].bstrValue = ""; |
| 51 | + properties[i].dwAttrib = 0; |
| 52 | + properties[i].dwFields = 0; |
| 53 | + properties[i].pProperty = null; |
| 54 | + } |
| 55 | + fetched = 0; |
| 56 | + |
| 57 | + // COM interop. |
| 58 | + HRESULT hr; |
| 59 | + uint innerFetched; |
| 60 | + IDebugField[] field = new IDebugField[1]; |
| 61 | + |
| 62 | + while (fetched < count) |
| 63 | + { |
| 64 | + field[0] = null; |
| 65 | + innerFetched = 0; |
| 66 | + |
| 67 | + // Get next field. |
| 68 | + if (fetched < fieldCount) |
| 69 | + hr = fields.Next(1, field, ref innerFetched); |
| 70 | + // No more fields. |
| 71 | + else return COM.S_FALSE; |
| 72 | + |
| 73 | + if (hr != COM.S_OK || innerFetched != 1 || field[0] == null) |
| 74 | + throw new COMException("CEnumPropertyInfo.Next"); |
| 75 | + |
| 76 | + // Get property from field. |
| 77 | + CFieldProperty fieldProperty = |
| 78 | + new CFieldProperty(provider, address, binder, field[0]); |
| 79 | + |
| 80 | + DEBUG_PROPERTY_INFO[] property = |
| 81 | + new DEBUG_PROPERTY_INFO[1]; |
| 82 | + fieldProperty.GetPropertyInfo((uint) infoFlags, radix, 0, null, 0, property); |
| 83 | + properties[fetched++] = property[0]; |
| 84 | + } |
| 85 | + return COM.S_OK; |
| 86 | + } |
| 87 | + } |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +## Unmanaged code |
| 92 | + This example shows an implementation of `IEnumDebugPropertyInfo2::EnumChildren` for a method's locals in unmanaged code. |
| 93 | + |
| 94 | +```cpp |
| 95 | +STDMETHODIMP CEnumPropertyInfo::Next( |
| 96 | + in ULONG count, |
| 97 | + out DEBUG_PROPERTY_INFO* pelements, |
| 98 | + out ULONG* pfetched ) |
| 99 | +{ |
| 100 | + if (pfetched) |
| 101 | + *pfetched = 0; |
| 102 | + if (!pelements) |
| 103 | + return E_INVALIDARG; |
| 104 | + else |
| 105 | + memset( pelements, 0, count * sizeof(DEBUG_PROPERTY_INFO)); |
| 106 | + |
| 107 | + HRESULT hr = S_OK; |
| 108 | + ULONG idx = 0; |
| 109 | + while (idx < count) |
| 110 | + { |
| 111 | + ULONG fetchedFields; |
| 112 | + IDebugField* pfield; |
| 113 | + |
| 114 | + //get the next field |
| 115 | + hr = m_fields->Next( 1, &pfield, &fetchedFields ); |
| 116 | + if (FAILED(hr)) |
| 117 | + return hr; |
| 118 | + if (fetchedFields != 1) |
| 119 | + return E_FAIL; |
| 120 | + idx++; |
| 121 | + |
| 122 | + //create a CFieldProperty to retrieve the DEBUG_PROPERTY_INFO |
| 123 | + CFieldProperty* pproperty = |
| 124 | + new CFieldProperty( m_provider, m_address, m_binder, pfield ); |
| 125 | + pfield->Release(); |
| 126 | + if (!pproperty) |
| 127 | + return E_OUTOFMEMORY; |
| 128 | + |
| 129 | + hr = pproperty->Init(); |
| 130 | + if (FAILED(hr)) |
| 131 | + { |
| 132 | + pproperty->Release(); |
| 133 | + return hr; |
| 134 | + } |
| 135 | + |
| 136 | + hr = pproperty->GetPropertyInfo( m_infoFlags, |
| 137 | + m_radix, |
| 138 | + 0, |
| 139 | + NULL, |
| 140 | + 0, |
| 141 | + pelements + idx - 1); |
| 142 | + pproperty->Release(); |
| 143 | + if (FAILED(hr)) |
| 144 | + return hr; |
| 145 | + } |
| 146 | + |
| 147 | + if (pfetched) |
| 148 | + *pfetched = idx; |
| 149 | + return hr; |
| 150 | +} |
| 151 | +``` |
| 152 | +
|
| 153 | +## See also |
| 154 | +[Sample implementation of locals](../../extensibility/debugger/sample-implementation-of-locals.md) |
| 155 | +[Enumerating locals](../../extensibility/debugger/enumerating-locals.md) |
0 commit comments