sticky
Visual Studio智能设备开发之Native C++项目常见问题 RRS feed

全部回复

  •  

    1.一个调用了DLL的应用程序在设备上运行时,如何把这个DLL拷贝到设备中?  [回到顶端]

      

    如果你开发一个调用DLLC++应用程序,像MFC应用程序调用Win32DLL. 你不得不把调用 的这个DLL拷贝到设备上。如果不拷,这个MFC应用程序将无法找到这个DLL, 你会得到找不到DLL错误信息,因为MFC应用程序不能把这个Win32DLL自动的部署到设备上。你可以把这个DLL拷贝到下面三个目录下,这三个目录下都能被MFC应用程序找到。

    1.设备根目录: "\\"

    2.设备的 windows目录: \\windows

    3.MFC 应用程序的执行目录: \\Programs Files\\MFCapplicationName

      

    如果你使用LoadLibrary去加载这个Win32DLL, 也是一样的问题,同样需要把DLL拷贝到上面三个目录中的任意一个目录。同样还有P/Invoke 调用的DLL也是一样的问题。

      

    相关的问题:
    http://social.msdn.microsoft.com/forums/en-US/vssmartdevicesnative/thread/994eabde-fd91-45be-9daf-c2f46f2a85d9/

     

    2009年7月13日 14:08
  •  

    2.如何读取联系人的IM字段数据?  [回到顶端]

      

    我们知道,用IPOutlookApp接口可以得到联系人的一些信息。为了这得到这些信息,使用GetDefaultFolder方法得到 contact folder,然用可以用IContact接口得到 联系人的每个字段信息,但是IContact接口没有提供方法去得到IM, NickName相关的信息。

     

    我们可以使用IItem接口,它提供了getprops方法去得到IM,NickName等数据信息。

      

    注意:你必须使用IPOutlookApp2接口,它比IPOutlookApp接口增加了GetItemFromOidEx方法。调用这个方法去得到IItem接口。

     

    下面是一个示例:

      

    void CPoomViewTestDlg::OnBnClickedButton3()

    {

        CoInitializeEx( NULL, 0);

        IPOutlookApp2 * m_Outlook;

     

     

        HRESULT hr = CoCreateInstance(_uuidof(Application),

                          NULL,

                          CLSCTX_INPROC_SERVER,

                          _uuidof(IPOutlookApp),

                          (LPVOID*)&m_Outlook);

     

        m_Outlook->Logon(NULL);

     

        //Search contact only

        IFolder * pFolder=NULL;

        IPOutlookItemCollection *ipItemCollection=NULL;

        m_Outlook->GetDefaultFolder(OlDefaultFolders::olFolderContacts,&pFolder);

     

        int count=0;

        BSTR firstname;

        BSTR strIM;

        if(pFolder)

        {

           pFolder->get_Items(&ipItemCollection);

           if(ipItemCollection)

           {

               ipItemCollection->get_Count(&count);

     

              

               //get first contact information

               IContact *pContact;

               IItem *pItem;

              

               if (SUCCEEDED(ipItemCollection->Item(1,reinterpret_cast<IDispatch**>(&pContact))))

               {

                  CEOID oid = 0;

                  pContact->get_Oid((long*)&oid);

                  //get IItem interface

                  m_Outlook->GetItemFromOidEx(oid, 0, &pItem);

               }

     

        // TO DO: Add your control notification handler code here

       

                HRESULT hr = E_FAIL;

                CEPROPVAL *buf = NULL;

                ULONG cbBuffer = 0;

                HANDLE hHeap = GetProcessHeap();      

                CEPROPID rgPropId[1];

                rgPropId[0]=PIMPR_IM1_ADDRESS;

     

                cbBuffer = 0;

                hr = pItem->GetProps(rgPropId,CEDB_ALLOWREALLOC,1,&buf,&cbBuffer,hHeap);

                CEPROPVAL * ppropval = buf;

                 if(ppropval[0].wFlags!=CEDB_PROPNOTFOUND)

                 {

                       if(LOWORD(ppropval[0].propid) == CEVT_LPWSTR)

                       AfxMessageBox(ppropval[0].val.lpwstr);

                 }

     

               HeapFree(hHeap, 0, buf);

              

               pContact->Release();

               pContact = NULL;

               pItem->Release();

               pItem=NULL;

              

           }

        }

     

           ipItemCollection->Release();

           ipItemCollection=NULL;

           pFolder->Release();

            pFolder = NULL;

           m_Outlook->Logoff();

            m_Outlook->Release();

            m_Outlook = NULL;

     

    }

       

    我们也可以用IItem:Edit去打开联系人修改界面。从上面的代码可以看出IItem的功能比IContact更强,如果IContact不能满足需求,你可以考虑使用IItem,看一下它有没有提供这样的方法。

     

    相关的问题:

    http://social.msdn.microsoft.com/forums/en-US/vssmartdevicesnative/thread/6dab0483-61f5-40f7-9bb7-a4fff54d555d/

    http://social.msdn.microsoft.com/forums/en-US/windowsmobiledev/thread/13bdbcaf-c236-4863-b6dd-64376c7386d8/

      

    2009年7月13日 14:10
  •   

    3.如何使用MAPI去读取emailsSMSs数据信息?  [回到顶端]

      

    首先,我们需要先理解Message Store的概念,Message Store 是和邮件的帐户信息对应的。ActiveSync是默认的Message Store。其它的Message Store需要用户自己手工增加帐户来实现,如果设备支持SMS的话,设备上也会有SMSMessage Store

      

    每一个Message Store包含一个或多个目录,有些目录有特殊的标识符让我们也能容易找到。比如收件箱目录(Inbox)就用一个特殊的标识符:PR_CE_IPM_INBOX_ENTRYID。待发箱(Outbox)的特殊标识符:PR_CE_IPM_DRAFTS_ENTRYID。这些标识符在CEMAPI.H文件中可以找到。

      

    下面是一个示例如何去用MAPI去读取设备上每一个Message Store的信息以各个Message Store 中每一个目录。

      

    void CMAPI6TestDlg::OnBnClickedButton1()

    {

      // TODO: Add your control notification handler code here

         HRESULT hr;

    ICEMAPISession * pSession = NULL;

         SRowSet * pRows = NULL;

         IMsgStore * pStore = NULL;

     

    hr = MAPIInitialize(NULL);

    if (hr != S_OK) {

        // MAPIInitialize failed.

        AfxMessageBox(L"error");

    }

     

    hr = MAPILogonEx(0, NULL, NULL, 0, (LPMAPISESSION *)&pSession);

    if (hr != S_OK) {

       AfxMessageBox(L"error");

    }

      IMAPITable *ptable;

      hr=pSession->GetMsgStoresTable(0,&ptable);

     

         enum{

         ePR_DISPLAY_NAME,

         ePR_ENTRYID,//ePR_CE_UNIQUE_STORE_ID,

         NUM_COLS

         };

     

      SizedSPropTagArray(NUM_COLS,Columns) =

         {  

         NUM_COLS,

         PR_DISPLAY_NAME,

         PR_ENTRYID,

         };

      hr= ptable->SetColumns((LPSPropTagArray)&Columns,0);

      //if(FAILED(hr))AfxMessageBox(L"error"); PR_CE_UNIQUE_STORE_ID

     

      LPENTRYID pEntryId = NULL;

      ULONG cbEntryId = 0;

        IMAPIFolder *pFolder;

      ULONG ulObjType = 0;

      IMAPITable *ptbl;

      SRowSet *prowset = NULL;

      static const SizedSSortOrderSet(1, sortOrderSet) = { 1, 0, 0, { PR_MESSAGE_DELIVERY_TIME, TABLE_SORT_DESCEND } };

      static const SizedSPropTagArray (3, spta) = { 3, PR_SENDER_NAME,PR_SUBJECT,PR_MESSAGE_DELIVERY_TIME };

     

      //hr = ptable->QueryRows(1, 0,&pRows);

     

      while(SUCCEEDED(ptable->QueryRows(1, 0,&pRows)))

      {

         if(pRows->cRows==0)

             return;

     

         //Read message store name

         TCHAR *pszStoreName =pRows->aRow[0].lpProps[0].Value.lpszW;

     

      //get activesync store,email store is 0 index

      hr = pSession->OpenMsgStore(0,

                   pRows->aRow[0].lpProps[1].Value.bin.cb,

                   (ENTRYID *)pRows->aRow[0].lpProps[1].Value.bin.lpb,

                   NULL,

                   0,

                   &pStore);

      

      //Read folder

      LPSPropValue rgprops=NULL;

     

      ULONG cValues;

      ULONG rgTag[]={1,PR_CE_IPM_DRAFTS_ENTRYID}; //You can read any folder with its name tag

     

      hr=pStore->GetProps((LPSPropTagArray)rgTag,MAPI_UNICODE,&cValues,&rgprops);

     

    hr = pStore->OpenEntry(rgprops->Value.bin.cb, (LPENTRYID)rgprops->Value.bin.lpb, NULL, 0, &ulObjType, (LPUNKNOWN*)&pFolder);

     

       hr = pFolder->GetContentsTable(0, &ptbl);

       hr = ptbl->SortTable((SSortOrderSet *)&sortOrderSet, 0);

     

       hr = ptbl->SetColumns ((SPropTagArray *) &spta, 0);

     

        // iterate through each message in the table

       while (TRUE)

        {

     

            // Free the previous row

            FreeProws (prowset);

            prowset = NULL;

     

            hr = ptbl->QueryRows (1, 0, &prowset);

            if ((hr != S_OK) || (prowset == NULL) || (prowset->cRows == 0))

                break;

     

            ASSERT (prowset->aRow[0].cValues == spta.cValues);

            SPropValue *pval = prowset->aRow[0].lpProps;

     

            //Read Email filed value, which is correspond with spta

            LPCTSTR pszSender = pval[0].Value.lpszW;

            LPCTSTR pszSubject = pval[1].Value.lpszW;

            LPCTSTR time=pval[2].Value.lpszW;       

     

        }

     

      }

     

      //Release

      FreeProws(pRows);

      ptbl->Release();

      ptbl=NULL;

      pFolder->Release();

      pFolder=NULL;

      pStore->Release();

      pStore=NULL;

     

    }

     

    相关的问题:

    http://social.msdn.microsoft.com/forums/en-US/vssmartdevicesnative/thread/60045e0b-2d5b-419d-a3ff-9ee1ec5e867c/

     

    2009年7月13日 14:11
  •   

    4.如何让设备全屏显示?  [回到顶端]

     

    Pocket PC界面包含下面几个方面(除了主屏面)

     

    任务栏,在屏面的最上面,显示应用程序的标题,也有开始菜单。

    命令栏,也叫菜单栏。在屏幕的下面。

    软键盘(SIP)按钮,在在命令栏的上。

      

    为了创建一个能尽量使用多空间的窗口,调用SHFullScreen方法去隐藏界面上的一些信息。然后调用ShowWindows方法隐藏命令栏(Command bar),然后用MoveWindow方法来调用当前窗口),下面是一个代码示例:

     

        DWORD dwState = SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON;

        SHFullScreen(this->m_hWnd,dwState);

     

        //You can hide the menu bar using one of the following ways

        ::ShowWindow(SHFindMenuBar(this->m_hWnd),SW_HIDE);

        ::ShowWindow(FindWindow(L"menu_worker",NULL)->m_hWnd,SW_HIDE);

     

        //Move current window out of screen

        RECT rc; 

    SetRect(&rc,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));

     

        ::MoveWindow( this->m_hWnd,

            rc.left, rc.top,

            rc.right, rc.bottom,

            FALSE);

      

    相关的问题:

    http://social.msdn.microsoft.com/forums/en-US/vssmartdevicesnative/thread/9e68103a-5d52-4f50-ac3a-b2e73e56666c/
    http://social.msdn.microsoft.com/forums/en-US/vssmartdevicesnative/thread/b55c28bb-1695-4755-846f-12456150d414/

    http://social.msdn.microsoft.com/forums/en-US/vssmartdevicesnative/thread/e042f3a7-cece-4139-8f52-25f522a22e2a/

     

    2009年7月13日 14:15
  •  

    5.如何得到Windows Mobile 手机号码?  [回到顶端]

     

    一些手机设备的电话号码存储在SIM卡中,有些不是,这是由SIM的供应商决定的。如果号码存储在SIM卡中,我们可以用以下的方法得到它:

    首先可以用SmsGetPhoneNumber方法得到

    其它可以调用 lineGetDevCaps方法得到它

      

    下面是一个从SDK中的示例,它用 lineGetDevCaps来得到电话号码:

      

    #include "stdafx.h"

    #include "windows.h"

    #include "tapi.h"

    #include "tsp.h"

    #include <windows.h>

     

    #define EXIT_ON_NULL(_p)     \

        if (_p == NULL)    \

    {   \

        hr = E_OUTOFMEMORY; \

        goto FuncExit; \

    }

     

    #define EXIT_ON_FALSE(_f)     \

        if (!(_f))    \

    {   \

        hr = E_FAIL; \

        goto FuncExit; \

    }

     

    #define TAPI_API_LOW_VERSION   0x00020000

    #define TAPI_API_HIGH_VERSION  0x00020000

     

    #define CAPS_BUFFER_SIZE    512

     

    #define MAX_LOADSTRING 25

     

    TCHAR szNumber[MAX_LOADSTRING];

    HRESULT SHGetPhoneNumber(LPTSTR szNumber, UINT cchNumber, UINT nLineNumber);

     

    /////////////////////////////////////////////////////////////////////////////

    // WinMain

    /////////////////////////////////////////////////////////////////////////////

    int WINAPI WinMain(HINSTANCE hInstance,

                       HINSTANCE hPrevInstance,

                       LPTSTR  lpCmdLine,

                       int   nCmdShow)

    {

        SHGetPhoneNumber(szNumber, MAX_LOADSTRING, 1);//getting phone number of line 1

        MessageBox(NULL, szNumber, TEXT("Phone Number"), MB_OK);

        return 0;

    }

    /////////////////////////////////////////////////////////////////////////////

    // Function: SHGetPhoneNumber

    // szNumber - Out Buffer for the phone number

    // cchNumber - size of sznumber in characters

    // nLineNumber - In which phone line (1 or 2) to get the number for

    /////////////////////////////////////////////////////////////////////////////

    HRESULT SHGetPhoneNumber(LPTSTR szNumber, UINT cchNumber, UINT nLineNumber)

    {

        HRESULT  hr = E_FAIL;

        LRESULT  lResult = 0;

        HLINEAPP hLineApp;

        DWORD    dwNumDevs;  //number of line devices

        DWORD    dwAPIVersion = TAPI_API_HIGH_VERSION;

        LINEINITIALIZEEXPARAMS liep;

     

        DWORD dwTAPILineDeviceID;

        const DWORD dwAddressID = nLineNumber - 1;

     

        liep.dwTotalSize = sizeof(liep);

        liep.dwOptions   = LINEINITIALIZEEXOPTION_USEEVENT;

     

        //initialize line before accessing

        if (SUCCEEDED(lineInitializeEx(&hLineApp, 0, 0, TEXT("ExTapi_Lib"), &dwNumDevs, &dwAPIVersion, &liep)))

        {

     

            BYTE* pCapBuf = NULL;

            DWORD dwCapBufSize = CAPS_BUFFER_SIZE;

            LINEEXTENSIONID  LineExtensionID;

            LINEDEVCAPS*     pLineDevCaps = NULL;

            LINEADDRESSCAPS* placAddressCaps = NULL;

     

            pCapBuf = new BYTE[dwCapBufSize];

            EXIT_ON_NULL(pCapBuf);

     

            pLineDevCaps = (LINEDEVCAPS*)pCapBuf;

            pLineDevCaps->dwTotalSize = dwCapBufSize;

     

            // Get TSP Line Device ID

            dwTAPILineDeviceID = 0xffffffff;

            for (DWORD dwCurrentDevID = 0 ; dwCurrentDevID < dwNumDevs ; dwCurrentDevID++)

            {

                //ensure TAPI, service provider, and application are all using the same versions

                if (0 == lineNegotiateAPIVersion(hLineApp, dwCurrentDevID, TAPI_API_LOW_VERSION, TAPI_API_HIGH_VERSION,

                    &dwAPIVersion, &LineExtensionID))

                {

                    lResult = lineGetDevCaps(hLineApp, dwCurrentDevID, dwAPIVersion, 0, pLineDevCaps);

     

                    //increase buffer size if too small to hold the device capabilities

                    if (dwCapBufSize < pLineDevCaps->dwNeededSize)

                    {

                        delete[] pCapBuf;

                        dwCapBufSize = pLineDevCaps->dwNeededSize;

                        pCapBuf = new BYTE[dwCapBufSize];

                        EXIT_ON_NULL(pCapBuf);

     

                        pLineDevCaps = (LINEDEVCAPS*)pCapBuf;

                        pLineDevCaps->dwTotalSize = dwCapBufSize;

     

                        lResult = lineGetDevCaps(hLineApp, dwCurrentDevID, dwAPIVersion, 0, pLineDevCaps);

                    }

                    //lResult of 0 means the device capabilities were successfully returned

                    if ((0 == lResult) &&

                        (0 == _tcscmp((TCHAR*)((BYTE*)pLineDevCaps+pLineDevCaps->dwLineNameOffset), CELLTSP_LINENAME_STRING)))

                    {

                        dwTAPILineDeviceID = dwCurrentDevID;

                        break;

                    }

                }

            }

     

            placAddressCaps = (LINEADDRESSCAPS*)pCapBuf;

            placAddressCaps->dwTotalSize = dwCapBufSize;

     

            lResult = lineGetAddressCaps(hLineApp, dwTAPILineDeviceID, dwAddressID, dwAPIVersion, 0, placAddressCaps);

     

            //increase buffer size if too small to hold the address capabilities

            if (dwCapBufSize < placAddressCaps->dwNeededSize)

            {

                delete[] pCapBuf;

                dwCapBufSize = placAddressCaps->dwNeededSize;

                pCapBuf = new BYTE[dwCapBufSize];

                EXIT_ON_NULL(pCapBuf);

     

                placAddressCaps = (LINEADDRESSCAPS*)pCapBuf;

                placAddressCaps->dwTotalSize = dwCapBufSize;

     

                lResult = lineGetAddressCaps(hLineApp, dwTAPILineDeviceID, dwAddressID, dwAPIVersion, 0, placAddressCaps);

            }

            //lResult of 0 means the address capabilities were successfully returned

            if (0 == lResult)

            {

                if (szNumber)

                {

                    szNumber[0] = TEXT('\0');

     

                    EXIT_ON_FALSE(0 != placAddressCaps->dwAddressSize);

     

                    // A non-zero dwAddressSize means a phone number was found

                    ASSERT(0 != placAddressCaps->dwAddressOffset);

                    PWCHAR tsAddress = (WCHAR*)(((BYTE*)placAddressCaps)+placAddressCaps->dwAddressOffset);

     

                    StringCchCopy(szNumber, cchNumber, tsAddress);

                }

     

                hr = S_OK;

            }

     

            delete[] pCapBuf;

        } // End if ()

     

    FuncExit:

        lineShutdown(hLineApp);

     

        return hr;

    }

     

    相关的问题:

    http://social.msdn.microsoft.com/forums/en-US/vssmartdevicesnative/thread/f4bcfde9-22ae-4608-926a-14eb14744072/

    http://social.msdn.microsoft.com/forums/en-US/netfxcompact/thread/916958b4-b94d-46ca-a064-ef8ee4af26aa/

     

    2009年7月13日 14:16
  •  

    6.如何用读取POOM的信息,比如:联系人,约会和任务  [回到顶端]

      

    我们可以用‘IPOutlookApp: GetDefaultFolder’得到contact folder。一旦我们得到了contact folder,我们可以IFolder:get_Items方法得到这个目录下所有项目,下面的代码是是刚讲的方法来读取联系人的信息。读取约会和任务信息,也是类似的方法。只是要取它们自己的folder: appointment folder, task folder.

     

    void CPoomViewTestDlg::OnBnClickedButton1()

    {

      // TODO: Add your control notification handler code here

     

     

      IPOutlookApp * m_Outlook;

     

    //hr=CoCreateInstance(CLSID_Application,NULL,CLSCTX_INPROC_SERVER,IID_IPOutlookApp,reinterpret_cast<void **>(&m_Outlook));

     

      HRESULT hr = CoCreateInstance(CLSID_Application,

                          NULL,

                          CLSCTX_INPROC_SERVER,

                          IID_IPOutlookApp,

                          (LPVOID*)&m_Outlook);

       hr = CoCreateInstance(_uuidof(Application),

                          NULL,

                          CLSCTX_INPROC_SERVER,

                          _uuidof(IPOutlookApp),

                          (LPVOID*)&m_Outlook);

     

     

      m_Outlook->Logon(NULL);

     

      //Search contact only

      IFolder * pFolder=NULL;

      IPOutlookItemCollection *ipItemCollection=NULL;

      m_Outlook->GetDefaultFolder(OlDefaultFolders::olFolderContacts,&pFolder);

     

      int count=0;

      BSTR firstname;

      BSTR lastname;

      if(pFolder)

      {

          pFolder->get_Items(&ipItemCollection);

          if(ipItemCollection)

          {

             ipItemCollection->get_Count(&count);

     

     

             //enumerate all contacts

             for(int i=1;i<=count;i++)

             {

                 IContact *pconApp;

                 ipItemCollection->Item(i,reinterpret_cast<IDispatch**>(&pconApp));

                 pconApp->get_FirstName(&firstname);

                 pconApp->get_LastName(&lastname);

     

                 pconApp->Release();

                 pconApp=NULL;

             }

     

             ipItemCollection->Release();

             ipItemCollection=NULL;

          }

          pFolder->Release();

          pFolder=NULL;

            

         m_Outlook->Release();

         m_Outlook=NULL;

     

       }

    }

      

    相关的问题:

    http://social.msdn.microsoft.com/forums/en-US/vssmartdevicesnative/thread/e04e6408-03b7-4fc9-8393-bbb2d6167aa9/

    http://social.msdn.microsoft.com/forums/en-US/vssmartdevicesnative/thread/575c7178-dd95-43b6-9595-0791d7f0a0ea/

     

    2009年7月13日 14:17
  •  

    7.如何控件设备的背光  [回到顶端]

     

    没有标准的API来控件Windows Mobile 设备的背光,这是由OEM自己实现的,但是对于一些设备,我们可以通过修改注册表来控制背光。

      

    背光的注册表路径:

     KEY: HKEY_CURRENT_USER\ControlPanel\BackLight \acBrightness

     

    我们只修改这个值,就可以改变背光的强弱。

     

    注意:修改注册表信息能改变背光的强弱,有些设备需要重启来能改变背光的调整。

     

    相关的问题:

    http://social.msdn.microsoft.com/forums/en-US/vssmartdevicesnative/thread/fe8d1f61-686b-4f67-a127-44952ce9837b/

    http://social.msdn.microsoft.com/forums/en-US/vssmartdevicesnative/thread/e73b2ca8-dc45-4bec-a35f-5c52865a6920/

     

    2009年7月13日 14:17