0

アプリケーションにエクスプローラーのようなフレームを実装しようとしています。これは 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が呼び出されることを期待していますが、それは起こりません。このフォルダーの代わりに、システム エクスプローラーで開かれます。

助けてください。ありがとうございました。

4

1 に答える 1

0

私は問題を解決しました。

まず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;
  }

IServiceProviderまた、メソッドにサポートを追加する必要がありますQueryInterface

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てクラスをキャストすることはできないため、私のように何かを書く必要があります。IUnknownstatic_cast<IUnknown*>(this)

その後BrowseObjectは罰金と呼ばれる必要があります。

于 2012-04-24T19:50:40.010 に答える