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?