雙語或多語成品軟體的編制 (轉)

worldblog發表於2007-12-07
雙語或多語成品軟體的編制 (轉)[@more@]雙語或多語成品的編制
呂維·CPCW
  只用一套就可以方便地支援多種文字和多個地域,那麼這個軟體就可以方便地被翻譯成本地版本,這個過程叫做地域化(Localization)。怎樣才能不修改任何原始碼就使之能動態地轉換到不同的地域資源上呢?那就是使用的特性之一?-資源。把在軟體中用到的可見資源維繫在一個資源DLL(Dynamic Link Library動態連結庫)中,就能使地域化很容易地被實現,因為它把具體的文字單獨提取放在一箇中,所以,一個可檔案就可以裝載幾種不同的語言文字,並且選擇用子程式來裝載適合的文字DLL。建立一個CString的例項,並用該字串的資源識別符號(string ID)LoadString,即可避免繁瑣的字串編碼工作。

  在大多數情況下,資源包含在應用程式的單元中,如果呼叫AfxSetRe Handle,就可以指向另一個不同的單元,示例StateDemo程式就是這樣處理的。呼叫AfxSetResource Handle,從DLL資源中採集軟體所需資源,透過替換掉不同語種的DLL資源,程式便可以使用一套完全不同的資源(如String字串、Dialogue對話方塊、Bmp點陣圖、Menu選單等)。

  初始情況下,作為主執行體的StateDemo不含任何資源。首先,建立一個包含所有英文資源的DLL,在使用這個資源DLL時,應用程式就會以英文形式出現,即軟體為英文版;然後,建立中文DLL,再次執行StateDemo程式,程式就以中文形式出現(即使應用程式未被重新編譯)。

  一.應用程式的建立與編譯

  1.建立StateDemo.EXE檔案(1)建立StateDemo工作區

  在 Visual C++ 5.0開發環境下,單擊File | New選項,在建立型別選擇框New中選擇MFC AppWizard(exe)、Projectname:StateDemo,建立新專案StateDemo工作區,應用程式型別選擇Multiple Documents,單擊Finish完成工作區的建立。

  (2)新增字串資源

  這步實際上是在為英文資源DLL新增字串資源,因為後面將把英文資源StateDemo.rc從專案中移走,並把它複製到英文資源的專案中,而不是剛建立的StateDemo.EXE檔案專案,執行體exe檔案會引用這個資源,而字串就在資源DLL中。選擇StateDemo專案資源中的String Table,在StringTable中單擊右鍵選擇New String,新增如下程式碼,然後選擇選單中File | Save All選項即完成。

  ID:IDS_MINE=300

  //主IDS_MINE定義為300,即ID的值為300

  Caption(標題):Hi! it's my demo vc5 program of English version.

  //這是英文版軟體中字串的演示

  執行結果如圖1所示。

  圖1.執行結果

  (3)新增CStateDemo類的資料成員

  本程式要動態地裝入包含所有資源的DLL,所以必須儲存DLL的Handle(控制程式碼),在後面會釋放Handle,並在CStateDemoApp類中新增私有資料成員(程式碼如下)。

  private:

   HINSTANCE m_hDemoDLL;//資源DLL handle控制程式碼

  可以在MS-VC5的DevelopStudio位於左方的Workspace視窗中選擇ClassView標籤,單擊CstateDemoApp類,單擊滑鼠右鍵選擇Add Member Variable,然後輸入Type與Declarition,並選擇私有型別。

  (4)修改CStateDemoApp::InitInstance

  應用程式需裝入包含所有資源的DLL,在本例程式中,英文資源DLL都命名為Resource.dll。把下面的程式碼加入初始化函式InitInstance的頂部。

  BOOL CStateDemoApp::InitInstance()

  {

   AfxEnableControlContainer();

   //Standard initialization

   //If you are not using these features and wish to reduce the size

   //of your final executable, you should remove from the following

   //the specific initialization routines you do not need.

   //調入StateDemo資源DLL.

   m_hDemoDLL=AfxLoadLibrary (_T("Resource.dll"));

   if(!m_hDemoDLL)

   //如果Resource.dll檔案Handle不存在

   {

   AfxMessageBox(_T("I can't load the resource DLL !"));

   //沒有找到Resource.dll檔案時,彈出訊息框發出警告:I can't load the resource DLL !;

   //警告訊息框如圖2所示

   return FALSE;

   }

   //告訴應用程式設定資源控制程式碼m_hDemoDLL;

   AfxSetResourceHandle(m_hDemoDLL);

  }

  

  圖2. 警告訊息框

  (5)使用Wizarar處理CStateDemoApp的ExitInstance函式

  在此需要釋放前面用AfxLoadLibrary裝入的DLL,將下面的程式碼新增到函式ExitInstance中就可達到此目的。選擇選單View | Class Wizard,在Message Maps的Classname Edit視窗中選擇CstateDemoApp,然後在Messages下找到ExitInstance,選擇Edit Code並加入以下程式碼。

  int CStateDemoApp::ExitInstance()

  {

   //TODO: Add your specialized code here and/or call the base class

   if(m_hDemoDLL)

   AfxFreeLibrary(m_hDemoDLL);//釋放DLL資源;

   retrun CWinApp::ExitInstance();

  }

  (6)修改CStateDemoView::OnDraw

  在Multiple-Document型別中顯示不同語種字串和icon等各種資源,在函式中加入下列程式碼。

  void CStateDemoView::OnDraw(CDC*pDC)

  {

   CStateDemoDoc* pDoc = GetDocument();

   ASSERT_VALID(pDoc);

   pDC->DrawIcon(10,10,AfxGetApp()->LoadIcon(IDR_MAINFRAME));

   //從資源DLL中調入圖示(ID為IDR_MAINFRAME)並在視窗10,10位置繪製;

   CString strMessage;//定義strMessage為Cstring字串型別;

   //從resource DLL中顯示字串;

   strMessage.LoadString(IDS_DEMO);

   pDC->TextOut(60,65,strMessage);

  }

  (7)從StateDemo Project中移走StateDemo.rc

  因需要程式中不含有任何資源,只在Resource.dll中含有資源,所以,要在此專案中移走所有資源,並把它們放進Resource.dll中,但不是刪除,這就是使用MFC的靈活性。具體操作如下:選擇Workspace下的FileView,單擊StateDemo.rc,按鍵盤上Delete鍵刪除,此時所有資源就不在專案中了。

  (8)編譯StateDemo專案

  開始編譯專案,單擊選單Build | Execute StateDemo.exe選項,由於此時專案中沒有資源,因此會彈出報錯訊息框"I can't load the resource DLL !",如圖2所示,單擊OK,不予理會。

  現在,StateDemo專案的執行體StateDemo.exe就建成了,它不包含任何資源,而是依靠動態連結庫DLL來提供所有資源。

  下面來建立中、英文資源DLL,在這個DLL建立之後,把資源DLL拷回到本專案的De或Release目錄中,就可執行該應用程式了。

  2.建立英文資源Resource.dll

  (1)建立英文新專案區

  在建立型別選擇框New中選擇MFC AppWizard(dll),建立一個英文新專案區,在Location下為工作區選擇目錄...StateDemo即...StateDemoEnglish作為該專案區目錄,單擊OK,在Step1中選擇Regular DLL using MFC DLL,單擊OK即可。

  (2)刪除專案中所有檔案

  剛才建立的DLL已包含了一些資源,但它的各種檔案都不需要,所以在Workspace FileView中選中所有檔案,按Delete刪除所有檔案。

  (3)從StateDemo專案中複製英文資原始檔

  現在要用剛才從StateDemo中移出的英文資源,前面曾把一個資源字串加入到StateDemo.rc檔案中,在此,資源字串就起作用了。將...StateDemo目錄下的StateDemo.rc和Resource.h複製到...StatedemoEnglish目錄下。目的是把...StateDemores下的所有資源轉移到...StateDemoEnglishres目錄下。下面列出需從專案StateDemo中複製到專案英文中的所有檔案及其註釋。

   需要複製的檔案 註釋

   StateDemo.rc 資原始檔

   resource.h 資源標頭檔案

   resStateDemo.ico 主程式的圖示

   resStateDemo.rc2 資源描述檔案

   resStateDoc.ico 文擋圖示

   resToolbar.bmp 工具條點陣圖

  表1.

  (4)將資原始檔新增到英文專案中去,使圖示變為英文資源式樣

  把StateDemo.rc加入到英文專案中去,你可以在VC5 Develop Studio的Workspace視窗的File View選項卡中選擇"English"。單擊右鍵選擇Add project to workspace選項,把檔案加入專案中。在此,你可以從Resource View選項卡中看到,在最開始的StateDemo專案中加入的字串IDS_DEMO("It's my demo...")現在已被移到了英文專案中,並將成為Resource.dll的一員。

  既然這個英文專案是英文資源DLL,並命名為Resource.dll(與後面建立的中文Resource.dll同名,這樣才能使EXE執行程式存取雙語或多語種DLL),所以要修改圖示來演示StateDemo.exe被調入時是英文版的。把IDR_MAINFRAME圖示修改為英文文化特徵的,或在Resource View選項卡的圖示一欄單擊右鍵選擇Import來匯入你想要的圖示,它可以是16*16,也可以是32*32,本演示程式是使用英國國旗作為IDR_MAINFRAME,以示是英文版的。你可以按自己的需要和風格任意修改在Resource View中的其他資源。

  (5)修改連結目標程式中的設定

  建立英文資源DLL的任務已經基本完成,還需修改DLL程式在Link前的設定。選擇Workspace選項卡,選擇Project | Settings選項,在視窗中選擇Link標籤,改變一些Link設定,將輸出的檔名改為Resource.dll,也就是中英文資源同名的那個英文資源DLL,在連結命令Project Options中加入NOENTRY,它的功能是告訴連結器這是一個含有唯一資源的DLL,不包括入口點。圖3顯示了修改過的Link選項卡對話方塊,注意必須把/NOENTRY選項加進公用項編譯中。

  

  圖3. Link選項卡對話方塊

  至此,英文資源DLL就建立成功了。執行它時,按熱鍵F7連結(此時有視窗彈出,讓使用者選擇所要相關的exe檔案,可省去),Resource.DLL就在...StateDemoEnglishDebug目錄下了。如需執行英文版演示程式,則把它複製到StateDemoDebug目錄下,然後執行StateDemo.exe檔案,現在就是英文資源起作用了,它顯示英文和英國國旗(如圖4所示)。

  

  圖4. 英文版演示程式

  3.建立中文資源Resource.dll

  (1)建立中文新專案區並刪除中文專案中所有檔案

  在建立型別選擇框New中選擇MFC AppWizard(dll),建立一箇中文新專案區,在Location下為工作區選擇目錄...StateDemo即...StateDemoChinese作為該專案區目錄,單擊OK。其他選項如上面建立英文專案區所述。

  剛建立的DLL已包含了一些資源,但它的各種檔案在此都不需要。所以,在Workspace FileView中選中所有檔案,按Delete刪除所有檔案。

  (2)複製資原始檔

  仍然使用前面從StateDemo中移出的英文資源,同樣將目錄...StateDemo下StateDemo.rc和Resource.h複製到剛建立的中文資源專案目錄Chinese下,將...StateDemo目錄下的StateDemo.rc和Resource.h複製到...StatedemoChinese目錄下。目的是把...StateDemores下的所有資源轉移到...StateDemoChineseres目錄下,需從專案StateDemo複製到專案Chinese的所有檔案和註釋也如上述表1所示。

  (3)把資原始檔新增到中文專案中使圖示變為中文資源式樣

  把StateDemo.rc加入到Chinese專案中去,你可以在VC5 Develop Studio的Workspace視窗的File View選項卡中選擇"Chinese",單擊右鍵選擇Add project to workspace選項把檔案加入到專案中。在此,StateDemo專案中的字串IDS_DEMO("it's my demo...")已經移到中文專案中,並將成為中文Resource.dll的一員。現在的Resource.dll是中文資源DLL(與前面建立的英文Resource.dll同名),把IDS_DEMO改為中文字串,程式碼如下:IDS_DEMO=300,

  Caption(標題):"你好!這是MS VC5中文演示程式!"

  執行結果如圖5所示。

  圖5. 中文版演示程式

  字串修改完成後,需要對選單進行地域化處理,即把選單項改為中文。開啟Resource View標籤,雙擊Menu項,在右邊工作區所顯示的MFC標準選單中把英文翻譯成中文;也可以新增選單項,按軟體所需作完全個性化的設計。本演示程式使用中國國旗做IDR_MAINFRAME,以表示是中文版。你還可以按自己的需要和風格任意修改Resource View中的其他資源。

  (4)修改中文DLL連結目標程式和資源元件中的設定

  中文資源DLL也需要修改DLL程式在Link前的設定,其方法與英文的相同:依次選擇Workspace選項卡、Project | Settings選單、Link選項卡,改變一些Link設定,將輸出的檔名改為Resource.dll,在連結命令Project Options中加入NOENTRY(參見圖3)。修改資源元件中的設定,在Project | Settings選單中的Resource選項卡中,將預設的文字改為中文(如果是中文Windows,則此處就已經是中文了),接下來刪除預處理定義_AFXDLL,最後在Directory中輸入Visual C++ 5.0目錄1.chs的路徑,這個目錄下裝的是中文特定資源。還有其他資源如1.fra法語、1.ita義大利語、1.kor韓文等,都可以在需要時選擇使用。

  刪除預處理定義_AFXDLL並輸入資源的路徑的目的是要包含通用的資源,如果沒有這樣做,則應用程式會從安裝的MFC中收集通用的資源。應用程式特定資源會被地域化,通用的MFC資源(諸如游標、列印預覽和通用屬性頁)則不需要。所修改的設定如圖6所示。

  圖6. 資源設定的修改

  (5)連結並執行中文資源DLL

  按熱鍵F7進行連結,中文資源Resource.DLL就在...StateDemoChineseDebug目錄下了。要看中文,就把它複製到StateDemoDebug目錄下,然後再執行StateDemo.exe檔案,這時顯示的就是中文版了。所有資源都中文化了,如中國國旗、中文選單等,起作用的就是剛建立的中文資源Resource.dll,執行結果如圖7所示。要注意的是,由於中文資源DLL包含了所有通用的MFC資源,所以它比英文要大一些。

  圖7. 中文版演示程式

  至此,兩種資源的DLL都建立好了。在本演示程式中,資源全部被從可執行檔案中移走並被放入一個DLL中。在MFC類引用任何資源時(比如CString::LoadString),都可以使用當前的資源控制程式碼。通常情況下,當前資源控制程式碼和應用程式的資源控制程式碼是一樣的,但本演示程式透過AfxSetResourceHandle改變了這種情況,該函式透過傳給AfxSetResourceHandle的控制程式碼使MFC提取所有的資源。當英文的DLL被中文的DLL所取代時,資源ID就訪問定位在中文DLL的資源。由於DLL是從初始的DLL複製翻譯過來的,所以,所有的資源應是完整的,只不過是被翻譯成中文罷了。Windows應用程式的資源一般維繫在執行程式上,當需要時才被裝入。當你的應用程式需要某種資源時,需要給Windows提供兩件東西:應用程式的例項控制程式碼和資源的識別符號。

  二.應用程式的多語種安裝

  標準軟體安裝程式製作工具Install Shield 5是在Microsoft Visual C++ 5.0 Enterprise Edition中提供的。在所有制作安裝軟體的工具中,它是最專業、功能最強大的。用Install Shield 5製作一般的實用安裝程式很簡單,只需在生成圖示等很少幾處加入程式碼。這裡只討論在安裝軟體前識別Windows版本和語言,並按照所基於的自動選擇你的雙語種或多語種軟體的語言進行安裝。

  在Windows作業系統下,提供的資源有很完善的功能。為了獲取當前作業系統的語言版本,可以呼叫Win32函式GetOEMCP(),它的作用是獲取當前作業系統的OEM(Original Equipment Manufacturer源裝置供應商) 內碼表,其函式定義如下:

  UNIT GetOEMCP(VOID)//GetOEMCP(VOID)不帶任何引數;

  如果函式呼叫成功,則返回當前系統OEM內碼表定義的值;如果當前系統沒有OEM內碼表,則返回使用者定義的預設值。下面列舉了幾個定義的值所代表的意思。

  定義的值 代表的意思

  936 Chinese (P.R.C , Singapore) 中華人民共和國,新加坡

  950 Chinese (Taiwan,HK) 台灣、香港

  437 United States 美國

  949 Korean 韓國

  932 Japan 日本

  855 Russian 俄羅斯

  安裝在Windows 95或平臺下的軟體之前,先要根據當前系統的語言版本來選擇與該語言版本所對應的動態連結庫DLL,從而生成符合該作業系統版本的軟體。例如,你可以用下面的程式碼來判斷當前是否是簡體中文:

  if(GetOEMCP()==936)

   {

   .....

   }

  此外,還有一種方法就是採用AutoRun技術。如果應用軟體是以光碟為載體,則可以在檔案AutoRun上下功夫。AutoRun是一個放在光碟目錄下的檔案,當光碟放入的時候,Windows 95會自動執行它。根據不同語言版本軟體所需的不同資源DLL檔案,用Install Sheld 5製作兩套安裝程式,分別放在各自的目錄下,而且安裝時的SPLASH版權封面圖片setup.bmp也可以根據地域的不同而不同,例如把中文大陸國標碼安裝程式放在GBSetup目錄下,中文BIG5碼安裝程式放在BIG5Setup目錄下。你可以像上面一樣,在AutoRun.exe中加入如下程式碼。

  if(GetOEMCP()==936)

  {

  ::WinExec(_T("GBSetupsetup.exe"),SW_SHOW);

  //呼叫SDK函式WinExec執行命令列程式setup.exe

  }

  if(GetOEMCP()==950)

  {

  ::WinExec(_T("BIG5Setupsetup.exe"),SW_SHOW);

  }

  現在就可以自動識別Windows作業系統語言版本而安裝各自相應語言版本的軟體了。在某種情況下,使用者需要更大的自由度,你可以在安裝前彈出視窗,詢問要安裝哪種語言版本。在AutoRun.exe可執行檔案中,根據使用者的選擇來呼叫各自目錄下的安裝檔案進行安裝。

  至此,你就可以用本文所講述的內容編制自己的雙語或多語種軟體了。在軟體測試完畢並且完成了幫助檔案等必需的工作後,再製作一個具有個性的安裝檔案,這樣,你的雙語或多語種成品軟體就誕生了。  


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-989390/,如需轉載,請註明出處,否則將追究法律責任。

相關文章