【问题标题】:IShellBrowser::BrowseObject isn't called未调用 IShellBrowser::BrowseObject
【发布时间】:2012-04-23 09:27:25
【问题描述】:

我正在尝试在我的应用程序中实现类似资源管理器的框架。这也必须在 WinXP 下工作。

我已经在我的窗口类中实现了IShellBrowser + 我已经实现了IUnknown 接口。

我的班级属性:

IShellViewPtr m_shView;
HWND m_wndHolder;
CListViewCtrl  view;

这是WM_CREATE处理程序的代码

m_hWndClient = view.Create(m_hWnd, rcDefault, NULL, 
            WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
            WS_CLIPCHILDREN, WS_EX_CLIENTEDGE); // view isn't null after it

CMessageLoop* pLoop = _Module.GetMessageLoop();
        pLoop->AddMessageFilter(this);
        pLoop->AddIdleHandler(this);

IShellFolderPtr pParentFolder;
ATLVERIFY(SHGetDesktopFolder(&pParentFolder) == S_OK); // OK

FOLDERSETTINGS fs;
fs.fFlags = FVM_DETAILS;
fs.ViewMode = FVM_LIST;

ATLVERIFY(pParentFolder->CreateViewObject(view, IID_IShellView, (void**)&m_shView) == S_OK); // OK

RECT r; 
GetClientRect(&r);

ATLVERIFY(m_shView->CreateViewWindow(NULL, &fs, static_cast<IShellBrowser*>(this), &r, &m_wndHolder) == S_OK); // OK
ATLVERIFY(m_shView->UIActivate(SVUIA_ACTIVATE_NOFOCUS) == S_OK); // OK

应用程序启动后,我有类似资源管理器的框架。 我想处理双击事件以浏览框架中的文件夹。我希望在双击我的BrowseObject 实现后会被调用,但它没有发生。而不是这个文件夹在系统资源管理器中打开。

请帮忙。谢谢。

【问题讨论】:

    标签: c++ com explorer windows-shell


    【解决方案1】:

    我已经解决了这个问题。

    如果你的班级,首先你必须IServiceProvider 接口。实现应该是这样的:

    QueryService( REFGUID guidService, REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject ) 
      {
        if (IID_IShellBrowser == riid)
        {
          *ppvObject = static_cast<IShellBrowser*>(this);
          AddRef();
          return S_OK;
        }
    
        *ppvObject = NULL;
        return E_NOINTERFACE;
      }
    

    您还必须在您的QueryInterface 方法中添加IServiceProvider 支持。

    STDMETHOD (QueryInterface)( REFIID riid,  __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject)
    {
        if (!ppvObject)
            return E_POINTER;
    
        *ppvObject = NULL;
    
        if ( riid == IID_IShellBrowser )
            *ppvObject = static_cast<IShellBrowser*>(this);
        else if ( riid == IID_IUnknown )
            *ppvObject = static_cast<IUnknown*>(static_cast<IShellBrowser*>(this));
    
       else if ( riid == IID_IServiceProvider )
            *ppvObject = static_cast<IServiceProvider*>(this);
    
        if (*ppvObject)
        {
            AddRef();
            return S_OK;
        }
        return E_NOTIMPL;
    }
    

    在你继承IServiceProvider 之后,你不能只使用static_cast&lt;IUnknown*&gt;(this) 将你的类转换为IUnknown,所以你需要像我一样写一些东西。

    之后BrowseObject 应该可以正常调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      • 1970-01-01
      • 1970-01-01
      • 2018-05-01
      相关资源
      最近更新 更多