Explorer Selected File - how to retrieve from ToolBar (ToolBand)
-
hello. Does anybody now how to retrieve the currently selected (highlighted) filename as shown in the windows explorer window from a toolbar that is implemented with the TOOL / Desk Band interfaces? -- When I click on a custom toolbar button, I need to know the name of the selected file in order to "operate" on that file.. Any help is appreciated! sas
-
hello. Does anybody now how to retrieve the currently selected (highlighted) filename as shown in the windows explorer window from a toolbar that is implemented with the TOOL / Desk Band interfaces? -- When I click on a custom toolbar button, I need to know the name of the selected file in order to "operate" on that file.. Any help is appreciated! sas
Use the SHShellFolderView_Message() function to send the SFVM_GETSELECTEDOBJECTS message to the main browser window. link : http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shshellfolderview_message.asp This supposedly only works for win 2k+. If you need it for windows 98, there is a trick that might help you - if you're in a deskband, you're in an in-process dll, so you can just send LVM_* messages to the inner list view. I have noticed that the lParam member of the LVITEM structure, for explorer list views, is in fact a pointer to the item's PIDL. This isn't documented, it might not work everywhere, but it does work most of the time.
-
Use the SHShellFolderView_Message() function to send the SFVM_GETSELECTEDOBJECTS message to the main browser window. link : http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shshellfolderview_message.asp This supposedly only works for win 2k+. If you need it for windows 98, there is a trick that might help you - if you're in a deskband, you're in an in-process dll, so you can just send LVM_* messages to the inner list view. I have noticed that the lParam member of the LVITEM structure, for explorer list views, is in fact a pointer to the item's PIDL. This isn't documented, it might not work everywhere, but it does work most of the time.
thanks. I am using win XP. I tried code like this, per your help, but the app crashes at the SHShellFolderView_Message line: LPITEMIDLIST* ppidl; LRESULT numItems = (LPARAM)SHShellFolderView_Message(m_hExplorerHwnd, SFVM_GETSELECTEDOBJECTS, (LPARAM)ppidl); is there something I'm missing, do I need to instantiate the array of pidls? m_hExplorerHwnd is the hwnd of the actual explorer.exe gui any help is appreciated. sas
-
thanks. I am using win XP. I tried code like this, per your help, but the app crashes at the SHShellFolderView_Message line: LPITEMIDLIST* ppidl; LRESULT numItems = (LPARAM)SHShellFolderView_Message(m_hExplorerHwnd, SFVM_GETSELECTEDOBJECTS, (LPARAM)ppidl); is there something I'm missing, do I need to instantiate the array of pidls? m_hExplorerHwnd is the hwnd of the actual explorer.exe gui any help is appreciated. sas
hmm... I tried it and it crashed too. Never mind, I found a better way. This example lists all the selected items and displays them in a message box:
HWND hWndBrowser = ::GetAncestor(m_hWnd, GA_ROOT); char szBuf[4096]; IShellBrowser *pISB = (IShellBrowser*)SendMessage(hWndBrowser, WM_USER+7, 0, NULL); if (pISB) { IShellView *pISV = NULL; if (SUCCEEDED(pISB->QueryActiveShellView(&pISV))) { IDataObject *pIDO; HDROP hDrop; UINT uNumFiles; char szFile[MAX_PATH]; pISV->GetItemObject(SVGIO_SELECTION, IID_IDataObject, (void**)&pIDO); FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM stg = { TYMED_HGLOBAL }; if ( FAILED( pIDO->GetData ( &etc, &stg ))) return E_INVALIDARG; hDrop = (HDROP) GlobalLock ( stg.hGlobal ); if ( !hDrop ) { ReleaseStgMedium ( &stg ); return E_INVALIDARG; } uNumFiles = DragQueryFile ( hDrop, 0xFFFFFFFF, NULL, 0 ); szBuf[0] = '\0'; for (UINT uFile = 0; uFile < uNumFiles; uFile++) { if (!DragQueryFile( hDrop, uFile, szFile, MAX_PATH )) continue; wsprintf(szBuf, "%s\n%s", szBuf, szFile); } MessageBox(lpcmi->hwnd, szBuf, "Selected Files", MB_OK); GlobalUnlock ( stg.hGlobal ); ReleaseStgMedium ( &stg ); pIDO->Release(); pISV->Release(); } }
This is called from within a band object's IContextMenu::InvokeCommand() method,
m_hWnd
is the band object's window handle. Since you already have the handle to the main explorer window, you won't have to call GetAncestor(). -
hmm... I tried it and it crashed too. Never mind, I found a better way. This example lists all the selected items and displays them in a message box:
HWND hWndBrowser = ::GetAncestor(m_hWnd, GA_ROOT); char szBuf[4096]; IShellBrowser *pISB = (IShellBrowser*)SendMessage(hWndBrowser, WM_USER+7, 0, NULL); if (pISB) { IShellView *pISV = NULL; if (SUCCEEDED(pISB->QueryActiveShellView(&pISV))) { IDataObject *pIDO; HDROP hDrop; UINT uNumFiles; char szFile[MAX_PATH]; pISV->GetItemObject(SVGIO_SELECTION, IID_IDataObject, (void**)&pIDO); FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM stg = { TYMED_HGLOBAL }; if ( FAILED( pIDO->GetData ( &etc, &stg ))) return E_INVALIDARG; hDrop = (HDROP) GlobalLock ( stg.hGlobal ); if ( !hDrop ) { ReleaseStgMedium ( &stg ); return E_INVALIDARG; } uNumFiles = DragQueryFile ( hDrop, 0xFFFFFFFF, NULL, 0 ); szBuf[0] = '\0'; for (UINT uFile = 0; uFile < uNumFiles; uFile++) { if (!DragQueryFile( hDrop, uFile, szFile, MAX_PATH )) continue; wsprintf(szBuf, "%s\n%s", szBuf, szFile); } MessageBox(lpcmi->hwnd, szBuf, "Selected Files", MB_OK); GlobalUnlock ( stg.hGlobal ); ReleaseStgMedium ( &stg ); pIDO->Release(); pISV->Release(); } }
This is called from within a band object's IContextMenu::InvokeCommand() method,
m_hWnd
is the band object's window handle. Since you already have the handle to the main explorer window, you won't have to call GetAncestor().