原創 visualfc
WTL的應用程序向導(LUA版)使用IupLua編寫,本文將對其源代碼作一下簡要說明,并分析了該向導的多語言界面處理機制。
WTL的應用程序向導源代碼可以從
http://code.google.com/p/visualfc/downloads/list下載。下面對其作一下簡要說明。
一、開發環境:
本向導開發環境是Lua for Windows,該項目地址為:
http://luaforwindows.luaforge.net/
wiz_main.wlua是向導主文件,使用純文本格式編寫。
wiz_chs.wlua是中文向導,初始化了中文界面后調用wiz_main.wlua
resource目錄為向導使用的中文資源文件和圖片
Template目錄為應用程序向導模板目錄,從WTL80發行包中獲取并增加部分功能。
二、向導控件:
IupLua當前版本(2.7)未提供向導控件,所以我使用IupLua編寫了一個向導控件。源代碼位于iup\iupwizard.lua 文件中。
三、Iup的id擴展:
這個在以前文章中有過介紹,僅舉例說明 iup.button{title="ok",id="btn_id"},這樣可以直接引用btn_id來表示此button,源碼位于iup\iupid.lua中。
四、vswizard.dll文件
主要提供了分析Template目錄下模板文件的功能以及一些輔助函數供LUA使用。
這是從VFC的WTL向導中移植過來,源碼位于source\iup_vswizard目錄下
其中luabind目錄為自己寫的一個c++到lua的簡單綁定。
五、絕對路徑
我發現在Lua中很難獲取lua文件的絕對路徑,最后我使用了在vswizard.dll中導出get_module_path
函數的辦法以供lua模塊使用,如果誰有更簡便的方法望告之以加以改進。
六、多語言界面處理:
Iup目前版本不支持UNICODE,但可以支持代碼頁。本向導的多語言處理采用了lua的表方式進行處理,在lua源文件中需要顯示字符串的地方,使用ui("Sample string")的來取代"Sample string"。
通過resource\build_lang.lua這個多語言生成工具,可以從lua源文件中直接提取ui("..."),并生成lang_chs.lua供翻譯使用,當修改了向導中的ui字符串后,重新運行build_lang.lua,取可重新提取ui("...")字符串,并且不會影響到已經翻譯好的字符串。
我截取了resource\lang_chs.lua部分源代碼,該文件通過build_lang.lua自動生成。
local lang = {}
lang["Project Name"] = "項目名稱"
lang["Location"] = "本地目錄"

--ui("test str")
function ui(str)
if lang[str] ~= nil and lang[str] ~= "" then
return lang[str]
else
return str
end
end
啟用中文界面的wiz_main.wlua文件源碼如下:
require "vswizard"
local app_path = vswizard.get_module_path()
local_lang = string.upper(vswizard.get_local_lang())
if local_lang == "CHS" then
dofile(app_path.."\\Resource\\lang_chs.lua")
end
dofile(app_path.."\\wiz_main.wlua")
如果當前語言為中文則加載lang_chs.lua文件并獲得了 ui 函數,在wiz_main.wlua中判斷是否已經獲取了ui函數,如果沒有則使用源字符串輸出。
local ui = ui or function(str) return str end
最后可以看一下build_lang.lua源代碼,從中可以發現使用LUA來作此類工具非常的容易。
function make_file(name, out_name)
file = io.open(name,"r")
assert(file,"Error to load File"..name)
s = file:read("*all")
words = {}
saves = {}
for w in string.gmatch(s,"ui%s-%(%s-(\".-\")%s-%)") do
if words[w] == nil then
saves[#saves+1] = w
words[w] = [[""]]
end
end
file:close()
file = io.open(out_name,"r")
old = ""
if file then
old = file:read("*all")
end
for w,w1 in string.gmatch(old,"lang%[(\".-\")%]%s-=%s-(\".-\")") do
if w1 ~= "" then
words[w] = w1
end
end
file = io.open(out_name,"w")
assert(file,"Error to write file"..out_name)
file:write("-- lang file for "..name.."\n\n")
file:write("local lang = {}\n")
for k,v in ipairs(saves) do
file:write(string.format("lang[%s] = %s\n",v,words[v]))
end
file:write(
[[
--ui("test str")
function ui(str)
if lang[str] ~= nil and lang[str] ~= "" then
return lang[str]
else
return str
end
end
]])
end
make_file("..\\wiz_main.wlua","lang_chs.lua")