:
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 | 
 
沒有留言:
張貼留言