EasyDgm是一個用于攔截短消息,發送短信的插件代碼。用該插件攔截短信沒有提示音,發送也不提示用戶。但是本身該代碼是老外開發的,只是針對8位編碼的字符,沒有根據我們中文的編碼來做成完全Unicode版本的,為此以下改寫就是實現Unicode字符串的發送。
1、 修改DatagramService工程中的代碼,將其內用到的8位描述符修改為16位,具體修改的描述羅列如下:
//修改前內容
IMPORT_C static CDatagram* NewL(TDesC8& aBuf);
IMPORT_C static CDatagram* NewL(const TDesC8& aBuf,const TDesC8& aAddress); IMPORT_C virtual const TDesC8& GetData();
IMPORT_C virtual void SetDataL(const TDesC8& aData);
void ConstructL(const TDesC8& aBuf);
HBufC8* iData;
//修改后內容
IMPORT_C static CDatagram* NewL(TDesC& aBuf);
IMPORT_C static CDatagram* NewL(const TDesC& aBuf, const TDesC8& aAddress); IMPORT_C virtual const TDesC& GetData();
IMPORT_C virtual void SetDataL(const TDesC& aData);
void ConstructL(const TDesC& aBuf);
HBufC* iData;
2、 修改SMSDatagramService工程中CSMSSender類的代碼,將其內用到的8位描述符修改為16位,具體修改的描述羅列如下:
//修改前
void CreateSMSMessageL(const TDesC8& aText, const TDesC8& aAddress);
void SendSMSL(const TDesC8& aText, const TDesC8& aAddress, TRequestStatus& aStatus);
//修改后
void CreateSMSMessageL(const TDesC& aText, const TDesC8& aAddress);
void SendSMSL(const TDesC& aText, const TDesC8& aAddress, TRequestStatus& aStatus);
3、 修改SMSDatagramService工程中CSMSSender類內創建短信的函數CreateSMSMessageL內,將原來的代碼
smsSettings.SetAlphabet(TSmsDataCodingScheme::ESmsAlphabet7Bit);
改成適合unicode的通道值
smsSettings.SetAlphabet(TSmsDataCodingScheme::ESmsAlphabetUCS2);
4、 刪除原有的def,重新為兩份工程定稿dll,這個具體參看如何編寫dll。
以上操作已經將EasyDgm插件修改成適合Unicode的代碼類型了,當然該代碼中還有可以進行優化的部分,在這里就不多做贅述。
具體使用的時候,可以參考S60v3_EasyDgmTest的例子,一般都是將里面的兩份代碼smsdatagramreceiver.cpp和smsdatagramsender.cpp直接拿來用的,但是也要改成16位描述符。
考慮到有些網友問我要修改后的EasyDgm代碼,先特給出下載地址 http://www.shnenglu.com/Files/franksunny/EasyDgm.rar
posted @
2008-05-16 20:12 frank.sunny 閱讀(2582) |
評論 (9) |
編輯 收藏
摘要:
DLL(Dynamic Link Library)是一段特殊的代碼,它能夠被外部程序在程序運行的時候調用。在DLL里面的代碼可以同時被許多外部程序共享,而且不會引起手機內存的重復分配。
DLL根據接口的類型Symbian系統支持兩種類型的DLL:靜態接口DLL和多態接口DLL
靜態接口DLL在主調程序啟動的時候被系統自動載入到手機內存里面(唯一的例外是如果該DL...
閱讀全文
posted @
2008-05-16 20:10 frank.sunny 閱讀(4644) |
評論 (0) |
編輯 收藏
第二版的開機自啟動比較麻煩,需要涉及到創建mdl文件并且需要在mdl中將另一程序開啟,所以略過。至于第三版的開機自啟動相對來說更加簡單些:
假設你的應用ID為:ef37946b
1)在data下新建一個文件, [ef37946b].rss(注意加上[])文件具體代碼如下
#include <startupitem.rh>
RESOURCE STARTUP_ITEM_INFO dispatcher
{
executable_name = "!:\\sys\\bin\\AutoStart.exe";
recovery = EStartupItemExPolicyNone;
}
此處的AutoStart.exe是你的應用程序文件名。
注:筆者試圖通過修改此處為其他應用程序名從而啟動指定其他程序,但是沒有成功。
2)在mmp文件中增加以下代碼
START RESOURCE [ef37946b].rss
TARGETPATH \private\101f875a\import
HEADER
END
確保:
LANG SC
CAPABILITY ReadUserData
注意“\private\101f875a\import”不能夠變。
3)在pkg文件中增加以下代碼
"$(EPOCROOT)epoc32\data\z\private\101f875a\import[ef37946b].rSC"-"!:\private\101f875a\import\[ef37946a].rSC"
如果是采用carbide c++編譯,那么使用上述代碼就可以了。
如果是使用makesis命令行打包或者使用.Net編譯,那么你需要修改成絕對路徑,路徑名視你的安裝目錄而定。
例如:
"C:\Symbian\9.1\S60_3rd_MR\Epoc32\Data\z\private\101f875a\import[ef37946b].rSC"-"!:\private\101f875a\import\[ef37946a].rSC"
posted @
2008-05-09 22:48 frank.sunny 閱讀(2775) |
評論 (15) |
編輯 收藏
實現應用程序的圖標隱藏,2nd和S60的3rd差別很大,相對來說3rd因為有一個[appname]_reg.rss文件,所以顯得很簡單,默認的在APP_REGISTRATION_INFO中有一個屬性值:
BYTE hidden = KAppNotHidden;
我們要實現圖標隱藏,只需將其值賦為KAppIsHidden即可。具體示例代碼如下:
RESOURCE APP_REGISTRATION_INFO
{
app_file="Hello_Hide_app_0xEC12F4E3";
localisable_resource_file = qtn_loc_resource_file_1;
localisable_resource_id = R_LOCALISABLE_APP_INFO;
hidden = KAppIsHidden;
embeddability=KAppNotEmbeddable;
newfile=KAppDoesNotSupportNewFile;
}
在2nd版本中顯得略微復雜些,具體實現如下(本人尚未測試過):
I installed the application without name (.app only) or in a folder out of \system\apps\<myapp>\, for example, c:\system\data. In that way the app was not in the list.
posted @
2008-05-09 22:48 frank.sunny 閱讀(2002) |
評論 (0) |
編輯 收藏
首先,需要使程序有獲知焦點變化的能力。具體通過在AppUI類中重載CAknAppUi:: HandleForegroundEventL(TBool aForeground )函數來實現。
其次,在獲知焦點變化的同時,改變應用程序的焦點,通過TApaTask::SendToBackground()和TApaTask::BringToForeground()兩個函數來實現。由于這里用到的TApaTask類,需要包含APGTASK.H和apgrfx.lib。
再次,因為需要在調用其上函數時,必須用我們的應用程序的窗口組id(window group id)初始化(Initialise) TApaTask這個對象,這個實現需要用到,獲取當前應用程序窗口組id的函數CEikonEnv::Static()->RootWin().Identifier()。剛好以上函數又要包含w32std.h和w32.lib。
l 具體實現代碼如下:
void CHelloUIAppUi::HandleForegroundEventL(TBool aForeground)
{
if(aForeground)
{
TApaTask task ( CEikonEnv::Static()->WsSession() );
task.SetWgId( CEikonEnv::Static()->RootWin().Identifier() );
//Foreground run
task.BringToForeground();
ActivateLocalViewL(iHelloUIContainerView->Id());
}
else
{
TApaTask task ( CEikonEnv::Static()->WsSession() );
task.SetWgId( CEikonEnv::Static()->RootWin().Identifier() );
//background run
task.SendToBackground();
}
}
posted @
2008-05-09 22:45 frank.sunny 閱讀(3811) |
評論 (2) |
編輯 收藏
摘要:
如何在CarBidesymbian 3rd版本下調試控制臺程序
本人搭建的環境為ActivePerl-5.8.8.822 + jdk1.6.0_04 + Carbide.C++ V1.2 + S60-SDK-200634-3.1(FP1),至今環境沒有發現什么大問題,搭建完調試控制臺程序時發現問題——程序編譯能通過,但是一旦運行(Run)和調試(Debug)就沒有...
閱讀全文
posted @
2008-03-11 19:57 frank.sunny 閱讀(2521) |
評論 (0) |
編輯 收藏
今天在單位看計算機世界,看到上面一篇文章寫得很不錯。摘錄和總結了幾個句子,同時對里面的觀點有達人想說些什么的話,也給小弟以更好的見識:
第一點:“以用戶體驗為中心,站在用戶用戶的角度、根據用戶的理解(而不是程序員的理解)來進行軟件開發。關于此有一個基本的原則:就是不能由系統內部的交互來主導涉及,而應該有系統外部的用戶與系統的交互進行指導。”
這個其實是軟件開發的指導原則,軟件行業本身就是服務行業,為此對于這個指導原則,個人非常贊同。
第二點:“重用,介于目前廣泛的代碼級重用,真正的重用已經開始了核心競爭力的重用,核心競爭力的重用,包括了對業務邏輯重用、業務行為重用乃至最關鍵的知識的重用。而開源軟件的興起,使得這些基于核心競爭力的高層次重用方式成為可行。”
這點說實話,有點深奧,現在對我來說代碼級重用還不是很到家,至于專家所說的核心競爭力重用,知識重用,我還是不能理解到。 如果有哪位高手能夠指點迷津一下,那自當心懷感激。
第三點:“軟件質量要靠程序員修煉真功夫”
這個是毫無疑問的,怎么說,我們做的也是手藝活,修煉是硬道理。
第四點“個人修煉到團隊修煉的三境界(以修復一個bug為例):
第一境界:不惜努力很有責任心的,修復完這個bug并將其檢查過后完事。
第二境界:修復一個后,思考下在項目中是否還有其它地方有過類似操作,并提醒項目團隊可能范同樣問題的其它同事,由一個bug,解決一類可能存在的bug。
第三境界:如果同類型bug出現三四次,作為項目負責人應該考慮:如果是程序員水平問題,那就應該對其進行必要的培訓;如果是需求問題,那就需要與客戶(策劃)進行確認。”
其實這個說得還比較好的,比較形象,我也贊成,說到底還是一個態度問題,現在有多少程序員是已經達到第一境界的哦,我從事團隊工作不算長(以前在小公司一直是單干戶),在我覺得,這種人很稀有,更何況后面兩個境界的了。
第四點:“作為一個團隊,要非常注重用戶的滿意度,對團隊的成功有高度的榮譽和渴望。”
這一點其實還是一個態度問題,跟第一點有點重復,不過層次更高了些,因為第一點可以說是自上而下的君主立憲,這一點是自下而上的,團隊內人人都能做到的道德規范。
posted @
2008-01-17 08:45 frank.sunny 閱讀(1545) |
評論 (2) |
編輯 收藏
C中如何調用C++函數?
前陣子被問及一個在C中如何調用C++函數的問題,當時簡單回答是將函數用extern "C"聲明,當被問及如何將類內成員函數聲明時,一時語塞,后來網上查了下,網上有一翻譯C++之父的文章可以作為解答,遂拿來Mark一下。
將 C++ 函數聲明為``extern "C"''(在你的 C++ 代碼里做這個聲明),然后調用它(在你的 C 或者 C++ 代碼里調用)。例如:
// C++ code:
extern "C" void f(int);
void f(int i)
{
// ...
}
然后,你可以這樣使用 f():
/* C code: */
void f(int);
void cc(int i)
{
f(i);
/* ... */
}
當然,這招只適用于非成員函數。如果你想要在 C 里調用成員函數(包括虛函數),則需要提供一個簡單的包裝(wrapper)。例如:
// C++ code:
class C
{
// ...
virtual double f(int);
};
extern "C" double call_C_f(C* p, int i) // wrapper function
{
return p->f(i);
}
然后,你就可以這樣調用 C::f():
/* C code: */
double call_C_f(struct C* p, int i);
void ccc(struct C* p, int i)
{
double d = call_C_f(p,i);
/* ... */
}
如果你想在 C 里調用重載函數,則必須提供不同名字的包裝,這樣才能被 C 代碼調用。例如:
// C++ code:
void f(int);
void f(double);
extern "C" void f_i(int i) { f(i); }
extern "C" void f_d(double d) { f(d); }
然后,你可以這樣使用每個重載的 f():
/* C code: */
void f_i(int);
void f_d(double);
void cccc(int i,double d)
{
f_i(i);
f_d(d);
/* ... */
}
注意,這些技巧也適用于在 C 里調用 C++ 類庫,即使你不能(或者不想)修改 C++ 頭文件。
該翻譯的文檔Bjarne Stroustrup的原文鏈接地址是
http://www.research.att.com/~bs/bs_faq2.html#callCpp
本來貼出來以后受到很多C/C++朋友的關注,非常榮幸,在“夢在天涯”的提醒下,本人后來又完成了一個Demo工程,發現和BJ說的有點出入,希望有高手指點,Demo工程下載鏈接如下:http://www.shnenglu.com/Files/franksunny/cCallCppDemo.rar
posted @
2007-11-29 20:38 frank.sunny 閱讀(60675) |
評論 (21) |
編輯 收藏
摘要:
描述符<下>轉換
業余有時候把一個事情當作任務來做的時候,往往會很受限制,就象這篇文檔,上次寫了個上篇,關于描述符的下篇,自己就遲遲沒有勇氣和時間寫完,好幾次都想靜下心來好好完成它,但是都未能如愿,可如果不寫顯然我也不好意思寫其它的一些東西,閑話提到這里,花了幾天業余時間總算是完成了,該文質量不足之處還望讀者您見諒。
通過前面關于描述...
閱讀全文
posted @
2007-11-28 22:51 frank.sunny 閱讀(4961) |
評論 (15) |
編輯 收藏
摘要:
描述符Descriptors
<上>概念和使用
接觸Symbian已經一個半月多了,自從上個月熟悉了框架之后,一直都不敢再寫什么東西了,因為沒有經歷過代碼怎么可能寫得出東西呢?起筆猶豫了很久,打算涉足Symbian與標準C++的一個不同點——描述符。希望自己能夠借這個機會搞清楚描述符這個東西。
一、總介
由于手機系統的資源區別于P...
閱讀全文
posted @
2007-10-19 17:23 frank.sunny 閱讀(3618) |
評論 (6) |
編輯 收藏