Windows Mobile开发总结
10. WM手机默认中文编码是什么?
默认编码是Unicode, 所有的WM手机都是UNICODE的, 且SP平台和PPC都一样! 很多跟我一样刚接触WM开发的人都会碰到一个问题, 为什么同样的代码在VC6开发
的应用程序中没有问题, 但把相关代码复制到Windows Mobile上运行就出现如此多的编译错误, 如error C2664: 'CWnd::MessageBoxW' : cannot convert
parameter 1 from 'char [100]' to 'LPCTSTR'. 都是没有考虑到这一点(编码问题), 需要使用提供的字符串相关的API与函数加以处理. 字符串处理函数可以看这篇
文章WinCE下非常有用的字符串操作函数.
下面简单介绍Unicode C-Runtime 转换函数
mbstowcs(
wchar_t *wcstr, // Output string.
const char *mbstr, // Input string.
size_t count ); // Character count
wcstombs(
char *mbstr, // Output string.
const wchar_t *wcstr, // Input string.
size_t count ); // Character count
MultiByteToWideChar与WideCharToMultiByte
// 演示API使用, UTF-8转换Unicode汉字代码(Copy修改即可)
char str[256] = {(char)0xE4,(char)0xBD,(char)0xA0,(char)0xE5,(char)0xA5 ,(char)0xBD,(char)0x61,(char)0x62,(char)0x63,(char)0}; //一段UTF-8编码
WCHAR* strA;
int i = MultiByteToWideChar(CP_UTF8, 0, (char*)str, -1, NULL, 0);
strA = new WCHAR[i];
MultiByteToWideChar(CP_UTF8, 0, (char *)str, -1, strA, i);
i = WideCharToMultiByte(CP_ACP, 0, strA, -1, NULL, 0, NULL, NULL);
char *strB=new char[i];
WideCharToMultiByte(CP_ACP, 0, strA, -1, strB, i, NULL, NULL);
//strB即为所求
//AfxMessageBox(strB);
delete []strA;
delete []strB;
11. 在Windows Mobile下使用XML
XML当前被大量使用于应用程序配置, 存储少量数据以及Web Services等应用; 甚至到通信报文内容也以xml格式来传递, 方便服务端数据在不同手机与开发平台上
解析. 因为不管是C++, C#, 还是Java语言都有提供相关API来解析XML格式内容.
在WM开发中, 可以使用微软提供的COM接口或者第三方开源XML解析库如TinyXML, 相关内容请自行浏览在Windows Mobile下使用MSXML, TinyXml 介绍,
Windows Mobile下tinyXML的开发等博文.
12. 如何建立拨号链接进行网络通信
在WM中需先进行拨号链接操作, 链接成功建立后才可以进行后续的Socket通信等; 感觉这方面微软处理没有Symbian下那么友好, Nokia手机会在你的应用首次使用
网络时, 弹出窗口提醒你该操作可能产生GPRS流量费用, 询问你采用何种上网方式接入, 是cmnet还是cmwap. 因为讲述GPRS这方面文章很多, 可以直接看我整理的
Windows Mobile 开发系列文章收藏 - GPRS/上网设置.
13. 界面美化 - 贴图
用户对手机软件的界面是很在意的,做的好看了他会觉得有技术含量,做的好用了他会更加喜欢我们的产品。所以一套好的UI是必不可少的。手机软件开发的大部分
工程是在做UI系统。一套好的自主的手机软件UI系统是产品核心竞争力的一部分。在Windows Mobile的界面开发,使用C + SDK做漂亮的界面不容易,一旦在界面上控
件比较多,控件的布局更是头痛。横竖屏切换的时候也得考虑,不同手机屏幕尺寸可能也不一样; 不同的字体下, 界面差异也非常大……
其实要做出好的界面最后还是要回归RECT,也就是自己绘制贴图。 如果要做的很漂亮,那还是自己封装一套界面控件,这样控制起来方便。横竖屏问题,你绘制的
时候不应该写死的位置坐标,应该取相对坐标。在横竖屏切换的时候会触发WM_SIZE等一些消息,里面改变相对坐标的横竖屏大小就OK啦.
拿配置信息设置窗口来说, 主要需处理WM_PAINT, WM_MOUSEMOVE, WM_LBUTTONDOWN等一系列窗口消息.
相关参考代码
PAINTSTRUCT ps;
HDC hdc, hdcCopy;
HBITMAP hBitmap;
RECT rt;
int iRet = 0;
POINT ptM;
switch (message)
{
case WM_PAINT://WM_ERASEBKGND
hdc = BeginPaint(hDlg, &ps);
hdcCopy = CreateCompatibleDC(NULL);
if (doCloseDlg)
{
hBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_LOGINCLOSE)); // 鼠标移动到窗体关闭按钮时候, 载入不同的位图
}
else
{
hBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_LOGIN));
}
SelectObject(hdcCopy, hBitmap);
GetClientRect(hDlg, &rt);
BitBlt(hdc, rt.left, rt.top, rt.right, rt.bottom, hdcCopy, 0, 0, SRCCOPY);
DeleteObject(hBitmap);
ReleaseDC(hDlg, hdc);
EndPaint(hDlg, &ps);
break;
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
ptM.x = LOWORD(lParam);
ptM.y = HIWORD(lParam);
SetRect(&rt, 190, 0, 235, 20);
if (PtInRect(&rt, ptM))
{
doCloseDlg = true;
}
else
{
doCloseDlg = false;
}
InvalidateRect(hDlg, &rt, TRUE);
UpdateWindow(hDlg);
break;
case WM_LBUTTONUP:
// 判断当前用户鼠标点击位置是否位于关闭按钮区域
ptM.x = LOWORD(lParam);
ptM.y = HIWORD(lParam);
SetRect(&rt, 190, 0, 235, 20);
if (PtInRect(&rt, ptM))
{
EndDialog(hDlg, LOWORD(wParam));
}
doCloseDlg = false;
break;
}
最终实现效果大致如图下:
14. 用户登录过程例子
我是新开一个线程来处理, 可以灵活加入如超时控制等, 通过自定义处理消息来通知主窗体当前进度情况.这个你先定义这个消息如#define USER_LOGIN_MESSAGE
WM_USER + 300, 需要触发的时候SendMessage/PostMessage给指定窗口, 如PostMessage(g_hWnd, USER_LOGIN_MESSAGE, LOADCONFIG, 0); 然后
在对应的窗体消息处理里面处理, SendMessage和PostMessage后两个参数就对应WndProc的后两个参数,可用于传值。
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case USER_LOGIN_MESSAGE:
break;
}
return 0;
}
用户登录大致代码
#define USER_LOGIN_MESSAGE WM_USER + 300
//用户登录服务器步骤
typedef enum tagTLoginStep
{
INITMENU = 0, //初始化菜单
LOADCONFIG = 1, //载入流媒体配置信息
INITWINSOCK = 2, //初始化Winsock库
CREATESOCKET = 3, //创建socket
CONNECTSERVER = 4, //正在连接服务器
SENDREQUEST = 5, //发送请求
GETRESPONSE = 6, //获取响应
PARSEPACKET = 7, //解析报文
LOGINOK = 8, //登录成功
LOGINFINISH = 9, //登录操作完成
LOGINFAIL = 10,//登录失败
REFRESHVIDEO = 11 //刷新画面
}TLoginStep;
//======================================================
case IDM_LOGIN:
SetCursor(LoadCursor(NULL, IDC_WAIT)); // 显示系统自带的WAIT进度圈
ShowCursor(TRUE);
PostMessage(g_hWnd, USER_LOGIN_MESSAGE, INITMENU, 0);
if (packetHelper == NULL)
{
packetHelper = new PacketHelper();
SetTimer(g_hWnd, 1, 1000, NULL);// 用于实时显示视频数据传输速率
}
hMenu = (HMENU)SHMenuBar_GetMenu(g_hWndMenuBar, IDM_HELP);
if (hMenu != NULL)
{
EnableMenuItem(hMenu, IDM_LOGIN, MF_BYCOMMAND | MF_GRAYED);
}
DWORD dwThreadId;
HANDLE hThread;
hThread = CreateThread(NULL, 0, LPTHREAD_START_ROUTINE(UserLoginProc), packetHelper, 0, &dwThreadId);
if (hThread)
{
CloseHandle(hThread);
}
break;
其效果大致如下图所示, 其中涉及菜单等操作可以看Windows Mobile入门中菜单部分.
15. 计算当前传输速率
在视频监控程序里面我们一般会在画面上同时显示当前传输速率为多少kbps, 我在这里采用通过2个变量来保存到上一秒收到的字节数以及到这一秒收到的数据量,
通过对这2数相减, 大致计算出这一秒传输了多大的数据量. 定义一个每隔1s触发的定时器, 然后在窗体中处理WM_TIMER消息. 为了能够上STATIC上字体显示成白色, 需在窗体中处理WM_CTLCOLORSTATIC消息
case WM_CTLCOLORSTATIC:
SetBkMode((HDC)wParam, TRANSPARENT);
SetTextColor((HDC)wParam, RGB(255, 255, 255));
return (LRESULT) GetStockObject(BLACK_BRUSH);
16. 如何制作.CAB安装包
C#怎么安装 cab呢?一般情况下通过vs 2005新建安装部署工程,里面就有打包cab来生成可部署到手机上的安装包. 另外有一个WinCE CAB Manager工具可以帮忙.
17. 模拟器 vs 真机
要弄清楚一点, 不管当前模拟器真实度有多么高, 但其毕竟不是真机; 如果条件可以的话, 尽早把程序部署到手机上跑跑看, 会发现一些在模拟器上没有注意到的问题, 如
网络情况, 稳定性, 传输速率. 当然还有其它一系列差异, 手机性能(CPU, 内存使用).
更多WM应用开发的常见问题, 可以看文章WM应用开发的常见问题解答, Windows Mobile 开发常见问题集2, Windows Mobile 开发系列文章收藏 - 开篇,
Windows Mobile开发文章收藏.
移动流媒体应用发展与限制
1. 资费问题
拿中国移动举例来说, 当前其GPRS是按流量来收费的; 就拿我自己动感地带套餐每月赠送50M流量, 按一路视频传输128kbps来计算, 让我们来看看, 可以看多少分钟
视频, 50M = 50 * 1024 * 8 (传输速率是按位计算的, 1 Byte = 8 bit), 结果是大致可以看50分钟, 如果把视频传输速率调低到32kbps, 我们也只能够看3小时多的
视频, 差不多也是当前智能手机电池能够支持极限, 当然这样处理同时也会降低视频画面的清晰度. 超出部分流量移动是按0.01¥/KB收取, 1分钟视频竟高达近10块大
洋.这个价格可不是像我这类的普通人承担得起的. 所以3G网络下, 中国联通率先对其资费进行了更改, 独创了全新的计费方式和计费理念:以M/T作为多媒体内容的下
载计费单位。可参见运营商的纠结:3G最好计费方式是什么模样
2. 网络状态, 无线网络带宽窄,干扰严重
我测试得到的情况是, 在办公室里面信号比较稳定, 平均传输速率在160 ~ 220kbps之间浮动. 下班回家在公交车上看视频, 视频所需缓冲时间加长, 画面显示需等待5-
10s不等, 在一些繁忙路口, 四周高楼大厦环境下, 存在信号盲区, 网络连接不上或者提示超时. 2.75G EDGE网络下(其速度最多236 kbps,对QCIF视频画面质量传
输来说足够了), 但实际情况下,稳定的传输速率通常在30 ~ 50kbps左右。并且随着使用用户的增加,网络的性能将会进一步下降。另外无线网络的干扰严重,
导致网络传输的误码的可能性大大增加。
当前的3G模块比较耗电. 未来随着3G的推广, 以及有消息称中国移动TD-LTE(4G)2010年会进入商用,下载一部164兆的电影,仅花了不到2分钟,而通常300兆的
电影,则只要3到5分钟就能下载完毕。对此,业内人士介绍,4G可以达到百兆以上的速率,对于3G来说又是一个质的飞跃。如果说3G 是国道,4G就是高速公路。
而对于4G与2G、3G之间最大的不同,技术人员介绍,除了速度比他们快之外,视频监控、视频通话效果也将更加流畅、高清。在网上看高清视频,不用担心画面卡或
声像不同步……与3G相比,4G带宽可达到170M以上,其下载速度比3G快80倍。
3. 手机自身缺陷(屏幕大小, CPU性能, 电池)
现在的智能手机性能上现在问题不大, 一些手机的CPU频率都超过600MHZ了, 还有消息称未来会有双核处理器的手机上市. 拿多普达的S1(220MHZ, 128M), 其运算
处理能力, 每秒解码15-20帧数据不成问题, 但考虑到网络等因素, 平均传输8 ~ 12fps比较合适. 但手机的CPU, 内存等提高, 必然会碰到的一个问题就是电池能源有限.
尽管手机设备的运算能力越来越强,但是由于它是由电池供电的,因此编解码处理不能太复杂,并且最好能够根据用户设备的电池来调整流媒体的接收和处理,能源管
理技术也是移动流媒体的一个研究热点。什么时候我们才能够用上完全使用太阳能, 提取人体产生能量或者其它新能源技术的手机呢.
终端系统平台、LCD多样化, 手机操作系统现在是类似于中国古代的战国时代, Symbian、Linux、Windows Mobile、Palm OS, 新近的苹果iPhone, 谷歌Android.
对于开发应用来说是一个机遇, 但反过来说同样也是一个巨大的挑战; 需适应的终端平台越来越多, 屏幕型号越来越走向多样化.
我对联通的WCDMA, 电信CDMA2000不太了解, 大家都可以谈谈当前3G发展情况, 运营商碰到的各种瓶颈, 如相关手机终端的缺乏, 基础网络建设等等. 在网上看到了
几个消息视频通话,3G最大谎言, 中国3G之父成都炮轰三大营运商“忽悠过了头”, 手机上网应用冷热不均 消费者感知重在实用, IT时代周刊封面文章:决战3G; 当然
也有一些其它消息, 中国移动定制的OPhone将在下个月上市了, Nokia也会在年底发布基于TD标准的3G手机, 加上其它厂商也会有一些手机上市, 手机终端缺乏问题
会得到一定程度上的解决. 各个运营商也都上马了手机软件商店, 如中移动Mobile Market 在本月已开张 三七分成, 但其会不会碰到中国式软件难题呢, 不好预测.
运营商:拿什么来吸引你,我的3G客户, 但不可否认移动互联网是一场革命, 它带给我们的将是生活模式、工作模式,以及思维模式的巨大改变!智能手机正加快策动二次PC革命, 手机的未来:一场想象力的盛宴; 国务院:积极发展移动多媒体、手机电视等文化也让我们看到了一线希望.
作者:peterzb(个人开发历程知识库 - 博客园)
出处:http://peterzb.cnblogs.com/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
分类: 安防监控, Windows Mobile, Mobile, C++
标签: Windows Mobile, 流媒体, Mobile, 视频监控, UI