2017-02-17 42 views
0

Lucida ConsoleはWindows 7にTTFフォントがプリインストールされており、コンソールアプリケーションでプログラムで設定したいと思っています。何らかの理由でコンソールフォントをLucidaにプログラムで設定する方法を教えてください。

  1. SetCurrentConsoleFontEx「でも、この範囲内で宣言されていません」。 I #include <windows.h>ここで定義する必要があります。

  2. CONSOLE_FONT_INFOEXには何を入れますか? @Alfが示唆するよう

  3. #define _WIN32_WINNT 0x0601は、

それがしやすいコンソールのタイトルを右クリックして、手動であり、フォント選択は効果がありませんが、私はむしろコードでそれを行うだろう。 SetCurrentConsoleFontExCONSOLE_FONT_INFOEXも、あなたは時代遅れのSDKを使用している_WIN32_WINNTを設定した後に存在しない場合は、Windows XP +上で実行する必要があります

は、私が

+0

コンパイラによっては、「」(https://msdn.microsoft.com/en-us/library/6sehtctf.aspx)を含める前に[_WIN32_WINNT'を定義する必要があるかもしれません。使用したい機能がWindows XPで利用できないようで、Windows Server 2008が必要です。 –

+0

Windows XPでは、コンソールウィンドウの情報を変更することで、煩雑な方法でこれを行うことができます。私の所在地は、ウィンドウの起動方法に固有のものです。ショートカットからショートカットに保存されていれば、それ以外の場合はレジストリに保存されます。 –

+0

FWIW 'SetcurrentConsoleFontEx'は' SetCurrentConsoleFontEx'でなければなりません。もしあなたが1つの場所で間違っていたら.... –

答えて

1

のWindows 7上のMinGW G ++ 4.8.1を使用します。非公式の第三者ヘッダーファイルを使用するため、MinGWでは珍しくありません。

Windows上でコンソールフォントを扱うことは、コンソールがそのフォントを内部アレイに格納するため問題になります。文書化されていない関数を使わなければならないかもしれません。

Vista以降では、SetCurrentConsoleFontExが必要です。問題はもちろん、ドキュメンテーションが実際には悪く、どのメンバが使用されているかを知らせずに、Set関数とGet関数の両方に構造体CONSOLE_FONT_INFOEXが使用されています。

それだけcbSizeFaceNameを設定する必要のようです設定し、他のすべてはゼロになります

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

あなたがdwFontSize.Yを設定することができ、特定のフォントサイズを設定したい場合。 FontFamilyに注意してください。間違った値に設定した場合、Windowsはデフォルトのターミナルフォントに戻ります。 Vista以前のシステムで

使用すると、フォントの配列にアクセスすることができる唯一のことは、サイズです:あなたが設定されているフォントた伝えることができないので

#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 
} 

これはかなり無駄です。 Vista以前のシステムでフォントを設定することを依然として求めているなら、手を汚さなければならない。まず、変更を適用するターミナルウィンドウを決定する必要があります。

端末のデフォルトはHKEY_CURRENT_USER\Consoleに保存され、アプリごとの設定はサブキーに保存できます。アプリケーションがショートカットで起動されている場合、これらのデフォルト値はoverriddenになります。

あなたが実行しているコンソールだけを変更したい場合は、さらに難しくなりますが、Windows自体がフォントを直接設定する方法を知っています。コンソールのメニューで[プロパティ]を選択してフォントの変更を適用すると、これが実際に表示されます。おそらくバージョンごとに変わるかもしれませんが、マップされたメモリと秘密のメッセージが使われていると思います。ブレークポイントをWinDbgに設定して調査を開始できます。シンボルを正しく設定したら、bp console!Write*と入力してください。を入力してください(複数の場合は、すべての書き込み関数に設定してください)。使用している構造体のレイアウトを把握する必要があります。そのため、一度に1つのコンソール設定を適用してメモリをダンプ/比較する必要があります。

編集:一部の人々はすでにこれを考え出したよう

に見えます。 This bug analysis paperには構造体の定義があり、マップされたメモリのトリックを実装するfound a SetConsolePalette functionもあります。 ReactOSはまったく同じ実装を使用しないかもしれませんが、take a look at itでも構いません。

Windowsがconhost.exeを使用して起動したときに内部がおそらく変更されたため、SetCurrentConsoleFontExを呼び出す必要があります。

+0

Vista以前のバージョンは、文書化されていない実装の詳細に依存しており、予告なしに変更する可能性があることを明示することをお勧めします。 – IInspectable

関連する問題