Creating CDebugContext
A code context, represented by the IDebugCodeContext2 interface, consists of the instructions that make up the program. A document context, represented by the IDebugDocumentContext2 interface, consists of the actual lines of source of the program. And a memory context, represented by the IDebugMemoryContext2 interface, is a location in memory.
In TextInterpreter, the code context is the same as the document context (each line of the document is also a line of "code"), so both interfaces are implemented on the same object. Since IDebugCodeContext2 inherits from IDebugMemoryContext2, the methods on the IDebugMemoryContext2 interface have to be implemented as well even though TextInterpreter doesn't use that context.
In a typical implementation, the IDebugMemoryContext2 and IDebugCodeContext2 interfaces would be implemented on separate objects since the action of the methods is different depending on the interface used. TextInterpreter doesn't really use the code and memory contexts, so they are implemented on the same object as the document context.
注意
The methods on the IDebugMemoryContext2 interface work with bytes, whereas the same methods as implemented on the IDebugCodeContext2 interface work with instructions that could be multiple bytes in size. This is why these interfaces are normally implemented on separate objects.
To create CDebugContext
In Solution Explorer, right-click the TextInterpreter project; click Add Class, click an ATL Simple Object, and click Add.
For the Short name, type DebugContext.
Modify the .h file to be Context.h and the .cpp file to be Context.cpp.
Clear the Attributed option.
Change the Interface to IDebugCodeContext2.
Click Next or click the Options link on the left.
Change the Interface from Dual to Custom.
Click Finish to add the ATL object to the project.
Open the TextInterpreter.idl file and remove the declaration for the IDebugCodeContext2 interface, which looks similar to the following (the uuid may be different):
[ object, uuid(93CB9590-3EA6-4368-AB78-479AC3F2FF01), helpstring("IDebugCodeContext2 Interface"), pointer_default(unique) ] interface IDebugCodeContext2 : IUnknown{ };
Open the Context.h file, find the declaration for the new CDebugContext class, and modify the class declaration to include an additional inherited interface (IDebugDocumentContext2) so it looks like the following:
class ATL_NO_VTABLE CDebugContext : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CDebugContext, &CLSID_DebugContext>, public IDebugCodeContext2, public IDebugDocumentContext2 {
In Context.h in the CDebugContext class, add the following bold line to the BEGIN_COM_MAP block. Since you added an interface manually, you must add the COM_MAP entry manually as well.
BEGIN_COM_MAP(CDebugContext) COM_INTERFACE_ENTRY(IDebugCodeContext2) COM_INTERFACE_ENTRY(IDebugDocumentContext2) END_COM_MAP()
In Context.h in the CDebugContext class, add the following bold lines. These are the declarations for the methods on the IDebugCodeContext2, IDebugMemoryContext2, and IDebugDocumentContext2 interfaces.
END_COM_MAP() //////////////////////////////////////////////////////////// // IDebugCodeContext2 methods STDMETHOD(GetDocumentContext)(IDebugDocumentContext2 **ppSrcCxt); // GetLanguageInfo is declared in the IDebugDocumentContext2 interface. //////////////////////////////////////////////////////////// // IDebugCodeContext2 methods inherited from IDebugMemoryContext2 STDMETHOD(GetName)(BSTR* pbstrName); STDMETHOD(GetInfo)(CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO* pInfo); STDMETHOD(Add)(UINT64 dwCount, IDebugMemoryContext2** ppMemCxt); STDMETHOD(Subtract)(UINT64 dwCount, IDebugMemoryContext2** ppMemCxt); STDMETHOD(Compare)( CONTEXT_COMPARE compare, IDebugMemoryContext2** rgpMemoryContextSet, DWORD dwMemoryContextSetLen, DWORD* pdwMemoryContext); //////////////////////////////////////////////////////////// // IDebugDocumentContext2 methods STDMETHOD(GetDocument)(IDebugDocument2 **ppDocument); STDMETHOD(GetName)(GETNAME_TYPE gnType, BSTR *pbstrFileName); STDMETHOD(EnumCodeContexts)(IEnumDebugCodeContexts2 **ppEnumCodeCxts); STDMETHOD(GetLanguageInfo)(BSTR* pbstrLanguage, GUID* pguidLanguage); STDMETHOD(GetStatementRange)( TEXT_POSITION* pBegPosition, TEXT_POSITION* pEndPosition); STDMETHOD(GetSourceRange)( TEXT_POSITION* pBegPosition, TEXT_POSITION* pEndPosition); STDMETHOD(Compare)( DOCCONTEXT_COMPARE compare, IDebugDocumentContext2** rgpDocContextSet, DWORD dwDocContextSetLen, DWORD* pdwDocContext); STDMETHOD(Seek)(int ncount, IDebugDocumentContext2 **ppDocContext);
Open the Context.cpp file, find the definition for the new CDebugContext class, and add the following bold lines. These are the definitions for the methods on the IDebugMemoryContext2, IDebugDocumentContext2, and IDebugCodeContext2 interfaces. All of these return E_NOTIMPL for now.
// CDebugContext ////////////////////////////////////////////////////////////////////////////// // IDebugMemoryContext2 methods HRESULT CDebugContext::GetInfo(CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO* pInfo) { return E_NOTIMPL; } HRESULT CDebugContext::Add(UINT64 dwCount, IDebugMemoryContext2** ppMemCxt) { return E_NOTIMPL; } HRESULT CDebugContext::Subtract(UINT64 dwCount, IDebugMemoryContext2** ppMemCxt) { return E_NOTIMPL; } HRESULT CDebugContext::Compare(CONTEXT_COMPARE compare, IDebugMemoryContext2** rgpMemoryContextSet, DWORD dwMemoryContextSetLen, DWORD* pdwMemoryContext) { return E_NOTIMPL; } ////////////////////////////////////////////////////////////////////////////// // IDebugDocumentContext2 methods HRESULT CDebugContext::GetDocument(IDebugDocument2 **ppDocument) { return E_NOTIMPL; } HRESULT CDebugContext::GetName(BSTR* pbstrName) { return E_NOTIMPL; } HRESULT CDebugContext::EnumCodeContexts(IEnumDebugCodeContexts2 **ppEnumCodeCxts) { return E_NOTIMPL; } HRESULT CDebugContext::GetLanguageInfo(BSTR* pbstrLanguage, GUID* pguidLanguage) { return E_NOTIMPL; } HRESULT CDebugContext::Compare(DOCCONTEXT_COMPARE compare, IDebugDocumentContext2** rgpDocContextSet, DWORD dwDocContextSetLen, DWORD* pdwDocContext) { return E_NOTIMPL; } HRESULT CDebugContext::Seek(int ncount, IDebugDocumentContext2 **ppDocContext) { return E_NOTIMPL;} ////////////////////////////////////////////////////////////////////////////// // IDebugCodeContext2 methods HRESULT CDebugContext::GetDocumentContext(IDebugDocumentContext2 **ppSrcCxt) { //TODO: RETURN DOCUMENT CONTEXT return E_NOTIMPL; } HRESULT CDebugContext::GetName(GETNAME_TYPE gnType, BSTR *pbstrFileName) { //TODO: RETURN CONTEXT FILENAME return E_NOTIMPL; } HRESULT CDebugContext::GetSourceRange( TEXT_POSITION* pBegPosition, TEXT_POSITION* pEndPosition) { //TODO: RETURN SOURCE RANGE return E_NOTIMPL; } HRESULT CDebugContext::GetStatementRange( TEXT_POSITION* pBegPosition, TEXT_POSITION* pEndPosition) { //TODO: RETURN STATEMENT RANGE return E_NOTIMPL; }
Build the project to make sure there are no errors.