visual ventana usar una studio paso para paquete instalacion hechas hacer ejemplos crear como aplicaciones c++ winapi

c++ - ventana - paquete visual studio



Cómo obtener la ruta de una ventana activa de explorador de archivos en c++ winapi (1)

He estado golpeando mi cabeza en la pared de cómo puedo hacer esto. Básicamente, mi aplicación necesita averiguar la ruta del directorio del explorador de archivos activo (es decir, el explorador de archivos en primer plano) en Windows en C ++ utilizando winapi.

En lugar de esto:

TCHAR* getWindowDir(){ TCHAR* windowTitle = new TCHAR[MAX_PATH]; HWND windowHandle = GetForegroundWindow(); GetWindowText(windowHandle,windowTitle,MAX_PATH); return windowTitle; }

Lo cual obviamente devuelve el título de la ventana. Quiero que devuelva el directorio activo.


Cree una instancia de IShellWindows y IShellWindows para enumerar todas las ventanas abiertas de Explorer. Usando varias interfaces relacionadas, puede obtener el identificador de ventana y la carpeta actual en forma de PIDL de cada elemento enumerado por IShellWindows . Si el identificador de ventana es igual al resultado de GetForegroundWindow() , convierta el PIDL en una ruta.

A continuación, presento un código para obtener información sobre todas las ventanas del Explorador. Se basa parcialmente en el código de Raymond Chen, pero utiliza punteros inteligentes para un código menos frágil y más limpio. También agregué el manejo de errores a través de excepciones.

Primero, los requisitos obligatorios y algunos códigos de utilidad:

#include <Windows.h> #include <shlobj.h> #include <atlcomcli.h> // for COM smart pointers #include <vector> #include <system_error> #include <memory> // Throw a std::system_error if the HRESULT indicates failure. template< typename T > void ThrowIfFailed( HRESULT hr, T&& msg ) { if( FAILED( hr ) ) throw std::system_error{ hr, std::system_category(), std::forward<T>( msg ) }; } // Deleter for a PIDL allocated by the shell. struct CoTaskMemDeleter { void operator()( ITEMIDLIST* pidl ) const { ::CoTaskMemFree( pidl ); } }; // A smart pointer for PIDLs. using UniquePidlPtr = std::unique_ptr< ITEMIDLIST, CoTaskMemDeleter >;

Ahora definimos una función GetCurrentExplorerFolders() para devolver información sobre todas las ventanas abiertas de Explorer, incluyendo el identificador de ventana y el PIDL de la carpeta actual.

// Return value of GetCurrentExplorerFolders() struct ExplorerFolderInfo { HWND hwnd = nullptr; // window handle of explorer UniquePidlPtr pidl; // PIDL that points to current folder }; // Get information about all currently open explorer windows. // Throws std::system_error exception to report errors. std::vector< ExplorerFolderInfo > GetCurrentExplorerFolders() { CComPtr< IShellWindows > pshWindows; ThrowIfFailed( pshWindows.CoCreateInstance( CLSID_ShellWindows ), "Could not create instance of IShellWindows" ); long count = 0; ThrowIfFailed( pshWindows->get_Count( &count ), "Could not get number of shell windows" ); std::vector< ExplorerFolderInfo > result; result.reserve( count ); for( long i = 0; i < count; ++i ) { ExplorerFolderInfo info; CComVariant vi{ i }; CComPtr< IDispatch > pDisp; ThrowIfFailed( pshWindows->Item( vi, &pDisp ), "Could not get item from IShellWindows" ); if( ! pDisp ) // Skip - this shell window was registered with a NULL IDispatch continue; CComQIPtr< IWebBrowserApp > pApp{ pDisp }; if( ! pApp ) // This window doesn''t implement IWebBrowserApp continue; // Get the window handle. pApp->get_HWND( reinterpret_cast<SHANDLE_PTR*>( &info.hwnd ) ); CComQIPtr< IServiceProvider > psp{ pApp }; if( ! psp ) // This window doesn''t implement IServiceProvider continue; CComPtr< IShellBrowser > pBrowser; if( FAILED( psp->QueryService( SID_STopLevelBrowser, &pBrowser ) ) ) // This window doesn''t provide IShellBrowser continue; CComPtr< IShellView > pShellView; if( FAILED( pBrowser->QueryActiveShellView( &pShellView ) ) ) // For some reason there is no active shell view continue; CComQIPtr< IFolderView > pFolderView{ pShellView }; if( ! pFolderView ) // The shell view doesn''t implement IFolderView continue; // Get the interface from which we can finally query the PIDL of // the current folder. CComPtr< IPersistFolder2 > pFolder; if( FAILED( pFolderView->GetFolder( IID_IPersistFolder2, (void**) &pFolder ) ) ) continue; LPITEMIDLIST pidl = nullptr; if( SUCCEEDED( pFolder->GetCurFolder( &pidl ) ) ) { // Take ownership of the PIDL via std::unique_ptr. info.pidl = UniquePidlPtr{ pidl }; result.push_back( std::move( info ) ); } } return result; }

Ejemplo que muestra cómo llamar a GetCurrentExplorerFolders() , convertir PIDL en ruta y detectar excepciones.

int main() { ::CoInitialize( nullptr ); try { std::wcout << L"Currently open explorer windows:/n"; for( const auto& info : GetCurrentExplorerFolders() ) { wchar_t path[ 32767 ]; if( ::SHGetPathFromIDListEx( info.pidl.get(), path, ARRAYSIZE(path), 0 ) ) std::wcout << L"hwnd: 0x" << std::hex << info.hwnd << L", path: " << path << L"/n"; } } catch( std::system_error& e ) { std::cout << "ERROR: " << e.what() << "/nError code: " << e.code() << "/n"; } ::CoUninitialize(); }

Posible resultado:

Currently open explorer windows: hwnd: 0x0030058E, path: C:/Windows hwnd: 0x000C06D4, path: C:/Program Files