Optional background information
A while ago I asked this question which specifically talks about text sizes and DLUs, and was made without me realizing what each DPI awareness actually meant. It never went anywhere, however. It's most likely my fault for not writing a clear question by asking about my implementation-specific problem rather than the general problem that comes out of it ("xX Problem"?).
I asked that question because I was writing a dynamic GUI layout engine — one that could handle changes to control presence and visibility — and needed to know which window the base units would be relative to. At the time, I decided that coordinates should be based on the parent and sizes should be based on the child, but now I realize that'll cause problems if the child's DPI is larger than the parent's.
Of course, this type of thing extends beyond just DLU calculation. For instance, a window that draws pictures on both vertical halves will have to worry about the per-monitor DPI changing right down the middle. So allow me to ask the general, unambiguous question.
The actual question
Today I found these two MSDN articles:
- https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266(v=vs.85).aspx
- https://msdn.microsoft.com/en-us/library/windows/desktop/mt744321(v=vs.85).aspx
After reading them, I now understand this much about system DPI awarenesses:
PROCESS_SYSTEM_DPI_AWARE- when asked for the DPI of something, the system will give the DPI of the primary monitor
- this value cannot and thus will not change throughout the lifetime of the program
- is equivalent to calling the older
SetProcessDPIAware()
PROCESS_DPI_UNAWARE- like
PROCESS_SYSTEM_DPI_AWAREexcept the DPI is fixed at 96
- like
PROCESS_PER_MONITOR_DPI_AWARE- the system gives the DPI of whatever monitor a window happens to be on; when that changes, a
WM_DPICHANGEDis sent - the page on that message says this can also happen if the monitor DPI changes; I didn't know you could do that now
- the system gives the DPI of whatever monitor a window happens to be on; when that changes, a
What I would like to know is:
In the case of PROCESS_PER_MONITOR_DPI_AWARE, is the DPI of all child (NOT owned) windows of a window the same as that of the parent window?
Note the superlative: the part about the DPI not changing for the life of the program means that the answer is "yes" for the other two awareness values.
Or as another example, let's say I have a 300px-wide window with two controls, both 100px wide, at opposite edges. If I drag that window between two monitors with different DPIs such that one of the controls is on one monitor and the other control is on the other, and then query their DPI (using GetDC() and GetDeviceCaps()), will they be the same?
If the answer is yes, then I will not need to worry about converting coordinates between parent windows and child windows.
If the answer is no, then the next question would be is WM_DPICHANGED sent to child windows, or only to toplevels? Because I would still need a way to know when the DPI of the children changed, so I can at least try to rearrange it to look correct (which I have not yet figured out how to do, and which is another question entirely, but which I assume should just be MulDiv()).
Thanks.