Delphi 中文化中 PixelsPerInch 對界面效果的影響以及解決

Bruce

提出問題
(此段文字受到大家批評,既然我的本意是盡量原創,所以還是保留,希望不喜歡的人只當是我的「竊以為」,不要太過叫真,看看而已) 中文化技術從關子將它引入簡體中文世界到現在也不知多少年頭了,隨著中文化工具和中文化技術的發展,中文化變得簡單起來,中文化隊伍空前的膨脹,但是這些中文化還是以 MS VC++ 的中文化為主,因為以 Visual Localize 3.0 為代表的軟體幾乎把 C++ 程式的中文化帶到了會英文就會中文化的地步。但是網路上的好東西不只 VC++ 是好東西,還有許多別的寶藏。Delphi 打著「聰明人編程用 Delphi」的旗幟聲勢浩大的走來,Delphi 編寫的軟體體積小,不需執行庫,得到越來越多人的喜歡。但是 Delphi 的中文化技術好像一直就沒有進步過,無論是國外國內,都沒有可視的資源修改工具。自從有了 Formread ,這種現象才得到了稍微的緩解。但是這個工具也只是提供了效果預覽,還不支援資源回寫,實在是不令人樂觀。最近我對 Delphi 的中文化產生了興趣,試著做了點東西,其間遇到了無數問題,經過參看 BruceZ 和 LLF 等朋友的文章,再加上無數次的試驗,現將我的經驗告訴大家。
所需工具
eXescope 6.1 用於匯入匯出 dfm 檔案,formread 2.5 用於編輯修改預覽 dfm。
簡明步驟
使用 eXescope 開啟可執行檔案,在 RCDate 欄,匯出一個以腳本形式存在的 dfm ,顯示亂碼的不要管他,不必關閉 eXescope。執行 formread 找到匯出的 dfm 檔案修改字串集,字型字號和英文字串,保存,選擇 eXescope 匯入修改後的 dfm 替換英文版的。優缺點: eXescope 匯出的是真正的 dfm 檔案,而不像 Reshacker 匯出的是一個純文字檔案: (,但是如果您不選用匯入功能而是和 BruceZ 說的剪貼回去,經常會出現斷句的現象。formread 可讀取 .exe .dfm .txt 檔案,但在 2000 下無法開啟.exe檔案,並且無法保存修改結果,.txt 無法彩色顯示腳本,修改時非常累眼。自然 .dfm 最好了。請老老實實的使用「代碼編輯區」手工修改相關資源,字串編輯區回寫時老是破壞腳本。
範例實踐
object AboutComponent: TAboutComponent
 Left = 285
 Top = 184
 BorderIcons = [biSystemMenu]
 BorderStyle = bsDialog
 Caption = 'About...'
 ClientHeight = 142
 ClientWidth = 345
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -13
 Font.Name = 'MS Sans Serif'
 Font.Style = []
 Position = poScreenCenter
 OnCreate = FormCreate
 OnShow = FormShow
 PixelsPerInch = 96
 TextHeight = 13
 object Label1: TLabel
  Left = 7
  Top = 8
  Width = 134
  Height = 22
  Caption = 'TSyntaxMemo'
  Font.Color = clBlack
  Font.Height = -19
  Font.Name = 'Arial'
  Font.Style = [fsBold]
  ParentFont = False
 end
 object Label2: TLabel
  Left = 151
  Top = 14
  Width = 122
  Height = 13
  Caption = '(c) 1997 - 99 David Brock'
 end
 object Button1: TButton
  Left = 256
  Top = 104
  Width = 75
  Height = 25
  Caption = 'OK'
  ModalResult = 1
  TabOrder = 0
 end
end
這是一個最標準最好中文化的 dfm ,只需依次將上面綠色部分修改為'關於...';'GB2312_CHARSET';''-12';'新細明體';'12';等等就可以完成中文化,預覽一下,您會發現界面已經變成簡體新細明體 9 點字的界面。如果您還想調整一下控件的位置,還可以調整一下黃色部分。但是我建議您最好不要修改,因為 Delphi 可以使用第三方控件,而這些東西在 formread 裡是顯示不出來的,修改工作將是一件非常痛苦的事情,好的辦法是調節一下自己的語系風格,讓長度盡量貼近原文。這是比較簡單易行的辦法。其實這些內容也不算什麼新鮮東西了,在好多中文化人的文章中都做過介紹,講的比我還詳細。大家可到 ! 漢化新世紀】尋找相關文章,我讓大家注意一下例子中紅色的部分,這才是我要講的重點部分。
重中之重
大家再看下段例子
object ConfigForm: TConfigForm
 Left = 133
 Top = 50
 BorderIcons = [biSystemMenu]
 BorderStyle = bsDialog
 Caption = 'Setup Xnews'
 ClientHeight = 462
 ClientWidth = 612
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clBtnText
 Font.Height = -13
 Font.Name = 'MS Sans Serif'
 Font.Style = []
 OldCreateOrder = False
 Position = poScreenCenter
 OnClose = FormClose
 OnCloseQuery = FormCloseQuery
 OnShow = FormShow
 PixelsPerInch = 120
 TextHeight = 16
 object Label20: TLabel
  Left = 25
  Top = 424
  Width = 260
  Height = 32
  Caption = 
   'Note: Some changes will not take place until'#13#10'the next time the ' +
   'affected window is opened'
 end
 
大家看看紅色的部分,的一段例子是非常標準的 delphi 格式,第二段則是從 Xnews 中擷取的一段代碼,作者使用了非標準的象素每英吋值。在中文化過程中我採用了常規的方法,但問題來了。無論是預覽還是匯入即時執行,視窗都變的非常的小,文字也扭曲的和蚊幾一樣難看,我曾經一度以為是作者採用了第三方的 VCL 檔案,按照 LLF 的方法追蹤,修改,可是並沒有變化。這個問題困擾了我非常長一段時間,某天再次閱讀 LLF 的文章看到了他講到 TextHeight 值的設定對字型顯示的影響,我的腦幾裡頓時一亮,想到了可能作者設定的象素值對文字的顯示產生了影響,說幹就幹,立即將 120 改為 96,呵呵果然字型變成了新細明體9點字的顯示效果,但是......
新的問題又來了,原來很小的視窗變的非常大,可能使用高解析度的朋友感覺還不是太大,但是對800*600的朋友影響就已經很大了,我曾經嘗試修改所有控件的位置長寬。上面也講過這真是一種痛苦的工作,費了好多天的時間以後,發現幾乎是完全失敗的。從此中文化工作又進入了一個僵持期。
因為我總是不理解既然在 DEFAULT_CHARSET 下 Font.Height = -13 Font.Name = 'MS Sans Serif' 的字型下可以顯示正常那麼為什麼改成中文後字號沒有多大變化,顯示效果就會有這麼大反差那。
天天想天天頭疼,突然有一天我想到,Delphi 對中文的支援會不會只是將它當作 物件來處理那,馬上動手修改 96/12=8 那麼 120/8=15 將 Font.Height 改為 -15, TextHeight 改為 15,預覽,Yeah~漂亮的中文界面又回來了。
題外的話
我不從事 C 和 Delphi 的開發工作,所以對一些概念非常模糊,搞點中文化也純粹是為了自娛自樂。所以對某些東西也不求甚解,比如在 C 下,英文界面最好看應該是 MS Sans Serif,8點字 最好看,而中文則是 新細明體,9點字,新細明體顯然比 MS Sans Serif 大一點;但是到了 Delphi 則成了英文界面 MS Sans Serif,-13 ,中文界面 新細明體,-12 按照上面的邏輯是不是應該認為 -XX字號越小那麼字型就應該越大,但是我舉的第二個例子證實了這個想法又是錯誤的。不知道誰能給我解釋一下 ? 謝謝

十分感謝 Ronnier 的回答: 您寫的很好啊。對於 TextHeight 和 Font.Height 的關係,我都沒有注意過,不過就經驗來說,只要記住,對於有 ParentFont = False 的,使 Font.Height 等於負的 TextHeight 就行了,而對於沒有 ParentFont = False 的,使 Font.Height 等於負的 (TextHeight-1)。其實 -12 就是代表 12px,-13 代表 13px,至於為什麼要用負的,微軟有規定如下:
font_height: This value is the height of the font in pixels. If this number is negative, the font mapper picks a font with characters with height approximately the absolute value of this number. If it's positive, the font mapper picks a font with a character cell height equal to the height value. The cell height includes some blank internal leading space (more about this later), so this makes the characters a little bit smaller. 所以說用正的也可以,但是按微軟的解釋,字會稍稍變小。這是規定,就不必深究了。:-)
一點牢騷
此段文字有人身攻擊嫌疑,接受偉兄建議,去掉了。我爭取做到以後只談技術,少說無聊的話。
真正的原因 (附錄)
自己只是在瞎琢磨,今天漢化新世紀的偉兄給我摘錄了梁利峰兄的一段舊文字,解決了心中的疑慮,慚愧慚愧,還是看書不專。現轉貼如下:
因為 Windows 其實不知道我們的顯示器的大小,所以是透過我們的設定來標示英吋的大小的。好的,我們再來看一下 Windows 中關於字號的設定。 在顯示內容對話框裡可以設定字型的大小,不過只有兩種設定,一種是小字型,另一種是大字型。其中小字型表示 96dpi ,而大字型表示 120dpi 。小字型是預設選項,而大字型是在用戶所選的螢幕解析度太大 (如 1600x1200) 時,為了避免字型太小看不清楚而選擇使用的。另外,用戶也可以自己設定字型的解析度,不過值就不一定是多少了。
我們常說的「新細明體,9」,表示的單位其實是磅,也就是 9 磅的新細明體。
我們來換算一下。在小字型的時候,解析度是 96dpi ,也就是說一英吋能顯示 96 個像素;9 磅是 1/8 英吋,所以 96/8=12 像素。也就是說,我們通常見到的字型就是這種 12x12 點陣的字型了。
另外,在大字型的時候,解析度是 120dpi ,9 磅是 1/8 英吋,所以 120/8=15 ,就是說大字型時,顯示的 9 磅字型其實是 15x15 點陣的字型。 在 VB、VC 或 Delphi 裡,對於視窗設定字型後,視窗的大小會自動隨用戶所選擇的是大字型還是小字型而自動調整視窗的大小,這一點就是因為它們使用了邏輯單位。預設情況下,對於 VB 來說是緹,對於 VC 和 Delphi 來說是磅。



回教學