关键字: exe, 后台程序, 调试, Console, 多个实例, 窗口, 字体
其实我也只是一个Symbian的初学者,我能深刻的感受到一个初学者在探索新的开发平台时的坎坷。以下的心得是我经过一段很长时间的探索才得到的,这其 中走了很多弯路,也得到了很多人的帮助。现在我将其整理了一下贴出来,希望能给寻求相关知识的朋友一些帮助,以便于大家少走一些弯路。
当然我的水平有限,理解不深,错误在所难免,希望大家发现后能及时指正。
1.为什么要用exe形式的程序?
相信绝大部分人做Symbian程序都是从app开始的,app的例子非常多,很容易上手。但是有些需求在用app实现中出现了一些问题,假设我们要做一 个来电检测程序,把所有来电号码都记录在一个文件中。如果用app做当然可以实现,但是问题是这个app是有窗口界面的,但这个窗口对使用者来说毫无价 值,白白浪费了一大块资源,但是又不能把这个窗口关掉,一旦关掉,app就终止运行了,来电检测也就无法实现了。类似的程序的最佳解决方案就是做成exe 形式。
通常exe程序是用来做后台服务的,对使用者来说他是不可见的,通常没有界面,这样既节省了资源,有不会因为使用者不小心关闭了程序而导致功能无法实现。
2.exe程序的框架
exe的例子也有一些,大家可以参考那些例子来建立mmp文件以及程序基础框架,这里就不多说了。
exe总是从E32Main函数开始执行的,我是用如下的E32Main代码的:
这里的处理程序 RUNMAIN 其实是我定义的一个宏,通常情况下,他是:
#define RUNMAIN() TRAPD(error, MainL());
实际上就是去掉用MainL。为什么这么做,后面会提到。
MainL的代码如下,构建了CActiveScheduler,然后就是具体的处理了
其实我也只是一个Symbian的初学者,我能深刻的感受到一个初学者在探索新的开发平台时的坎坷。以下的心得是我经过一段很长时间的探索才得到的,这其 中走了很多弯路,也得到了很多人的帮助。现在我将其整理了一下贴出来,希望能给寻求相关知识的朋友一些帮助,以便于大家少走一些弯路。
当然我的水平有限,理解不深,错误在所难免,希望大家发现后能及时指正。
1.为什么要用exe形式的程序?
相信绝大部分人做Symbian程序都是从app开始的,app的例子非常多,很容易上手。但是有些需求在用app实现中出现了一些问题,假设我们要做一 个来电检测程序,把所有来电号码都记录在一个文件中。如果用app做当然可以实现,但是问题是这个app是有窗口界面的,但这个窗口对使用者来说毫无价 值,白白浪费了一大块资源,但是又不能把这个窗口关掉,一旦关掉,app就终止运行了,来电检测也就无法实现了。类似的程序的最佳解决方案就是做成exe 形式。
通常exe程序是用来做后台服务的,对使用者来说他是不可见的,通常没有界面,这样既节省了资源,有不会因为使用者不小心关闭了程序而导致功能无法实现。
2.exe程序的框架
exe的例子也有一些,大家可以参考那些例子来建立mmp文件以及程序基础框架,这里就不多说了。
exe总是从E32Main函数开始执行的,我是用如下的E32Main代码的:
Code:
GLDEF_C TInt E32Main()
{
CTrapCleanup* cleanup = CTrapCleanup::New();
RUNMAIN(); // 宏
_LIT(KMsgPanicEpoc32ex,"EPOC32EX");
__ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));
delete cleanup;
return 0;
}
#define RUNMAIN() TRAPD(error, MainL());
实际上就是去掉用MainL。为什么这么做,后面会提到。
MainL的代码如下,构建了CActiveScheduler,然后就是具体的处理了
Code:
void MainL()
{
CActiveScheduler* scheduler = new(ELeave) CActiveScheduler();
CleanupStack::PushL(scheduler);
CActiveScheduler::Install(scheduler);
// 具体的处理
// ......
CleanupStack::PopAndDestroy(scheduler);
}
3.如何调试exe 又了上面的代码,这个exe已经可以编译和运行了,虽然他什么实质的事情都没做,但是他的的确确已经是一个合格的exe了。如果你把编译好的程序放到手机 上运行(用文件管理器打开),你会发现什么都没有发生,你无法判断它是否执行了,执行到哪里了。这就带来一个调试的问题。 首先说说如何在VC6环境中调试,这个比较简单,调试app的时候,我们是指定vc6运行那个模拟器程序的,而调试exe你只要指定vc6调试时运行你生 成的那个exe就可以了,当然这个exe是wins编码的,不能是手机上运行的armi编码。调试运行后也会显示手机模拟器的界面,不过没有9宫格主菜单 了。 比较麻烦的是手机上的执行调试,如前面提到的那样,我们可能什么都看不到,那么如何让exe显示一些信息呢?这里就需要用到控制台Console。Console就如Windows上的dos窗口,是纯文本的,对付信息显示是绰绰有余。 Console的用法也非常简单,先构造CConsoleBase,然后就可以用它的Printf函数在控制台上输出数据了。 我把Console单独放在一组cpp/h文件中,如下: Code:
// ================= Start of console.h ======================= 看到这里的 RUNMAIN 宏了吗,他的作用就是在调试的时候去执行ConsoleMainL,而不是MainL,两者的区别就是ConsoleMainL先建立了一个Console,最后再将其释放。 放到手机上运行一下吧,运行后会出现一个全屏的白色窗口,其实你可能看不清这个窗口,因为它是一闪而过的。怎么会这样,呵呵,因为我们的MainL()函数里面什么都没做,exe程序当然就立即结束了。你可以尝试在MainL()函数“具体的处理”这部分加上两句话: CONSOLEPRINTINFO(_L("Hello World!")); CActiveScheduler::Start(); 第一句是在控制台上显示Hello World;第二句开始检测CActive事件,这里用这个只是为了能让程序保持住,而不会立即结束。在手机上运行后,你会发现一个白色窗口,上面显示 Hello World。新的问题又来了,这个程序现在总也结束不了了,这时候需要一个线程管理工具来终止这个exe,这样的工具有AppMan和TaskSpy。 注意你的线程名称,当你是用了Console时,线程名称就是控制台名称“MyExe”,当不用Console时,线程名称就是那个exe的名字,这点对下一段很有用。为了保持一致,建议大家将控制台名称设定为exe程序的名称。 另外你可以根据你的需要定义你的显示宏,而不一定是我这里的 CONSOLEPRINTINFO 和 CONSOLEPRINTNUM。 |
4.如何防止exe运行多个实例 和app不同的是,exe可以运行多个实例,在某些情况下,这是有用的。但是如果我们不需要这个特性,那么如何才能阻止exe运行多个实例以减少资源占用呢?这就需要用TFindProcess。 将MainL写成: Code:
_LIT(KPROCESSNAME, "MyExe*"); // 线程名称 这里判断线程的数量用了 if (pcount <= 1),而不是<1,因为当前在做判断的线程也算一个。 当发现有其他相同的线程在运行时,本线程就跳过具体的处理,直接结束了。这样就达到了我们的目的。 |
5. 如何让exe程序显示信息窗口 exe是后台的程序,通常是没有窗口界面的,但是我们有时候需要让使用者获得一些信息。比如一个闹钟提醒程序,平时在后台运行,到时间后除了要播放闹铃,可能还需要在屏幕上显示一些用户预先设置的提示信息,如"XXX生日"之类的。这时候就需要来构造一个窗口。 Code:
// ================= Start of Window.h ======================= 先要建立一个CWsScreenDevice: Code:
iScreen = new (ELeave) CWsScreenDevice(iWs); Code:
_LIT(FONT_CH16, "CombinedChinesePlain16"); |