wxWindow:GetPPI()

251 views
Skip to first unread message

Gunter Königsmann

unread,
Feb 4, 2019, 1:18:21 AM2/4/19
to wx-users
Dear all,

I've read that wxGetDisplayPPI() is kind of deprecated since it doesn't return a per-display ppi rate. So I've switched to wxDisplay::GetPPI(int display). But I seem unable to find a way to find out which display my application currently is shown on.

If there were such a way I would propose a wxWindow::GetPPI() function that

Gunter Königsmann

unread,
Feb 4, 2019, 1:19:11 AM2/4/19
to wx-users
(accidentally hit the "send" button)

automatically returns the ppi for the current window.

Vojtěch Král

unread,
Feb 4, 2019, 3:38:56 AM2/4/19
to wx-users
In our code we do something like:

const unsigned display_idx = wxDisplay::GetFromWindow(window);
const wxSize ppi = (display_idx != wxNOT_FOUND ? wxDisplay(display_idx) : wxDisplay(0u)).GetPPI();

BR, VK

Dne pondělí 4. února 2019 7:19:11 UTC+1 Gunter Königsmann napsal(a):

Vadim Zeitlin

unread,
Feb 4, 2019, 5:00:12 AM2/4/19
to wx-u...@googlegroups.com
On Sun, 3 Feb 2019 22:18:21 -0800 (PST) Gunter Königsmann wrote:

GK> I've read that wxGetDisplayPPI() is kind of deprecated since it doesn't
GK> return a per-display ppi rate. So I've switched to
GK> wxDisplay::GetPPI(int display). But I seem unable to find a way to find
GK> out which display my application currently is shown on.

See wxDisplay::GetFromWindow().

GK> If there were such a way I would propose a wxWindow::GetPPI() function

Since 3.1.2 you can get the PPI appropriate for the given window via

wxDisplay(window).GetPPI()

(previously you had to use GetFromWindow() explicitly).

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

Vojtěch Král

unread,
Feb 4, 2019, 9:23:47 AM2/4/19
to wx-users
It should be noted, however, that on Linux the wxDisplay::GetFromWindow() function only works reliably once the window is on screen / has been on screen for a bit.
The following code:

std::cerr << "screen idx:" << wxDisplay::GetFromWindow(this) << std::endl;
Bind(wxEVT_SHOW, [this](wxShowEvent &event) {
std::cerr << "screen idx:" << wxDisplay::GetFromWindow(this) << std::endl;
CallAfter([=]() {
std::cerr << "screen idx:" << wxDisplay::GetFromWindow(this) << std::endl;
});
});

outputs

0
0
1

on my machine when I use an external screen (with `0` being the external screen and `1` the default laptop built-in screen).

I'm not sure what's going on there, but I've learned not to rely on bare wxDisplay::GetFromWindow() in window construction code.

BR,
~VK


Dne pondělí 4. února 2019 11:00:12 UTC+1 Vadim Zeitlin napsal(a):

Nathan Hartman

unread,
Feb 4, 2019, 10:03:53 AM2/4/19
to wx-u...@googlegroups.com
On Mon, Feb 4, 2019 at 9:23 AM Vojtěch Král <vojtec...@prusa3d.cz> wrote:
It should be noted, however, that on Linux the wxDisplay::GetFromWindow() function only works reliably once the window is on screen / has been on screen for a bit.

Doh!

I'm not sure what's going on there, but I've learned not to rely on bare wxDisplay::GetFromWindow() in window construction code.

Well that begs the question, how to handle high DPI reliably?

Vadim Zeitlin

unread,
Feb 4, 2019, 8:59:09 PM2/4/19
to wx-u...@googlegroups.com
On Mon, 4 Feb 2019 06:23:46 -0800 (PST) Vojtěch Král wrote:

VK> It should be noted, however, that on Linux the wxDisplay::GetFromWindow()
VK> function only works reliably once the window is on screen / has been on
VK> screen for a bit.

Yes, it must be "mapped" to the display to know which display it's on.
This is annoying and inconvenient but I don't believe there is any around
it when using X11.

VK> I'm not sure what's going on there, but I've learned not to rely on bare
VK> wxDisplay::GetFromWindow() in window construction code.

Yes, unfortunately this is how you need to do it. Note that
wxWindowCreateEvent is sent by wxGTK only once the window has been
realized, so it's safe to do everything in this event handler.

Vojtěch Král

unread,
Feb 5, 2019, 3:42:37 AM2/5/19
to wx-users
Dne úterý 5. února 2019 2:59:09 UTC+1 Vadim Zeitlin napsal(a):
Note that
wxWindowCreateEvent is sent by wxGTK only once the window has been
realized, so it's safe to do everything in this event handler.

Ah, didn't know that one. Brilliant, thanks!
~VK

Vojtěch Král

unread,
Feb 5, 2019, 3:52:59 AM2/5/19
to wx-users
Dne úterý 5. února 2019 2:59:09 UTC+1 Vadim Zeitlin napsal(a):
Note that
wxWindowCreateEvent is sent by wxGTK only once the window has been
realized, so it's safe to do everything in this event handler.

Eh, spoke too soon. Looks like I still need the CallAfter() even in the wxWindowCreateEvent handler.
BR, ~VK

Vadim Zeitlin

unread,
Feb 5, 2019, 11:20:30 AM2/5/19
to wx-u...@googlegroups.com
On Tue, 5 Feb 2019 00:52:59 -0800 (PST) Vojtěch Král wrote:

VK> Dne úterý 5. února 2019 2:59:09 UTC+1 Vadim Zeitlin napsal(a):
VK> >
VK> > Note that
VK> > wxWindowCreateEvent is sent by wxGTK only once the window has been
VK> > realized, so it's safe to do everything in this event handler.
VK>
VK> Eh, spoke too soon. Looks like I still need the CallAfter() even in the
VK> wxWindowCreateEvent handler.

This is bad news :-( I thought being "realized" was enough for this to
work, but apparently it only actually works when the window is "mapped",
which means that it needs to be done in the (first) wxShowEvent handler.
But then according to a quick web search it is apparently possible to get
wxPaintEvent ("expose" in Old GTKese or "draw" in modern) before "mapped"
which doesn't help at all.

What all this boils down to is that we probably need some new event or
maybe we can postpone sending wxWindowCreateEvent under GTK+ until the
window is fully ready to be used. Paul, if you're reading this, would you
have any (better) ideas about how could we make structuring application
code which needs to get the DPI applicable to the window when initializing
it? Does anybody know how do typical GTK+ applications do this?

Thanks in advance for any information,

Vojtěch Král

unread,
Feb 5, 2019, 11:37:44 AM2/5/19
to wx-users
Dne úterý 5. února 2019 17:20:30 UTC+1 Vadim Zeitlin napsal(a):
Paul, if you're reading this, would you
have any (better) ideas about how could we make structuring application
code which needs to get the DPI applicable to the window when initializing
it? Does anybody know how do typical GTK+ applications do this?

I'd just like to note here that this isn't specific to getting DPI, it's accessing window geometry in general.
In Slic3rPE we sanitize window position/size on startup to avoid, for example, placing windows on disconcected screens,
and that too needs to be done with EVT_SHOW+CallAfter on Linux to make it work and without EVT_SHOW+CallAfter on Windows to avoid flickery resizes.

Cross-platform dev is amusing...
Cheers, ~VK

Gunter Königsmann

unread,
Feb 11, 2019, 2:34:15 AM2/11/19
to wx-users
A bit off-topic, now. But - as my application can be moved from a high-dpi to a low-dpi screen I'll have to support ppi changes, anyway, so as a second thought no harm is done if mapping the window changes the ppi rate another time. 

But trying to do so I've encountered a practical problem I hope an expert can tell me a simple solution to: I use a wxAUIToolbar - and can call SetToolBitmap() every time the ppi changes. But how do I make the toolbar pane update its size afterwards especially as the size of the toolbar otherwise is locked?


Gunter Königsmann

unread,
Mar 1, 2019, 4:01:42 PM3/1/19
to wx-users
Found it:

m_manager.AddPane(m_worksheet->m_mainToolBar,
wxAuiPaneInfo().Name(wxT("toolbar")).
Top().TopDockable(true).Show(true).
BottomDockable(true).
CaptionVisible(false).CloseButton(false).
LeftDockable(false).DockFixed().
RightDockable(false).Gripper(false).Row(1)
);

Kind regards,

Gunter.

Thomas Krebs

unread,
Mar 13, 2019, 6:56:57 AM3/13/19
to wx-users
Hi,

I found that wxDisplay::GetPPI() doesn't work for us inMSW either.
I tried the display sample and even there I always get a dpi of 96 (the Windows default value) on whatever computer/display I use.
I assume at least there should be some manifest file on Windows if I get the docs on MS right like here:


Vadim Zeitlin

unread,
Mar 13, 2019, 12:19:00 PM3/13/19
to wx-u...@googlegroups.com
On Wed, 13 Mar 2019 03:56:57 -0700 (PDT) Thomas Krebs wrote:

TK> I found that wxDisplay::GetPPI() doesn't work for us inMSW either.

Concerning the "either" part, I still have "Fix GetPPI() on window
creation in wxGTK" in my TODO list, I just didn't have time to get back to
it yet...

TK> I tried the display sample and even there I always get a dpi of 96 (the
TK> Windows default value) on whatever computer/display I use.
TK> I assume at least there should be some manifest file on Windows if I get
TK> the docs on MS right like here:
TK> https://docs.microsoft.com/en-us/windows/desktop/hidpi/high-dpi-desktop-application-development-on-windows

Yes, it's the responsibility of your application to provide the
appropriate (i.e. with <dpiAwareness>PerMonitorV2</dpiAwareness> in it)
manifest, the library can't do it for you.

Regards,

Thomas Krebs

unread,
Mar 14, 2019, 4:47:29 AM3/14/19
to wx-users
Vadim,

Whatever I do I have never been able to get a manifest file that makes an application work in such a dpi aware mode.
I encounter all those problems that can be found about manifest files and dpi awareness.
Has anyone been able to get the wx display sample running correctly on MSW?

Gunter Königsmann

unread,
Mar 14, 2019, 7:06:01 AM3/14/19
to wx-u...@googlegroups.com

I encounter all those problems that can be found about manifest files and dpi awareness.
Has anyone been able to get the wx display sample running correctly on MSW?

An highDPI manifest that works with an application would be:

Vadim Zeitlin

unread,
Mar 14, 2019, 7:39:15 AM3/14/19
to wx-u...@googlegroups.com
On Thu, 14 Mar 2019 01:47:29 -0700 (PDT) Thomas Krebs wrote:

TK> Whatever I do I have never been able to get a manifest file that makes an
TK> application work in such a dpi aware mode.

If you mean "per-monitor DPI aware", then it's not in wx master yet, you
have to use https://github.com/wxWidgets/wxWidgets/pull/334 (which is WIP
still) for this. But "normal" DPI-aware mode, i.e. using the same (but non
default) value for all monitors, definitely works in 3.1.

TK> I encounter all those problems that can be found about manifest files and
TK> dpi awareness.
TK> Has anyone been able to get the wx display sample running correctly on MSW?

Yes. What manifest are you using exactly?

Thomas Krebs

unread,
Mar 14, 2019, 9:08:42 AM3/14/19
to wx-users
I used e.g. those about dpi awareness from:
without success.
I do not see any effect unless I set the DPI setting in Visual Studio VC14 under: "Manifest tool/Input Output" to "High DPI values" which then makes the application not to start any more. :-(

David Connet

unread,
Mar 14, 2019, 10:01:47 AM3/14/19
to wx-u...@googlegroups.com
On 3/14/2019 1:47 AM, Thomas Krebs wrote:
> Vadim,
>
> Whatever I do I have never been able to get a manifest file that makes
> an application work in such a dpi aware mode.
> I encounter all those problems that can be found about manifest files
> and dpi awareness.
> Has anyone been able to get the wx display sample running correctly on MSW?

I've had no issues... I also set
```
#define wxUSE_NO_MANIFEST 1
```
in my .rc and put the manifest together myself.

One thing I've noted (by observation, I haven't dug any deeper) is that
the system DPI seems to be governed by the primary monitor. So my home
system with a 100% monitor is scaled on the 200% one. (and vis-versa at
work)

Dave

QuentinC

unread,
Apr 6, 2019, 10:22:06 AM4/6/19
to wx-u...@googlegroups.com
Hello,

IN wxFileDialog, I see a method GetCurrentlySelectedFile.
However, I don't see anything to be notified when the selection change
in the documentation at
https://docs.wxwidgets.org/trunk/classwx_file_dialog.html

IN fact I don't see a reasonable way to use GetCurrentlySelectedFile,
except running a timer to check every second if the selection has
changed since
the last time. But it's a bad idea.

How do I proceed to be notified that the selection has changed inside
the dialog ? I don't see any event I can bind to.
The goal is to play a preview of an MP3 file.

Thank you.

Vadim Zeitlin

unread,
Apr 6, 2019, 11:29:06 AM4/6/19
to wx-u...@googlegroups.com
On Sat, 6 Apr 2019 16:21:57 +0200 QuentinC wrote:

Q> IN wxFileDialog, I see a method GetCurrentlySelectedFile.
Q> However, I don't see anything to be notified when the selection change
Q> in the documentation at
Q> https://docs.wxwidgets.org/trunk/classwx_file_dialog.html

There is nothing like this. As the commit 926df8a162a, which added this
method, says:

Add wxFileDialog::GetCurrentlySelectedFilename().

Also send wxEVT_UPDATE_UI events for the extra controls in wxFileDialog.

The combination of these changes allows extra controls to update their state
depending on the current selection in the dialog. Show a simple example of
doing it in the dialogs sample.

And, of course, you could also check the sample to see how it's actually done.

Q> IN fact I don't see a reasonable way to use GetCurrentlySelectedFile,
Q> except running a timer to check every second if the selection has
Q> changed since the last time. But it's a bad idea.

wxEVT_UPDATE_UI is a bit similar, but less bad, so this is what you should
use.

Regards,

QuentinC

unread,
Apr 19, 2019, 2:01:36 AM4/19/19
to wx-u...@googlegroups.com
Hello,


VZ> There is nothing like this. As the commit 926df8a162a, which added
this method, says:
VZ> Add wxFileDialog::GetCurrentlySelectedFilename().
VZ> Also send wxEVT_UPDATE_UI events for the extra controls in
FileDialog.
VZ> The combination of these changes allows extra controls to update
their state depending on the current selection in the dialog. Show a
simple example of doing it in the dialogs sample.
VZ> And, of course, you could also check the sample to see how it's
actually done.


Thank you. With your explanations and the sample, I have been able to
make a preview of the file currently selected and it works well.

Now I have another question about wxFileDialog.
On save, I have an extra button "Format options...". As the name
suggests, this button is supposed to open a dialog where the user can
choose a few additional options for the file he's going to save.
Problem: the dialog box ahs to depend on the format currently selected,
i.e. the filter index; and there might be no additional format options,
in which case the button must be disabled.
To give you a concrete example, the options aren't the same if I'm going
to save a JPG or PNG image. I'm not doing it for images but for audio
files but the principle is the same: you can choose /compression for
MP3, in OGG it is called quality and works differently, while you have
no compression options at all for Wave since it's an uncompressed format.

However,
1 - There is no GetCurrentlySelectedFilterIndex method similar to
GetCurrentlySelectedFilename
2 - When called while the dialog is open, GetFilterIndex always return
the filter index initially selected when the dialog is open, i.e. it
doesn't follow selection changes. It is only updated when the dialog is
closed.
3 - By using the same trick as the example for currently selected
filename, I get no notification for changes in the filter combobox.

So I think, this time, I have no way to implement what I want to do,
although it would be rather useful.

BY looking a bit in the sources, I think I know what is missing.
The CDN_SELCHANGE windows message is caught, but not the CDN_TYPECHANGE.
But then it would be rather strange to have the same wxXXXEvent event
triggered by two different messages, so we would need two wxFileDialog
specific events.


Could you do something about this ?
Thank you.

Vadim Zeitlin

unread,
Apr 19, 2019, 9:34:24 AM4/19/19
to wx-u...@googlegroups.com
On Fri, 19 Apr 2019 08:01:31 +0200 QuentinC wrote:

Q> Now I have another question about wxFileDialog.
Q> On save, I have an extra button "Format options...". As the name
Q> suggests, this button is supposed to open a dialog where the user can
Q> choose a few additional options for the file he's going to save.
Q> Problem: the dialog box ahs to depend on the format currently selected,
Q> i.e. the filter index; and there might be no additional format options,
Q> in which case the button must be disabled.
Q> To give you a concrete example, the options aren't the same if I'm going
Q> to save a JPG or PNG image. I'm not doing it for images but for audio
Q> files but the principle is the same: you can choose /compression for
Q> MP3, in OGG it is called quality and works differently, while you have
Q> no compression options at all for Wave since it's an uncompressed format.
Q>
Q> However,
Q> 1 - There is no GetCurrentlySelectedFilterIndex method similar to
Q> GetCurrentlySelectedFilename
Q> 2 - When called while the dialog is open, GetFilterIndex always return
Q> the filter index initially selected when the dialog is open, i.e. it
Q> doesn't follow selection changes. It is only updated when the dialog is
Q> closed.
Q> 3 - By using the same trick as the example for currently selected
Q> filename, I get no notification for changes in the filter combobox.
Q>
Q> So I think, this time, I have no way to implement what I want to do,
Q> although it would be rather useful.
Q>
Q> BY looking a bit in the sources, I think I know what is missing.
Q> The CDN_SELCHANGE windows message is caught, but not the CDN_TYPECHANGE.
Q> But then it would be rather strange to have the same wxXXXEvent event
Q> triggered by two different messages, so we would need two wxFileDialog
Q> specific events.
Q>
Q>
Q> Could you do something about this ?

Sorry, the only thing I can do is to recommend you to open a ticket with a
request for this enhancement, but I just have too many other things in the
pipeline to promise to do it in the near future. Of course, if you would
consider contributing a patch/PR implementing the currently missing
GetCurrentlySelectedFilterIndex() in a way similar to the existing
GetCurrentlySelectedFilename(), it would be gratefully accepted. And it
should be quite straightforward to do, if it's really just a matter of
handling CDN_TYPECHANGE in the existing hook procedure.

Regards,

QuentinC

unread,
Apr 19, 2019, 6:34:47 PM4/19/19
to wx-u...@googlegroups.com
Hello,

VZ>If you would consider contributing a patch/PR implementing the
currently missing GetCurrentlySelectedFilterIndex() in a way similar to
the existing
GetCurrentlySelectedFilename(), it would be gratefully accepted. And it
should be quite straightforward to do, if it's really just a matter of
handling CDN_TYPECHANGE in the existing hook procedure.

I might be able to do it so that it works for me, but I'm still afraid
that submitting a pull request is going to be hard.

1 - This would be my first pull request to an open source project, so
I'm not really sure of the exact procedure and all what I need to do
beside code
2 - I don't have any mac or linux; and on windows I'm using mingw-w64;
if I need to make the equivalent for something else than msw, or even
only check if it still compiles correctly and/or has no side effect on
other compilers and platforms, never count on me. I tried once to
install Visual Studio and didn't succeed, I have been lost in the
installer; I don't want to waste time configuring things and I'm very
thankful that people in the WXWidgets project made it easy to compile
without 10GB of complicated stuff.
3 - I'm blind, so indentation, alignment, spacing, etc. will be broken
in the submitted code for sure and I won't be able to do much about it.

Igor Korot

unread,
Apr 19, 2019, 10:22:28 PM4/19/19
to wx-u...@googlegroups.com
Hi,

On Fri, Apr 19, 2019 at 5:34 PM QuentinC <webm...@quentinc.net> wrote:
>
> Hello,
>
> VZ>If you would consider contributing a patch/PR implementing the
> currently missing GetCurrentlySelectedFilterIndex() in a way similar to
> the existing
> GetCurrentlySelectedFilename(), it would be gratefully accepted. And it
> should be quite straightforward to do, if it's really just a matter of
> handling CDN_TYPECHANGE in the existing hook procedure.
>
> I might be able to do it so that it works for me, but I'm still afraid
> that submitting a pull request is going to be hard.
>
> 1 - This would be my first pull request to an open source project, so
> I'm not really sure of the exact procedure and all what I need to do
> beside code

Don't be afraid. The procedure is very easy.

0. Create a fork of the wxWidgets repository. It is very easy - go to github.com
and click on the button "create fork".
1. Clone your fork of wxWidgets repository on you local hard drive.
You should have a Git client or GitHub client to do that.
2.. Create a branch on you local fork.
3. Make your modifications locally on you forked repository.
4. Update the "dialog" sample and documentation.
5. Compile and test.
6. Push you changes to your local repository.
7. Open the wxWidgets repository and click the "Create Pull Request" button.

> 2 - I don't have any mac or linux; and on windows I'm using mingw-w64;
> if I need to make the equivalent for something else than msw, or even
> only check if it still compiles correctly and/or has no side effect on
> other compilers and platforms, never count on me. I tried once to
> install Visual Studio and didn't succeed, I have been lost in the
> installer; I don't want to waste time configuring things and I'm very
> thankful that people in the WXWidgets project made it easy to compile
> without 10GB of complicated stuff.

It is possible to submit the patchPR to only one OS and hopefully someone
will submit this for other OSes.

> 3 - I'm blind, so indentation, alignment, spacing, etc. will be broken
> in the submitted code for sure and I won't be able to do much about it.

The styling of the code might be the issue.
But you can also submit a patch with the new ticket on trac.wxwidgets.org.

Thank you.

>
> --
> Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.
>
> To unsubscribe, send email to wx-users+u...@googlegroups.com
> or visit http://groups.google.com/group/wx-users

Igor Korot

unread,
Apr 19, 2019, 11:01:56 PM4/19/19
to wx-u...@googlegroups.com
Hi,
I just checked the documentation for GTK and OSX.
On both of those OSes (including GTK+2) this functionality is not supported.

GTK+3 file dialog does not have a type selection possibility.
GTK+2 does, but changing it is not exposed to the external program.

On OSX this is also not available - there is no such notification in
Cocoa for it.

So this will be MSW-specific.

Vadim Zeitlin

unread,
Apr 20, 2019, 8:49:08 AM4/20/19
to wx-u...@googlegroups.com
On Sat, 20 Apr 2019 00:34:37 +0200 QuentinC wrote:

Q> I might be able to do it so that it works for me, but I'm still afraid
Q> that submitting a pull request is going to be hard.
Q>
Q> 1 - This would be my first pull request to an open source project,

There is always a first time for everything!

Q> so I'm not really sure of the exact procedure

We have a brief guide at https://trac.wxwidgets.org/wiki/HowToSubmitPatches
Please let us know if you have any questions not covered by it.

Q> and all what I need to do beside code

You need to update the documentation files under interface/wx. Adding some
code to test the new functionality in the dialogs sample would be welcome,
although not required.

Q> 2 - I don't have any mac or linux; and on windows I'm using mingw-w64;
Q> if I need to make the equivalent for something else than msw, or even
Q> only check if it still compiles correctly and/or has no side effect on
Q> other compilers and platforms, never count on me. I tried once to
Q> install Visual Studio and didn't succeed, I have been lost in the
Q> installer; I don't want to waste time configuring things and I'm very
Q> thankful that people in the WXWidgets project made it easy to compile
Q> without 10GB of complicated stuff.

If you submit a PR via GitHub it will get tested by the CI builds on
several platforms, including Linux and Mac and MSVS under MSW, so you will
know if it breaks compilation there.

Note that even the feature you would be adding is MSW-specific, you still
need to implement the API for the other platforms, however it should simply
return wxNOT_FOUND (-1) there. And the documentation should mention this,
of course.

Q> 3 - I'm blind, so indentation, alignment, spacing, etc. will be broken
Q> in the submitted code for sure and I won't be able to do much about it.

We can take care of reformatting the code before merging taking into
account the special circumstances.

Regards,

QuentinC

unread,
Apr 23, 2019, 2:48:07 PM4/23/19
to wx-u...@googlegroups.com
Hello,

I have succeeded in adding a GetCurrentlySelectedFilterIndex() in
wxFileDialog. It works well.
Now I have to submit the thing to you...

However, it has raised another problem. I have found a workaround, but I
don't understand why. It's related to wxFileDialog, but not to the
feature I'm adding to it.

Upon clicking on the btnFormat wxButton, I open a dialog box to let the
user select some options.
If I set the wxFileDialog as the parent of my format options dialog box,
I get an assertion error "Incorrect window".
IN short, my dialog box can't be a child of the wxFileDialog...
There were no problem with this with the old Win32 code.

It works if I take the parent of the wxFileDialog as the parent of my
format options dialog instead, i.e. the main window of my application.
But then I enter in a weird situation where there are two modals dialogs
at the same time. When my format options dialog box is closed, the
wxFileDialog remains open but become unreachable because the focus goes
back in the main window; this because it's the parent of the format
options dialog. But the main window can't have the focus since the
wxFileDialog is still open. I can't do anything with the keyboar, I'm
traped in a kind of focus blackhole. I can still click with the mouse
somewhere in the wxFileDialog to reactivate it if I find it. I guess it
goes behind the main window although it's modal.
Setting explicitly the focus back to the btnFormat solves the problem,
but I still don't understand very well why I need to do that...

The question is, why I get this asertion "Incorrect window" when I try
to create a modal dialog box child of the wxFileDialog ?
Am I doing something wrong, or it's a bug ?

Here's some parts of my code below.

Thank you.

wxFileDialog fd(...)
fd.SetExtraControlCreator(&createSaveFilePanel);
if (wxID_OK==fd.ShowDialog()) {
// ... saving the file
}


static wxWindow* createSaveFilePanel (wxWindow* parent) {
auto panel = new wxPanel(parent);
auto btnFormat = new wxButton(panel, wxID_ANY,
U(translate("FormatOptionsBtn")));
// ... other controls, sizer and stuff like that
btnFormat->Bind(wxEVT_BUTTON, [=](auto& e){
wxFileDialog* fd = wxStaticCast(parent, wxFileDialog);
int filterIndex = fd->GetCurrentlySelectedFilterIndex();
showFormatDialog(fd->GetParent(), filterIndex);
btnFormat->SetFocus(); // If I don't explicitly set the focus back to
the button after the dialog is closed, the focus is lost in a weird place
});
return panel;
}

void showFormatDialog (wxWindow* parent, int filterIndex) {
FormatDialog dlg(parent);
// ... setting up the dialog
if (wxID_OK==dlg.ShowModal()) {
// ... saving the options chosen
}
}

Vadim Zeitlin

unread,
Apr 23, 2019, 6:24:00 PM4/23/19
to wx-u...@googlegroups.com
On Tue, 23 Apr 2019 20:48:00 +0200 QuentinC wrote:

Q> Now I have to submit the thing to you...

If you have a ?GitHub account, you just need to create your fork of the
wxWidgets repository (if not done yet) and push your changes as a new
branch in it. GitHub will answer with the URL to which you can go to open a
new pull request when you do "git push".

Q> Upon clicking on the btnFormat wxButton, I open a dialog box to let the
Q> user select some options.
Q> If I set the wxFileDialog as the parent of my format options dialog box,
Q> I get an assertion error "Incorrect window".

I'm not sure which assertion exactly is that (there is no assert with this
message exactly in our code), but the problem is probably due to the fact
that wxFileDialog doesn't have a valid HWND at all, as it's not our own
window. This hasn't been a problem originally before because no code, that
could potentially rely on having a valid HWND, could be executed anyhow
while the dialog was shown, but this is not the case any more with the
custom controls support.

Could you please try removing SetHWND(NULL) call from
wxFileDialog::MSWOnInitDialogHook() and add a line

wxON_BLOCK_EXIT_THIS0(SetHWND, NULL)

to wxFileDialog::ShowModal() instead to ensure that it's still getting
reset? AFAICS this should be enough to make it work, but I haven't tested
it.

For completeness, another possible fix might be to create wxNativeWindow
using the file dialog HWND and use it as a parent instead, but this would
be a hack and I'm not 100% sure it's going to work anyhow.

Good luck,

QuentinC

unread,
Apr 25, 2019, 4:43:03 PM4/25/19
to wx-u...@googlegroups.com
Hello,

VZ> If you have a ?GitHub account, you just need to create your fork of the
wxWidgets repository (if not done yet) and push your changes as a new
branch in it. GitHub will answer with the URL to which you can go to
open a new pull request when you do "git push".

NO problem, I have a GitHub account already since a long time.
I already host a few of my projects in it, projects that are in theory
open source, but no one has ever contributed.

VZ> I'm not sure which assertion exactly is that (there is no assert
with this message exactly in our code)

Exact, the message wasn't 100% correct, sorry. I have been able to copy
it, here it is:

A debugging check in this application has failed.
../../src/msw/window.cpp(1273): assert ""((HWND)GetHWND())"" failed in
GetLayoutDirection(): invalid window

IF I click on "continue", the application continue working normally. I
get the assertion error each time I click on the button that triggers my
dialog box, before it is shown.

VZ> Could you please try removing SetHWND(NULL) call from
wxFileDialog::MSWOnInitDialogHook() and add a line
wxON_BLOCK_EXIT_THIS0(SetHWND, NULL)
to wxFileDialog::ShowModal() instead to ensure that it's still getting
reset? AFAICS this should be enough to make it work, but I haven't
tested it.

I have tried and it doesn't change anything, the assert error keep
poping up with the same message as above.

I haven't yet tried your other solution.

Thank you.

QuentinC

unread,
Apr 30, 2019, 4:38:05 PM4/30/19
to wx-u...@googlegroups.com
Hello,

As discussed, I have created a pull request to add the method
wxFileDialog::GetCurrentlySelectedFilterIndex().
Here it is: https://github.com/wxWidgets/wxWidgets/pull/1310

The only thing I'm not very happy with is that the method returns an
undefined value for others than MSW, because the variable is never
initialized anywhere in that case. I think and hope I can still change
this before the code is merged but I don't know exactly how/where to
change it.

For example, in include/wx/filedlg.h, am I allowed to write:
int m_currentlySelectedFilterIndex = wxNOT_FOUND;
instead of:
int m_currentlySelectedFilterIndex;

MinGW-w64 / GCC allows it but I'm unsure if it's a GCC feature, or a
C++11 addition that may be disallowed in wxWidgets project.

Mini question: if I push a new commit to fix this, do I need to recreate
a pull request, or is it automatically updated ?

IN any case, thank you for your feedback.

Vadim Zeitlin

unread,
May 2, 2019, 2:09:21 PM5/2/19
to wx-u...@googlegroups.com
On Tue, 30 Apr 2019 22:37:56 +0200 QuentinC wrote:

Q> As discussed, I have created a pull request to add the method
Q> wxFileDialog::GetCurrentlySelectedFilterIndex().
Q> Here it is: https://github.com/wxWidgets/wxWidgets/pull/1310

Thanks! I've merged it now but still replying to some of the questions
here in case it could be useful:

Q> The only thing I'm not very happy with is that the method returns an
Q> undefined value for others than MSW, because the variable is never
Q> initialized anywhere in that case. I think and hope I can still change
Q> this before the code is merged but I don't know exactly how/where to
Q> change it.

wxFileDialogBase is, as its name indicates, a base class and wxFileDialog
platform-specific implementation inherits from it, so it's enough to
initialize this variable in wxFileDialogBase::Init(), which is called from
(both of) its ctor(s), and this is how I've done it.

Q> For example, in include/wx/filedlg.h, am I allowed to write:
Q> int m_currentlySelectedFilterIndex = wxNOT_FOUND;
Q> instead of:
Q> int m_currentlySelectedFilterIndex;

No, in place member initialization is a C++11 feature and we still support
non-C++11 compilers, so, unfortunately, you can't do this.

Q> Mini question: if I push a new commit to fix this, do I need to recreate
Q> a pull request, or is it automatically updated ?

No, you can add commits to your PRs without any problems. OTOH you should
avoid having any merges in the branch from which you make the PR, such as
your f0ace019d4 commit, the only merge should come at the end, when the PR
is merged into master.

Thanks again for your contribution!

thomas....@gmail.com

unread,
Oct 21, 2021, 9:53:12 AM10/21/21
to wx-users
Hi,

May I pick up this thread again:
I got the app using a proper manifest file insofar the process shows as Per-Monitor (V2) in the Details of the Windows Task Manager.
However I still get the dpi through DisplaySize() / wxDisplaySizeMM() as 96 dpi, so apparently the WIndows standard value.
We're using 3.1.5. Does this still not yet work again?

Thomas

Vadim Zeitlin

unread,
Oct 21, 2021, 10:03:00 AM10/21/21
to wx-u...@googlegroups.com
On Thu, 21 Oct 2021 06:53:12 -0700 (PDT) thomas....@gmail.com wrote:

t> I got the app using a proper manifest file insofar the process shows as
t> Per-Monitor (V2) in the Details of the Windows Task Manager.
t> However I still get the dpi through DisplaySize() / wxDisplaySizeMM() as 96
t> dpi, so apparently the WIndows standard value.
t> We're using 3.1.5. Does this still not yet work again?

You should just call wxWindow::GetDPIScaleFactor(), this definitely
returns the correct value in 3.1.5 and, if you use per-monitor-v2 DPI
awareness, also correctly changes if you move your window between the
displays with different DPI scaling.

wxGetDisplaySizeMM() returns (what is supposed to be) the actual, physical
display size and doesn't really help with the DPI scaling factor
determination, as it can be changed in Windows display settings -- without
changing your physical display size.
Reply all
Reply to author
Forward
0 new messages