Domanda

Sto cercando di determinare come posso rilevare quando l'utente cambia la dimensione del carattere di Windows da normale a extra grande, la dimensione del carattere viene selezionata eseguendo i seguenti passaggi su un computer Windows XP:

  1. Fai clic con il tasto destro sul desktop e seleziona Proprietà.
  2. Fai clic sulla scheda Aspetto.
  3. Seleziona la dimensione del carattere: normale / caratteri grandi / caratteri molto grandi

La mia comprensione è che la modifica della dimensione del carattere provoca una modifica DPI, quindi ecco cosa ho provato finora.


Il mio obiettivo:

Voglio rilevare quando la Dimensione carattere di Windows è cambiata da Carattere normale a Grande o Extra grande e intraprendere alcune azioni in base alla modifica della dimensione del carattere. Presumo che quando cambia la dimensione del carattere di Windows, anche il DPI cambierà (specialmente quando la dimensione è Caratteri extra large


Quello che ho provato finora:

Ricevo diversi messaggi tra cui: WM_SETTINGCHANGE, WM_NCCALCSIZE, WM_NCPAINT, ecc ... ma nessuno di questi messaggi è unico per la situazione in cui la dimensione del carattere cambia, in altre parole, quando ricevo il messaggio WM_SETTINGSCHANGE Voglio sapere cosa cambiato.

In teoria quando definisco OnSettingChange e Windows lo chiama, lpszSection dovrebbe dirmi qual è la sezione che cambia e che funziona bene, ma poi controllo la sezione data chiamando SystemParametersInfo e passo l'azione SPI_GETNONCLIENTMETRICS, e Passo attraverso il debugger e mi assicuro di guardare i dati in NONCLIENTMETRICS restituiti per eventuali modifiche al carattere, ma non si verificano nessuno.

Anche se non ha funzionato, dovrei comunque essere in grado di controllare il DPI quando cambiano le Impostazioni. In realtà non mi interesserebbero gli altri dettagli, ogni volta che ricevo il messaggio WM_SETTINGCHANGE, verificherei semplicemente il DPI ed eseguirò le azioni che mi interessano eseguire, ma non sono nemmeno in grado di ottenere il DPI di sistema.

Ho cercato di ottenere il DPI invocando il metodo GetSystemMetrics, anche per ogni controller di dominio:

Dekstop DC- > GetDeviceCaps LOGPIXELSX / LOGPIXELSY Finestra DC- > GetDeviceCaps LOGPIXELSX / LOGPIXELSY Current DC- > GetDeviceCaps LOGPIXELSX / LOGPIXELSY

Anche se cambio DPI nella finestra Proprietà grafica questi valori non restituiscono nulla di diverso, mostrano sempre 96.

Qualcuno potrebbe aiutarmi a capirlo per favore? Cosa dovrei cercare? Dove dovrei guardare?

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);
}

Il DPI restituisce sempre 96, ma le modifiche alle impostazioni hanno effetto quando cambio la dimensione del carattere in Caratteri extra-grandi o se cambio il DPI su 120 (dalle proprietà grafiche).

È stato utile?

Soluzione

[MODIFICA dopo la rilettura] Sono quasi certo che cambiando in "caratteri grandi" non provoca una modifica DPI, piuttosto è un'impostazione del tema. Dovresti essere in grado di verificare applicando i caratteri di grandi dimensioni " modificare e quindi aprire le proprietà di visualizzazione avanzate in cui risiede l'impostazione DPI, avrebbe dovuto rimanere a 96 dpi.


La modifica del DPI dovrebbe richiedere un riavvio. Forse l'impostazione non si è propagata in un luogo in cui GetDeviceCaps può recuperarla?

Forse prova a cambiare un'impostazione che non richiede il riavvio (forse la risoluzione) e poi vedi se riesci a rilevare la modifica. Se puoi, probabilmente la tua risposta è che non puoi rilevare la modifica DPI fino a dopo il riavvio.

Altri suggerimenti

Quando si chiama GetDeviceCaps () su Desktop DC, si sta forse utilizzando un controller di dominio che potrebbe essere memorizzato nella cache da MFC e quindi contenente informazioni non aggiornate? Stai effettuando la chiamata GetDeviceCaps () in modo sincrono dall'interno del tuo gestore OnSettingsChange? Ho potuto vedere come una o entrambe queste cose potrebbero farti ottenere una versione non aggiornata di DPI.

Raymond Chen ha scritto di questo e dei suoi la soluzione era simile a questa (nota che ho aggiunto :: operatori per evitare di chiamare i wrapper MFC delle API):

int GetScreenDPI()
{
  HDC hdcScreen = ::GetDC(NULL);
  int iDPI = -1; // assume failure
  if (hdcScreen) {
    iDPI = ::GetDeviceCaps(hdcScreen, LOGPIXELSX);
    ::ReleaseDC(NULL, hdcScreen);
  }
  return iDPI;
}

Ho un sospetto che WM_THEMECHANGED si prenderà cura di te. Tuttavia, non ha alcun accenno a ciò che è cambiato. Dovrai utilizzare OpenThemeData e memorizzare le impostazioni iniziali della cache, quindi confrontare ogni volta che ricevi il messaggio.

Probabilmente non hai bisogno di preoccuparti di ciò che è cambiato, non puoi avere una routine di layout per tutti gli usi che regola il tuo modulo / finestra di dialogo / qualunque cosa prendendo tutto in considerazione e presuppone di iniziare da zero?

Quale problema stai cercando di risolvere?

Vedi http://msdn.microsoft.com /en-us/library/ms701681(VS.85).aspx , questo è spiegato qui (citazione: " Se non si annulla il ridimensionamento dpi, questa chiamata restituisce il valore predefinito di 96 dpi. ")

Non credo che il DPI di visualizzazione cambi quando cambiano le dimensioni del carattere. Windows probabilmente sta semplicemente inviando i messaggi WM_PAINT e WM_NCPAINT a tutte le finestre aperte e si stanno ridisegnando usando il carattere di sistema corrente (ora grande).

Guarda questi valori nel registro:

Tema di Windows XP HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ ThemeManager \ SizeName Valori possibili: NormalSize, LargeFonts e ExtraLargeFonts Questi valori sono indipendenti dalla lingua .

Tema classico di Windows HKCU \ Pannello di controllo \ Aspetto \ Attuale Valori possibili: Windows Classic, Windows Classic (grande), Windows Classic (extra grande), Windows Standard, Windows Standard (grande), Windows Standard (extra grande) Tieni presente che questi valori sono dipendenti dalla lingua .

Windows Vista non supporta questa funzione. Se vogliamo un carattere più grande, è sufficiente modificare l'impostazione DPI. In tal caso, GetDeviceCaps dovrebbe funzionare.

Spero che questo aiuti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top