How to get the GetDpiForWindow function signature correctly using LoadLibraryA and GetProcAddress ?

Qingyao Lin 20 Reputation points
2024-06-05T06:12:59.9666667+00:00

I am trying to use Rust write a cross-platform screenshot program to make it work on Windows 7 and above (such as Windows 7 and 10).

By consulting, the scaling ratio of each window in the system above Windows 10 is independent, which means that the use of the following code often can not get the correct scaling ratio.

use windows::Win32::Graphics::Gdi::{GetDC, GetDeviceCaps, LOGPIXELSX};
use windows::Win32::UI::WindowsAndMessaging::GetDesktopWindow;

fn main() {
	let handle = GetDesktopWindow();
	let window_hdc = GetDC(handle);
	// if window scala is 96 on the window 10
	// but g_scala_x is 125 
	let g_scala_x = GetDeviceCaps(window_hdc, LOGPIXELSX) as f32;
}

Use GetDpiForWindow to get the correct scale

use windows::Win32::UI::HiDpi::GetDpiForWindow;
use windows::Win32::UI::WindowsAndMessaging::GetDesktopWindow;

fn main() {
	let handle = GetDesktopWindow();
	let window_hdc = GetDC(handle);

    let window_scala = GetDpiForWindow(window_hdc);
}

To be cross-platform, I tried checking the existence of the GetDpiForWindow function through LoadLibraryA and GetProcAddress to determine the current version of the system, but I ran into problems:

use windows::Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryA};
use windows::Win32::Graphics::Gdi::{GetDC, GetDeviceCaps, LOGPIXELSX};
use windows::Win32::UI::HiDpi::GetDpiForWindow;

fn main() {
	let handle = GetDesktopWindow();
	let window_hdc = GetDC(handle);
	let user32_dll_pcstr = PCSTR(b"user32.dll\0".as_ptr());
    let user32_dll = LoadLibraryA(user32_dll_pcstr).unwrap();

    let get_dpi_for_window_pcstr = PCSTR(b"GetDpiForWindow\0".as_ptr());

    let window_scala = match GetProcAddress(user32_dll, get_dpi_for_window_pcstr) {
         Some(func) => {
             println!("GetDpiForWindow function is available");
             // Error !!! func takes 0 arguments but 1 argument
             func(window_hdc) as f32
         }
         None => {
             println!("GetDpiForWindow function is not available");
             let window_hdc = GetDC(handle);
             GetDeviceCaps(window_hdc, LOGPIXELSX) as f32
         }
    }
}

Why? What happened? Why can't GetProcAddress get the correct GetDpiForWindow function?

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,492 questions
{count} votes

Accepted answer
  1. RLWA32 42,366 Reputation points
    2024-06-05T07:42:57.6566667+00:00

    Take a close look at the documentation at GetDpiForWindow function.

    The argument to the function is a window handle (HWND), not a device context (HDC).


0 additional answers

Sort by: Most helpful