Win Mobile利用mapirule接收短信

来源:互联网 发布:风行电影软件下载 编辑:程序博客网 时间:2024/05/22 03:23

一。在能够使用 MAPI 规则客户端之前,我们需要将其注册为 COM 对象,同时将它的类标识符添加到下面的注册表项中:HKEY_CLASSES_ROOT/CLSID/。为了使收件箱意识到 MAPI 规则客户端的存在,我们还必须将它的类标识符写入下面的注册表项中: HKEY_LOCAL_MACHINE/Software/Microsoft/Inbox/Svc/SMS/Rules。

 

//注册为COM对象

    lr = RegCreateKeyEx(HKEY_CLASSES_ROOT, TEXT("//CLSID//{3AB4C10E-673C-494c-98A2-CC2E91A48115}"),
                               0, NULL, 0, 0, NULL,
                               &hKey, &dwDisposition);

    lr = RegCreateKeyEx(hKey, TEXT("InprocServer32"),
                               0, NULL, 0, 0, NULL,
                               &hSubKey, &dwDisposition);

    lstrcpy(wszValue, TEXT("//windows//mapirule.dll"));
    lr = RegSetValueEx(hSubKey, NULL, 0, REG_SZ, (LPBYTE) wszValue, (lstrlen(wszValue) + 1) * sizeof(TCHAR));

   //注册到Inbox:

   lr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("//Software//Microsoft//Inbox//Svc//SMS//Rules"),
                               0, NULL, 0, 0, NULL,
                               &hKey, &dwDisposition);

    lr = RegSetValueEx(hKey, TEXT("{3AB4C10E-673C-494c-98A2-CC2E91A48115}"), 0, REG_DWORD,
                          (LPBYTE) &dwDisposition, sizeof(DWORD));

二。注册成功后系统会自动调用函数ProcessMessage接收短信,当接收到短信内容是"zzz"时放入内存映射文件中(还有其它方法传递给应用程序,比如消息等),然后删除该短信。

 

HRESULT CMailRuleClient::ProcessMessage(IMsgStore *pMsgStore, ULONG cbMsg, LPENTRYID lpMsg,
            ULONG cbDestFolder, LPENTRYID lpDestFolder, ULONG *pulEventType, MRCHANDLED *pHandled)
{
    HRESULT hr = S_OK;
    SizedSPropTagArray(1, sptaSubject) = { 1, PR_SUBJECT};
  SizedSPropTagArray(1, sptaEmail) = { 1, PR_SENDER_EMAIL_ADDRESS};
    ULONG cValues = 0;
    SPropValue *pspvSubject = NULL;
 SPropValue *pspvEmail = NULL;
    IMessage *pMsg = NULL;
    HRESULT hrRet = S_OK;

    // Get the message from the entry ID
    hr = pMsgStore->OpenEntry(cbMsg, lpMsg, NULL, 0, NULL, (LPUNKNOWN *) &pMsg);
    if (FAILED(hr))
    {
       
  RETAILMSG(TRUE, (TEXT("Unable to get the message!/r/n")));
       goto Exit;
    }
   
    // For SMS, the subject is also the message body
    hr = pMsg->GetProps((SPropTagArray *) &sptaSubject, MAPI_UNICODE, &cValues, &pspvSubject);
 if (FAILED(hr))
    {
       
  RETAILMSG(TRUE, (TEXT("Unable to get the message body!/r/n")));
       goto Exit;
    }
 // get the sender's address or phone number
 hr = pMsg->GetProps((SPropTagArray *) &sptaEmail, MAPI_UNICODE, &cValues, &pspvEmail);

    if (FAILED(hr))
    {
       
        RETAILMSG(TRUE, (TEXT("Couldn't get the sender's address!/r/n")));

        goto Exit;
    }
 
 // Here we filter the message on some predetermined string. For sample purposes
 // here we use "zzz". What happens when the filter condition(s) are met is up to
 // you. You can send WM_COPYDATA messages to other app windows for light IPC, send
 // an SMS message in response, or whatever you need to do.

 if (wcsstr(pspvSubject->Value.lpszW, L"zzz") != NULL)
 {
  if (g_hSmsAvailableEvent != NULL) {
   // We have received an SMS message that needs to be send to our client.
   // Since we run in the process space of Inbox, we are using a memory mapped
   // file to pass the message and phone number to our client, that typically
   // runs in another process space (therefor we can not simply copy strings).
   // We protect the memory mapped file with a Mutex to make sure that we are
   // not writing new SMS data while the reading client is still processing
   // a previous SMS message.
   WaitForSingleObject(g_hMutex, INFINITE);
   lstrcpy(g_pSmsBuffer->g_szPhoneNr, pspvEmail->Value.lpszW);
   lstrcpy(g_pSmsBuffer->g_szMessageBody, pspvSubject->Value.lpszW);
   ReleaseMutex(g_hMutex);
   SetEvent(g_hSmsAvailableEvent);
  }
 
  // Delete the message and mark it as handled so it won't show up in Inbox
  hr = DeleteMessage(pMsgStore, pMsg, cbMsg, lpMsg, cbDestFolder, lpDestFolder, pulEventType, pHandled);
 }
 else
 {
  // a 'normal' message, pass it on
  *pHandled = MRC_NOT_HANDLED;
 }

// Clean up
Exit:
    if (pspvEmail)
    {
        MAPIFreeBuffer(pspvEmail);
    }
 if (pspvSubject)
    {
        MAPIFreeBuffer(pspvSubject);
    }
    if (pMsg)
    {
        pMsg->Release();
    }
   

    return hr;
}

三。应用程序监听内存映射文件(调用TerminateSMSMessagePassing )void TerminateSMSMessagePassing (void)
{
 // Make sure to have one last empty string available to copy to the client.
 memset(g_pClientSmsBuffer, 0, sizeof(SMS_BUFFER));

 SetEvent(g_hClientEvent);    // optionally allow the calling application to  return from GetData.
 CloseHandle(g_hClientEvent);
 CloseHandle(g_hClientMutex);

 if (g_pClientSmsBuffer) {
  UnmapViewOfFile(g_pClientSmsBuffer);
  g_pClientSmsBuffer = NULL;
 }
 if (g_hClientMMObj) {
  CloseHandle(g_hClientMMObj);
  g_hClientMMObj = NULL;
 }
}

四。应用得到短信内容和发短信的号(调用SMSMessageAvailable )

BOOL SMSMessageAvailable (wchar_t *lpDestination, wchar_t *lpPhoneNr)
{
 WaitForSingleObject(g_hClientEvent, INFINITE);

 if (g_pClientSmsBuffer != NULL) {
  WaitForSingleObject(g_hClientMutex, INFINITE);
  lstrcpy(lpPhoneNr, g_pClientSmsBuffer->g_szPhoneNr);
  lstrcpy(lpDestination, g_pClientSmsBuffer->g_szMessageBody);
  ReleaseMutex(g_hClientMutex);
 } else {
  *lpPhoneNr = '/0';
  *lpDestination = '/0';
 }
 return *lpPhoneNr != '/0';
}

五。注销MailRuleClient对象

STDAPI DllUnregisterServer()
{
    HKEY hKey = NULL;
    HRESULT hr = E_FAIL;
    LRESULT lr;
    DWORD dwDisposition;

    // Delete registry keys
    RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("//CLSID//{3AB4C10E-673C-494c-98A2-CC2E91A48115}"));
   
    lr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("//Software//Microsoft//Inbox//Svc//SMS//Rules"),
                               0, NULL, 0, 0, NULL,
                               &hKey, &dwDisposition);
    if (lr != ERROR_SUCCESS)
    {
        goto Exit;
    }

    lr = RegDeleteValue(hKey, TEXT("{3AB4C10E-673C-494c-98A2-CC2E91A48115}"));

    hr = S_OK;

Exit:
    if (hKey)
    {
        RegCloseKey(hKey);
    }

    return hr;
}

六。在C++中调用过程如下:

HINSTANCE hInstLibrary = LoadLibrary(_T("//windows//mapirule.dll"));
 if (hInstLibrary == NULL)  {
  FreeLibrary(hInstLibrary);
  return 0;
 }

//注册

 if (DllRegisterServer() == 0)
 {
  MessageBox("Could not initialize the IMailRuleClient DLL");
  FreeLibrary(hInstLibrary);
  return 0;
 }

   CaptureSMSMessages();
   while(true){
     SMSMessageAvailable(lpDestination,lpPhoneNr);
     if(*lpDestination != '/0'){
      OutputDebugString(lpDestination);
      break;
     }
    }

TerminateSMSMessagePassing();

 DllUnregisterServer();
 FreeLibrary(hInstLibrary);

七。在C#中调用//导入库文件

  #region P/Invoke helpers
  [DllImport("mapirule.dll")]
  public static extern int DllRegisterServer();
  [DllImport("mapirule.dll")]
  public static extern void DllUnregisterServer();
  [DllImport("coredll.dll")]
  public static extern IntPtr LoadLibrary(string libName);
  [DllImport("coredll.dll")]
  public static extern bool FreeLibrary(IntPtr hLibModule);
  #endregion

 public class UnmanagedAPI
 {
  [DllImport("mapirule.dll")]
  public static extern int SMSMessageAvailable(StringBuilder message, StringBuilder phoneNumber);
  [DllImport("mapirule.dll")]
  public static extern void CaptureSMSMessages();
  [DllImport("mapirule.dll")]
  public static extern void TerminateSMSMessagePassing();
 }
 #endregion

//注册

    hLibModule = LoadLibrary("mapirule.dll");
    if (DllRegisterServer() != 0)
    {
     MessageBox.Show("Could not initialize the IMailRuleClient DLL");
    }

//监听并取得消息

UnmanagedAPI.CaptureSMSMessages();

   while (! bDone)
   {
    UnmanagedAPI.SMSMessageAvailable(sbSms, sbPhoneNr);

    if (sbSms.Length != 0)
    {
     parentForm.ReceivedSMSMessage = sbPhoneNr.ToString() + " - " + sbSms.ToString();
     parentForm.Invoke(new EventHandler(parentForm.UpdateListBox));
    }
   }

//注销

DllUnregisterServer();

FreeLibrary(hLibModule);

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/procedurecode/archive/2007/10/23/1839708.aspx

原创粉丝点击