ArcEngine 元件(如 MapControl、IWorkspaceEdit)透過事件介面發送通知。以編輯事件為例,介面定義:
__interface IWorkspaceEditEvents : IUnknown {
HRESULT OnStartEditing(VARIANT_BOOL withUndoRedo);
HRESULT OnStopEditing(VARIANT_BOOL saveEdits);
HRESULT OnStartEditOperation();
HRESULT OnAbortEditOperation();
HRESULT OnStopEditOperation();
HRESULT OnUndoEditOperation();
HRESULT OnRedoEditOperation();
};
class CArcEditEvents :
public CComObjectRoot,
public IWorkspaceEditEvents
{
public:
CArcEditEvents() {}
~CArcEditEvents() {}
BEGIN_COM_MAP(CArcEditEvents)
COM_INTERFACE_ENTRY(IWorkspaceEditEvents)
END_COM_MAP()
STDMETHOD(OnStartEditing)(VARIANT_BOOL withUndoRedo) {
MessageBox(NULL, _T("開始編輯"), _T("通知"), MB_OK);
return S_OK;
}
STDMETHOD(OnStopEditing)(VARIANT_BOOL saveEdits) { return S_OK; }
STDMETHOD(OnStartEditOperation)() { return S_OK; }
STDMETHOD(OnAbortEditOperation)() { return S_OK; }
STDMETHOD(OnStopEditOperation)() { return S_OK; }
STDMETHOD(OnUndoEditOperation)() { return S_OK; }
STDMETHOD(OnRedoEditOperation)() { return S_OK; }
};
CComObjectRoot 提供參考計數與 IUnknown 基礎實作,COM_MAP 宣告支援介面。
// 成員變數
CArcEditEvents* g_pEvents = nullptr;
DWORD m_dwCookie = 0;
// 建議通知
void AdviseEditEvents(IWorkspaceEdit* pWorkspaceEdit) {
g_pEvents = new CComObject();
CComPtr pUnk = g_pEvents;
AtlAdvise(pWorkspaceEdit, pUnk, __uuidof(IWorkspaceEditEvents), &m_dwCookie);
}
// 解除通知
void UnadviseEditEvents(IWorkspaceEdit* pWorkspaceEdit) {
if (m_dwCookie) {
AtlUnadvise(pWorkspaceEdit, __uuidof(IWorkspaceEditEvents), m_dwCookie);
m_dwCookie = 0;
}
if (g_pEvents) {
g_pEvents->Release();
g_pEvents = nullptr;
}
}
IConnectionPointContainer、IConnectionPoint 尋找與 Advise/Unadvise 呼叫。IUnknown,故 CComObjectRoot 為必要基底。virtual HRESULT __stdcall MethodName(Params),簡化虛函數宣告。同理可監聽 MapControl 滑鼠事件(IMapControlEvents2)、圖層事件(ILayerEvents)等:
AtlAdvise 建立連線。VC++ 監聽 ArcEngine COM 事件核心流程:定義事件接收器 → 實作介面方法 → AtlAdvise 建立連線 → 處理事件 → AtlUnadvise 釋放。掌握 ATL 連線點機制與智慧指標用法,即可靈活應對各類 GIS 事件驅動開發需求。