:
2015/05/20 發現有一個 GHOSTXP 安裝的OS,執行WINPOS 必死
死亡點 .Font.Name = '細明體'。以往這一行是沒問題,我將 細明體字型mingliu.ttc COPY安裝。問題就解決
1. VB6 程式碼
皆是以 ANSI規格存檔,繁體VB6 是以 BIG5碼存檔,簡體VB6是以 GBK碼存檔。所以直接把程式碼放至對方的OS下開啟,均會看到一堆中文的亂碼。
2. 以VB6 IDE 開啟程式碼,若是可以看到中文繁體字/簡體字。
有一些注意事項:
A. 程式原始碼要跨越不同語系的作業系統,必須要事先轉碼,將 ANSI BIG5 ßà ANSI GBK (在各個OS下,才不會看到亂碼)。
B. 簡體OS + VB6 只認識ANSI GBK的原始碼、繁體OS + VB6 只認識ANSI BIG5的原始碼。
C. VB6 IDE 讀入 ANSI 的程式碼,會以 UniCode方式在畫面上呈現,但是原始碼檔案仍然是以 ANSI規格存檔。
D. 簡體OS + VB6 IDE 可以看到中文繁體字/簡體字,因為簡體OS
UniCode 之GBK字集
同時支援繁體字/簡體字。讀入 ANSI之 GBK編碼(內含繁/簡字碼),會自動對應至 IDE 的 UniCode之GBK字集方式在畫面上呈現。 PS: GBK之繁體字碼
跟 BIG5繁體字碼完全不相容。
E. 繁體OS + VB6 IDE,BIG5 只支援繁體字集,所以原始碼檔案根本無法存入簡體字碼
若要在 IDE或 textbox輸入框 或 label 內看到簡體字,必須安裝 Unicode補完計畫
F. 共同點: 繁體OS 的UniCode 跟 簡體OS UniCode,中文繁體/簡體編碼是相同的
?ASCW(“华”) =
21326 繁體OS跟 簡體OS 解出來的 UniCode碼是相同。
?ASCW("華") =
-31761 = 0xFFFF83EF = U+83EF 繁體OS跟
簡體OS 解出來的 UniCode碼是相同。
ASCW相對 CHRW
上述字串轉成 ANSI 的陣列時:
'UniCode 華 在 BIG5 ANSI 為 B5(181) D8(216)
'UniCode 華 在 GBK ANSI 繁體字 為
C8(200) 41(65)
'UniCode 华 在 BIG5 ANSI 為 85(133) 4F(79)
'可能是有安裝 UniCode裝補計畫,才可以得到 BIG5 之簡體編碼
'UniCode 华 在 GBK ANSI 繁體字 為
BB(187) AA(170)
AA() = StrConv("華", vbFromUnicode, &H404)
'UNICODE 轉為 台灣之 ANSI--> BIG5
BB() = StrConv("華", vbFromUnicode, &H804) 'UNICODE
轉為 大陸之 ANSI--> GBK
CC() = StrConv("华", vbFromUnicode, &H404)
'UNICODE 轉為 台灣之 ANSI--> BIG5
DD() = StrConv("华", vbFromUnicode, &H804) 'UNICODE
轉為 大陸之 ANSI--> GBK
3. 程式碼補強: (以繁體 OS + VB6
為開發基礎)
必須引用下列 API 函式:
Private Declare Function GetSystemDefaultLangID Lib "kernel32" ()
As Integer
' LangID
2052 簡體 1028 繁體
Private Declare Function LCMapString Lib "kernel32" Alias
"LCMapStringA" _
(ByVal Locale As
Long, ByVal dwMapFlags As Long, _
ByVal lpSrcStr As
String, ByVal cchSrc As Long, _
ByVal lpDestStr As
String, ByVal cchDest As Long) As Long
Private Declare Function lstrlen Lib "kernel32" Alias
"lstrlenA" (ByVal lpString As String) As Long
|
依照 OS 語系,動態變更 程式元件語系
Public Sub
FormCharset_Change(x_FORM As Form)
On Error Resume Next
Dim LangID As Integer
Dim T_CONTROL As Control
LangID = GetSystemDefaultLangID '2052 簡體 1028 繁體
With x_FORM
If LangID = 2052 Then '2052 簡體
If
.Font.Charset = 136 Then
.Font.Charset = 134
End If
.Caption =
Big5_2_SimplifiedChinese(.Caption)
End If
End With
For Each T_CONTROL In x_FORM.Controls
With T_CONTROL
If LangID = 2052 Then '2052 簡體
If .Font.Charset = 136 Then
.Font.Charset = 134
End If
'無效,以下在執行階段,簡體OS 找不到"細明體" 這三個字,會自動以 宋體取代。所以以下程式碼永遠執行不到
' .Font.Name = "宋体"
'End If
'If .Font.Name = "新細明體" Then
' .Font.Name = "新宋体"
'End If
If (TypeOf T_CONTROL Is
SSTab) Then
'在 簡體OS 發現,開發階段 TAB有焦點存檔,該 TAB的字體會轉換錯誤
'TAB 元件已經自行 將內容轉過一次碼 ,我們 Big5_2_SimplifiedChinese() 再轉一次就會 亂掉 (但是元件編碼 還是得自己修改)
'或 事後 手動設定 元件內容
.Caption = UniCode_GBK繁體_to_GBK簡體(.Caption)
Else
.Caption = Big5_2_SimplifiedChinese(.Caption)
.text = Big5_2_SimplifiedChinese(.text)
End If
End If
End With
Next
End Sub
|
繁體 轉 简体
(執行階段 應該在 簡體OS 下,LCMapString &H804 才會正常)
'1. GB字集 裡含有 繁體字型 與 簡體字型
'2. GB裡的 繁體字型部份 轉為 Unicode後 , 便與 Big5 轉為 Unicode後的值 是一樣的
'3. 使用 LCMapString函數 , 可將 GB裡的 繁與簡 字體 做內碼映射轉換
'Big5 to GB 方法為:
'Big5 -> Unicode (使用MultiByteToWideChar) -> GB繁字集(GBK) -> GB簡字集(GB2312) (使用LCMapString)
'?Big5_2_SimplifiedChinese("租賃項目")
'租賃項目 --> 租赁项目 (繁體OS+VB6 DEBUG 視窗看的到, UNICODE 簡體 )
'租賃項目 --> 租赁项目 (繁體OS+VB6 DEBUG 視窗看到是亂碼, ANSI 簡體 適合傳入 VB6 程式碼動態文字[因為VB6 內部程式流程是用 ANSI碼] )
Function
Big5_2_SimplifiedChinese(x_text As String) As String
Const
LCMAP_SIMPLIFIED_CHINESE = &H2000000
Const
LCMAP_TRADITIONAL_CHINESE = &H4000000
‘0x0404 Chinese
Taiwan 950
CHT
‘0x0804 Chinese PRC
936 CHS
Dim STf As String
Dim STlen As Integer
Dim STj As String
Debug.Print
"---------------------------------------------------------"
Dim ST As String
Dim Te As String
Te = x_text
ST = Te
ST = StrConv(ST, vbFromUnicode,
&H804) '再將 Unicode碼 轉換為 ANSI( GBK編碼)
0x0804 Chinese PRC
936 CHS
Te = StrConv(ST, vbUnicode,
&H404) '上一行程式碼因為要跨平台,所以要強烈指定 原始碼之區域編碼
Debug.Print "STEP 1: " &
Te '在繁體作業系統 看到會是亂碼 (在簡體作業系統上,可以看到 GB字集 繁體字)
'可能是因為 LCMapString() 只會針對執行程式時,所得到的本地語系 作動
'由於當執行下列程式流程時,一定是在簡體 OS下,所以 LCMapString &H804 會有反應
'反而在繁體 OS下 指定 LCMapString &H804 看不出結果
'//轉換 Gb碼繁體 到 Gb碼簡體,使用API函數 LCMapString
STf = Te
STlen = lstrlen(STf)
STj = Space(STlen)
LCMapString &H804,
LCMAP_SIMPLIFIED_CHINESE, STf, STlen, STj, STlen
Debug.Print "STEP 2: " & STj '在繁體作業系統 看到會是亂碼 (在簡體作業系統上,可以看到 GB字集 簡體字)
' '?form1.Big5_2_SimplifiedChinese("租賃項目")
' 'STEP 1: 逤揎?醴 <------ 傳入 簡體 VB6 程式碼流程可以正常使用,可以看到 GB字集 繁體字
' 'STEP 2: 逤醣?醴 <------ 傳入 簡體 VB6 程式碼流程可以正常使用,可以看到 GB字集 簡體字
Big5_2_SimplifiedChinese = Te '可以看到 GB字集 繁體字, 因為我的程式碼有很多 直接指明 字串內容
'Big5_2_SimplifiedChinese = STj 'GB字集 簡體字 (僅適用 元件上的靜態文字,變為簡體)
'由於VB6 程式碼的訊息文字,幾乎是繁體字,就算動態設定至元件,仍是繁體字
'既然無法全面一致,建議用 GB字集 繁體字模式
End Function
|
4. 關於LCMapString() 只會針對執行程式時,所得到的本地語系 作動,若是在執行階段是在繁體OS下,參數一
只有 &H804 (台灣)才能正常作用。若是在執行階段是在簡體OS下,參數一
只有 &H404 (大陸)才能正常作用。
5. 關於LCMapString() 當參數三 傳入是 UniCode,參數五 回傳就是 UniCode。
當參數三 傳入是 ANSI,參數五
回傳就是 ANSI。
'以下範例 Test1() / Test2() 必須在 繁體OS 才能看出結果
'嚴格來說應該是說: UniCode 簡體 轉 UniCode 繁體,因為 VB 程式碼內的中文字串是 UniCode
Sub Test1() 'UniCode
簡體 轉 UniCode 繁體(for 台灣語系 404)
Const LCMAP_SIMPLIFIED_CHINESE =
&H2000000
Const LCMAP_TRADITIONAL_CHINESE =
&H4000000
STj = "中华人民共和国"
STlen = lstrlen(STj)
STf = Space(STlen)
LCMapString &H404, &H4000000,
STj, STlen, STf, STlen
'0x0404 Chinese Taiwan 950
CHT
Debug.Print "Test1:" & STj
& " ----> " & STf
End Sub
'以下範例 Test1() / Test2() 必須在 繁體OS 才能看出結果
Sub Test2() 'UniCode
繁體 轉 UniCode 簡體(for 台灣語系 404)
Const LCMAP_SIMPLIFIED_CHINESE =
&H2000000
Const LCMAP_TRADITIONAL_CHINESE =
&H4000000
STf = "中華人民共和國"
STlen = lstrlen(STf)
STj = Space(STlen)
LCMapString &H404, &H2000000,
STf, STlen, STj, STlen
'0x0404 Chinese Taiwan 950
CHT
Debug.Print "Test2:" & STf
& " ----> " & STj
End Sub
'以下範例 Test5() / Test6() 必須在 簡體OS 才能看出結果 (在 繁體OS 會無變化)
'可能是因為 LCMapString 只會針對執行程式時,所得到的本地語系 作動
'嚴格來說應該是說: UniCode 簡體 轉 UniCode 繁體,因為 VB 程式碼內的中文字串是 UniCode
Sub Test5() ''UniCode 簡體 轉 UniCode 繁體(for 大陸語系 804)
Const LCMAP_SIMPLIFIED_CHINESE =
&H2000000
Const LCMAP_TRADITIONAL_CHINESE =
&H4000000
STj = "中华人民共和国"
STlen = lstrlen(STj)
STf = Space(STlen)
LCMapString &H804, &H4000000, STj, STlen, STf,
STlen '0x0804 Chinese
PRC 936 CHS
Debug.Print
"Test5:" & STj & " ----> " & STf
End Sub
'以下範例 Test5() / Test6() 必須在 簡體OS 才能看出結果 (在 繁體OS 會無變化)
'可能是因為 LCMapString 只會針對執行程式時,所得到的本地語系系 作動
Sub Test6() 'UniCode
繁體 轉 UniCode 簡體(for 大陸語系 804)
Const LCMAP_SIMPLIFIED_CHINESE =
&H2000000
Const LCMAP_TRADITIONAL_CHINESE =
&H4000000
STf = "中華人民共和國"
STlen = lstrlen(STf)
STj = Space(STlen)
LCMapString &H804, &H2000000, STf, STlen, STj,
STlen '0x0804 Chinese
PRC 936 CHS
Debug.Print
"Test6:" & STf & " ----> " & STj
End Sub
|
沒有留言:
張貼留言