window mobile 经常被忽略的知识点(1)
1 联网分2种,第一种最普通的,就是通过ActiveSync选择DMA 单位网络 ,然后在网卡里面设置IP即可,这样就可以打开网页。 这种方法网上到处都是,就不详细说了,
但是如果要进行UDP编程,就必须使用第二种方式,具体设置方法请见我的另一篇博文。
2 发送短信 SmsSendMessage
3 短信拦截
SDK中提供了一个Mapirule的例子,展示如何拦截短信。为了过滤垃圾短信或者拦截某些特定号码的短信,我们需要在ProcessMessage这个函数中插一杠。无非根据发送方电话号码(pspvEmail->Value.lpszW)或短信内容(pspvSubject->Value.lpszW)酌情处理。在编译好mapirule.dll后,要对注册表进行一点改动。例中也有说明:1)在注册表中增加一项HKEY_CLASSES_ROOT\CLSID\{3AB4C10E-673C-494c-98A2-CC2E91A48115\InProcServer32,默认值为mapirule.dll,字符型;2)增加一项HKEY_LOCAL_MACHINE\Software\Microsoft\Inbox\Svc\SMS\Rules,新键名为{3AB4C10E-673C-494c-98A2-CC2E91A48115},值为1,DWORD型。注册表改完,mapirule.dll拷到windows目录下。重启一下手机,拦截开始起作用。
4 电话
除了使用TAPI的lineMakeCall可呼叫电话外,有一简单的函数PhoneMakeCall也可调用:
PHONEMAKECALLINFO info;
info.cbSize = sizeof(PHONEMAKECALLINFO);
info.dwFlags = PMCF_PROMPTBEFORECALLING;
info.pszDestAddress = L”13800138000”;
info.pszAppName = NULL;
info.pszCalledParty = NULL;
info.pszComment = NULL;
PhoneMakeCall(&info);
TAPI也支持来电拦截。具体参见lineInitialize
5 创建程序快捷方式
系统提供了两个API来支持创建快捷方式:
DWORD WINAPI SHCreateShortcut(
LPTSTR szShortcut,
LPTSTR szTarget
);
DWORD WINAPI SHCreateShortcutEx(
LPTSTR lpszDir,
LPTSTR lpszTarget,
LPTSTR szShortcut,
LPDWORD lpcbShortcut
);
6 程序自启动
1)将可执行程序文件或快捷方式文件放至\windows\Startup目录;
2)创建一个service.dll,注入到services.exe里。
7关机与重启
ExitWindowEx(EWX_POWEROFF, 0);//关机(pocket pc不支持,各厂商自己实现)
ExitWindowEx(EWX_REBOOT, 0); //重启
8 使用鼠标、键盘钩子
wince系统对于钩子技术的支持,显然不及windows。有一些技术文档干脆说wince不支持钩子。其实,不尽然。我们还是可以从coredll.dll中,得到一些有用的接口,来实现拦截一些简单的键盘或鼠标的动作。如果在一个程序中已经启动了钩子,其他的程序使用钩子将无效。
由于使用了微软未公开的函数,可能会有潜在的问题,建议慎用。微软有可能在以后的版本中不支持钩子。
9 POOM操作
POOM是基于微软COM技术的一套针对手机上(PIM)个人信息管理的COM接口库。POOM不仅包含了对联系人(IContact)的操作,还包含了任务(ITask)、约会提醒(IAppointment)等关于个人信息管理的内容。以下代码演示如何取得联系人姓名:
HRESULT hr;
IPOutlookApp * polApp = NULL;
IFolder *pFolder = NULL;
IPOutlookItemCollection * pItemCol = NULL;
int nItems;
CoInitializeEx(NULL, 0);
hr = CoCreateInstance(_uuidof(Application), NULL, CLSCTX_INPROC_SERVER,_uuidof(IPOutlookApp), (LPVOID*)&polApp);
polApp->Logon(NULL);
polApp->GetDefaultFolder(olFolderContacts, &pFolder);
pFolder->get_Items(&pItemCol);
pItemCol->get_Count(&nItems);
BSTR bstrFirstName;
BSTR bstrLastName;
IContact * pContact;
for (int i=1; i<=nItems; i++)
{
hr = pItemCol->Item(i, reinterpret_cast<IDispatch**>(&pContact));
if (SUCCEEDED(hr))
{
pContact->get_FirstName(&bstrFirstName); //姓
pContact->get_LastName(&bstrLastName); //名
SysFreeString(bstrLastName);
SysFreeString(bstrFirstName);
}
}
polApp->Logoff();
polApp->Release();
CoUninitialize();
10 MAPI是一个基于COM的库,提供了客户端应用程序操作“消息“(信息)的编程方法,包括短信、电子邮件等都可使用MAPI来操作。
11 手机震动
可使用函数Vibrate来使手机震动:
int caps = -1;
caps = VibrateGetDeviceCaps(VDC_AMPLITUDE);
if(caps <= 0)
{
return;
}
HRESULT hr = Vibrate(0, NULL, TRUE, INFINITE);
Sleep(150);
也可以使用函数NLedSetDevice:
NLED_COUNT_INFO nci;
int nIndex = 1;
if(NLedGetDeviceInfo(NLED_COUNT_INFO_ID, (PVOID) &nci))
{
nIndex = (int)nci.cLeds - 1;
}
NLED_SETTINGS_INFO settings;
settings.LedNum = nIndex;
settings.OffOnBlink = 1;
NLedSetDevice(NLED_SETTINGS_INFO_ID, &settings);
Sleep(150);
settings.LedNum = nIndex;
settings.OffOnBlink = 0;
NLedSetDevice(NLED_SETTINGS_INFO_ID, &settings);
12 IMEI、IMSI、手机号码与手机型号
IMEI:移动通信国际识别码(International Mobile Equipment Identity number),由15位数字组成,用于在手机网络中识别每一部独立的手机。相当于移动电话的身份证。每组移动通信国际识别码都有15个阿拉伯数字,并且前6码为原制造厂编码,中间8码为“流水号”,最后1码为备用码。移动通信国际识别码的每一码所出现的数字均起到移动电话身分辨正的功能,并且是国际上公认通的共享数码准则。
IMSI:国际移动用户识别码(International Mobile Subscriber Identity),在GSM系统中,给每个移动用户分配一个唯一的国际用户识别码IMSI,此码在网中所有位置包括漫游区都是有效的。
手机号码一般不是存放在sim卡中的,而是存放在运营商的数据库里。一些手机平台开放了获取手机号码的接口;但目前多数运营商出于隐私和安全性考虑,屏蔽了该类接口。
具体代码略,网上可查。
一般说来,注册表项HKEY_LOCAL_MACHINE\Ident下Name项值就是手机型号;手机型号也可能包含在UA串中,使用下面的函数来获取UA串:
HRESULT ObtainUserAgentString(
DWORD dwOption,
LPCSTR pcszUAOut,
DWORD* cbSize
);
该函数读出来的值存放在注册表HKEY_LOCAL_MACHINE\ Security\Internet Explorer\User Agent下CustomBase项中。
13 GetSystemTime取得的是格林威治时间,GetLocalTime取得的是当前时区时间。
14 窗口自适应输入法
PPC中,输入法显示时,界面可供用户操作的空间变小。如何使得界面能自适应输入法状态呢?
SIPINFO si = {0};
si.cbSize = sizeof(si);
SHSipInfo(SPI_GETSIPINFO, 0, &si, 0);
BOOL bShow = si.fdwFlags&SIPF_ON;
此时,bShow为真则表示输入法处于显示状态,否则是隐藏。
SIPINFO是这样定义的:
typedef struct tagSIPINFO
{
DWORD cbSize;
DWORD fdwFlags;
RECT rcVisibleDesktop;
RECT rcSipRect;
DWORD dwImDataSize;
void *pvImData;
} SIPINFO;
由rcVisibleDesktop和rcSipRect可以算出我们需要的界面大小。
响应WM_SETTINGCHANGE消息,通过SHSipInfo函数去得到输入法面板参数和桌面可视区域参数,然后配置窗口。
以上大多整理自网上
sylar 2010.2.1 cug@live.cn