Windows 글꼴 크기가 C ++ MFC를 변경했을 때 감지 할 수 없습니다.
-
03-07-2019 - |
문제
사용자가 일반 Wind
- 데스크탑을 마우스 오른쪽 버튼으로 클릭하고 속성을 선택하십시오.
- 모양 탭을 클릭하십시오.
- 글꼴 크기 선택 : 정상/큰 글꼴/추가 큰 글꼴
내 이해는 글꼴 크기 변화가 DPI 변경을 초래한다는 것입니다. 따라서 지금까지 시도한 내용이 있습니다.
내 목표:
나는 때를 감지하고 싶다 창 글꼴 크기 정상에서 크거나 큰 글꼴로 변경되었으며 글꼴 크기 변화에 따라 일부 작업을 수행합니다. Windows 글꼴 크기가 변경되면 DPI도 변경 될 것이라고 가정합니다 (특히 크기가 여분의 큰 글꼴 인 경우
내가 지금까지 시도한 것 :
WM_SETTINGCHANGE, WM_NCCALCSIZE, WM_NCPAINT 등을 포함한 여러 메시지를받습니다. 그러나 글꼴 크기가 변경 될 때, 즉 WM_SETTINGSCHANGE 메시지를받을 때이 메시지는 상황에 고유하지 않습니다.
이론적으로 개시 체인지를 정의하고 Windows가 호출 할 때 LPSZsection은 변경 섹션이 무엇인지 알려야하며, 그 결과는 잘 작동하지만 SystemParametersInfo를 호출하여 주어진 섹션을 확인하고 동작 SPI_GETNONCLIENTMETRICS를 통과합니다. 디버거와 나는 글꼴 변경에 대해 반환 된 비 클리어 트릭의 데이터를 시청하지만 아무런 일이 발생하지 않습니다.
그것이 작동하지 않더라도 설정이 변경되면 여전히 DPI를 확인할 수 있어야합니다. WM_SetTingChange 메시지를받을 때마다 DPI를 확인하고 수행하는 데 관심이있는 작업을 수행 할 때마다 다른 세부 사항에 대해 신경 쓰지 않을 것입니다. 그러나 시스템 DPI도 얻을 수 없습니다.
각 DC에 대해 getsystemmetrics 방법을 호출하여 DPI를 얻으려고했습니다.
dekstop dc-> getDeviceCaps logpixelsx/logpixelsy window dc-> getDeviceCaps logpixelsx/logpixelsy current dc-> getDeviceCaps logpixelsx/logpixelsy
그래픽 속성 창에서 DPI를 변경하더라도 이러한 값은 다른 것을 반환하지 않으며 항상 96을 보여줍니다.
아무도 내가 이것을 알아 내도록 도와 줄 수 있습니까? 무엇을 찾고 있어야합니까? 어디서보고 있어야합니까?
afx_msg void CMainFrame::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
int windowDPI = 0;
int deviceDPI = 0;
int systemDPI = 0;
int desktopDPI = 0;
int dpi_00_X = 0;
int dpi_01_X = 0;
int dpi_02_X = 0;
int dpi_03_X = 0;
CDC* windowDC = CWnd::GetWindowDC(); // try with window DC
HDC desktop = ::GetDC(NULL); // try with desktop DC
CDC* device = CWnd::GetDC(); // try with current DC
HDC hDC = *device; // try with HDC
if( windowDC )
{
windowDPI = windowDC->GetDeviceCaps(LOGPIXELSY);
// always 96 regardless if I change the Font
// Size to Extra Large Fonts or keep it at Normal
dpi_00_X = windowDC->GetDeviceCaps(LOGPIXELSX); // 96
}
if( desktop )
{
desktopDPI = ::GetDeviceCaps(desktop, LOGPIXELSY); // 96
dpi_01_X = ::GetDeviceCaps(desktop, LOGPIXELSX); // 96
}
if( device )
{
deviceDPI = device->GetDeviceCaps(LOGPIXELSY); // 96
dpi_02_X = device->GetDeviceCaps(LOGPIXELSX); // 96
}
systemDPI = ::GetDeviceCaps(hDC, LOGPIXELSY); // 96
dpi_03_X = ::GetDeviceCaps(hDC, LOGPIXELSX); // 96
CWnd::ReleaseDC(device);
CWnd::ReleaseDC(windowDC);
::ReleaseDC(NULL, desktop);
::ReleaseDC(NULL, hDC);
CWnd::OnWinSettingChange(uFlags, lpszSection);
}
DPI는 항상 96을 반환하지만 글꼴 크기를 추가 큰 글꼴로 변경하거나 DPI를 120으로 변경하면 (그래픽 속성에서) 설정 변경이 적용됩니다.
해결책
다시 읽은 후 편집] "큰 글꼴"으로 바꾸는 것은 DPI 변경을 유발하지 않고 오히려 테마 설정입니다. "큰 글꼴"변경을 적용한 다음 DPI 설정이 살아남은 고급 디스플레이 속성을 열어 96dpi로 유지해야합니다.
DPI 변경에는 재부팅이 필요합니다. 어쩌면 설정이 GetDeviceCaps를 검색 할 수있는 곳으로 전파되지 않았을까요?
부부 부팅 수비 설정 (아마도 해상도)을 변경 한 다음 변경 사항을 감지 할 수 있는지 확인하십시오. 가능하다면, 당신의 대답은 아마도 재부팅 후까지 DPI 변경을 감지 할 수 없다는 것입니다.
다른 팁
데스크탑 DC에서 getDeviceCaps ()를 호출 할 때 MFC에 의해 캐시 될 수있는 DC를 사용하고 있으므로 오래된 정보가 포함되어 있습니까? getDeviceCaps ()가 InsettingSchange 핸들러 내부에서 동기식으로 호출하고 있습니까? 이러한 것들 중 하나 또는 두 가지 중 하나가 DPI의 구제 버전을 어떻게 얻을 수 있는지 알 수있었습니다.
레이몬드 첸 이것에 대해 썼습니다 그리고 그의 솔루션은 다음과 같이 보였습니다 (API의 MFC 포장지를 호출하지 않기 위해 :: 운영자가 추가했습니다) :
int GetScreenDPI()
{
HDC hdcScreen = ::GetDC(NULL);
int iDPI = -1; // assume failure
if (hdcScreen) {
iDPI = ::GetDeviceCaps(hdcScreen, LOGPIXELSX);
::ReleaseDC(NULL, hdcScreen);
}
return iDPI;
}
나는 hunch wm_themechanged가 당신을 돌볼 것입니다. 그래도 변경 사항에 대한 암시는 없습니다. OpenTheMedata 및 캐시 초기 설정을 사용한 다음 메시지를받을 때마다 비교해야합니다.
당신은 아마도 무엇이 바뀌 었는지 신경 쓰지 않아도 될 것입니다. 모든 것을 고려하여 양식/대화/대화를 조정하는 일반 목적 레이아웃 루틴을 가질 수는 없습니까?
어떤 문제를 해결하려고합니까?
보다 http://msdn.microsoft.com/en-us/library/ms701681(vs.85).aspx , 이것은 설명되어 있습니다 (인용문 : "DPI 스케일링을 취소하지 않으면이 호출은 기본값 96 DPI를 반환합니다."
글꼴 크기가 변경 될 때 디스플레이 DPI가 변경되지 않는다고 생각합니다. Windows는 아마도 그것을 보내고있을 것입니다 WM_PAINT
그리고 WM_NCPAINT
모든 열린 창에 메시지를 보내며 현재 (현재 큰) 시스템 글꼴을 사용하여 스스로를 다시 그리기하고 있습니다.
레지스트리에서 이러한 값을보십시오.
wind 언어 독립적.
Windows Classic Theme HKCU 제어판 lookance current 가능한 값 : Windows Classic, Windows Classic (Large), Windows Classic (Extra Large), Windows Standard, Windows Standard (Large), Windows Standard (Extra Large)는 이러한 값이 언어 의존적.
Windows Vista는이 기능을 지원하지 않습니다. 더 큰 글꼴을 원한다면 DPI 설정을 변경하십시오. 이 경우 getDeviceCaps가 작동해야합니다.
도움이 되었기를 바랍니다.