问题
I'm trying to implement explorer-like frame in my application. This must work under WinXP too.
I've implemented IShellBrowser
in my window-class + i've implemented IUnknown
interface.
My class atributs:
IShellViewPtr m_shView;
HWND m_wndHolder;
CListViewCtrl view;
Here is the code of WM_CREATE
handler
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
After the application is started i have explorer-like frame in it.
I want to handle double click event in order to navigate through the folders in the frame. I expect that after double-clicking my implementation of BrowseObject
will be called, but it doesn't happened. Instead of this folders are opened in system explorer.
Please help. Thank you.
回答1:
I've solved the problem.
First you have to IServiceProvider
interface if your class. Implementation should look like this:
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;
}
Also you have to add IServiceProvider
support in your QueryInterface
method.
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;
}
After you'll inherit IServiceProvider
, you can't cast you class to IUnknown
using just static_cast<IUnknown*>(this)
, so you need to write something like i did.
After that BrowseObject
should be called fine.
来源:https://stackoverflow.com/questions/10277918/ishellbrowserbrowseobject-isnt-called