Windows FileChooser parent window

On Windows, native file choosers have the annoying property that they are not automatically focused when the user clicks on the main window while one is open. Also once the file chooser is behind another window, there’s no way to bring it back to focus and your app just appears to hang.

Normally if you show dialogs in Windows, you have to set up an owner HWND, eg. for an open dialog that’s most likely your main window.

So let’s apply the following patch to juce_win32_FileChooser.cpp. This grabs the current component with keyboard focus and assumes that’s the parent window for the file chooser. It’s a bit hacky but it gets the job done:

filechooser-5.diff.txt (3.4 KB)

The file choosers now behave as expected — if you click the main window, the file chooser will pop to the top and the title bar will flash. No more “hangs”.

Thanks, didn’t know that was a problem, I’ll have a look at that…

I tend to have to use something like:

m_pParent->getParentComponent()->toFront (true);

where m_pParent is a class member…

MainContentComponent*   m_pParent;

after closing a chooser… so it’s not Windows only.


hmm - just looked at your suggested changes, but you seem to be ignoring the async flag - I think this might break code that uses the file chooser asynchronously (which will before too long be the way we all have to use them). Have you actually tried using it asynchronously, in case that actually works as expected? (as well as being a far safer way to do it compared to the old modal loop approach)

The idea is that for both modal and asynchronous calls the HWND will come from the currently focused component.

I did notice that when using launchAsync() the resulting dialog is the old Windows 95-style dialog, which is a consequence of using the OFN_ENABLEHOOK flag.

Anyway, file choosers on Windows by definition run a modal loop one way or another, so there using the modal versions will probably be the safer choice.

An alternative solution is to override inputAttemptWhenModal() so it raises the file chooser.

    virtual void inputAttemptWhenModal() override
        // find handle of the native popup window
        HWND hwnd = GetWindow((HWND) getWindowHandle(), GW_ENABLEDPOPUP);
        if (!hwnd) return;
        FLASHWINFO fw = { sizeof(fw) };
        fw.hwnd = hwnd;
        fw.dwFlags = FLASHW_CAPTION;
        fw.uCount = 6;
        fw.dwTimeout = 70;

This works much better if there are multiple top-level windows.