I have the same problem, I tried using GetDC + GetDeviceCaps + ReleaseDC, except using Graphics worked, atleast on Vista32. I am not experienced with DPI yet, but nobody had answered this and at least this might be helpful for others.
Check out Creating a DPI-Aware Application. This mention why it might always return 96 regardless of actual DPI setting.
Quote from above link:
DPI scaling in a Win32 application
In Win32 applications, do the following:
- Use the SetProcessDPIAware function to cancel dpi scaling.
- When sizing drawn interface elements, use physical measurements, such as centimeters. By using physical dimensions rather than pixels, you ensure consistent sizing on all types of displays.
- To get the system dpi setting, use the CDC::GetDeviceCaps function with the LOGPIXELSX flag. If you do not cancel dpi scaling, this call returns the default value of 96 dpi.
- Use the GetSystemMetrics function to get preferred sizes of user interface elements, such as window borders. When dpi scaling is disabled, the measurement values that are returned for interface elements are scaled to the selected dpi setting. If dpi scaling is active, the function returns measurements based on 96 dpi, regardless of the system dpi setting.
Answered from: About DPI Issue
Sample code rewritten with using-statement (original source):
float dpiX = 96, dpiY = 96;
using(Graphics graphics = this.CreateGraphics())
{
dpiX = graphics.DpiX;
dpiY = graphics.DpiY;
}