• Programming: find a minimized file-explorer window

    From R.Wieser@address@is.invalid to comp.os.ms-windows.programmer.win32,alt.windows7.general on Tue Oct 7 10:12:54 2025
    From Newsgroup: alt.windows7.general

    Hello all,

    I'm in a bit of picle : I'm using user32.dll's ShellExecute to open another file explorer window, which I than want to move around.

    The problem is that ShellExecute doesn't seem to return a handle to the just-created explorer window (if someone knows how to get it from
    ShellExecute I would like to know!).

    So, I'm using FindWindowEx to find the file-explorer window. Alas, it
    doesn't find the window if its created mimimized.

    Question: how do I find a (or rather: the last-created) file-explorer
    window, minimized or not ?

    I've just been googeling, but am not getting any results (pertaining to the problem. Lots of others though. :-( )

    Regards,
    Rudy Wieser


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Paul@nospam@needed.invalid to comp.os.ms-windows.programmer.win32,alt.windows7.general on Tue Oct 7 06:25:34 2025
    From Newsgroup: alt.windows7.general

    On Tue, 10/7/2025 4:12 AM, R.Wieser wrote:
    Hello all,

    I'm in a bit of picle : I'm using user32.dll's ShellExecute to open another file explorer window, which I than want to move around.

    The problem is that ShellExecute doesn't seem to return a handle to the just-created explorer window (if someone knows how to get it from ShellExecute I would like to know!).

    So, I'm using FindWindowEx to find the file-explorer window. Alas, it doesn't find the window if its created mimimized.

    Question: how do I find a (or rather: the last-created) file-explorer window, minimized or not ?

    I've just been googeling, but am not getting any results (pertaining to the problem. Lots of others though. :-( )

    Regards,
    Rudy Wieser



    Probably quicker to pop it in the Toaster, and see what comes out.

    CoPilot
    -------

    I'm using user32.dll's ShellExecute to open another
    file explorer window, which I then want to move around.

    ShellExecute does not seem to return a handle to the just-created explorer window.

    Using FindWindowEx, if the File Explorer window is minimized, I cannot find the window.

    How do I find this (last-created) file-explorer window, whether it is minimized or not ?

    Returned Answer
    ---------------

    [Picture]

    xxx

    *************************************** As Text ******************************************

    You're absolutely rightrCo'ShellExecute' doesn't return a window handle ('HWND'), which makes
    tracking the newly opened File Explorer window a bit tricky. And yes, 'FindWindowEx' won't
    locate minimized windows reliably because they may not be visible in the Z-order or may not
    match your search criteria. Here's a more robust approach to identify and manipulate the
    newly opened File Explorer window:

    ---

    ### Strategy: Use Process Tracking + Window Enumeration

    Instead of relying on 'ShellExecute', switch to 'ShellExecuteEx' or 'CreateProcess' to get
    the process ID (PID) of the launched explorer instance. Then, enumerate all top-level windows
    and match them to that PID.

    ---

    ### Step-by-Step Solution

    1. Use 'ShellExecuteEx' to launch Explorer and get the PID:

    '''cpp
    SHELLEXECUTEINFO sei = { sizeof(sei) };
    sei.fMask = SEE_MASK_NOCLOSEPROCESS;
    sei.lpVerb = L"open";
    sei.lpFile = L"explorer.exe";
    sei.lpParameters = L"C:\\Your\\Target\\Path";
    sei.nShow = SW_SHOWNORMAL;

    if (ShellExecuteEx(&sei)) {
    DWORD pid = GetProcessId(sei.hProcess);
    // Now use this PID to find the window
    }
    ```

    2. Enumerate all top-level windows and match the PID:

    '''cpp
    HWND targetHwnd = nullptr;

    EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL {
    DWORD windowPid;
    GetWindowThreadProcessId(hwnd, &windowPid);

    if (windowPid == (DWORD)lParam) {
    // Optional: Check if it's an Explorer window
    wchar_t className[256];
    GetClassName(hwnd, className, sizeof(className)/sizeof(wchar_t));
    if (wcscmp(className, L"CabinetWClass") == 0 || wcscmp(className, L"ExplorerWClass") == 0) {
    targetHwnd = hwnd;
    return FALSE; // Stop enumeration
    }
    }
    return TRUE;
    }, (LPARAM)pid);
    ```

    3. Handle minimized windows:

    Once you have the 'HWND', you can restore and move it:

    '''cpp
    ShowWindow(targetHwnd, SW_RESTORE); // Restore if minimized
    MoveWindow(targetHwnd, x, y, width, height, TRUE); // Move it
    '''

    ---

    ### Notes

    - Explorer.exe reuse:

    Windows may reuse an existing 'explorer.exe' process,
    so launching a new one doesn't always mean a new PID. You might
    need to monitor window creation events or use a timestamp to correlate.

    - Alternative:
    Consider using UI Automation (via 'UIAutomationClient') or Windows Accessibility APIs
    if you need more control over Explorer windows.

    ---

    Want help wrapping this into a reusable function or class? Or are you working in a specific language like C#, C++, or Python with ctypes?
    *************************************** As Text ******************************************

    Paul

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Paul@nospam@needed.invalid to comp.os.ms-windows.programmer.win32,alt.windows7.general on Tue Oct 7 06:29:54 2025
    From Newsgroup: alt.windows7.general

    On Tue, 10/7/2025 6:25 AM, Paul wrote:
    On Tue, 10/7/2025 4:12 AM, R.Wieser wrote:
    Hello all,

    I'm in a bit of picle : I'm using user32.dll's ShellExecute to open another >> file explorer window, which I than want to move around.

    The problem is that ShellExecute doesn't seem to return a handle to the
    just-created explorer window (if someone knows how to get it from
    ShellExecute I would like to know!).

    So, I'm using FindWindowEx to find the file-explorer window. Alas, it
    doesn't find the window if its created mimimized.

    Question: how do I find a (or rather: the last-created) file-explorer
    window, minimized or not ?

    I've just been googeling, but am not getting any results (pertaining to the >> problem. Lots of others though. :-( )

    Regards,
    Rudy Wieser



    Probably quicker to pop it in the Toaster, and see what comes out.

    CoPilot
    -------

    I'm using user32.dll's ShellExecute to open another
    file explorer window, which I then want to move around.

    ShellExecute does not seem to return a handle to the just-created explorer window.

    Using FindWindowEx, if the File Explorer window is minimized, I cannot find the window.

    How do I find this (last-created) file-explorer window, whether it is minimized or not ?

    Returned Answer
    ---------------

    [Picture]

    https://i.postimg.cc/FzptvhWS/HWND-graphics.gif <=== forgot the picture. "Download Original"
    for a cleaner copy

    Paul

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From R.Wieser@address@is.invalid to comp.os.ms-windows.programmer.win32,alt.windows7.general on Tue Oct 7 14:05:39 2025
    From Newsgroup: alt.windows7.general

    Paul,

    Probably quicker to pop it in the Toaster, and see what comes out.
    ...
    Instead of relying on 'ShellExecute', switch to 'ShellExecuteEx' or 'CreateProcess' to get the process ID (PID) of the launched explorer instance. Then, enumerate all top-level windows and match them to
    that PID.
    ...
    Windows may reuse an existing 'explorer.exe' process,
    so launching a new one doesn't always mean a new PID. You might
    need to monitor window creation events or use a timestamp to
    correlate.

    :-) I did not need an AI to find the information mentioned in the second paragraph.

    After failing to get it to work reliably I also found the "doesn't always return a new PID" information as mentioned in the third paragraph. Which
    is why I dropped it.

    As for monitoring the window creation events ? Why now do I get the
    feeling that that is just leading to /at least/ double the problems that
    such a method would solve ? :-|

    As for "use a timestamp" ? That sounds interresting, but I've never heard that a created window exposes a timestamp...

    I'll probably revisit the problem though, even just to see if I missed something.

    Regards,
    Rudy Wieser


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From VanguardLH@V@nguard.LH to comp.os.ms-windows.programmer.win32,alt.windows7.general on Tue Oct 7 11:14:19 2025
    From Newsgroup: alt.windows7.general

    "R.Wieser" <address@is.invalid> wrote:

    Hello all,

    I'm in a bit of picle : I'm using user32.dll's ShellExecute to open another file explorer window, which I than want to move around.

    The problem is that ShellExecute doesn't seem to return a handle to the just-created explorer window (if someone knows how to get it from ShellExecute I would like to know!).

    So, I'm using FindWindowEx to find the file-explorer window. Alas, it doesn't find the window if its created mimimized.

    Question: how do I find a (or rather: the last-created) file-explorer window, minimized or not ?

    I've just been googeling, but am not getting any results (pertaining to the problem. Lots of others though. :-( )

    Regards,
    Rudy Wieser

    https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindoww

    Says the returned value is the HWND of the newly created window, or NULL
    if it failed.

    https://learn.microsoft.com/en-us/windows/win32/learnwin32/creating-a-window

    That also states the returned value for CreateWindowEx is HWND if the
    open worked, NULL if it failed.

    I suspect you used ShellExecute to run a specific exe file, like
    explorer.exe, but that won't give the file handle, but the PID for the
    newly loaded process. From:

    https://stackoverflow.com/questions/7620322/get-pid-from-shellexecute

    looks like you need to preset a flag, and then use GetProcessID to get
    the PID.

    https://forums.codeguru.com/showthread.php?467956-RESOLVED-ShellExecute-and-PID

    That mentions using ShellExecuteEx to get the PID. Then:

    https://stackoverflow.com/questions/11711417/get-hwnd-by-process-id-c

    mentions how to get the window handle(s) for a PID.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Paul@nospam@needed.invalid to comp.os.ms-windows.programmer.win32,alt.windows7.general on Tue Oct 7 13:47:25 2025
    From Newsgroup: alt.windows7.general

    On Tue, 10/7/2025 8:05 AM, R.Wieser wrote:
    Paul,

    Probably quicker to pop it in the Toaster, and see what comes out.
    ...
    Instead of relying on 'ShellExecute', switch to 'ShellExecuteEx' or
    'CreateProcess' to get the process ID (PID) of the launched explorer
    instance. Then, enumerate all top-level windows and match them to
    that PID.
    ...
    Windows may reuse an existing 'explorer.exe' process,
    so launching a new one doesn't always mean a new PID. You might
    need to monitor window creation events or use a timestamp to
    correlate.

    :-) I did not need an AI to find the information mentioned in the second paragraph.

    After failing to get it to work reliably I also found the "doesn't always return a new PID" information as mentioned in the third paragraph. Which
    is why I dropped it.

    As for monitoring the window creation events ? Why now do I get the
    feeling that that is just leading to /at least/ double the problems that
    such a method would solve ? :-|

    As for "use a timestamp" ? That sounds interresting, but I've never heard that a created window exposes a timestamp...

    I'll probably revisit the problem though, even just to see if I missed something.

    Regards,
    Rudy Wieser



    The main value of the AI answer is the breadcrumbs.

    You have to *prove* any theories offered, hold water.

    I just spent hours, doing a transition of disk partitions,
    the AI having made a suggested serving of the order and
    spacing, and the AI had "nailed it". After I did as it
    suggested, right after that, what I was trying to do
    "just worked". I could not though, just blindly accept the idea,
    as there was no way to guess what the downstream impact
    would be. But in the end, the AI saved me some time,
    because it limited the permutations and combinations I
    would have needed to test, if I tried to brute force it
    using ordinary search results (hints but not enough detail
    to be sure).

    Paul
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From JJ@jj4public@gmail.com to comp.os.ms-windows.programmer.win32,alt.windows7.general on Wed Oct 8 08:31:12 2025
    From Newsgroup: alt.windows7.general

    On Tue, 7 Oct 2025 10:12:54 +0200, R.Wieser wrote:

    Hello all,

    I'm in a bit of picle : I'm using user32.dll's ShellExecute to open another file explorer window, which I than want to move around.

    The problem is that ShellExecute doesn't seem to return a handle to the just-created explorer window (if someone knows how to get it from ShellExecute I would like to know!).

    So, I'm using FindWindowEx to find the file-explorer window. Alas, it doesn't find the window if its created mimimized.

    Question: how do I find a (or rather: the last-created) file-explorer window, minimized or not ?

    I've just been googeling, but am not getting any results (pertaining to the problem. Lots of others though. :-( )

    Regards,
    Rudy Wieser

    Use `Shell.Application` COM object to enumerate all explorer windows.
    Minimized or not, and hidden or not. Do like what it does, if COM usage is
    not applicable/acceptable.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From R.Wieser@address@is.invalid to comp.os.ms-windows.programmer.win32,alt.windows7.general on Wed Oct 8 07:52:32 2025
    From Newsgroup: alt.windows7.general

    VanguardLH

    https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindoww

    Says the returned value is the HWND of the newly created window,
    or NULL if it failed.

    https://learn.microsoft.com/en-us/windows/win32/learnwin32/creating-a-window

    That also states the returned value for CreateWindowEx is HWND if the
    open worked, NULL if it failed.

    I don't see how I can provide a executables filename to those. Can you explain/give an example ?

    https://stackoverflow.com/questions/7620322/get-pid-from-shellexecute

    looks like you need to preset a flag, and then use GetProcessID to get
    the PID.

    https://forums.codeguru.com/showthread.php?467956-RESOLVED-ShellExecute-and-PID

    That mentions using ShellExecuteEx to get the PID. Then:

    There is also mentioned that it doesn't /always/ return that pid. Reason enough for me not to want to use that method.

    https://stackoverflow.com/questions/11711417/get-hwnd-by-process-id-c

    mentions how to get the window handle(s) for a PID.

    Getting window handles isn't a problem. Picking the one that just got
    created from those is.

    Mind you, a single explorer.exe process can have multiple file-browser
    windows open.

    Regards,
    Rudy Wieser


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From R.Wieser@address@is.invalid to comp.os.ms-windows.programmer.win32,alt.windows7.general on Wed Oct 8 08:18:01 2025
    From Newsgroup: alt.windows7.general

    Paul,

    The main value of the AI answer is the breadcrumbs.

    Indeed. I wish more people would understand that, and not regard them as facts. There is even a possibility that the "breadcrumbs" are actually rat-poisson pellets ...

    You have to *prove* any theories offered, hold water.

    Yep. The problem is that "A fool can ask more questions in an hour than a wise man can answer in seven years." The same goes for a fools
    suggestions.

    Regards,
    Rudy Wieser


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From R.Wieser@address@is.invalid to comp.os.ms-windows.programmer.win32,alt.windows7.general on Wed Oct 8 09:34:52 2025
    From Newsgroup: alt.windows7.general

    Paul,

    By the way :

    Returned Answer
    ...
    if (ShellExecuteEx(&sei)) {
    DWORD pid = GetProcessId(sei.hProcess);
    // Now use this PID to find the window
    }
    ```

    2. Enumerate all top-level windows and match the PID:

    '''cpp
    HWND targetHwnd = nullptr;

    EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL {
    DWORD windowPid;
    GetWindowThreadProcessId(hwnd, &windowPid);

    if (windowPid == (DWORD)lParam) {
    // Optional: Check if it's an Explorer window
    wchar_t className[256];
    GetClassName(hwnd, className,
    sizeof(className)/sizeof(wchar_t));
    if (wcscmp(className, L"CabinetWClass") == 0 ||
    wcscmp(className, L"ExplorerWClass") == 0) {
    targetHwnd = hwnd;
    return FALSE; // Stop enumeration
    }
    }
    return TRUE;
    }, (LPARAM)pid);
    ```

    When I checked my (now year-old) experimenting/testing code does exactly
    that - but even when I sleep for a second before EnumWindows I do not get a match. A slew of windows, but no match.

    Proc 0000060C
    Pid 00000ED4
    hWnd 00040264 Pid:000005BC 'CabinetWClass'
    hWnd 000801AE Pid:000005BC 'ExploreWClass'
    hWnd 0010017C Pid:000005BC 'ExploreWClass'

    (just showing the explorer-class results).

    Regards,
    Rudy Wieser



    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From R.Wieser@address@is.invalid to comp.os.ms-windows.programmer.win32,alt.windows7.general on Thu Oct 9 07:11:35 2025
    From Newsgroup: alt.windows7.general

    Another thing :

    2. Enumerate all top-level windows and match the PID:

    '''cpp
    HWND targetHwnd = nullptr;

    EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL {
    DWORD windowPid;
    GetWindowThreadProcessId(hwnd, &windowPid);

    if (windowPid == (DWORD)lParam) {
    // Optional: Check if it's an Explorer window
    wchar_t className[256];
    GetClassName(hwnd, className,
    sizeof(className)/sizeof(wchar_t));
    if (wcscmp(className, L"CabinetWClass") == 0 ||
    wcscmp(className, L"ExplorerWClass") == 0) {
    targetHwnd = hwnd;
    return FALSE; // Stop enumeration
    }
    }
    return TRUE;
    }, (LPARAM)pid);

    The code doesn't consider the, very likely, possibility of another file-explorer window already being open.

    Regards,
    Rudy Wieser


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Jakob Bohm@egenagwemdimtapsar@jbohm.dk to comp.os.ms-windows.programmer.win32,alt.windows7.general on Mon Oct 13 00:02:46 2025
    From Newsgroup: alt.windows7.general

    On 2025-10-08 03:31, JJ wrote:
    On Tue, 7 Oct 2025 10:12:54 +0200, R.Wieser wrote:

    Hello all,

    I'm in a bit of picle : I'm using user32.dll's ShellExecute to open another >> file explorer window, which I than want to move around.

    The problem is that ShellExecute doesn't seem to return a handle to the
    just-created explorer window (if someone knows how to get it from
    ShellExecute I would like to know!).

    So, I'm using FindWindowEx to find the file-explorer window. Alas, it
    doesn't find the window if its created mimimized.

    Question: how do I find a (or rather: the last-created) file-explorer
    window, minimized or not ?

    I've just been googeling, but am not getting any results (pertaining to the >> problem. Lots of others though. :-( )

    Regards,
    Rudy Wieser

    Use `Shell.Application` COM object to enumerate all explorer windows. Minimized or not, and hidden or not. Do like what it does, if COM usage is not applicable/acceptable.


    Previous posts already included how to do the enumeration without COM
    overhead . The problem is that launching (directly or indirectly) explorer.exe may randomly cause the launched explorer process to pass
    the request to any of the already running explorer.exe processes, in
    which case the problem is to determine /which one/ of the explorer
    windows owned by the various explorer.exe processes pertains to the
    request just made to ShellExecuteEx().


    Enjoy

    Jakob
    --
    Jakob Bohm, MSc.Eng., I speak only for myself, not my company
    This public discussion message is non-binding and may contain errors
    All trademarks and other things belong to their owners, if any.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From R.Wieser@address@is.invalid to comp.os.ms-windows.programmer.win32,alt.windows7.general on Mon Oct 13 07:32:43 2025
    From Newsgroup: alt.windows7.general

    Jakob, others,

    The problem is that launching (directly or indirectly) explorer.exe may randomly cause the launched explorer process to pass the request to any of the already running explorer.exe processes, in which case the problem is
    to determine /which one/ of the explorer windows owned by the various explorer.exe processes pertains to the request just made to ShellExecuteEx().

    As mentioned, I *never* get a process handle back which has an explorer
    window (might be because I'm using WinXP), so I just scan all the windows.
    It doesn't make a difference (just takes a bit more time).

    Also, ShellExecute(Ex) may return well before the actual window has been created (regardles of the SEE_MASK_WAITFORINPUTIDLE flag application).

    One other problem I found is that when I get a CabinetWClass window the next attempt to open the same folder doesn't create a new window, but just (restores and) focusses the old one.

    And something I overlooked : You cannot tell a minimized (or maximized)
    window to move around.

    Bottom line: I have to create the new explorer window normally, move it
    around and only than, if wanted, minimize it.

    Regards,
    Rudy Wieser


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Schugo@schugo@schugo.de to comp.os.ms-windows.programmer.win32,alt.windows7.general on Mon Oct 13 15:53:34 2025
    From Newsgroup: alt.windows7.general

    On 13.10.2025 07:32, R.Wieser wrote:
    Jakob, others,

    The problem is that launching (directly or indirectly) explorer.exe may
    randomly cause the launched explorer process to pass the request to any of >> the already running explorer.exe processes, in which case the problem is
    to determine /which one/ of the explorer windows owned by the various
    explorer.exe processes pertains to the request just made to
    ShellExecuteEx().

    As mentioned, I *never* get a process handle back which has an explorer window (might be because I'm using WinXP), so I just scan all the windows. It doesn't make a difference (just takes a bit more time).

    Also, ShellExecute(Ex) may return well before the actual window has been created (regardles of the SEE_MASK_WAITFORINPUTIDLE flag application).

    One other problem I found is that when I get a CabinetWClass window the next attempt to open the same folder doesn't create a new window, but just (restores and) focusses the old one.

    And something I overlooked : You cannot tell a minimized (or maximized) window to move around.

    Bottom line: I have to create the new explorer window normally, move it around and only than, if wanted, minimize it.

    hi,

    have you maybe tried FindWindow?
    If you know the exact title bar text it should work.
    (if you don't open the same folder window twice...)

    ciao..

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From R.Wieser@address@is.invalid to comp.os.ms-windows.programmer.win32,alt.windows7.general on Mon Oct 13 18:04:24 2025
    From Newsgroup: alt.windows7.general

    Schugo,

    have you maybe tried FindWindow?

    Yep. I used that in my first version of my program (from before I posted my question).

    The thing is that that doesn't quite work when you try to open a
    CabinetWClass window using the same folder.

    If you know the exact title bar text it should work.

    I thought of that too, but I dislike the idea of having the commandline
    parsed twice (once by my program, a second time by explorer.exe).

    (if you don't open the same folder window twice...)

    Well, the thing is that I would like my program to work regardless of the commandline thats provided (including "/e", "/n" or neither). I'm looking
    at it as a challenge. :-)

    Thanks for the suggestion.

    Regards,
    Rudy Wieser


    --- Synchronet 3.21a-Linux NewsLink 1.2