2

I am learning how to draw GUI's with GDI/GDI+, i found this http://msdn.microsoft.com/en-us/library/windows/desktop/dd756596(v=vs.85).aspx#step_2__declare_that_the_application_is_dpi-aware Does every application do that calculation so it can be displayed properly or what ?

Can someone explain how to calculate client coordinates of buttons,images and all controls on your window so they have the same align on different resolutions ?

Thanks in advance.

VisaToHell
  • 508
  • 1
  • 12
  • 29

2 Answers2

3

With GDI, you can use GetDeviceCaps function with LOGPIXELSX and LOGPIXELSY to find your DPI, and use these values to scale your sizes:

HDC hdc = GetDC(hwnd);
int ppix = GetDeviceCaps(hdc, LOGPIXELSX);
int ppiy = GetDeviceCaps(hdc, LOGPIXELSY);
ReleaseDC(hdc);

// for a control that is 1.5 inches wide and 0.5 inches high.

int ctrl_width = int(1.5 * ppix + 0.5);
int ctrl_height = int(0.5 * ppiy + 0.5);

// for a button that conforms to Microsoft's UI guidelines of 75x23 @ 96dpi.

int btn_width = (75 * ppix + 48) / 96;
int btn_height = (23 * ppiy + 48) / 96;

GDI+ makes this considerably simpler:

Graphics g;
g.SetPageUnit(UnitInch);

// now you can specify draw coordinates in inches
// and it'll figure out DPI for you.

Do note that the GDI+ solution will only affect GDI+ draw calls—not GDI calls or coordinates of controls.

Cory Nelson
  • 29,236
  • 5
  • 72
  • 110
  • Is that the algorithm used by all windows applications ? – VisaToHell Jun 16 '12 at 19:33
  • The good ones, yes ;). Unfortunately a lot of them are not DPI-aware. – Cory Nelson Jun 16 '12 at 19:34
  • All applications which controls were drawn by Visual C++ IDE have that built in right ? – VisaToHell Jun 16 '12 at 20:44
  • Yes, a dialog made in the designer is DPI-aware and you shouldn't need to do anything special for them other than that manifest bit in your link. – Cory Nelson Jun 16 '12 at 22:26
  • @VisaToHell, you have to be careful with this advice in Windows Vista and later - Windows will lie to you about DPI when you ask, unless you declare your application to be DPI aware. See http://msdn.microsoft.com/en-us/library/ms701681%28v=vs.85%29.aspx – Mark Ransom Jun 17 '12 at 01:48
2

Ignoring dpi-awareness is starting to become painful pretty quickly. Display technology has been stuck at 96 dpi for a very long time, 20 years already. Vista with its automatic dpi scaling and highly accessible "ruler" applet was a game changer. Apple with its push for "retina" displays is the real driving force. Next Apple MacBook has a 2880 x 1800 display, your typical 1024x768 window is going to be a postage stamp on a display like that.

Tooling to make it automatic is readily available, XAML based class libraries (WPF, Silverlight, Metro) are entirely resolution independent. HTML and Winforms auto-scale pretty well. But of course little help with GDI. And none whatsoever in User32, firmly stuck in pixel-land. You can certainly write the code, it's just not pleasant code to write. If you are still programming the raw API for legacy reasons then the automatic scaling built into Vista and up will be attractive. Well, for reducing the effort, it isn't going to look very attractive :)

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536