Windows Mobile發送短信應用分為兩種,一是調用Windows Mobile自有的發送短信視窗,将接收使用者的手機号碼傳遞給該視窗,完成短信發送(暫且稱為視窗短信),另一種是通過調用API将文本發送給指定的号 碼,這中發送方式對于使用者是無感覺的(暫且稱為無感覺短信,下面對這兩種方式的實作分别介紹。
視窗短信:
視窗短信實作比較簡單, 可以直接使用下面的啟動參數啟動系統的EXE檔案即可, System.Diagnostics.Process.Start("tmail.exe", "-transport /"SMS/" -to /"" + 手機号碼 + "/" -body /"短信内容/"");但要注意的是,在發送完畢後,短信清單頁面會在你關閉發送資訊視窗後呈現出來,可以在頁面的關閉事件中,使用FindWind方 法,找到系統的【短信】視窗,将其關閉即可。
無感覺短信
1.Windows Mobile 5.0及以上版本
無感覺短信 接口與Mobile作業系統的版本有關,如果是基于Windows Mobile5.0 的裝置 ,完成短信發送比較容易,因為微軟已經給你封裝好了底層的API,可以直接進行調用,引用 Microsoft.WindowsMobile.PocketOutlook.dll後,使用SmsMessage smsSend = new SmsMessage(phone, sms);smsSend.Send();方法便可以完成對一條短息的發送。
///.h檔案
#include <sms.h>
#pragma comment (lib, "sms.lib")
#define MAXLEN 1024
#define SENDMODE 1 //是發送還是接收
bool SendSMS(bool bSendConfirmation,bool bUseDefaultSMSC,TCHAR* pszCenterPhone,TCHAR * pszDUserPhone,TCHAR* pszMessage);
bool RecvSMS(TCHAR* pszRecvMsg,int nRecvLen);
///cpp檔案
bool SendSMS(bool bSendConfirmation,bool bUseDefaultSMSC,TCHAR* pszCenterPhone,TCHAR * pszDUserPhone,TCHAR* pszMessage)
{
SMS_HANDLE smshHandle;
SMS_ADDRESS smsaSource;
SMS_ADDRESS smsaDestination;
TEXT_PROVIDER_SPECIFIC_DATA tpsd;
SMS_MESSAGE_ID smsmidMessageID=0;
HRESULT hr=0;
TCHAR *lpszMessage = pszMessage;
// 打開SMS
if(FAILED(SmsOpen(SMS_MSGTYPE_TEXT, SMS_MODE_SEND, &smshHandle, NULL)))
{
//printf(("SmsOpen failed!"));
MessageBox(NULL,_T("SmsOpen 失敗."),_T("提示"),MB_OK);
return false;
}
// 建立短信中心位址(号碼)
if(!bUseDefaultSMSC)
{
smsaSource.smsatAddressType = SMSAT_INTERNATIONAL;
_tcsncpy(smsaSource.ptsAddress, pszCenterPhone, SMS_MAX_ADDRESS_LENGTH);
}
// 建立目标位址(号碼)
memset (&smsaDestination, 0, sizeof (smsaDestination));
smsaDestination.smsatAddressType = SMSAT_INTERNATIONAL;
_tcsncpy(smsaDestination.ptsAddress, pszDUserPhone, SMS_MAX_ADDRESS_LENGTH);
// 設定提供者服務
memset (&tpsd, 0, sizeof (tpsd));
tpsd.dwMessageOptions = bSendConfirmation ? PS_MESSAGE_OPTION_STATUSREPORT : PS_MESSAGE_OPTION_NONE;
tpsd.psMessageClass = PS_MESSAGE_CLASS1;
tpsd.psReplaceOption = PSRO_NONE;
// 發送
if(SUCCEEDED(hr=SmsSendMessage(smshHandle, ((bUseDefaultSMSC) ? NULL : &smsaSource),
&smsaDestination, NULL, (PBYTE) lpszMessage,
_tcslen(lpszMessage) * sizeof(TCHAR), (PBYTE) &tpsd,
sizeof(TEXT_PROVIDER_SPECIFIC_DATA), SMSDE_OPTIMAL,
SMS_OPTION_DELIVERY_NONE, &smsmidMessageID)))
{
MessageBox(NULL,_T("發送成功"),_T("提示"),MB_OK);
}
else
{
MessageBox(NULL,_T("發送發送"),_T("提示"),MB_OK);
VERIFY(SUCCEEDED(SmsClose(smshHandle)));
return false;
}
//關閉
VERIFY(SUCCEEDED(SmsClose(smshHandle)));
return true;
}
bool RecvSMS(TCHAR* pszRecvMsg,int nRecvLen)
{
SMS_HANDLE smshHandle = 0;
SMS_MESSAGE_ID smsmidMessageID = 0;
HRESULT hRet = 0;
SMS_HANDLE smshRecieveHandle;
DWORD dwReturn = 0;
HANDLE hSmsEvent;
dwReturn = SmsOpen(SMS_MSGTYPE_TEXT, SMS_MODE_RECEIVE, &smshRecieveHandle, &hSmsEvent);
// 程式會在此等待子產品來短信,直到逾時或者有短信來到
dwReturn = WaitForSingleObject(hSmsEvent, INFINITE);
// 判斷是否成功接收到短信
if(dwReturn == WAIT_ABANDONED || dwReturn == WAIT_TIMEOUT)
{
return FALSE;
}
// 成功接收到短信,先設定好短信大小
DWORD dwMessageSize = nRecvLen;
// 初始化短信結構
SMS_ADDRESS smscAddress;
SMS_ADDRESS inAddress;
SYSTEMTIME rcvTime;
TEXT_PROVIDER_SPECIFIC_DATA txtProviderData;
DWORD dwProviderLength = 0;
dwProviderLength = sizeof(TEXT_PROVIDER_SPECIFIC_DATA);
memset(&txtProviderData, 0, dwProviderLength);
memset(&smscAddress, 0, sizeof(SMS_ADDRESS));
memset(&inAddress, 0, sizeof(SMS_ADDRESS));
memset(&rcvTime, 0, sizeof(SYSTEMTIME));
TCHAR *tchMsgBuffer = pszRecvMsg;
// 把短信從子產品裡讀出來放到buffer裡,執行完以後,tchMsgBuffer裡存放的就是接收到短信的UNICODE編碼
DWORD dwBytesRead = 0;
hRet = SmsReadMessage(
smshRecieveHandle,
&smscAddress,
&inAddress,
&rcvTime,
(LPBYTE)tchMsgBuffer,
dwMessageSize,
(LPBYTE)&txtProviderData,
dwProviderLength,
&dwBytesRead
);
SmsClose(smshHandle);
SmsClose(smshRecieveHandle);
smshHandle = NULL;
if(FAILED(hRet))
{
return FALSE;
}
return TRUE;
}
CString GetSMSCenterPhone()
{
CString strSmsCenter;
SMS_ADDRESS smsaCenter;
UINT hRet = SmsGetSMSC(&smsaCenter);
if(FAILED(hRet))
{
return _T("");
}
strSmsCenter = smsaCenter.ptsAddress;
return strSmsCenter;
}
//格式轉換
CString abc;
TCHAR *pData = (TCHAR*)(LPCTSTR)abc;
調用方式:
void test()
{
#ifdef SENDMODE
SendSMS(true,true,_T("138xxxxxxxx"),_T("+86136xxxxxxxx"),_T("測試.短信發送成功."));
#else
int nRecvLen = MAXLEN;
TCHAR *pRecvBuf = NULL;
pRecvBuf = (TCHAR *)LocalAlloc(LPTR,nRecvLen*sizeof(TCHAR));
if(!pRecvBuf)
{
RecvSMS(pRecvBuf,nRecvLen);
}
LocalFree(pRecvBuf);
pRecvBuf = NULL;
#endif
}
補充下,上面的是在手機發送給手機的情況下成功了,下面的就是在一個短信中心項目中測試的情況.(沒有想到短信中心和一般手機上的情況不一樣的.唉)
bool CUserSMSRegisterView::SendSMS(bool bSendConfirmation,bool bUseDefaultSMSC,TCHAR* pszCenterPhone,TCHAR * pszDUserPhone,TCHAR* pszMessage)
{
//SendMessage(NN_MESSAGE, NNF_STATUS_NOTIFY,NULL);
SMS_HANDLE smshHandle;
SMS_ADDRESS smsaSource;
SMS_ADDRESS smsaDestination;
TEXT_PROVIDER_SPECIFIC_DATA tpsd;
SMS_MESSAGE_ID smsmidMessageID=0;
HRESULT hr=0;
//TCHAR *lpszMessage = _T("ZXZQ");
TCHAR *lpszMessage = pszMessage;
// 打開SMS
if(FAILED(SmsOpen(SMS_MSGTYPE_TEXT, SMS_MODE_SEND, &smshHandle, NULL)))
{
CSNormalView::CloseNotify();
ShowMessage(_T("SmsOpen 失敗."));
return false;
}
建立短信中心位址(号碼)
;
//_tcsncpy(smsaSource.ptsAddress, pszCenterPhone, SMS_MAX_ADDRESS_LENGTH);
//}
//if(!bUseDefaultSMSC)
//{
// smsaSource.smsatAddressType = SMSAT_NATIONAL;
// _tcsncpy(smsaSource.ptsAddress, _T("13800755500"), SMS_MAX_ADDRESS_LENGTH);
//}
// 建立目标位址(号碼)
memset (&smsaDestination, 0, sizeof (smsaDestination));
smsaDestination.smsatAddressType = SMSAT_NATIONAL;
_tcsncpy(smsaDestination.ptsAddress, pszDUserPhone, SMS_MAX_ADDRESS_LENGTH);
//_tcsncpy(smsaDestination.ptsAddress, _T("955580788"), SMS_MAX_ADDRESS_LENGTH);
// 設定提供者服務
memset (&tpsd, 0, sizeof (tpsd));
//tpsd.dwMessageOptions = bSendConfirmation ? PS_MESSAGE_OPTION_STATUSREPORT : PS_MESSAGE_OPTION_NONE;
tpsd.dwMessageOptions = PS_MESSAGE_OPTION_NONE;
tpsd.psMessageClass = PS_MESSAGE_CLASSUNSPECIFIED;
tpsd.psReplaceOption = PSRO_NONE;
tpsd.dwHeaderDataSize = 0;
ZeroMemory(tpsd.pbHeaderData, sizeof(tpsd.pbHeaderData));
tpsd.dwHeaderDataSize = 0;
tpsd.fMessageContainsEMSHeaders = FALSE;
tpsd.dwProtocolID = SMS_MSGPROTOCOL_UNKNOWN;
// 發送
if(SUCCEEDED(hr=SmsSendMessage(smshHandle,NULL,
&smsaDestination, NULL, (PBYTE) lpszMessage,
_tcslen(lpszMessage) * sizeof(TCHAR), (PBYTE) &tpsd,
sizeof(TEXT_PROVIDER_SPECIFIC_DATA), SMSDE_OPTIMAL,
SMS_OPTION_DELIVERY_NONE, &smsmidMessageID)))
{
//::MessageBox(NULL,_T("發送成功"),_T("提示"),MB_OK);
}
else
{
VERIFY(SUCCEEDED(SmsClose(smshHandle)));
CSNormalView::CloseNotify();
ShowMessage(_T("發送失敗"));
return false;
}
//關閉
VERIFY(SUCCEEDED(SmsClose(smshHandle)));
//CSNormalView::CloseNotify();
ShowMessage(_T("短信發送成功"));
return true;
}
SendSMS(true,true,_T("13800755500"),_T("9555xxxx"),_T("ZXZQ"));
//以下是相關資料
#include <sms.h> //要支援短信發送就要包含sms.h頭檔案和庫檔案
#pragma comment(lib,"sms.lib")
void SendSMS1(LPCTSTR lpszMessage, LPCTSTR lpszRecipient,LPCTSTR lpszSMSC,BOOL bSendConfirmation, BOOL bUseDefaultSMSC)
{
SMS_HANDLE smshHandle; //短信句柄
SMS_ADDRESS smsaDestination;//接收号碼
TEXT_PROVIDER_SPECIFIC_DATA tpsd;
SMS_MESSAGE_ID smsmidMessageID;
// 打開發送句柄
// 協定字元串,SMS_MODE_SEND:發送模式 psmshHandle:傳回的句柄 phMessageAvailableEvent:通知的事件
if(FAILED(SmsOpen(SMS_MSGTYPE_TEXT, SMS_MODE_SEND, &smshHandle, NULL)))
{
return;
}
// Create the destination address
//SMSAT_NATIONAL:國内電話 SMSAT_INTERNATIONAL:國際電話
smsaDestination.smsatAddressType = SMSAT_UNKNOWN;
_tcsncpy(smsaDestination.ptsAddress, lpszRecipient, SMS_MAX_ADDRESS_LENGTH);
// Set up provider specific data
memset(&tpsd, 0, sizeof(tpsd));
//tpsd.dwMessageOptions = PS_MESSAGE_OPTION_NONE;//表示不需要狀态報告
tpsd.dwMessageOptions = PS_MESSAGE_OPTION_STATUSREPORT;//表示需要狀态報告
tpsd.psMessageClass = PS_MESSAGE_CLASSUNSPECIFIED; //短信中心不需要特别設定的
//PS_MESSAGE_CLASS0表示短信在被接收後立即顯示且不存儲在收件箱(稱為閃信)
//PS_MESSAGE_CLASS1表示一般的情況,被接收後存儲到收件箱并發送一個确認回短信中心,發送方收到一個已被接收的狀态報告。
tpsd.psReplaceOption = PSRO_NONE;
//手動清空頭資訊
ZeroMemory(tpsd.pbHeaderData, sizeof(tpsd.pbHeaderData));
tpsd.dwHeaderDataSize = 0;
tpsd.fMessageContainsEMSHeaders = FALSE;
tpsd.dwProtocolID = SMS_MSGPROTOCOL_UNKNOWN;
// Send the message, indicating success or failure
/*
*smshHandle: SmsOpen打開的句柄