2009-12-17 51 views
8

如何在我的C++ Windows控制檯應用程序中更改字體?在C++控制檯應用程序中使用Unicode字體

它似乎沒有使用默認使用的字體cmd.exe(Lucida控制檯)。當我通過現有的cmd.exe運行我的應用程序(鍵入name.exe)時,它看起來像這樣:http://dathui.mine.nu/konsol3.png這是非常正確的。 但是,當我獨立運行我的應用程序(雙擊.exe)時,它看起來像這樣:http://dathui.mine.nu/konsol2.png。 相同的代碼,兩種不同的外觀。

所以現在我想知道如何改變字體,所以無論它如何運行,它總是看起來是正確的。


編輯:

好,一些更多的信息。當我使用這個小片段時:

SetConsoleOutputCP(CP_UTF8); 
wchar_t s[] = L"èéøÞǽлљΣæča"; 
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL); 
char* m = new char[bufferSize]; 
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL); 
wprintf(L"%S", m); 

它使用正確的字體。但在我的實際應用中我使用WriteConsoleOutput()打印字符串代替:

CHAR_INFO* info = new CHAR_INFO[mWidth * mHeight]; 
for(unsigned int a = 0; a < mWidth*mHeight; ++a) { 
    info[a].Char.UnicodeChar = mWorld.getSymbol(mWorldX + (a % mWidth), mWorldY + (a/mWidth)); 
    info[a].Attributes = mWorld.getColour(mWorldX + (a % mWidth), mWorldY + (a/mWidth)); 
} 
COORD zero; 
zero.X = zero.Y = 0; 
COORD buffSize; 
buffSize.X = mWidth; 
buffSize.Y = mHeight; 
if(!WriteConsoleOutputW(window, info, buffSize, zero, &rect)) { 
    exit(-1); 
} 

,然後使用錯誤的字體。我用兩個不同的窗口,像這樣創建:

mHandleA = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, 
            NULL, CONSOLE_TEXTMODE_BUFFER, NULL); 

我可能是設置語言編碼的只是標準輸出什麼?

+0

嗯......奇怪的是,有一種方法來檢測控制檯與雙擊與幾個例外情況。這篇文章是一個好的開始,但它不夠遠:http://www.codeguru.com/cpp/misc/misc/consoleapps/article.php/c15893/ – 2009-12-17 15:03:24

+0

您使用哪種編譯器? – SjB 2009-12-17 15:09:21

+0

也許跟蹤啓動代碼 - 從pre main() - 查看實際構建控制檯窗口本身的代碼是什麼?我假設編譯器/控制檯項目提供的.exe文件必須有一些代碼,用於檢測您的應用程序是否已經在控制檯中啓動,或者是否需要控制檯,以便在這種情況下爲您創建控制檯窗口。這是我的直覺,不是研究的事實,但可能只有幾分鐘的調試才能驗證。在這一點上,你可以看到它的源代碼,看看你可能需要做什麼才能訪問該控制檯HWND,以不同的方式設置它的字體...... – Mordachai 2009-12-17 15:11:04

回答

2

對於Vista及更高版本,有SetCurrentConsoleFontEx,因爲已經有said

對於2K和XP,有一個無證函數SetConsoleFont;例如閱讀here。現在

typedef BOOL (WINAPI *FN_SETCONSOLEFONT)(HANDLE, DWORD); 
FN_SETCONSOLEFONT SetConsoleFont; 
.......... 
HMODULE hm = GetModuleHandle(_T("KERNEL32.DLL")); 
SetConsoleFont = (FN_SETCONSOLEFONT) GetProcAddress(hm, "SetConsoleFont"); 
// add error checking 
.......... 

SetConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), console_font_index); 

console_font_index是一個指數到控制檯字體表中,定義其是未知的。但是,console_font_index == 10已知識別Lucida控制檯(Unicode字體)。我不確定在不同的操作系統版本中這個值有多穩定。

UPDATE

杜特的評論後,我已經運行在一個乾淨的XP SP2安裝程序的實驗。

  • 最初,GetNumberOfConsoleFonts()實際上返回10,字體索引0..9指定各種柵格字體。

  • 後,我打開,在其屬性中選擇Lucida的字體的控制檯(只有一次;打開後馬上我可以關閉它,但效果是一樣的),突然GetNumberOfConsoleFonts()開始返回12,和指數10和11選擇不同大小的Lucida。

如此看來這一招工作對我來說,當我打它,因爲我一直運行與Lucida的字體至少一個控制檯應用程序中選擇。

因此,出於實用目的,jon hanson's answer似乎更好。除了提供更好的控制之外,它實際上也是可行:)

+0

它確實會改變字體,但GetNumberOfConsoleFonts()爲我返回10,我試過0-9(和10,11,.. )但沒有一個是Lucida Console。 所以現在的問題是,我該如何使用它來改變Lucida控制檯? :) – dutt 2009-12-17 19:48:05

4

Windows將cmd設置(包括字體)存儲在註冊表中,使用exe路徑作爲關鍵字。根鍵是'HKEY_CURRENT_USER \ Console',所以如果你看看那裏的註冊表,你會看到幾個以varous exe命名的子鍵。

要複製現有exe的設置,可以將密鑰導出到文本文件,然後編輯文件以將密鑰名稱更改爲exe的密鑰名稱,然後重新導入它。

您也可以逐步修改註冊表,但我懷疑這會立即生效w.r.t.到您的控制檯窗口。

3

您可以嘗試SetCurrentConsoleFontEx()函數。

+1

你可能想提及GetStdHandle太 - http://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx – 2009-12-17 15:41:10

+0

iirc只存在於Vista和更高版本,更喜歡這是可行的XP上以及許多人仍然運行它。 – dutt 2009-12-17 16:05:39

+0

奇怪,他們聲稱你需要Vista,但也聲稱你應該將_WIN32_WINNT定義爲0x0500(Windows 2000)或更高版本。似乎矛盾。 – 2009-12-17 16:32:28

相關問題