I read some articles on how to make a win32 prog DPI aware. I want to make a dialog which has
windows controls, bitmaps and gdiplus objects combined.
I am using VS2019 and started a MFC app from scratch.
What would be the right way to get a DPI aware app, because I set DPI to high in the MFC app setting and used GetDeviceCaps to draw the lines. But when DPI is set to HIGH the lines do not match with the controls anymore. When I switch it off, the graphics look blurry, but are on the right position.
I made some screenshots to show what I mean:
Thanks, but that didnt answer my question. How should I draw Gdiplus graphics and controls so that they are always drawn correctly (same position) on all Dpi settings?
The code that I use can be seen in the first screenshot.
Short answer you scale everything long answer you scale everything
Okay to get scale factor you need the DPI of the screen which you use Win32 API
HDC Dc = GetDC(GetDesktopWindow()); // Get Screen DC
int DpiX = GetDeviceCaps(Dc, LOGPIXELSX); // X DPI for this DC (96 for normal screen)
int DpiY = GetDeviceCaps(Dc, LOGPIXELSY); // Y DPI for this DC (96 for normal screen)
ReleaseDC(GetDesktopWindow(), Dc); // Release screen DC finished with it now
if (DpiX != 96 || DpiY != 96) // High DPI mode active
/* calculate scale */
double ScaleX = (double)DpiX/96;
double ScaleY = (double)DpiY/96;
Thanks for your reply. I already tried to calculate the coord with GetDeviceCaps, but that does not work correctly! When I set 150% font size in windows I get a ratio of 144/96=1.5 as expected, but the controls and the dialog itself do not scale that way!
Here a different example:
I have drawn two red rectangles, one with the size of the dialog and an inner one which is the size of a group box. For the size of the dialog rectangle I use GetClientRect. It works on all font sizes (DPI scalings) correct.
For the inner rectangle inside the group box I tried to recalculate the coords with GetDeviceCaps, but that does not work. If I change scaling in windows the inner rectangle is completely off.
So I tried to figure out the correct coords for the inner rectangle by trial and error. Below are the coords which draw the correct rectangles in relation to the group box.
But how can I calculate them, I get some weird values? In the x axis I would get a factor of 1.3328 and on the y axis a factor of 1.62 with 150% scaling, not 1.5 as expected!?
You are obviously loading the dialog from a resource file or template.
Those have a normal DPI scale of 48 and yes it gets messy.
1.) Don't do it .... manually create the dialog and insert the items.
2.) If you don't want to do it manually on window entries that draw on the WM_CREATE grab the size and scale of the window just like you did. Which is basically what Gerry is saying below and contain your draws to windows. That means if you want to draw something on the dialog background make an transparent invisible window in the resource so it scales with the rest of the dialog and draw on it.
You are sort of creating a mountain out of a molehill.
Thanks for your replies. I drew the controls with the MFC resource editor, so the scaling doesnt match as you said.
So, I started a Win32 desktop application from scratch without MFC or other wrappers. I will do all drawings and scalings myself for all elements. I hope this will solve my DPI problems. I know that this is much work, but I only have experience with VisualStudio and MFC and I have to learn the basic WIN32 stuff first. I wanted to know the underlying win32 basics anyway.
I am covering a book tutorial about programming win32 and when I am compiling the code provided,
radio buttons doesn't show when are checked, instead the checkbox that is in the same dialog window
shows when it is checked.
Yes, I had placed a brakepoint after the CheckRadioButton RADIO1 function at the "break" statement.
When I press the Radio1 radio button the program goes and stops at the breakpoint, but what I had observed is that when a press play again to the compiler the program continues to execute and then it's comes back at the break point without to press again the radio button.
Check in Resource.h file to see if those two radio buttons has consecutive values ... might be a problem if they are not.
Yes, that it was, in the resource.h the values of the radio butons were reversed, first it was Radio2 then Radio1. I putted their correspondent values in increasing order and problem was solved.
Many thank Flaviu
I just created a quick test with your code and it works fine. There must be something else happening that we cannot see. As suggested by Flaviu above, please check the defined values for the dialog buttons.
In addition what was said before, I suggest you add a default case for the inner switch in WM_COMMAND. Then set a breakpoint on that default. Maybe you're missing a case in that switch statement?
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
I got a strange message from my compiler. Same code, same (at nearly) settings for Debug and Release versions. But what is more important, same files and same code! But when I try to create Release version, I get this:
Thank you, your tip was useful. I checked all places in the project's settings where I met the word "manifest" and found one, where settings for Debug and Release were different. Release wanted to generate manifest file, but Debug did not. I excluded manifest generation for the Release version and finally got it.