Win32写高DPI程序并不麻烦,但还是要一定的技巧的。
使用WPF编写的程序原生就是DPI兼容的,无需额外处理。
使用WPF编写的程序原生就是DPI兼容的,无需额外处理。
<code class="lang-cpp">// 编译命令: // cl highdpi.cpp /DUNICODE // cl highdpi.cpp /DUNICODE /DNODPI /Felowdpi // 链接指令 #pragma comment(lib, "kernel32.lib") #pragma comment(lib, "user32.lib") #pragma comment(lib, "gdi32.lib") #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") // 包含文件 #include <windows.h> int g_dpix = 96, g_dpiy = 96; LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; HFONT hfont, holdfont; TCHAR *str = TEXT("黑体字输出123456ABCDEF示例"); static HWND hbtn1, hbtn2, hbtn3, hbtn4; switch(message) { case WM_CREATE: // 重新设置字体,以应用字体的DPI缩放 SendMessage(hwnd, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); // 创建控件,注意DPI缩放方法 hbtn1 = CreateWindowEx(0, TEXT("BUTTON"), TEXT("按钮一"), WS_CHILD|WS_VISIBLE, MulDiv(10, g_dpix, 96), MulDiv(10, g_dpiy, 96), MulDiv(90, g_dpix, 96), MulDiv(30, g_dpiy, 96), hwnd, (HMENU)1, NULL, NULL); hbtn2 = CreateWindowEx(0, TEXT("BUTTON"), TEXT("按钮二"), WS_CHILD|WS_VISIBLE, MulDiv(110, g_dpix, 96), MulDiv(10, g_dpiy, 96), MulDiv(90, g_dpix, 96), MulDiv(30, g_dpiy, 96), hwnd, (HMENU)2, NULL, NULL); hbtn3 = CreateWindowEx(0, TEXT("BUTTON"), TEXT("按钮三"), WS_CHILD|WS_VISIBLE, MulDiv(210, g_dpix, 96), MulDiv(10, g_dpiy, 96), MulDiv(90, g_dpix, 96), MulDiv(30, g_dpiy, 96), hwnd, (HMENU)3, NULL, NULL); hbtn4 = CreateWindowEx(0, TEXT("BUTTON"), TEXT("按钮四"), WS_CHILD|WS_VISIBLE, MulDiv(310, g_dpix, 96), MulDiv(10, g_dpiy, 96), MulDiv(90, g_dpix, 96), MulDiv(30, g_dpiy, 96), hwnd, (HMENU)4, NULL, NULL); // 重新设置字体,以应用字体的DPI缩放 SendMessage(hbtn1, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); SendMessage(hbtn2, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); SendMessage(hbtn3, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); SendMessage(hbtn4, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); // 创建字体,注意字体高度的取值(和Word中相同)和缩放 hfont = CreateFont(-MulDiv(16, g_dpiy, 72), 0, 0, 0, FW_THIN, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, TEXT("SimHei")); holdfont = (HFONT)SelectObject(hdc, hfont); // 输出文字,注意起始位置的缩放 TextOut(hdc, MulDiv(10, g_dpix, 96), MulDiv(50, g_dpiy, 96), str, lstrlen(str)); // 释放资源 SelectObject(hdc, holdfont); DeleteObject(hfont); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: // 退出程序 PostQuitMessage(0); return 0; default: return DefWindowProc(hwnd, message, wParam, lParam); } } int WINAPI WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, int ncmdshow) { // 关闭DPI缩放 FARPROC spdpia = GetProcAddress(GetModuleHandle(TEXT("user32")), "SetProcessDPIAware"); #ifndef NODPI if (spdpia != NULL) spdpia(); // 去掉这一句可看到DPI缩放效果 #endif // 获取DPI HDC hdc = GetDC(NULL); if (hdc != NULL) { g_dpix = GetDeviceCaps(hdc, LOGPIXELSX); g_dpiy = GetDeviceCaps(hdc, LOGPIXELSY); ReleaseDC(NULL, hdc); } // 注册窗口类 WNDCLASSEX wc = { sizeof wc, CS_VREDRAW|CS_HREDRAW, WndProc, 0, DLGWINDOWEXTRA, NULL, LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), (HBRUSH)GetStockObject(WHITE_BRUSH), NULL, TEXT("MyWndClass"), LoadIcon(NULL, IDI_APPLICATION) }; if (!RegisterClassEx(&wc)) return 1; // 在标题栏显示DPI数值 TCHAR title[200] = TEXT(""); wsprintf(title, TEXT("DPI: %d, %d"), g_dpix, g_dpiy); // 创建窗口,注意DPI缩放方法 HWND hWnd = CreateWindowEx(0, TEXT("MyWndClass"), title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, MulDiv(500, g_dpix, 96), MulDiv(300, g_dpiy, 96), NULL, NULL, NULL, NULL); // 显示和更新窗口 ShowWindow(hWnd, ncmdshow); UpdateWindow(hWnd); // 消息循环 MSG msg; while (GetMessage(&msg, 0, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; }</windows.h></code>
[修改于 9年1个月前 - 2015/11/05 12:12:21]
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |
200字以内,仅用于支线交流,主线讨论请采用回复功能。