2011-05-19 114 views
3

我使用的是固定尺寸的字體(例如:「Courier New」)。當我通過調用CFont :: CreateFont函數初始化CFont對象時,我只想指定字體高度。如何從CFont對象中獲取自動計算的字體寬度?

CFont Font; 
Font.CreateFont(nFontHeight, 0, 0, 0, 0, false, false, 
    0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, 
    FIXED_PITCH|FF_MODERN, _T("Courier New")); 

根據文檔,字體寬度將自動計算。我需要爲其他一些計算自動計算的值。

GetLogFont函數是沒用的,因爲看起來CFont只包含我們給出的值,即width = 0,並且它僅在第一次使用時計算該值。 (請檢查Microsoft documentation

另一個選擇是使用CDC :: GetTextExtent使用單個字符。但在這種情況下,即使在高處也可以看到一些細微的差異。例如,當我給-32作爲高度時,GetTextExtent爲y值返回33。

有沒有什麼辦法可以得到正確的計算寬度?

+0

你爲什麼要給它一個負高度? – RedX 2011-05-19 13:54:26

+1

檢查CreateFont的文檔。大於0的字體高度與字體的「單元格高度」的高度相匹配,而小於0的高度將其與「字符高度」相匹配。 – MikMik 2011-05-19 14:19:03

回答

2

你試過CDC::GetTextMetrics()嗎?我從來沒有使用它,但它似乎是你在找什麼。你可以得到平均和最大的字符寬度,我認爲這對於Courier New應該是一樣的。

+0

謝謝MikMik,我會盡快檢查並回來:) – 2011-05-23 05:39:13

+0

檢查! GetTextMetrics是準確的! – 2011-05-23 06:28:52

3

首先,如果您只想指定字體高度,您通常要使用CreatePointFont。其次,Windows 95/98/SE/Me已經不復存在,並且與他們一起,基本上都是使用微軟的「文本」宏(如_T("whatever"))的理由。如果你想寬字符,請他們直接:

CFont font; 
font.CreatePointFont(nFontHeight, L"Courier New"); 

然後,通過@MikMik的建議,你可以用GetTextMetrics獲得寬度 - 但只有後,您選擇的字體到一個DC(GetTextMetrics將選定字體的數據獲取到DC中,而不僅僅是原始字體 - 特別是在小字體大小的情況下,有些東西會進行調整以補償輸出設備的分辨率)。

但是,請注意,即使是固定寬度的字體,字符串的寬度爲而非必然爲char_width * num_chars。至少如果我記得正確的話,即使是固定寬度的字體仍然可以被修改,這意味着間距是根據哪些字符對一起出現進行調整的。典型的例子是一對像AV。因爲它們彼此相鄰的線通常處於相同的角度(或至少非常接近相同的角度),因此將調整間距以將它們靠近在一起 - 事實上,「V」的頂部將經常與「A」的底部重疊。即使每個單獨的字符具有與其他字符相同的寬度,字符串的寬度也可能不同。

不速之客,我不確定Courier New是如何做的,但我相當確定至少有一些固定寬度的字體。

+0

如果一個應用程序使用的文件比GUI更多,那麼即使在今天和這個年代,創建一個MBCS應用程序也是一個很好的藉口。令我感到驚訝的是,微軟還沒有創建一個UTF-8代碼頁並將其設爲默認值。附:我很想有一個使用字距變化的固定寬度字體的例子!固定寬度的整個點是具有一致的字符間距,字距會打破目的。 – 2011-05-19 16:58:38

+0

@Mark Ransom:是的,使用'char's而不是寬字符有很好的理由,但是擁有一個可以編譯爲一個源代碼的單一源代碼的大部分原因都消失了,至少IME,無論如何,對於實際的數據來說都不夠實際。 – 2011-05-19 17:03:45

+0

因此,如果連固定寬度的字體都不是固定的寬度,我需要計算整行的CDC :: GetTextExtent,對嗎? – 2011-05-23 05:42:57