3

I know how to get the HWND of the desktop: GetDesktopWindow().

But I haven't been able to find a function that returns the HWND of the currently active Windows Explorer main window.

How do I get the HWND of the currently active Windows Explorer window in a safe and reliable manner?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
WinWin
  • 7,493
  • 10
  • 44
  • 53
  • 1
    This is inherently unreliable - even if you get the HWND of the currently-active explorer window (assuming there even is any), there's nothing preventing the window from closing and being destroyed before your program can do anything with the HWND. – bdonlan Jun 09 '11 at 20:44
  • Why? Whatever you're attempting to do is probably unsupported. – Adrian McCarthy Jun 09 '11 at 20:45

2 Answers2

9

You can get the currently active window via GetForegroundWindow(). You could then do GetWindowThreadProcessId() to get a PID which you can then convert to a process handle with OpenProcess() (you will want PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights) and then you can check the process name with GetModuleFileNameEx(). Don't remember to close the process handle afterwards with CloseHandle().

Here's some code I just wrote in notepad. You'd probably do something along these lines.

DWORD  lpFileName[MAX_PATH] = {0};
DWORD  dwPID;
HANDLE hProcess;
HWND   hwnd = GetForegroundWindow();
GetWindowThreadProcessId( hwnd, &dwPID );
hProcess = OpenProcess( PROCESS_QUERY_INFOMRATION | PROCESS_VM_READ, false, dwPID );
GetModuleFileNameEx( hProcess, NULL, lpFileName, _countof( lpFileName ) );
PathStripPath( lpFileName );

if( _tcscmp( _T("explorer.exe"), lpFileName ) == 0 ) {
  _tprintf( _T("explorer window found") );
} else {
  _tprintf( _T("foreground window was not explorer window") );
}
CloseHandle( hProcess );

To get all open explorer windows you can use EnumWindows() which you provide a callback which receives all the top-level windows. You can then filter out however you want, maybe by process name (above), maybe by class name (GetClassName()).

Mike Kwan
  • 24,123
  • 12
  • 63
  • 96
  • & @Nick - thank you both for great & educating answers. Since you seem very knowledgeable, perhaps you have an idea about this question, too? http://stackoverflow.com/questions/6270539/how-to-shell-notifyicon-without-adding-an-icon-in-the-notification-area :) – WinWin Jun 09 '11 at 21:56
3

Well, if you're certain that a Windows Explorer window is currently the foreground window you can use GetForegroundWindow. Otherwise, I think you'd have to enumerate through all windows until you've found the top-most Explorer window. Here's an example that I wrote up of how to enumerate through all windows*. Then, according to this SO thread, you can use GetWindowThreadProcessId to filter windows owned by Explorer.

*It's been a while, but I think EnumWindows iterates from the top of the z-order to the bottom.

Community
  • 1
  • 1
Nick Spreitzer
  • 10,242
  • 4
  • 35
  • 58