使用Carbide.vs與VS.NET2003構建Symbian開發平臺-S60 平臺
1.簡介
???? 在過去的幾年里從事Symbian OS/C++的開發,選擇什么樣的IDE開發環境是一件很讓人郁悶的事。微軟的Visual C++ 6.0 缺乏人性化的設計,而VS.NET卻不能很好地支持Symbian Os/C++的開發,Borland C++ BuilderX Mobile Edition 還有Metrowerks CodeWarrior也并不是每個人都會喜歡的,幸運的是自從諾基亞的Carbide.vs出現后,開發Symbian OS/C++的應用程序變得非常方便與簡單。
???? 什么是Carbide.vs呢,正確地說Carbide.vs并不是一個類似 VS.NET或Codewarrior 一樣的IDE開發環境,Carbide.vs是一個插件,一個能夠處理Symbian OS Sdk命令行并改善VS.NET編寫的Symbian os c++ 應用程序代碼的一個插件,同時Carbide.vs也很好地集成到了VS.NET的IDE開發環境中,有了Carbide.vs我們編寫起Symbian os c++應用程序將會變得更容易、更方便、更快捷。
???? 本文適合于想學習Symbian C++ 應用程序開發的的初學者,如果你對SDK還有IDE的選擇感到疑惑或者你已經對VS.NET的集成開發環境很熟的話,建議你采用Carbide.vs,你會發現Carbide.vs+VS.NET 2003的搭配開發起來會更順手,更容易。
?2.準備工作
???? 在你準備編寫此教程的實驗時,請確保你的電腦滿足了以下的軟件環境(開發symbian os c++ 必備)
? 1.Microsoft Visual Studio.Net 2003 :
?????????? 這個是必備的,我們將會使用VC++.NET 2003進行Symbian os c++的開發,所以VC++.NET是必裝項目。
??2. Java JRE:
????????????Carbide.vs和Symbian os 的SDK都要求要Java JRE的運行環境 ,不然無法安裝,請到
http://sun.java.com
下載最新版本的JRE
?3.ActivePerl:
?????????? 必備的軟件 請到
http://www.activestate.com/Products/ActivePerl/
下載
?4.Symbian OS Series 60 SDK:
?????????????
這個是最重要的,SDK自帶了Symbian 的手機模擬器與編譯連接環境,至于選擇哪個版本的SDK要具體看你要開發的手機機型 ,如果不清楚要選擇哪個SDK的話,請到
http://www.forum.nokia.com/devices
查看機型對應的SDK并進行下載,在這里,我們面向的是 Series 60 第二版的SDK。在這里可以下載到S60系列的所有SDK
http://forum.nokia.com/info/sw.nokia.com/id/4a7149a5-95a5-4726-913a-3c6f21eb65a5/S60-SDK-0616-3.0-mr.html
??5.Carbide.vs:
????????????
我
們的主角,請到
http://forum.nokia.com/carbide
選擇Carbide.vs下載
?在用VS.NET 2003開發Symbian 項目的時候可能有些人會碰到 類似 “Error Spawning CL.exe” 的錯誤,可以通過這種方法來解決 ,依次打開菜單 工具->選項->->項目->VC++目錄 在右邊可執行目錄中確保
C:\Symbian\8.0a\S60_2nd_FP2_SC\epoc32\tools
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\bin
C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE
三項的存在,如果不存在的話,請添加進去(請對應SDK與VS.NET的路徑進行修改)
3.開始使用carbide.vs
?打開VS.NET 2003 依次打開菜單 文件 新建->項目 在項目名稱里填入 HelloWorld ,選擇合適的保存目錄,請注意保存的目錄路徑中不能有空格的存在,并且最好把項目保存在跟Symbian os sdk 相同的驅動器下,最后按確定
??? ?接下來你會看到Carbide.vs的設置向導 在這里。你可以設置要使用的SDK,本教程里是使用S60 2.X FP2的SDK,主要是面向操作系統是Symbian os 8.0a 的手機開發的,你可以選擇特定的SDK開發平臺開發你的應用。在此向導里,你還可以設置此程序的其它參數,比如項目名稱,項目的目錄結構,UID等等信息。在這里我們選擇了S60 2.X FP2的SDK并用了 S60 Viewed based application的項目模板,用于開發多視圖的s60 應用程序。
??? ?運行向導設置完畢后按Finish按鈕,Carbide.vs就幫我們把項目相關的文件生成好了并顯示在VS.NET 2003的項目資源管理器中了,想看看運行效果?按F5,VS.NET便開始幫你生成應用程序并自動調用手機模擬器,打開后定位到HelloWorld軟件,打開,是不是一個簡單的多視圖S60應用程序出現了,恭喜你,你現在已經開始你的Symbian os c++軟件開發之旅了。
?在這里我要說明一下,也許有網友會問我UID是什么東西,UID其實就是標識一個軟件的一種序列號,關于UID的說明不在教程范圍內,請在網上搜索相關的資料。
?
?也有人會問我怎么他的模擬器跟我的很不一樣啊?他那個是默認的藍色的很單調的模擬器,而且也是沒有主題的。而我卻是有一個諾基亞6630的模擬器而且也帶了漂亮皮膚的,Symbian sdk的模擬器其實是可以換膚的,至于模擬器內部操作系統的主題也可以更換,具體請瀏覽本站的相關文章 給Symbian的模擬器換皮膚(換成我們喜歡的手機皮膚) 下載此你所喜歡的皮膚并配置模擬器,再次啟動時你就可以看到新的皮膚界面了,以后就不用再對著那又藍又丑的模擬器界面了。呵呵呵
4.在HelloWorld里面顯示圖像
?接下來我們將讓HelloWorld項目顯示一個簡單的圖像。第一步,制作 一張 bmp 的圖像文件,并保存到你的項目的路徑下的 data 目錄下,在教程里的項目是保存在C:\Symbian\Dev\HelloWorld\中的,所以我們制作 了一張 名為 Picture.bmp 的圖像文件并保存在 C:\Symbian\Dev\HelloWorld\data 目錄下,或者你可以直接通過打開VS.NET 2003的項目資源管理器,在data目錄上右擊選擇 添加->添加現有項->選擇Picutre.bmp以添加到項目中去。
?對于位圖文件,Symbian 建議把所有的位圖都打包進一種擴展名為 *.mbm 的文件里面,*.mbm 其實是一種位圖集文件,里面可以包含很多的位圖,類似于windows平臺的資源文件,將程序里要用到的位圖打包進 *.mbm 文件里后,我們在程序里就可以很方便 地使用這些位圖文件。在還沒有第三方輔助工具的應用前,要打包位圖生成 *.mbm 需要自己編寫腳本去實現,現在有了Carbide.vs我們可以很方便地將我們的位圖打包進 *.mbm 文件里面,只要我們在 項目名.mmp (在教程里是HelloWorld.mmp) 文件上點擊右鍵選擇。Bitmap Collection Tool ,打開后選擇 Current Directory 指定你的data目錄,就會在左下角的Available bitmaps 列表中顯示可用的位圖文件,然后再把你所需要的位圖文件移到右邊的 Selected bitmaps 中,Display size:在這里我們設置成了 176 x 208 因為我們是要生成S60 2.x的應用程序,所以我們選擇 176 x 208的分辨率
????? 編輯完成后編譯生成一下項目,這樣就會在SYMBIAN 的模擬器目錄中生成 一個所謂的 HelloWorld.mbm 與 HelloWorld.mbg 文件,在SYMBIAN的SDK目錄下搜索找到? HelloWorld.mbg并用記事本打開,你可以看到以下的類似內容
?
?enum TMbmHelloworld
?{
?EMbmHelloworldPicture
?};
?
?????? 這個枚舉類型TMbmHelloworld就是HelloWorld項目的位圖定義了,剛才我們已經添加了一個名為Picutre.bmp的位圖文件,EMbmHelloworldPicture就是對應了我們的那個Picutre.bmp位圖文件,接下來我們的任務就是讓HelloWorld顯示這個位圖。
?在這之前我們提過HelloWorld.mbm文件,其實這個才我們程序里真正要載入的位圖資源文件。打開HelloWorldContainer.h,在CEikLabel類的定義前面輸入以下代碼
??
?#include "HelloWorld.mbg"
?_LIT(KMbmFileName,"HelloWorld.mbm");
????? ?剛看到 _LIT 很多人會問起這是一個什么函數啊,其實這個不是函數,這個是一個預定義宏,在這里我們通過_LIT宏將"HelloWorld.mbm"這個字串賦值給KMbmFileName常量,其實在Symbian 里面沒有類似windows平臺的字符串類型(string),取得代之的是被稱做 描述符(descriptor)的對象 。關于描述符的更多幫助請查看相關的資料。
????? Symbian os 手機操作系統的文件系統與windows的文件系統是類似的,所以只給出一個"HelloWorld.mbm"文件不足以讓程序找到這個文件的具體位置并裝載進程序里,此時我們需要取得這個文件在操作系統里的絕對路徑,請打開 HelloWorldContainer.cpp 文件,在CHelloWorldContainer::ConstructL 函數里添加以下的代碼,
?
?TFileNamefullName(KMbmFileName);
?CompleteWithAppPath(fullName);//自動為文件名添加文件路徑
???????在這里我們創建了一個標準的可修改標識符fullName,包含了我們的mbm文件名,接下去的第二行代碼則把應用程序的路徑添加到這個fullName中,使fullName成為一個絕對的文件路徑。估計到這里,你應該可以猜出ConstructL函數是什么意思了吧?呵呵,好了,讓我們編譯一下程序,跟蹤一下fullName是一個什么路徑吧,按上F5,等待............不是吧,出錯了,VS.NET報出了
error C3861: “CompleteWithAppPath”: 即使使用參數相關的查找,也未找到標識符 的錯誤,有過一定編程基礎的人會想到肯定是哪個文件或庫沒有給引進來,猜對了,我們需要把一個 aknutils.h 的頭文件包含進我們的源代碼中,請打開 HelloWorldContainer.h 并加入 #include "aknutils.h"。加完后再試試,是不是已經不會報錯了?
??????? 如果你想知道fullName到底會是一個什么樣的值,你可以在?CompleteWithAppPath(fullName);的下一行代碼處設置一個斷點,按F5編譯生成并運行模擬器,打開你的程序,運行到了斷點處時,程序會停下來,光標定位在了IDE窗口,通過IDE的自動窗口我們可以看到fullName此時的值 。
???????????? 此時我們發現fullName的值為 Z:\System\Apps\helloworld\HelloWorld.mbm,(如果你沒有發現以上的窗口,請依次打開VS.NET的菜單 調試->窗口->自動窗口)。在這里 Z 代表了手機模擬器的驅動器,當你安裝到了目標手機上后,這個驅動器就會變成C,或者是E了。
????????????? 好了,接下來我們來讓程序顯示出我們添加的位圖。首先我們在HelloWorldContainer.h 頭文件中添加以下代碼
?CFbsBitmap* iImage;
?????????? 接著定位到HelloWorldContainer.cpp 的ConstructL函數中,在我們之前編寫的代碼下面輸入
?iImage = new (ELeave) CFbsBitmap();
?User::LeaveIfError(iImage->Load(fullName,EMbmHelloworldPicture));
?
?????????? 再定位到 HelloWorldContainer.cpp 的Draw()函數 并在最后面輸入
?gc.BitBlt(TPoint(0,0),iImage);
???????????這樣就通過了圖形上下文(graphics context,gc)將你的位圖復制到了屏幕的左上角。
????????? 編譯一下,OH,MY GOD ,又出錯。具體錯誤信息為
?HelloWorld error LNK2019: 無法解析的外部符號 "public: __thiscall CFbsBitmap::CFbsBitmap(void)" (??0CFbsBitmap@@QAE@XZ) ,該符號在函數 "public: void __thiscall CHelloWorldContainer::ConstructL(class TRect const &)" (?ConstructL@CHelloWorldContainer@@QAEXABVTRect@@@Z) 中被引用
?HelloWorld error LNK2019: 無法解析的外部符號 "public: int __thiscall CFbsBitmap::Load(class TDesC16 const &,long,int)" (?Load@CFbsBitmap@@QAEHABVTDesC16@@JH@Z) ,該符號在函數 "public: void __thiscall CHelloWorldContainer::ConstructL(class TRect const &)" (?ConstructL@CHelloWorldContainer@@QAEXABVTRect@@@Z) 中被引用
??????????? 還是同樣的原理, 我們要引入一個庫文件才能解決這個問題,請在項目資源管理器中右擊項目->屬性->配置屬性->鏈接器->命令行 ,在右邊的 附加選項 中輸入 fbscli.lib?
???????? 再次編譯,OK了,好現在我們運行這個程序,哈哈,圖像在我們的程序里顯示出來啦。好高興。
?

??????? 可是當我們退出程序時卻出現了程序已關閉的錯誤。
??????? 我的天哪,怎么會這樣呢,為什么我的程序不能正常退出呢,遺憾的是模擬器只提示了很簡單的錯誤提示,并沒有更詳細的錯誤報告,我們可以通過在 C:\Symbian\8.0a\S60_2nd_FP2_SC\epoc32\wins\c\System\Bootdata 下創建一個 ErrRd 的空文件以讓模擬器顯示詳細的錯誤信息(請在相應的SDK目錄下操作),此時我們再次運行模擬器打開HelloWorld并關閉它,現在是不是提示信息多了一點呢?
????? ?模擬器報出了 ALLOC:17B18158 的錯誤,像這種類型的錯誤大多數情況下是因為我們使用了某個對象后忘記關閉它并釋放此對象的內存導致的,為了保證程序的正常運行,我們要在使用一個對象后及時將它刪除掉,于是我們定位到了HelloWorldContainer.cpp的~CHelloWorldContainer (析構函數) 中 輸入以下代碼
?
?delete iImage;
?? ?當我們再次編譯運行程序后,就不會再出現那討厭的出錯對話框了。
?
5.讓我們添加一些功能
?
?我們已經實現了在程序里顯示位圖的功能了,接下來我們將實現一個登陸框的功能,到時將會用到資源文件。
5.1 為菜單添加項目
?打開 HelloWorld.loc 文件,定義菜單的文本
?
?#define qtn_view1_login_item "Login"
?打開HelloWorld.hrh ,修改THelloWorldCommandIds 的枚舉定義,改成以下
?enum THelloWorldCommandIds
?{
???? EHelloWorldCmdAppTest = 1,
???? EHelloWorldCmdLogin
? };
?EHelloWorldCmdLogin其實就是對應了菜單項 "Login"
?程序的菜單資源定義在了 HelloWorld.rss 文件中,我們打開這個文件,找到以下的定義
?
RESOURCE MENU_PANE r_helloworld_app_menu
??? {
??? items =
??????? {
??????? MENU_ITEM { command = EHelloWorldCmdAppTest; txt = qtn_appl_option_item; },
??????? MENU_ITEM { command = EAknCmdExit; txt = qtn_appl_exit; }
??????? };
??? }
?把EHelloWorldCmdAppTest 替換成EHelloWorldCmdLogin,再把qtn_appl_option_item替換成qtn_view1_login_item ,這樣我們就把程序選項菜單的第一項替換成 "Login" 了。
?
?
5.2 創建登陸框
?
??????????? 在這里我們要創建一個登陸框,用于生成用戶名和密碼的對話框,按照傳統的Symbian OS C++開發,我們本來應該在HelloWorld.rss 里定義資源,但是有了Carbide.vs后我們卻可以利用 Carbide.vs提供的功能非常方便地生成我們所要的資源,請打開 HelloWorld.rss 定位到文件的最后,點擊右鍵->Add Fragment 將會出現Carbide.vs提供的生成資源窗口,在Template 處選擇 S60 Multiline query dialog ,在下方會出現此對話框的效果圖,就是我們所要的登陸框樣子,按下一步,指定一個比較有效的名字,r_login_query ,最后按Finish生成資源,你將會發現HelloWorld.rss多了幾行內容,這就是r_login_query的資源定義。
?RESOURCE DIALOG r_login_query {
??flags = EGeneralQueryFlags;
?buttons = R_AVKON_SOFTKEYS_OK_CANCEL;
?items = {
??DLG_LINE {
???type = EAknCtMultilineQuery;
???id = EMultilineFirstLine;
???control = AVKON_DATA_QUERY {
????layout = EMultiDataFirstEdwin;
????label = "Username:";
????control = EDWIN { maxlength = 8; };
???};
??},
??DLG_LINE {
???type = EAknCtMultilineQuery;
???id = EMultilineSecondLine;
???control = AVKON_DATA_QUERY {
????layout = EMultiDataSecondSecEd;
????label = "Password:";
????control = SECRETED { num_letters = 8; };
???};
??}
?};
}
?為了要讓程序更通用,本地化起來,我們有必要將UserName與Password的值定義到.loc文件中,打開HelloWorld.loc文件,加入以下定義:
?
?
?#define qtn_username "UserName:"
?#define qtn_password "Password:"
??接下來我們來編寫代碼讓這個登陸框顯示出來,請打開HelloWorldView.h 先加下以下文件的引用
?#include <AknQueryDialog.h>
?#include <aknnotewrappers.h>
?#include <StringLoader.h>
?#include "HelloWorld.hrh"
?再加入處理函數的聲明
?
?void HandleLoginL();
?接著打開HelloWorld.loc 我們還要定義一些要顯示的文本
?
?#define qtn_login_success "Congretulation You Have Loged in"
?#define qtn_login_fail "Sorry you have the wrong username or password"
?#define qtn_login_cancel "You have canceled the login"
?分別定義了登陸成功,登陸失敗,與取消登陸的三種顯示文本
?打開HelloWorld.rss文件,加入資源定義
?
?RESOURCE TBUF r_login_success { buf = qtn_login_success; }
?RESOURCE TBUF r_login_fail { buf = qtn_login_fail; }
?RESOURCE TBUF r_login_cancel { buf = qtn_login_cancel; }
?這樣我們就能在程序中動態裝入這些資源了,繼續打開HelloWorldView.cpp文件,實現HandleLoginL函數的定義
?void CHelloWorldView::HandleLoginL()
?{
???? _LIT(KCorrectLogin,"bention");//定義正確的用戶名
?????_LIT(KCorrectPwd,"123456");//定義正確的密碼
???? //顯示對話框
???? TBuf<8>?username(_L(""));
???? TBuf<8>?password(_L(""));
???? CAknMultiLineDataQueryDialog* dialog=CAknMultiLineDataQueryDialog::NewL(username,password);//聲明登陸對話框對象
?????if (dialog->ExecuteLD(R_LOGIN_QUERY)) {//調用登陸對話框
???????? if (username.Compare(KCorrectLogin)==0 && password.Compare(KCorrectPwd)==0) {
???????//登陸成功
???????CAknConfirmationNote* note = new (ELeave) CAknConfirmationNote();//定義一個信息提示框
???????HBufC* notePrompt=StringLoader::LoadLC(R_LOGIN_SUCCESS);//裝載R_LOGIN_SUCCESS文本資源,以顯示登陸成功信息
???????note->ExecuteLD(*notePrompt);//打開對話框
???????CleanupStack::PopAndDestroy(notePrompt);
????}
???else {
?????? //登陸失敗
???????CAknErrorNote* note = new (ELeave) CAknErrorNote();//定義一個錯誤提示框
???????HBufC*? notePrompt=StringLoader::LoadLC(R_LOGIN_FAIL);//裝載R_LOGIN_FAIL文本資源,以顯示登陸失敗信息
???????note->ExecuteLD(*notePrompt);
???????CleanupStack::PopAndDestroy(notePrompt);
???}
?}
?else {
??????//取消登陸
??????CAknWarningNote* note = new (ELeave) CAknWarningNote();//定義一個警告提示框
????? HBufC* notePrompt=StringLoader::LoadLC(R_LOGIN_CANCEL);//裝載R_LOGIN_CANCEL文本資源,以顯示取消登陸警告信息
??????note->ExecuteLD(*notePrompt);
??????CleanupStack::PopAndDestroy(notePrompt);
??}
?}
?接下去我們還差啥?就差把HandleLoginL放在處理菜單命令的函數中了,定位到HandleCommandL 中,HandleCommandL 是用來專門處理事件的,我們在switch結構中加入
?case EHelloWorldCmdLogin:
??{
???HandleLoginL();
???break;
??}
?其中的EHelloWorldCmdLogin 就是我們的登陸按鈕啦,這樣就實現了當我們點擊了Login按鈕后就會調用HandleLoginL去做相應的處理。
?好了編譯一下,我頂,又出錯,呵呵,別急,你還得在項目里引入? commonengine.lib 文件呢,具體做法與 引入fbscli.lib 文件一樣,記得要跟fbscli.lib之間隔開一個空格喲。
?
?好了,大功告成,現在再次編譯,成功,運行,打開軟件,點擊Login菜單項,輸入,是不是成功了?興奮?郁悶?
?
?
?????? 現在我們的程序全都是英文的,或許有人會問我為什么不用中文的啊,比如UserName為什么不寫成用戶名?呵呵,說實在的,我蠻懶 的,因為我們不能直接在資源文件里直接定義一個中文文本,在我寫的文章中有一篇關于在Symbian中如何顯示中文的文章, 關于SymbianSeries?60開發的中文顯示問題 有興趣的可以查看 ,按照文章的步驟去做相應的修改后你的程序就直接顯示中文啦。至此,本文的實戰代碼也到一段落了。
6.導入已有的Symbian os c++項目
?利用 Carbide.vs我們可以很方便 地導入現有的Symbian os c++項目,在打開VS.NET 2003后我們依次點擊 文件->Import Symbian Project .出現 導出向導,只要選擇項目的 .mmp 文件就可以導入了,剩下的不用我廢話了吧,聰明的你一定可以非常輕易地完成 。
7.后記
?Carbide.vs的確是一個非常不錯的VS.NET 2003輔助開發Symbian Os c++ 應用的工具,有了它,你還會用vc++ 6.0 嗎,讓我很爽的一點是用Carbide.vs基本上不用去手動配置SDK路徑了與EPOCROOT此類變量了。用Carbide.vs懶得有理,哈哈,寫起應用來也非常方便 。希望大家在看了本文后會喜歡上這個工具。
8.項目源文件下載
為了方便大家查看, 我把這 個helloworld項目的所有源文件打包供大家下載,大家在使用時只要導入mmp文件就可以使用了。
代碼下載:
點擊下載此文件
?聲明:本文是我在參考了《Getting Started with Nokia's Carbide.vs 2.0 Development Tools》? Andreas Jakl / Mopius 寫的英文教程后自己修改了部分東西并翻譯成中文而寫成的,原版大家可以到http://www.mopius.com 下載。寫這份教程是為了方便不喜歡E文或E文水平不高的同學方便學習的,由于本人表達能力有限,不足之處請大家多多指教
轉載請注明出處,謝謝合作。
Made in 藍色憂郁(Bention,翁培鋮?
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1355561