2017-02-17 5 views
0

Lucida Console ist TTF-Schriftart auf Windows 7 vorinstalliert und ich möchte es in der Konsolenanwendung programmatisch festlegen.Wie programmiere ich Konsolenschriftart programmatisch zu Lucida?

  1. Aus irgendeinem Grund SetCurrentConsoleFontEx „ist nicht einmal in diesem Bereich erklärt“. I #include <windows.h> wo sollte es definiert werden.

  2. Was würde ich in CONSOLE_FONT_INFOEX eingeben?

  3. #define _WIN32_WINNT 0x0601 als @Alf schon sagt, hat keine Auswirkung

Es ist leicht zu einem Rechtsklick auf den Konsolentitel und wählen Sie Schriftart dort manuell, aber ich würde lieber in Code tun.

es auf Windows XP + laufen sollte, verwende ich MinGW g ++ 4.8.1 auf Windows 7.

+0

Abhängig von Ihrem Compiler müssen Sie möglicherweise [_WIN32_WINNT' definieren, bevor Sie ''] (https://msdn.microsoft.com/en-us/library/6sehtctf.aspx) einschließen. Die Funktion, die Sie verwenden möchten, scheint nicht für Windows XP verfügbar zu sein, Windows Server 2008 vorausgesetzt. –

+0

In Windows XP denke ich, dass Sie dies auf umständliche Weise tun können, indem Sie die Informationen für das Konsolenfenster ändern. Wie ich mich erinnere, ist der Ort spezifisch für die Art, wie das Fenster gestartet wird. Wenn es von einer Verknüpfung ist es in der Verknüpfung gespeichert, und sonst ist es in der Registrierung gespeichert. –

+0

FWIW 'SetcurrentConsoleFontEx' sollte' SetCurrentConsoleFontEx' sein. Wenn Sie es an einem Ort falsch verstanden haben .... –

Antwort

1

Wenn SetCurrentConsoleFontEx und CONSOLE_FONT_INFOEX nicht einmal nach existieren Einstellung _WIN32_WINNT dann werden Sie eine veraltete SDK. Nicht selten mit MinGW, da es inoffizielle Header-Dateien von Drittanbietern verwendet.

Der Umgang mit Konsolenschriftarten unter Windows ist problematisch, da die Konsole ihre Schriftarten in einem internen Array speichert. Möglicherweise müssen Sie auch einige nicht dokumentierte Funktionen verwenden.

Unter Vista und später ist nur ein Anruf an SetCurrentConsoleFontEx erforderlich. Das Problem ist natürlich, dass die Dokumentation wirklich schlecht ist und die CONSOLE_FONT_INFOEX-Struktur für die Set- und Get-Funktionen verwendet wird, ohne Ihnen mitzuteilen, welche Member verwendet werden.

Wenn es nur Einstellung scheint Sie benötigen cbSize und FaceName zu setzen, kann alles andere gleich Null sein:

HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); 
CONSOLE_FONT_INFOEX cfie; 
ZeroMemory(&cfie, sizeof(cfie)); 
cfie.cbSize = sizeof(cfie); 
lstrcpyW(cfie.FaceName, L"Lucida Console"); 
SetCurrentConsoleFontEx(hStdOut, false, &cfie); 

Wenn Sie eine bestimmte Schriftgröße festlegen möchten Sie dwFontSize.Y einstellen. Seien Sie vorsichtig mit FontFamily, wenn Sie es auf den falschen Wert setzen Windows wird auf die Standard-Terminal-Schriftart zurückgesetzt.

Auf Pre-Vista-Systemen das einzige, was Sie in der Schriftart-Array zugreifen kann, ist die Größe:

#if 1 // Using old SDK? 
typedef struct _CONSOLE_FONT_INFOEX { 
ULONG cbSize; 
DWORD nFont; 
COORD dwFontSize; 
UINT FontFamily; 
UINT FontWeight; 
WCHAR FaceName[LF_FACESIZE]; 
} CONSOLE_FONT_INFOEX, *PCONSOLE_FONT_INFOEX; 
typedef BOOL (WINAPI*SETCURRENTCONSOLEFONTEX)(HANDLE hConsoleOutput,BOOL bMaximumWindow,CONSOLE_FONT_INFOEX*lpConsoleCurrentFontEx); 
SETCURRENTCONSOLEFONTEX SetCurrentConsoleFontEx = (SETCURRENTCONSOLEFONTEX) GetProcAddress(LoadLibraryA("KERNEL32"), "SetCurrentConsoleFontEx"); 
typedef BOOL (WINAPI*GETCURRENTCONSOLEFONTEX)(HANDLE hConsoleOutput,BOOL bMaximumWindow,CONSOLE_FONT_INFOEX*lpConsoleCurrentFontEx); 
GETCURRENTCONSOLEFONTEX GetCurrentConsoleFontEx = (GETCURRENTCONSOLEFONTEX) GetProcAddress(LoadLibraryA("KERNEL32"), "GetCurrentConsoleFontEx"); 
#endif 

static DWORD PrintFontInfoNT4(HANDLE hCon) 
{ 
    CONSOLE_FONT_INFO cfi; 
    BOOL succ = GetCurrentConsoleFont(hCon, false, &cfi); 
    printf("Get succ=%d nFont=%u dwFontSize=%dx%d\n", succ, cfi.nFont, cfi.dwFontSize.X, cfi.dwFontSize.Y); 
    return succ ? cfi.nFont : -1; 
} 

static DWORD PrintFontInfoNT6(HANDLE hCon) 
{ 
    CONSOLE_FONT_INFOEX cfie; 
    ZeroMemory(&cfie, sizeof(cfie)); 
    cfie.cbSize = sizeof(cfie); 
    BOOL succ = GetCurrentConsoleFontEx(hCon, false, &cfie); 
    printf("GetEx succ=%d nFont=%u size=%dx%d fam=%#x wei=%u name=%ls\n", succ, cfie.nFont, cfie.dwFontSize.X, cfie.dwFontSize.Y, cfie.FontFamily, cfie.FontWeight, cfie.FaceName); 
    return succ ? cfie.nFont : -1; 
} 

static void TestNT4() 
{ 
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); 
    typedef DWORD (WINAPI*GETNUMBEROFCONSOLEFONTS)(); 
    GETNUMBEROFCONSOLEFONTS GetNumberOfConsoleFonts = (GETNUMBEROFCONSOLEFONTS) GetProcAddress(LoadLibraryA("KERNEL32"), "GetNumberOfConsoleFonts"); 
    typedef BOOL (WINAPI*SETCONSOLEFONT)(HANDLE hConOut, DWORD nFont); 
    SETCONSOLEFONT SetConsoleFont = (SETCONSOLEFONT) GetProcAddress(LoadLibraryA("KERNEL32"), "SetConsoleFont"); 

    // This is the best you can do on NT/2000/XP/2003 without hacks 
    DWORD orgFont = PrintFontInfoNT4(hStdOut); 
    printf("GetNumberOfConsoleFonts=%u orgFont=%u\n", GetNumberOfConsoleFonts(), orgFont); 
    for (DWORD i = 0, c = GetNumberOfConsoleFonts(); i < c; ++i) 
    { 
     SetConsoleFont(hStdOut, i); 
     PrintFontInfoNT4(hStdOut); 
#if _WIN32_WINNT >= 0x0600 
     PrintFontInfoNT6(hStdOut); 
#endif 
     Sleep(1000); 
    } 
    SetConsoleFont(hStdOut, orgFont); // Restore the original font 
} 

Das ist ziemlich nutzlos, weil man nicht sagen kann, die Schriftart, die Sie festlegen. Wenn Sie immer noch darauf bestehen, die Schriftart auf Vista-Systemen zu setzen, müssen Sie sich die Hände schmutzig machen. Zuerst müssen Sie entscheiden, auf welche Terminalfenster Sie die Änderung anwenden möchten.

Die Standardeinstellungen des Terminals sind unter HKEY_CURRENT_USER\Console gespeichert und pro-App-Einstellungen können in Unterschlüsseln gespeichert werden. Diese Standardwerte können overridden sein, wenn die Anwendung über eine Verknüpfung gestartet wird.

Wenn Sie nur die Konsole ändern möchten, mit der Sie arbeiten, wird es noch schwieriger, aber Windows selbst weiß natürlich, wie man die Schriftart direkt einstellt. Sie können dies in Aktion sehen, wenn Sie "Eigenschaften" in einem Konsolenmenü wählen und eine Änderung der Schriftart anwenden. Dies kann sich wahrscheinlich von Version zu Version ändern, aber ich glaube, dass es einen zugeordneten Speicher und eine geheime Nachricht verwendet.Sie können Ihre Untersuchung beginnen, indem Sie einen Haltepunkt in WinDbg setzen; Nach dem korrekten Einrichten der Symbole geben Sie bp console!Write*TabGeben Sie ein (Bei mehreren Schreibfunktionen auf alle Schreibfunktionen einstellen). Sie müssen das Layout der Struktur, die es verwendet, herausfinden, so dass Sie möglicherweise eine Konsoleneinstellung zu der Zeit anwenden und den Speicher ablegen/vergleichen müssen.

Edit:

Es sieht aus wie einige Leute dies bereits herausgefunden haben. This bug analysis paper hat eine Strukturdefinition und ich auch found a SetConsolePalette function, die den zugeordneten Speichertrick implementiert. ReactOS verwendet möglicherweise nicht die exakt gleiche Implementierung, aber Sie könnten auch take a look at it.

Sie müssen SetCurrentConsoleFontEx auf Systemen, die es haben, noch aufrufen, da sich die Internals wahrscheinlich geändert haben, wenn Windows conhost.exe gestartet hat.

+0

Es könnte eine gute Idee sein, explizit zu formulieren, dass die Version vor Vista von undokumentierten Implementierungsdetails abhängig ist, die ohne vorherige Ankündigung geändert werden können. – IInspectable

Verwandte Themen