Pengembangan Aplikasi Desktop DPI Tinggi di Windows

Konten ini ditargetkan pada pengembang yang ingin memperbarui aplikasi desktop untuk menangani perubahan faktor skala tampilan (titik per inci, atau DPI) secara dinamis, yang memungkinkan aplikasi mereka menjadi tawar pada tampilan apa pun yang mereka render.

Untuk memulai, jika Anda membuat aplikasi Windows baru dari awal, sangat disarankan agar Anda membuat aplikasi Platform Windows Universal (UWP). Aplikasi UWP secara otomatis—dan dinamis—menskalakan untuk setiap tampilan yang dijalankan.

Aplikasi desktop yang menggunakan teknologi pemrograman Windows yang lebih lama (pemrograman Win32 mentah, Formulir Windows, Windows Presentation Framework (WPF), dll.) tidak dapat menangani penskalakan DPI secara otomatis tanpa pekerjaan pengembang tambahan. Tanpa pekerjaan seperti itu, aplikasi akan tampak buram atau berukuran salah dalam banyak skenario penggunaan umum. Dokumen ini menyediakan konteks dan informasi tentang apa yang terlibat dalam memperbarui aplikasi desktop untuk dirender dengan benar.

Tampilkan Faktor Skala &DPI

Seiring kemajuan teknologi tampilan, produsen panel tampilan telah mengemas peningkatan jumlah piksel ke dalam setiap unit ruang fisik pada panel mereka. Ini telah mengakibatkan titik per inci (DPI) panel tampilan modern jauh lebih tinggi daripada yang secara historis. Sebelumnya, sebagian besar layar memiliki 96 piksel per inci ruang fisik linier (96 DPI); pada tahun 2017, tampilan dengan hampir 300 DPI atau lebih tinggi tersedia.

Sebagian besar kerangka kerja antarmuka pengguna desktop warisan memiliki asumsi bawaan bahwa DPI tampilan tidak akan berubah selama masa pakai proses. Asumsi ini tidak lagi berlaku, dengan DPI tampilan yang umumnya berubah beberapa kali sepanjang masa pakai proses aplikasi. Beberapa skenario umum di mana faktor skala tampilan/perubahan DPI adalah:

  • Penyiapan multi-monitor di mana setiap tampilan memiliki faktor skala yang berbeda dan aplikasi dipindahkan dari satu tampilan ke tampilan lain (seperti 4K dan tampilan 1080p)
  • Docking dan undocking laptop DPI tinggi dengan tampilan eksternal DPI rendah (atau sebaliknya)
  • Koneksi melalui Desktop Jauh dari laptop/tablet DPI tinggi ke perangkat DPI rendah (atau sebaliknya)
  • Membuat pengaturan faktor skala tampilan berubah saat aplikasi sedang berjalan

Dalam skenario ini, aplikasi UWP menggambar ulang dirinya sendiri untuk DPI baru secara otomatis. Secara default, dan tanpa pekerjaan pengembang tambahan, aplikasi desktop tidak. Aplikasi desktop yang tidak melakukan pekerjaan ekstra ini untuk merespons perubahan DPI mungkin tampak buram atau berukuran salah kepada pengguna.

Mode Kesadaran DPI

Aplikasi desktop harus memberi tahu Windows jika mendukung penskalakan DPI. Secara default, sistem mempertimbangkan aplikasi desktop DPI tidak menyadari dan membentangkan bitmap jendela mereka. Dengan mengatur salah satu mode kesadaran DPI yang tersedia berikut, aplikasi dapat secara eksplisit memberi tahu Windows bagaimana mereka ingin menangani penskalaan DPI:

DPI Unaware

Aplikasi tidak sadar DPI merender pada nilai DPI tetap 96 (100%). Setiap kali aplikasi ini dijalankan pada layar dengan skala tampilan yang lebih besar dari 96 DPI, Windows akan meregangkan bitmap aplikasi ke ukuran fisik yang diharapkan. Ini menghasilkan aplikasi yang tampak buram.

Kesadaran DPI Sistem

Aplikasi desktop yang sadar DPI sistem biasanya menerima DPI monitor terhubung utama pada saat masuk pengguna. Selama inisialisasi, mereka menjabarkan UI mereka dengan tepat (kontrol ukuran, memilih ukuran font, memuat aset, dll.) menggunakan nilai DPI Sistem tersebut. Dengan demikian, aplikasi yang sadar DPI Sistem tidak diskalakan DPI (bitmap direntangkan) oleh Windows pada menampilkan penyajian pada DPI tunggal tersebut. Ketika aplikasi dipindahkan ke tampilan dengan faktor skala yang berbeda, atau jika faktor skala tampilan berubah, Windows akan menggigit skala jendela aplikasi, membuatnya tampak buram. Secara efektif, aplikasi desktop yang sadar DPI Sistem hanya merender dengan renyah pada satu faktor skala tampilan, menjadi buram setiap kali DPI berubah.

Kesadaran DPI Per Monitor dan Per Monitor (V2)

Disarankan agar aplikasi desktop diperbarui untuk menggunakan mode kesadaran DPI per monitor, memungkinkan mereka untuk segera merender dengan benar setiap kali DPI berubah. Ketika aplikasi melaporkan ke Windows bahwa aplikasi ingin berjalan dalam mode ini, Windows tidak akan meregangkan bitmap aplikasi ketika DPI berubah, sebaliknya mengirim WM_DPICHANGED ke jendela aplikasi. Hal ini kemudian menjadi tanggung jawab lengkap aplikasi untuk menangani mengubah ukuran dirinya sendiri untuk DPI baru. Sebagian besar kerangka kerja UI yang digunakan oleh aplikasi desktop (kontrol umum Windows (comctl32), Formulir Windows, Windows Presentation Framework, dll.) tidak mendukung penskalaan DPI otomatis, mengharuskan pengembang untuk mengubah ukuran dan memposisikan ulang konten jendela mereka sendiri.

Ada dua versi kesadaran Per-Monitor bahwa aplikasi dapat mendaftarkan dirinya sebagai: versi 1 dan versi 2 (PMv2). Mendaftarkan proses seperti yang berjalan dalam mode kesadaran PMv2 menghasilkan:

  1. Aplikasi diberi tahu ketika DPI berubah (HWND tingkat atas dan anak)
  2. Aplikasi melihat piksel mentah dari setiap tampilan
  3. Aplikasi tidak pernah diskalakan bitmap oleh Windows
  4. Area non-klien otomatis (keterangan jendela, bilah gulir, dll.) Penskalakan DPI menurut Windows
  5. Dialog Win32 (dari CreateDialog) secara otomatis DPI diskalakan oleh Windows
  6. Aset bitmap yang digambar tema dalam kontrol umum (kotak centang, latar belakang tombol, dll.) secara otomatis dirender pada faktor skala DPI yang sesuai

Saat berjalan dalam mode Per-Monitor v2 Awareness, aplikasi akan diberi tahu ketika DPI mereka telah berubah. Jika aplikasi tidak mengubah ukuran dirinya sendiri untuk DPI baru, antarmuka pengguna aplikasi akan tampak terlalu kecil atau terlalu besar (tergantung pada perbedaan nilai DPI sebelumnya dan baru).

Catatan

Kesadaran Per Monitor V1 (PMv1) sangat terbatas. Disarankan agar aplikasi menggunakan PMv2.

Tabel berikut menunjukkan bagaimana aplikasi akan dirender dalam skenario yang berbeda:

Mode Kesadaran DPI Versi Windows Diperkenalkan Tampilan aplikasi DPI Perilaku pada perubahan DPI
Menyadari T/A Semua tampilan adalah 96 DPI Peregangan bitmap (buram)
Sistem Vista Semua tampilan memiliki DPI yang sama (DPI tampilan utama pada saat sesi pengguna saat ini dimulai) Peregangan bitmap (buram)
Per Monitor 8.1 DPI tampilan tempat jendela aplikasi berada
  • HWND tingkat atas diberi tahu tentang perubahan DPI
  • Tidak ada penskalaan DPI dari elemen UI apa pun.

Per Monitor V2 Pembaruan Pembuat Windows 10 (1703) DPI tampilan tempat jendela aplikasi berada
  • HWND tingkat atas dan anak diberi tahu tentang perubahan DPI

Penskalaan DPI otomatis dari:
  • Area non-klien
  • Bitmap yang digambar tema dalam kontrol umum (comctl32 V6)
  • Dialog (CreateDialog)

Per Monitor (V1) Kesadaran DPI

Mode kesadaran Per Monitor V1 DPI (PMv1) diperkenalkan dengan Windows 8.1. Mode kesadaran DPI ini sangat terbatas dan hanya menawarkan fungsionalitas yang tercantum di bawah ini. Disarankan agar aplikasi desktop menggunakan mode kesadaran Per-Monitor v2, yang didukung pada Windows 10 1703 atau lebih tinggi.

Dukungan awal untuk kesadaran per monitor hanya menawarkan aplikasi berikut:

  1. HWND tingkat atas diberi tahu tentang perubahan DPI dan memberikan ukuran baru yang disarankan
  2. Windows tidak akan meregangkan bitmap antarmuka pengguna aplikasi
  3. Aplikasi melihat semua tampilan dalam piksel fisik (lihat virtualisasi)

Pada Windows 10 1607 atau lebih tinggi, aplikasi PMv1 juga dapat memanggil EnableNonClientDpiScaling selama WM_NCCREATE untuk meminta agar Windows menskalakan area non-klien jendela dengan benar.

Per Monitor DPI Scaling Support by UI Framework / Technology

Tabel di bawah ini menunjukkan tingkat dukungan kesadaran DPI per monitor yang ditawarkan oleh berbagai kerangka kerja Windows UI per Windows 10 1703:

Kerangka Kerja / Teknologi Dukungan Versi OS Penskalan DPI yang ditangani oleh Bacaan lebih lanjut
Universal Windows Platform (UWP) Penuh 1607 Kerangka kerja UI Platform Windows Universal (UWP)
Kontrol Mentah Win32/Common V6 (comctl32.dll)
  • DPI mengubah pesan pemberitahuan yang dikirim ke semua HWND
  • Aset yang digambar tema dirender dengan benar dalam kontrol umum
  • Penskalaan DPI otomatis untuk dialog
1703 Aplikasi Sampel GitHub
Formulir Windows Penskalaan DPI per monitor otomatis terbatas untuk beberapa kontrol 1703 Kerangka kerja UI Dukungan DPI Tinggi di Formulir Windows
Windows Presentation Framework (WPF) Aplikasi WPF asli akan menskalakan WPF DPI yang dihosting dalam kerangka kerja lain dan kerangka kerja lain yang dihosting di WPF tidak secara otomatis menskalakan 1607 Kerangka kerja UI Sampel GitHub
GDI Tidak T/A Aplikasi Lihat Penskalakan GDI High-DPI
GDI+ Tidak T/A Aplikasi Lihat Penskalakan GDI High-DPI
MFC Tidak T/A Aplikasi T/A

Memperbarui Aplikasi yang Ada

Untuk memperbarui aplikasi desktop yang ada untuk menangani penskalaan DPI dengan benar, aplikasi ini perlu diperbarui sehingga, minimal, bagian-bagian penting dari UI-nya diperbarui untuk merespons perubahan DPI.

Sebagian besar aplikasi desktop berjalan di bawah mode kesadaran DPI sistem. Aplikasi yang sadar sistem-DPI biasanya menskalakan ke DPI tampilan utama (tampilan tempat baki sistem berada pada saat sesi Windows dimulai). Ketika DPI berubah, Windows akan menggigit meregangkan UI aplikasi ini, yang sering menyebabkannya buram. Saat memperbarui aplikasi yang sadar DPI Sistem untuk menjadi sadar per-monitor-DPI, kode yang menangani tata letak UI perlu diperbarui sehingga dilakukan tidak hanya selama inisialisasi aplikasi, tetapi juga setiap kali pemberitahuan perubahan DPI (WM_DPICHANGED dalam kasus Win32) diterima. Ini biasanya melibatkan mengunjungi kembali asumsi apa pun dalam kode bahwa UI hanya perlu diskalakan sekali.

Selain itu, dalam kasus pemrograman Win32, banyak API Win32 tidak memiliki DPI atau konteks tampilan sehingga mereka hanya akan mengembalikan nilai relatif terhadap DPI Sistem. Ini dapat berguna untuk menyatu melalui kode Anda untuk mencari beberapa API ini dan menggantinya dengan varian yang sadar DPI. Beberapa API umum yang memiliki varian sadar DPI adalah:

Versi DPI tunggal Versi Per Monitor
GetSystemMetrics GetSystemMetricsForDpi
AdjustWindowRectEx AdjustWindowRectExForDpi
SystemParametersInfo SystemParametersInfoForDpi
GetDpiForMonitor GetDpiForWindow

Ada baiknya juga mencari ukuran yang dikodekan secara permanen di basis kode Anda yang mengasumsikan DPI konstanta, menggantinya dengan kode yang memperhitungkan penskalaan DPI dengan benar. Di bawah ini adalah contoh yang menggabungkan semua saran ini:

Contoh:

Contoh di bawah ini menunjukkan kasus Win32 yang disederhanakan untuk membuat HWND anak. Panggilan ke CreateWindow mengasumsikan bahwa aplikasi berjalan pada 96 DPI (USER_DEFAULT_SCREEN_DPI konstanta), dan ukuran atau posisi tombol tidak akan benar pada DPI yang lebih tinggi:

case WM_CREATE: 
{ 
    // Add a button 
    HWND hWndChild = CreateWindow(L"BUTTON", L"Click Me",  
        WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,  
        50,  
        50,  
        100,  
        50,  
        hWnd, (HMENU)NULL, NULL, NULL); 
} 

Kode yang diperbarui di bawah ini menunjukkan:

  1. Kode pembuatan jendela DPI menskalakan posisi dan ukuran HWND anak untuk DPI jendela induknya
  2. Menanggapi perubahan DPI dengan memposisikan ulang dan mengubah ukuran HWND anak
  3. Ukuran yang dikodekan secara permanen dihapus dan diganti dengan kode yang merespons perubahan DPI
#define INITIALX_96DPI 50 
#define INITIALY_96DPI 50 
#define INITIALWIDTH_96DPI 100 
#define INITIALHEIGHT_96DPI 50 

// DPI scale the position and size of the button control 
void UpdateButtonLayoutForDpi(HWND hWnd) 
{ 
    int iDpi = GetDpiForWindow(hWnd); 
    int dpiScaledX = MulDiv(INITIALX_96DPI, iDpi, USER_DEFAULT_SCREEN_DPI); 
    int dpiScaledY = MulDiv(INITIALY_96DPI, iDpi, USER_DEFAULT_SCREEN_DPI); 
    int dpiScaledWidth = MulDiv(INITIALWIDTH_96DPI, iDpi, USER_DEFAULT_SCREEN_DPI); 
    int dpiScaledHeight = MulDiv(INITIALHEIGHT_96DPI, iDpi, USER_DEFAULT_SCREEN_DPI); 
    SetWindowPos(hWnd, hWnd, dpiScaledX, dpiScaledY, dpiScaledWidth, dpiScaledHeight, SWP_NOZORDER | SWP_NOACTIVATE); 
} 
 
... 
 
case WM_CREATE: 
{ 
    // Add a button 
    HWND hWndChild = CreateWindow(L"BUTTON", L"Click Me",  
        WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 
        0, 
        0, 
        0, 
        0, 
        hWnd, (HMENU)NULL, NULL, NULL); 
    if (hWndChild != NULL) 
    { 
        UpdateButtonLayoutForDpi(hWndChild); 
    } 
} 
break; 
 
case WM_DPICHANGED: 
{ 
    // Find the button and resize it 
    HWND hWndButton = FindWindowEx(hWnd, NULL, NULL, NULL); 
    if (hWndButton != NULL) 
    { 
        UpdateButtonLayoutForDpi(hWndButton); 
    } 
} 
break; 

Saat memperbarui aplikasi sadar DPI Sistem, beberapa langkah umum yang harus diikuti adalah:

  1. Tandai proses sebagai sadar DPI per monitor (V2) menggunakan manifes aplikasi (atau metode lain, tergantung pada kerangka kerja UI yang digunakan).
  2. Buat logika tata letak UI dapat digunakan kembali dan pindahkan keluar dari kode inisialisasi aplikasi sehingga dapat digunakan kembali ketika perubahan DPI terjadi (WM_DPICHANGED dalam kasus pemrograman Windows (Win32).
  3. Membatalkan validasi kode apa pun yang mengasumsikan bahwa data sensitif DPI (DPI/font/ukuran/dll.) tidak perlu diperbarui. Ini adalah praktik yang sangat umum untuk menyimpan ukuran font dan nilai DPI pada inisialisasi proses. Saat memperbarui aplikasi untuk menjadi sadar DPI per monitor, data sensitif DPI harus dievaluasi ulang setiap kali DPI baru ditemui.
  4. Ketika perubahan DPI terjadi, muat ulang (atau rasterisasi ulang) aset bitmap apa pun untuk DPI baru atau, secara opsional, bitmap meregangkan aset yang saat ini dimuat ke ukuran yang benar.
  5. Grep untuk API yang tidak diketahui DPI Per Monitor dan ganti dengan API sadar DPI Per-Monitor (jika berlaku). Contoh: ganti GetSystemMetrics dengan GetSystemMetricsForDpi.
  6. Uji aplikasi Anda pada sistem multi-tampilan/multi-DPI.
  7. Untuk jendela tingkat atas apa pun dalam aplikasi yang tidak dapat Anda perbarui untuk skala DPI dengan benar, gunakan penskalaan DPI mode campuran (dijelaskan di bawah) untuk memungkinkan peregangan bitmap dari jendela tingkat atas ini oleh sistem.

Penskalakan DPI Mode Campuran (Penskalakan DPI Sub-Proses)

Saat memperbarui aplikasi untuk mendukung kesadaran DPI per monitor, terkadang dapat menjadi tidak praktis atau tidak mungkin untuk memperbarui setiap jendela dalam aplikasi sekaligus. Ini hanya bisa disebabkan oleh waktu dan upaya yang diperlukan untuk memperbarui dan menguji semua UI, atau karena Anda tidak memiliki semua kode UI yang perlu Anda jalankan (jika aplikasi Anda mungkin memuat UI pihak ketiga). Dalam situasi ini, Windows menawarkan cara untuk memudahkan ke dunia kesadaran per monitor dengan memungkinkan Anda menjalankan beberapa jendela aplikasi Anda (hanya tingkat atas) dalam mode kesadaran DPI asli mereka sementara Anda memfokuskan waktu dan energi Anda memperbarui bagian yang lebih penting dari UI Anda.

Di bawah ini adalah ilustrasi seperti apa tampilan ini: Anda memperbarui UI aplikasi utama Anda ("Jendela Utama" dalam ilustrasi) untuk dijalankan dengan kesadaran DPI per monitor saat Anda menjalankan jendela lain dalam mode yang ada ("Jendela Sekunder").

differences in dpi scaling between awareness modes

Sebelum Windows 10 Anniversary Update (1607), mode kesadaran DPI dari suatu proses adalah properti di seluruh proses. Dimulai di Windows 10 Anniversary Update, properti ini sekarang dapat diatur per jendela tingkat atas. (Jendela anak harus terus cocok dengan ukuran penskalaan induknya.) Jendela tingkat atas didefinisikan sebagai jendela tanpa induk. Ini biasanya merupakan jendela "reguler" dengan tombol minimalkan, maksimalkan, dan tutup. Skenario yang ditujukan untuk kesadaran DPI sub-proses adalah memiliki UI sekunder yang diskalakan oleh Windows (bitmap yang direntangkan) saat Anda memfokuskan waktu dan sumber daya Anda untuk memperbarui UI utama Anda.

Untuk mengaktifkan kesadaran DPI sub-proses, panggil SetThreadDpiAwarenessContext sebelum dan sesudah panggilan pembuatan jendela apa pun. Jendela yang dibuat akan dikaitkan dengan kesadaran DPI yang Anda tetapkan melalui SetThreadDpiAwarenessContext. Gunakan panggilan kedua untuk memulihkan kesadaran DPI utas saat ini.

Saat menggunakan penskalaan DPI sub-proses memungkinkan Anda mengandalkan Windows untuk melakukan beberapa penskalaan DPI untuk aplikasi Anda, itu dapat meningkatkan kompleksitas aplikasi Anda. Penting bahwa Anda memahami kelemahan pendekatan ini dan sifat kompleksitas yang diperkenalkannya. Untuk informasi selengkapnya tentang kesadaran DPI sub-proses, lihat Penskalaan DPI Mode Campuran dan API sadar DPI.

Menguji Perubahan Anda

Setelah Anda memperbarui aplikasi agar sadar per monitor DPI, penting untuk memvalidasi aplikasi Anda dengan benar merespons perubahan DPI di lingkungan DPI campuran. Beberapa spesifik untuk diuji meliputi:

  1. Memindahkan jendela aplikasi bolak-balik antara tampilan nilai DPI yang berbeda
  2. Memulai aplikasi Anda pada tampilan nilai DPI yang berbeda
  3. Mengubah faktor skala untuk monitor Anda saat aplikasi sedang berjalan
  4. Mengubah tampilan yang Anda gunakan sebagai tampilan utama, keluar dari Windows, lalu menguji ulang aplikasi Anda setelah masuk kembali. Ini sangat berguna dalam menemukan kode yang menggunakan ukuran/dimensi yang dikodekan secara permanen.

Jepit Umum (Win32)

Tidak menggunakan persegi panjang yang disarankan yang disediakan dalam WM_DPICHANGED

Ketika Windows mengirim pesan WM_DPICHANGED jendela aplikasi Anda, pesan ini menyertakan persegi panjang yang disarankan yang harus Anda gunakan untuk mengubah ukuran jendela Anda. Sangat penting bahwa aplikasi Anda menggunakan persegi panjang ini untuk mengubah ukurannya sendiri, karena ini akan:

  1. Pastikan bahwa kursor mouse akan tetap berada di posisi relatif yang sama pada Jendela saat menyeret antar tampilan
  2. Mencegah jendela aplikasi masuk ke siklus perubahan dpi rekursif di mana satu perubahan DPI memicu perubahan DPI berikutnya, yang memicu perubahan DPI lainnya.

Jika Anda memiliki persyaratan khusus aplikasi yang mencegah Anda menggunakan persegi panjang yang disarankan yang disediakan Windows dalam pesan WM_DPICHANGED, lihat WM_GETDPISCALEDSIZE. Pesan ini dapat digunakan untuk memberi Windows ukuran yang diinginkan yang ingin Anda gunakan setelah perubahan DPI terjadi, sambil tetap menghindari masalah yang dijelaskan di atas.

Kurangnya dokumentasi tentang virtualisasi

Ketika HWND atau proses berjalan karena DPI tidak sadar atau DPI sistem sadar, itu bisa bitmap direntangkan oleh Windows. Ketika ini terjadi, Windows menskalakan dan mengonversi informasi sensitif DPI dari beberapa API ke ruang koordinat utas panggilan. Misalnya, jika utas yang tidak menyadari DPI mengkueri ukuran layar saat berjalan pada tampilan DPI tinggi, Windows akan memvirtualisasi jawaban yang diberikan kepada aplikasi seolah-olah layar berada di 96 unit DPI. Atau, ketika utas yang sadar DPI Sistem berinteraksi dengan tampilan di DPI yang berbeda dari yang digunakan ketika sesi pengguna saat ini dimulai, Windows akan menskalakan beberapa panggilan API ke ruang koordinat yang akan digunakan HWND jika berjalan pada faktor skala DPI aslinya.

Saat Anda memperbarui aplikasi desktop ke skala DPI dengan benar, mungkin sulit untuk mengetahui panggilan API mana yang dapat mengembalikan nilai virtual berdasarkan konteks utas; informasi ini saat ini tidak cukup didokumenkan oleh Microsoft. Ketahuilah bahwa jika Anda memanggil API sistem apa pun dari konteks utas yang tidak sadar DPI atau sadar sistem DPI, nilai pengembalian mungkin divirtualisasi. Dengan demikian, pastikan utas Anda berjalan dalam konteks DPI yang Anda harapkan saat berinteraksi dengan layar atau jendela individual. Saat mengubah konteks DPI utas untuk sementara menggunakan SetThreadDpiAwarenessContext, pastikan untuk memulihkan konteks lama saat Anda selesai untuk menghindari perilaku yang salah di tempat lain dalam aplikasi Anda.

Banyak API Windows tidak memiliki konteks DPI

Banyak API Windows warisan tidak menyertakan konteks DPI atau HWND sebagai bagian dari antarmukanya. Akibatnya, pengembang sering harus melakukan pekerjaan tambahan untuk menangani penskalaan informasi sensitif DPI apa pun, seperti ukuran, titik, atau ikon. Sebagai contoh, pengembang yang menggunakan LoadIcon harus meregangkan bitmap ikon yang dimuat atau menggunakan API alternatif untuk memuat ikon berukuran benar untuk DPI yang sesuai, seperti LoadImage.

Reset paksa kesadaran DPI seluruh proses

Secara umum, mode kesadaran DPI dari proses Anda tidak dapat diubah setelah inisialisasi proses. Namun, Windows dapat mengubah secara paksa mode kesadaran DPI dari proses Anda jika Anda mencoba memecahkan persyaratan bahwa semua HWND di pohon jendela memiliki mode kesadaran DPI yang sama. Pada semua versi Windows, pada Windows 10 1703, tidak mungkin memiliki HWND yang berbeda di pohon HWND yang berjalan dalam mode kesadaran DPI yang berbeda. Jika Anda mencoba membuat hubungan induk anak yang melanggar aturan ini, kesadaran DPI tentang seluruh proses dapat diatur ulang. Ini dapat dipicu oleh:

  1. Panggilan CreateWindow di mana jendela induk yang diteruskan adalah mode kesadaran DPI yang berbeda dari utas panggilan.
  2. Panggilan SetParent di mana dua jendela dikaitkan dengan mode kesadaran DPI yang berbeda.

Tabel di bawah ini menunjukkan apa yang terjadi jika Anda mencoba melanggar aturan ini:

Operasi Windows 8.1 Windows 10 (1607 dan yang lebih lama) Windows 10 (1703 dan yang lebih baru)
CreateWindow (In-Proc) T/A Warisan anak (mode campuran) Warisan anak (mode campuran)
CreateWindow (Cross-Proc) Reset paksa (proses pemanggil) Warisan anak (mode campuran) Reset paksa (proses pemanggil)
SetParent (In-Proc) T/A Reset paksa (dari proses saat ini) Gagal (ERROR_INVALID_STATE)
SetParent (Lintas Proc) Reset paksa (proses jendela anak) Reset paksa (proses jendela anak) Reset paksa (proses jendela anak)

Referensi API DPI Tinggi

Penskalaan DPI Mode Campuran dan API sadar DPI.