开源软件《M8围棋谱》v0.8.8 首次登陆魅族软件中心,免费发布,技术总结
今日(2010/7/22),本人(liigo)开发的C/C++开源软件《M8围棋谱》v0.8.8 首次登陆魅族软件中心,免费发布。本文主要针对“如何满足魅族软件中心对软件的各项要求”作一些技术总结。
众所周知,魅族对发布在软件中心的软件有详细的要求、严格的审核,工作人员甚至帮你测试寻找BUG,细致入微,热心而且周到,工作效率也挺高,周六都在加班工作。在《M8围棋谱(v0.8.8)》申请进入魅族软件中心之前,我逐条对照《魅族手机应用软件审核标准1.2》,自我审核并修改了部分内容,后来有几经周折按照魅族软件中心工作人员的反馈,修改了另外部分内容。总结一下,此次为登陆魅族软件中心,大概修改了一下内容:
软件必须单实例运行;
必须设置标题栏文本;
软件在系统任务管理器中的显示文本必须与软件名称一致;
通过USB连接电脑时软件必须退出,且不弹出任何提示;
软件启动、退出、切换窗口时必须有动画效果;
软件在英文系统下运行不能有中文乱码;
如果软件有播放声音的功能,必须允许用户通过音量键(物理按键)调节声音,必须有选项可以关闭声音;
总体来说,它的审核有点过分琐碎、过分严格,有些细节在编码实现上有过分复杂(这是SDK设计不够友好)。
软件必须单实例运行,我是通过创建系统全局Event对象实现的,与官方示例代码稍有区别:
上面的代码中,首先创建全局Event对象,如果发现同名对象已存在,说明本软件已经有一个实例在运行,通过WinCE API函数FindWindow()找到主窗口并激活它,然后退出当前进程。
软件在系统任务管理器中的显示文本必须与软件名称一致。文档中似乎没有提到系统任务管理器中的显示文本取自何处,我总结得知,如果通过WinCE API函数SetWindowText()设置了主窗口标题栏文本,则显示该文本,否则显示软件EXE文件名(无路径)。所以要满足此条要求,只需设置标题栏文本为软件中文名称即可。
通过USB连接电脑时软件必须退出,且不弹出任何提示。这个实现起来稍微有一点麻烦,但是也简单,SDK文档有相关说明。首先要定义一个类成员 int m_usbNotifyMsg,在窗口初始化时(OnInitDialog)对其赋值:m_usbNotifyMsg = RegisterUsbNotifyMsg();,即通过调用MZ SDK 函数RegisterUsbNotifyMsg()获取“USB连接相关的”消息值。然后,在CMzWnd::MzDefWndProc()方法中处理USB连接消息,主要代码如下:
软件启动、退出、切换窗口时必须有动画效果。主要是 CMzWnd::AnimateWindow(MZ_ANIMTYPE_ZOOM_IN, true) 此类代码调用,SDK文档中有示例代码,简单。
软件在英文系统下运行不能有中文乱码。M8围棋谱软件需要读取GB编码的SGF棋谱文件,我(liigo)自行开发的SGF解析器解析出来的文本都是GB编码(char*),而软件本身是UNICODE的,中间需要进行编码转换。我原来使用C库函数 mbstowcs() 转换编码,后来被魅族软件中心测试人员发现,在软件运行在英文系统下时,此举会造成中文显示乱码。我分析后估计是locale的原因,事先调用C库函数setlocale()设置为中文locale应该就能解决吧?然后又发现WinCE下的C运行库似乎没有setlocale()函数。于是放弃这个思路,改用WinCE API函数MultiByteToWideChar()进行编码转换(GB2312->UCS2LE),主要代码如下:
如果软件有播放声音的功能,必须允许用户通过音量键(物理按键)调节声音,必须有选项可以关闭声音。我原来是调用WinCE API函数PlaySound()播放WAVE文件的,如此一来不好处理音量大小的控制。后来选择调用MZ SDK提供的COM接口IPlayerCore_Play,首先是相关COM对象的初始化(基本上是引用SDK文档中的示例代码,相当繁琐):
欲播放音乐文件时,先调用 m_pSysFile->SetName(m_luoziSoundFile),然后调用 m_pPlayCore->OpenFile(),然后调用 m_pPlayCore->Play(),当然,Play()之前可以调用 m_pPlayCore->SetVolume(m_soundVolume) 设置音量:
接下来要处理用户按下音乐键(物理按键)的消息了,以便增减音量。方法与处理USB连接事件大致相同(代码之繁琐有过之而无不及):
实现响应音乐键调节音量的过程中,有个细节我处理的不够理想,即,没有找到获取当前音量的方法。用户按“上音量键”我增加音量,用户按“下音量键”我减小音量,可是音量的初始值是什么呢?一直没找到方法读取,只好暂时以当前系统来电铃声音量替代。目前的效果不是很好:用户按音乐键时,系统会自动弹出一个音量调节进度显示框,而它显示的值有时明显不能跟我软件中的音量一致起来。归根结底还是没有取得音量初始值。郁闷。如果系统改进一下接口,在用户按下音乐键时,直接返回给我音量值多好。
总体的感觉,MZ SDK 的 API 接口设计不是非常友好,有些地方使用起来相当繁琐。是不是我易语言代码写多了,再不愿写又臭又长的代码?我倒是很期待Android SDK,想象中Google设计的API应该相当OK吧?无论如何,《M8围棋谱》进入魅族软件中心,还是值得庆祝的。顺便也祝愿魅族软件中心发展的越来越好。