1. 如何截获来电消息?
用TAPI提供的api函数就能实现,这些函数在TAPI.h中。实现步骤如下:
(1).初始化线路,并打开线路
#include <TAPI.h>
DWORD lineHandleCount;
HLINE *lineHandles;
HLINEAPP lineApp;
if(lineInitialize(&lineApp,theApp.m_hInstance,(LINECALLBACK)LineCallback,L"Video",&lineHandleCount)==0)
{
lineHandles = new HLINE[lineHandleCount];
for(DWORD i = 0; i < lineHandleCount; i++)
{
int rc;
DWORD ver;
LINEEXTENSIONID extensionID;
if( lineNegotiateAPIVersion( lineApp, i, 0x00010000, 0x00020000, &ver, &extensionID ) == 0 )
{
rc = lineOpen( lineApp,i,&lineHandles[ i],ver,0,(DWORD)0,
LINECALLPRIVILEGE_MONITOR|LINECALLPRIVILEGE_OWNER,LINEMEDIAMODE_INTERACTIVEVOICE,NULL);
}
}
}
(2).编写回调函数,在这个函数里实现功能
VOID CALLBACK LineCallback(DWORD hDevice, DWORD dwMsg, DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
switch(dwMsg)
{
case LINE_APPNEWCALL: // message of new incall
// your process
break;
case LINE_CALLSTATE: // message of call state changed
switch(dwParam1)
{
case LINECALLSTATE_DISCONNECTED: // 来电挂断
// your process
break;
// case ...
// ...
default:
break;
}
// case ......
// ...
default:
break;
}
}
(3).当结束程序时,关闭线路
for ( DWORD i=0; i<lineHandleCount; i++ )
{
lineClose( lineHandles[i]);
delete[] lineHandles;
lineShutdown( lineApp );
}
以上的代码可以参考 : http://www.cnblogs.com/randylee/archive/2008/12/31/683277.html
2. 如何不让Windows Mobile自带的电话程序截获来电?
来电消息是以广播形式发送的,Windows Mobile上所有的程序都能收到这个消息。我们开发了自己的来电程序,但是来电时,Windows Mobile的电话程序也能截获来电,跳出许多讨厌的窗口。怎么办?
我最开始的思路是,往底层走。从源头抓起,控制消息的发送。 TAPI是不行的,RIL层据说也不行,万般无奈之下只好放弃。接着就发现了"cprog.exe",差不多就解决了我的问题。
cprog.exe是Windows Mobile上的电话程序,负责接电话、打电话、弹出提示。我先是用Visual Studio Remote Tools 里的"远程进程查看器",杀死试WM正在运行的cprog.exe, 然后打个电话试了一下,发现还真是管用。电话打通后,WM手机没有任何来电提示,也没有任何弹出窗口;而打电话的那边听到的是“嘟...嘟...”的接通声,但是对方没人接!这样的话,如果加入我们自己的电话程序,就可以接管WM的电话工作了。
但是 cprog.exe 比较顽固。被关闭之后,隔一小段时间又会启动。估计是另一个服务程序检测到cprog.exe不在工作状态,又启动了它。所以我们必须在每次电话来时关闭cprog.exe。
代码如下:
/*
终止 cprog.exe (Windows Mobile的电话程序)。
需要包含
#include <Tlhelp32.h>
#pragma comment (lib, "Toolhelp.lib")
*/
BOOL Killcprog()
{
HANDLE hndAA;
PROCESSENTRY32 proBB;
DWORD ProcessID=0;
BOOL RET;
WCHAR s[20];
BOOL bSuccess = FALSE;
hndAA=(HANDLE)CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,(DWORD)NULL);
proBB.dwSize=sizeof(PROCESSENTRY32);
RET=Process32First(hndAA,&proBB);
while (RET)
{
GetFileTitle(proBB.szExeFile,s,20);
if(!_wcsicmp (_T("cprog.exe"), s))
{
ProcessID=proBB.th32ProcessID;
HANDLE ps = OpenProcess(1,false,ProcessID);
TerminateProcess(ps,-9);
bSuccess = TRUE;
break;
}
RET=Process32Next(hndAA,&proBB);
}
CloseHandle(hndAA);
return bSuccess;
}
/*
开启 cprog.exe (Windows Mobile的电话程序)。
*/
BOOL Startcprog()
{
BOOL bSuccess = FALSE;
PROCESS_INFORMATION ProcessInformation;
if(CreateProcess(_T("//Windows//cprog.exe"), NULL,
NULL, NULL, FALSE, 0x0, NULL, NULL, NULL, &ProcessInformation))
{
bSuccess = TRUE;
}
else
{
MyMessageBox(_T("Create process /"cprog.exe/" failed!"));
bSuccess = FALSE;
}
return bSuccess;
}
// 当检测到来电时,调用Killcprog()关闭cprog.exe;来电结束或通话结算后让系统恢复正常,就启动cprog.exe。
// 经实践,当cprog.exe启动后,如果当前仍有电话在呼叫,cprog.exe会立即弹出提示框,让你接电话!
// 可以对来电消息的回调函数做如下修改:
BOOL gbIsCalling; //protect program from more than one incall in the same time
DWORD ghDevice; //incall identifier
VOID CALLBACK LineCallBack(DWORD hDevice, DWORD dwMsg, DWORD dwCallbackInstance,
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
switch(dwMsg)
{
case LINE_APPNEWCALL: // message of new incall
if(!gbIsCalling)
{
ghDevice = dwParam2;
gbIsCalling = TRUE;
Killcprog();
}
break;
case LINE_CALLSTATE: // message of call state changed
switch(dwParam1)
{
case LINECALLSTATE_DISCONNECTED:
if(gbIsCalling && ghDevice == hDevice)
{
Startcprog();
gbIsCalling = FALSE;
}
break;
default:
break;
}
default:
break;
}
}
这个来电截获的方法还是有局限性。如果除了WM系统自带之外,还有程序响应来电消息,那只能杀死那些程序的进程才能阻止它们响应来电。
PS:
CSDN 的文字编辑功能是在太烂了,如何让文章的排版更好,字对的更齐啊!