I am trying to get the IDispatch * of an open explorer window using IShellWindows::FindWindowSW; however, I cannot seem to coax the method to return anything other than S_FALSE.
The code I am using is basically:
OleInitialize(nullptr);
CComPtr<IShellWindows> spWindows;
auto hr = spWindows.CoCreateInstance(CLSID_ShellWindows);
auto pidl = ILCreateFromPath(L"C:\\temp");
VARIANT vtLoc;
vtLoc.vt = VT_VARIANT | VT_BYREF;
vtLoc.pbVal = (BYTE *) pidl;
CComVariant vtEmpty;
long lhwnd;
CComPtr<IDispatch> spdisp;
hr = spWindows->FindWindowSW(&vtLoc, &vtEmpty,
SWC_EXPLORER, &lhwnd, SWFO_NEEDDISPATCH | SWFO_INCLUDEPENDING,
&spdisp);
Yes, I am sure there is an explorer window open with the location "C:\temp".
Slightly modifying the code from A big little program: Monitoring Internet Explorer and Explorer windows, part 1: Enumeration which enumerates over all registered windows and examines their locations (which is what I assume FindWindowSW does internally anyway) replicates the function. Which is basically what the answer by Victoria does.
bool ImageViewerMainWindow::GetFolderViewFromPath(const WCHAR * szPath, IFolderView2 ** ppfv) {
if( !m_spWindows ) return false;
if( !szPath ) return false;
if( !ppfv ) return false;
*ppfv = nullptr;
CComPtr<IUnknown> spunkEnum;
HRESULT hr = m_spWindows->_NewEnum(&spunkEnum);
if( S_OK != hr ) return false;
CComQIPtr<IEnumVARIANT> spev(spunkEnum);
for( CComVariant svar; spev->Next(1, &svar, nullptr) == S_OK; svar.Clear() ) {
if( svar.vt != VT_DISPATCH ) continue;
CComPtr<IShellBrowser> spsb;
hr = IUnknown_QueryService(svar.pdispVal, SID_STopLevelBrowser, IID_PPV_ARGS(&spsb));
if( S_OK != hr ) continue;
CComPtr<IShellView> spsv;
hr = spsb->QueryActiveShellView(&spsv);
if( S_OK != hr ) continue;
CComQIPtr<IPersistIDList> sppidl(spsv);
if( !sppidl ) continue;
CComHeapPtr<ITEMIDLIST_ABSOLUTE> spidl;
hr = sppidl->GetIDList(&spidl);
if( S_OK != hr ) continue;
CComPtr<IShellItem> spsi;
hr = SHCreateItemFromIDList(spidl, IID_PPV_ARGS(&spsi));
if( S_OK != hr ) continue;
CComHeapPtr<WCHAR> pszLocation;
hr = spsi->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &pszLocation);
if( S_OK != hr ) continue;
if( wcscmp(pszLocation, szPath) != 0 ) continue;
hr = spsv->QueryInterface(IID_PPV_ARGS(ppfv));
if( hr != S_OK ) continue;
return true;
}
return false;
}
But has anyone successfully used FindWindowSW to obtain an IDispatch * to an explorer window registered with IShellWindows?