如何通过COM接口以编程方式激活OLE控件?

时间:2011-05-19 07:27:00

标签: c windows com ole

我有一个通过ActiveX嵌入按钮控件的应用程序。该按钮由第三方提供,它实现了一系列ActiveX接口(其中包括IOleInPlaceObject)。我确实引用了按钮的IUnknown实现。

我遇到的问题是对象提供的IOleWindow::GetWindow函数总是返回错误;错误代码是0x80004005,显然是common HRESULT value,意思是E_FAIL。不太具描述性。

对于它的价值,该对象还通过它的IDispatch实现公开hWnd属性;查询成功,但属性的值始终为零。

一些谷歌搜索建议我可能需要在hWnd属性产生有用值之前“激活”OLE对象。有人知道怎么做,是否有专用的COM接口来激活OLE对象?

有趣的是,按钮 似乎有一个窗口句柄,如Spy++中所示。

更新:我刚发现IQuickActivate是由我正在处理的按钮控件实现的,可以用来'快速'(哼...)激活一个项目。但是,填充QACONTAINER结构似乎非常痛苦,所以我现在不愿意这样做。

2 个答案:

答案 0 :(得分:1)

事实证明,使用OLEIVERB_INPLACEACTIVATE函数发送IOleClientSite::DoVerb动词有帮助,如下所示:

IOleInPlaceObjectPtr oleInPlaceObj;
CheckAndThrow( unk->QueryInterface( &oleInPlaceObj ) ) );

HWND hwnd;
CheckAndThrow( oleInPlaceObj->GetWindow( &hwnd ) );

IOleObjectPtr oleObj;
if ( SUCCEEDED( unk->QueryInterface( &oleObj ) ) ) {
    IOleClientSitePtr clientSite;
    if ( SUCCEEDED( oleObj->GetClientSite( &clientSite ) ) ) {
        hr = oleObj->DoVerb( OLEIVERB_INPLACEACTIVATE,
                             NULL,
                             clientSite,
                             0,
                             NULL,
                             NULL );
        if ( SUCCEEDED( hr ) ) {
            if ( SUCCEEDED( oleInPlaceObj->GetWindow( &hwnd ) ) ) {
                return hwnd;
            }
        }
    }
}

unkIUnknownPtr,我正试图获取HWNDCheckAndThrow函数是一个辅助宏,如果给定的返回码表示失败,则会产生异常。

答案 1 :(得分:0)

当然按钮有一个有效的HWND,othrewise它不是一个按钮/窗口。 您可以使用HWND或类似内容获得GetDlgItem任何控件。

我不确定如何以编程方式激活对象。我会尝试以下方法:

  • 致电ReactivateAndUndo。根据文件,这可能做你需要的恕我直言。
  • 如果您拥有控件HWND(如果存在,您肯定可以获得它) - 可以模拟用户鼠标输入