2016-02-17 37 views
7

Mam program, który został utworzony w VS2008 z MFC. Teraz zmodyfikowałem go tak, aby był "Per Monitor DPI-Aware" i prawie się skończył. Zmodyfikowałem manifest i obsłużyłem wiadomość WM_DPICHANGE. Ale jest jeszcze jeden problem:Tworzenie wspólnych okien dialogowych "Monitorowanie DPI" na poziomie

użyłem CFileDialog pokazać klasę Open/Save dialogi i wykorzystywane SHBrowseForFolder funkcję, aby wyświetlić okno wyboru folderu. Ale wszystkie te dialogi są "Per Monitor DPI-Aware", nie będą dostosowywać swojego interfejsu użytkownika, gdy przeniesiesz je pomiędzy monitorami o różnych ustawieniach DPI.

Używam spy ++ do monitorowania wiadomości z tych okien dialogowych, stwierdzam, że mogą odbierać wiadomość WM_DPICHANGED, ale po prostu jej nie obsługują.

I testowałem otwarte okno dialogowe w notepad.exe na Windows 10, działało idealnie.

Czy ktoś wie, w jaki sposób mogę utworzyć te okna dialogowe "Per Monitor DPI-Aware"?

-------- EDIT --------

Są tam jeszcze dwa problemy:

  1. Kiedy przenieść okno do monitora z różnymi DPI, okno zmienia rozmiar, ale wysokość paska tytułu i tytuł rozmiaru czcionki nie są zmieniane.
  2. Pole wyboru kontrolek "rozmiar skrzynki również się nie zmienia.

Uważam, że te problemy mogą mieć jakieś powiązania, ale nie mogę tego rozgryźć.

-------- smutna wiadomość --------

Skompilowałem "DPI Tutorial próbka" Microsoft z VS2013 i ma ten sam problem.

https://code.msdn.microsoft.com/DPI-Tutorial-sample-64134744

+1

Cóż, normalnie byś tego nie zrobił. Te okna dialogowe, których używasz, są przestarzałe. W Open/Save/Browse for Folder użyjesz teraz [Common Item Dialog] (https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913%28v=vs.85%29. aspx? f = 255 & MSPPError = -2147217396), w szczególności 'IFileOpenDialog'. Są one dostępne w systemie Windows Vista lub nowszym i powinny już być świadome DPI. Wróć do starszych okien dialogowych na niższym poziomie systemów operacyjnych. –

+0

BTW od VS2012 (lub VS2010 nie do końca pewny), CFileDialog automatycznie korzysta z okna Common Item Dialog bez dodatkowej pracy. –

+0

@Cody Gray Sprawdziłem kod w "mfc \ dlgfile.cpp", i stwierdziłem, że CFileDialog Calss użył IFileDialog, aby wyświetlić okno dialogowe. 'if (m_bVistaStyle == TRUE) { ApplyOFNToShellDialog(); HRESULT hr = (static_cast (m_pIFileDialog)) -> Show (m_ofn.hwndOwner); nResult = (hr == S_OK)? IDOK: IDCANCEL; } ' –

Odpowiedz

0

Według MSDN oknie, które przetwarza WM_DPICHANGED wiadomość powinna zwrócić 0. Jednak każde okno MFC lub kontrolowania wyślesz WM_DPICHANGED zwróci 0, ponieważ rozmowy Thay do procedury domyślne okno dla nieznanych wiadomości.

W związku z tym sądząc, że niektóre okno przetwarza komunikat WM_DPICHANGED, testując jego wartość zwracaną przez zero na LRESULT, jest ona niepoprawna.

Pasek tytułu okna aplikacji do monitorowania DPI na monitor nie jest skalowany podczas przenoszenia między różnymi monitorami DPI, co udokumentowano w dokumencie MSDN. Niestety, nie-kliencki obszar okna nigdy nie dostosowuje DPI.

Kalkulator i inne na monitor Uświadomione aplikacje Windows mają niestandardowy pasek tytułu, zgodnie z opisem here.

1

Pasek tytułu (pasek napisów) można skalować, wywołując numer EnableNonClientDpiScaling, który jest dostępny w wersjach systemu Windows> = rocznica aktualizacji systemu Windows 10 (1607).

Jeśli chcesz dpi starszą dialog, który nie obsługuje per-skalowania DPI monitora można użyć SetThreadDpiAwarenessContext (z DPI_AWARENESS_CONTEXT_SYSTEM_AWARE lub DPI_AWARENESS_CONTEXT_UNAWARE) mieć okna najwyższego poziomu okna skalowany przez Windows skalę. Okno dialogowe może być rozmyte, ale będzie ono co najmniej poprawnie skalibrowane (dostępne również tylko w wersji> = 1607 kompilacji systemu Windows 10). Wzorzec użycia polega na wywołaniu tego interfejsu API przed otwarciem okna dialogowego, a następnie przywróceniu poprzedniego kontekstu DPI natychmiast po wywołaniu interfejsu API.