近10天,一直在忙活著讓乙個mfc中文版程式,支援設定其他語言。我用的stringtable來實現的,這個方法比較簡單高效,就是實現起來枯燥了一些。昨天晚上剛忙完,今天總結一下實現過程中關鍵的幾個點。
1、stringtable。
stringtable在此處主要是用來做翻譯的,比如,對話方塊的caption,控制項的windowtext,messagebox的一些提示,我們都可以在各個語言對應的stringtable中,新增其翻譯過來的內容。
(1)先新增stringtable。
若當前專案沒有stringtable,就選擇專案後,右鍵,選擇「新增」----「資源」----「stringtable」----「新建」。
若當前專案有stringtable,就切換到資源檢視,選擇乙個stringtable,右鍵,選擇「插入副本」,然後選擇想要新增哪種語言的stringtable即可。插入的新副本的stringtable。就是之前stringtable的複製版,然後翻譯裡面的內容。
(2)在stringtable中新增或者修改內容。
在中文stringtable中新增如下內容:
在英文stringtable中新增如下內容
若stringtable是從別的語言的stringtable複製過來的,就直接翻譯,修改內容即可。
2、在**中設定控制項語言。
在控制項所屬對話方塊的類成員函式oninitdialog()中,設定所屬該對話方塊的控制項的內容,比如「確認」「取消」按鈕,以及我在對話方塊中間新增的靜態文字框,,它們的控制項id分別為idok,idcancel,id_static,則**如下:
cstring strload;
stload.loadstring(btn_ok);
getdlgitem(idok)->setwindowtext(strload);//設定「確認」按鈕顯示的內容
stload.loadstring(btn_cancle);
getdlgitem(idcancel)->setwindowtext(strload);//設定「取消」按鈕顯示的內容
strload.loadstring(static_content);
getdlgitem(id_static)->setwindowtext(strload);//設定靜態文字框顯示的內容
3、設定執行緒和ui的語言。
langid idlang = setthreaduilanguage(makelcid(makelangid(lang_english, sublang_english_us), sort_default));//設定執行緒ui語言為英語
setthreadlocale(idlang);//設定執行緒語言和ui語言一致
langid idlang = setthreaduilanguage(makelcid(makelangid(lang_chinese, sublang_chinese_simplified), sort_default));//設定執行緒ui語言為中文
setthreaduilocale(idlang);//設定執行緒語言和ui語言一致
設定了執行緒和ui語言後,在第二步的cstring.loadstring(id)時,程式就會根據設定的語言,讀取對應語言的stringtable中對應字串id的內容。
至此,設定語言的基本功能已經實現了。效果如下:
設定語言為英文時:
設定語言為中文時:
至此,實現mfc程式多語言設定的工作基本完成,但在具體實現中,還遇到下面幾個問題。
1、設定messagebox按鈕的語言。
剛開始做多語言設定時,網上查了很多資料,都說messagebox中的確認取消按鈕的語言,是根據系統語言來變化的,自己設定不了。後來我**說messageboxex可以實現。比如,我在關閉對話方塊時,彈出「是否確認關閉對話方塊」的訊息提示,實現如下:
中文stringtable:
英文stringtable
(2)在對話方塊的onclose()訊息中新增訊息處理:
cstring strload;
strload.loadstring(msg_box_close);
int iret = messageboxex(null, strload, l"warn", mb_okcancel | mb_iconwarning, getthreadlocale());
if(iret == idcancel)
設定為中文時:
設定為英文時:
可以看到,只要我們設定了messageboxex函式的最後乙個引數,就可以切換messagebox中的確認取消按鈕的語言,但messagebox的提示內容和標題,還得自己在stringtable中新增,然後在**中設定。
2、選單。
選單實現多語言,跟stringtable類似,在資源裡,選擇該選單,右鍵,「插入副本」,然後選擇要新增的語言,新增後,直接在選單上翻譯就行。我們在**裡設定了執行緒和ui語言後,程式會根據設定的語言,自動選擇相應語言的選單。
如果想在**裡動態的修改選單語言,**如下:
cmenu*pmainmenu = cmenu::fromhandle(m_wndmenubar.getdefaultmenu());
if(pmainmenu != nullptr)
}//下面這行**很重要,只要修改了主選單,必須在修改後加上這行,不然選單更新不及時
m_wndmenubar.createfrommenu(pmainmenu->getsafehmenu(), true, true);
pmainmenu.detach();
需要注意的是,選單裡的橫線也是佔據乙個索引項的,比如:
注意索引為3和5的橫線。
3、多執行緒的問題。
前面我們也看到了,mfc設定語言,是以執行緒為單位來設定的,所以需要在每個執行緒裡,都通過呼叫setthreaduilanguage和setthreadlocale設定語言。如果發現某些地方的語言設定沒起作用,就先檢查是否在該執行緒中設定了語言。
4、資源訪問問題。
如果引用了dll模組,在dll中需要使用dll自帶的stringtable資源,那麼在loadstring時最好指定dll的資源控制代碼。
hinstance g_instance;
然後將g_instance傳給loadstring的第乙個引數即可。
以上就是我實現mfc程式設定多語言功能的總結。上述**都是一字一字在網頁裡編輯的,可能會有手誤,望見諒。
MFC實現程式托盤
今天將程式托盤加入了正在開發的程式中,實現如下。使程式托盤我們這裡要用到了乙個結構體notifyicondata,它包含了系統需要用來傳遞托盤區域資訊的訊息 還有需要用到乙個函式shell notifyicon,它的作用是對拖盤圖示進行顯示與刪除。struct notiflyicondata boo...
MFC程式視窗標題設定
mfc程式的預設的標題是 無標題 title 其中title是應用程式的名稱,我們應如何修改mfc視窗標題來符合自己的要求?mfc程式的文件類中定義了乙個虛函式settitle,用於設定視窗標題的前半部分,如果只是要修改 無標題 部分,可以過載文件類的該函式。視窗標題的後半部分可以通過setwind...
設定MFC程式開機自動啟動
設定程式開機啟動 bool autobootset 得到程式自身的全路徑 dword dwret getmodulefilename null,pfilename,max path tcscat pfilename,t auto 新增乙個子key,並設定值,下面應用程式名字 不加字尾.exe 關閉登...