許多 ActiveX 控制項(如媒體播放器、動畫控件)需響應 IE 工具列的「停止」按鈕,以中斷下載、停止播放。IE 透過 IOleCommandTarget 介面將命令(如 OLECMDID_STOP)傳遞給內嵌物件。本文示範如何在 MFC/ATL ActiveX 控制項中實作此介面並捕獲停止命令。
class CMyOleControl : public COleControl
{
// ...
protected:
// 宣告巢狀類別實作 IOleCommandTarget
DECLARE_INTERFACE_MAP()
BEGIN_INTERFACE_PART(CmdTargetObj, IOleCommandTarget)
STDMETHOD(QueryStatus)(const GUID* pguidCmdGroup, ULONG cCmds,
OLECMD rgCmds[], OLECMDTEXT* pcmdtext);
STDMETHOD(Exec)(const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt,
VARIANTARG* pvarargIn, VARIANTARG* pvarargOut);
END_INTERFACE_PART(CmdTargetObj)
};
BEGIN_INTERFACE_MAP(CMyOleControl, COleControl)
INTERFACE_PART(CMyOleControl, IID_IOleCommandTarget, CmdTargetObj)
END_INTERFACE_MAP()
// IUnknown 轉發
ULONG FAR EXPORT CMyOleControl::XCmdTargetObj::AddRef() {
METHOD_PROLOGUE(CMyOleControl, CmdTargetObj)
return pThis->ExternalAddRef();
}
ULONG FAR EXPORT CMyOleControl::XCmdTargetObj::Release() {
METHOD_PROLOGUE(CMyOleControl, CmdTargetObj)
return pThis->ExternalRelease();
}
HRESULT FAR EXPORT CMyOleControl::XCmdTargetObj::QueryInterface(REFIID iid, void** ppvObj) {
METHOD_PROLOGUE(CMyOleControl, CmdTargetObj)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}
// QueryStatus:可選實作,回報支援的命令
STDMETHODIMP CMyOleControl::XCmdTargetObj::QueryStatus(
const GUID* pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[], OLECMDTEXT* pcmdtext)
{
METHOD_PROLOGUE(CMyOleControl, CmdTargetObj)
// 可在此標記支援 OLECMDID_STOP 等
return S_OK;
}
// Exec:核心處理停止命令
STDMETHODIMP CMyOleControl::XCmdTargetObj::Exec(
const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt,
VARIANTARG* pvarargIn, VARIANTARG* pvarargOut)
{
METHOD_PROLOGUE(CMyOleControl, CmdTargetObj)
if (nCmdID == OLECMDID_STOP) {
// 使用者點擊 IE「停止」按鈕
// 在此執行:停止下載、暫停動畫、中斷網路請求等
::MessageBox(NULL, _T("STOP 按鈕被點擊"), _T("CMyOleControl"), MB_OK);
}
return S_OK;
}
IOleCommandTarget 是容器(IE)與物件通訊的標準介面。OLECMDID_STOP 為預定義命令 ID(值為 23),對應 IE 停止按鈕。METHOD_PROLOGUE 巨集將巢狀類別指標轉換為外層控制項指標。COM_INTERFACE_ENTRY 與 IObjectWithSite 等。regsvr32)。<OBJECT CLASSID="clsid:...">)。