在 Windows CE 应用程序将不会调用 RAPI 函数。
知道大家不想看文字,直接上示例(功能:复制文件到设备上)代码:
RAPI 被封装为一个类,先看头文件。
CeRAPI.h
// CeRAPI.h: interface for the CeRAPI class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_VOGUERAPI_H__10D13979_C6F2_4922_A4D7_B105644F969F__INCLUDED_) #define AFX_VOGUERAPI_H__10D13979_C6F2_4922_A4D7_B105644F969F__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define BUFFER_SIZE 10240 typedef struct _RAPIINIT { DWORD cbSize; HANDLE heRapiInit; HRESULT hrRapiInit; } RAPIINIT; typedef struct _CE_FIND_DATA { DWORD dwFileAttributes; FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; DWORD nFileSizeHigh; DWORD nFileSizeLow; DWORD dwOID; WCHAR cFileName[MAX_PATH]; } CE_FIND_DATA, *LPCE_FIND_DATA; class CCeRAPI { public: HINSTANCE hInst; typedef HANDLE (FAR PASCAL * pfnFunc0)(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); typedef BOOL (FAR PASCAL * pfnFunc1)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED); typedef BOOL (FAR PASCAL * pfnFunc2)(HANDLE); typedef HANDLE (FAR PASCAL * pfnFunc3)(LPCWSTR, LPCE_FIND_DATA); typedef DWORD (FAR PASCAL * pfnFunc4)(HANDLE, LPDWORD); typedef BOOL (FAR PASCAL * pfnFunc5)(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); typedef BOOL (FAR PASCAL * pfnFunc6)(HANDLE, LPCE_FIND_DATA); typedef BOOL (FAR PASCAL * pfnFunc7)(LPCWSTR, LPSECURITY_ATTRIBUTES); typedef BOOL (FAR PASCAL * pfnFunc8)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPWSTR, LPSTARTUPINFO, LPPROCESS_INFORMATION); typedef VOID (FAR PASCAL * pfnFunc9)(LPSYSTEM_INFO); typedef HRESULT (FAR PASCAL *pfnFnucA)(RAPIINIT*); typedef BOOL (FAR PASCAL *pfnFuncB)(LPCWSTR,LPCWSTR,BOOL); typedef DWORD (FAR PASCAL *pfnFuncC)(); typedef HRESULT (FAR PASCAL *pfnFuncD)(); pfnFunc0 CeCreateFile; pfnFunc1 CeWriteFile; pfnFunc2 CeCloseHandle; pfnFunc3 CeFindFirstFile; pfnFunc4 CeGetFileSize; pfnFunc5 CeReadFile; pfnFunc6 CeFindNextFile; pfnFunc7 CeCreateDirectory; pfnFunc8 CeCreateProcess; pfnFunc9 CeGetSystemInfo; FARPROC CeRapiUninit; //FARPROC CeRapiInit; pfnFuncB CeCopyFile; pfnFuncC CeGetLastError; pfnFuncD CeRapiGetError; //Leo Add pfnFnucA CeRapiInitEx; BOOL m_bRapiInitFlag; BOOL RapiConnectDevice(); BOOL CopyFiletoWinCE(CString strFileNamePC, CString strFileNamePPC); BOOL CCeRAPI::CopyFiletoPC(CString csCEFilename,CString csPCFilename); BOOL InitRapi(); // CString GetCStringFromFile(CString strFileName); CCeRAPI(); virtual ~CCeRAPI(); }; #endif // !defined(AFX_VOGUERAPI_H__10D13979_C6F2_4922_A4D7_B105644F969F__INCLUDED_)
// CeRAPI.cpp: implementation of the CeRAPI class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "RapiTest.h" #include "CeRAPI.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CCeRAPI::CCeRAPI() { m_bRapiInitFlag = FALSE; } CCeRAPI::~CCeRAPI() { } BOOL CCeRAPI::InitRapi() { LPTSTR pDllPath = new TCHAR[MAX_PATH + 10]; GetSystemDirectory(pDllPath, MAX_PATH); CString strDllPathName(pDllPath); strDllPathName += "\\Rapi.dll"; TRACE("%s\n",strDllPathName); //C:\WINDOWS\system32\rapi.dll hInst = LoadLibrary(strDllPathName); if(hInst) { //CeRapiInit = (FARPROC) GetProcAddress(hInst, "CeRapiInit"); CeRapiInitEx = (pfnFnucA) GetProcAddress(hInst, "CeRapiInitEx"); CeRapiUninit = (FARPROC) GetProcAddress(hInst, "CeRapiUninit"); CeCreateFile = (pfnFunc0)GetProcAddress(hInst, "CeCreateFile"); CeWriteFile = (pfnFunc1)GetProcAddress(hInst, "CeWriteFile"); CeCloseHandle = (pfnFunc2)GetProcAddress(hInst, "CeCloseHandle"); CeFindFirstFile = (pfnFunc3)GetProcAddress(hInst, "CeFindFirstFile"); CeGetFileSize = (pfnFunc4)GetProcAddress(hInst, "CeGetFileSize"); CeReadFile = (pfnFunc5)GetProcAddress(hInst, "CeReadFile"); CeFindNextFile = (pfnFunc6)GetProcAddress(hInst, "CeFindNextFile"); CeCreateDirectory = (pfnFunc7)GetProcAddress(hInst, "CeCreateDirectory"); CeCreateProcess = (pfnFunc8)GetProcAddress(hInst, "CeCreateProcess"); CeGetSystemInfo = (pfnFunc9)GetProcAddress(hInst, "CeGetSystemInfo"); CeCopyFile = (pfnFuncB)GetProcAddress(hInst, "CeCopyFile"); CeGetLastError = (pfnFuncC)GetProcAddress(hInst, "CeGetLastError"); CeRapiGetError = (pfnFuncD)GetProcAddress(hInst, "CeRapiGetError"); return TRUE; } else { FreeLibrary(hInst); return FALSE; } return FALSE; } BOOL CCeRAPI::CopyFiletoPC(CString csCEFilename,CString csPCFilename) { HANDLE hCEFile; DWORD dwFileSize = 0; int iFileBlockSize = 0; DWORD dwBytes = 0; char cBlockSize[BUFFER_SIZE]; int i = 0; DWORD dwSizeRet = 0 ; CFile PCFile; BSTR bstr = csCEFilename.AllocSysString(); SysFreeString(bstr); hCEFile = CeCreateFile(bstr, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(INVALID_HANDLE_VALUE == hCEFile) { TRACE("==Fail to open device file:%d\n",GetLastError()); return FALSE; } dwSizeRet = CeGetFileSize(hCEFile,&dwFileSize); TRACE("==Read file size return value:%d\n",dwSizeRet); dwFileSize = dwSizeRet + (dwFileSize << 32); iFileBlockSize = dwFileSize / BUFFER_SIZE; PCFile.Open(csPCFilename,CFile::modeReadWrite | CFile::typeBinary | CFile::modeCreate); for(i = 0;i < iFileBlockSize;i++) { memset(cBlockSize,0,sizeof(char) * BUFFER_SIZE); CeReadFile(hCEFile,cBlockSize,BUFFER_SIZE,&dwBytes,NULL); PCFile.Write(cBlockSize,BUFFER_SIZE); } if(0 != dwFileSize % BUFFER_SIZE) { memset(cBlockSize,0,sizeof(char) * BUFFER_SIZE); CeReadFile(hCEFile,cBlockSize,dwFileSize % BUFFER_SIZE,&dwBytes,NULL); PCFile.Write(cBlockSize,dwFileSize % BUFFER_SIZE); } CeCloseHandle(hCEFile); PCFile.Close(); return TRUE; } BOOL CCeRAPI::CopyFiletoWinCE(CString csPCFilename, CString csCEFilename) { CFile PCFile; HANDLE hCEFile; char cTemp[BUFFER_SIZE]; DWORD dwBytes = 0; int iFileLen = 0; int iFileNum = 0; int i = 0; PCFile.Open(csPCFilename, CFile::modeRead |CFile::typeBinary); iFileLen = PCFile.GetLength(); iFileNum = iFileLen / BUFFER_SIZE; BSTR bstr = csCEFilename.AllocSysString(); SysFreeString(bstr); hCEFile = CeCreateFile(bstr, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(INVALID_HANDLE_VALUE == hCEFile) //文件打开失败 { return FALSE; } for(i = 0;i < iFileNum;i++) { memset(cTemp,0,sizeof(char) * BUFFER_SIZE); if(PCFile.Read(cTemp, BUFFER_SIZE) >= 1) { CeWriteFile(hCEFile, cTemp, BUFFER_SIZE, &dwBytes, NULL); } } if(0 != iFileLen % BUFFER_SIZE) { memset(cTemp,0,sizeof(char) * BUFFER_SIZE); if(PCFile.Read(cTemp, iFileLen % BUFFER_SIZE) >= 1) { CeWriteFile(hCEFile, cTemp, iFileLen % BUFFER_SIZE, &dwBytes, NULL); } } CeCloseHandle(hCEFile); PCFile.Close(); return TRUE; } // CString CVogueRAPI::GetCStringFromFile(CString strFileName) // { // CString strOut; // LPSTR pText = NULL; // int iLen; // CFile f; // if (f.Open(strFileName, CFile::modeReadWrite)) // { // iLen = f.GetLength(); // pText = new char[iLen + 1]; // f.Read(pText, iLen); // pText[iLen] = '\0'; // CString str(pText); // strOut = str; // delete pText; // f.Close(); // } // else // { // strOut = "Error"; // } // return strOut; // } BOOL CCeRAPI::RapiConnectDevice() { RAPIINIT struRapiInit; //这个是CeRapiInitEx函数要求的入口参数: 定义在rapi.h中, 为了不include "rapi.h", 将其定义复制到工程中 DWORD dwWaitResult = 0; //等待初始化完成事件的变量 HRESULT hRapiResult = NULL; //CeRapiInitEx的返回HANDLE if(m_bRapiInitFlag == FALSE) //全局的一个标志,如果初始化成功就不再重复 { struRapiInit.cbSize = sizeof(RAPIINIT); //填满该结构体仅有的三个成员 struRapiInit.hrRapiInit = NULL; //明知是输出参数也顺手填一下, 以防万一 struRapiInit.heRapiInit = NULL; hRapiResult = CeRapiInitEx(&struRapiInit); //关键点 dwWaitResult = WaitForSingleObject(struRapiInit.heRapiInit, 2000); //关键点 if(hRapiResult == S_OK && struRapiInit.hrRapiInit == S_OK && dwWaitResult != WAIT_TIMEOUT) //三个返回值都判断, 以保证正确性 { m_bRapiInitFlag = TRUE; return TRUE; } else { return FALSE; } } else { m_bRapiInitFlag = TRUE; return TRUE; } }
// RapiTestDlg.cpp : implementation file // #include "stdafx.h" #include "RapiTest.h" #include "RapiTestDlg.h" #include "CeRapi.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif BOOL gbInitRAPI = FALSE; ///////////////////////////////////////////////////////////////////////////// // CRapiTestDlg dialog CRapiTestDlg::CRapiTestDlg(CWnd* pParent /*=NULL*/) : CDialog(CRapiTestDlg::IDD, pParent) { //{{AFX_DATA_INIT(CRapiTestDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CRapiTestDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CRapiTestDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CRapiTestDlg, CDialog) //{{AFX_MSG_MAP(CRapiTestDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(ID_CONNECT, OnConnect) ON_BN_CLICKED(IDC_PCTODEVICE, OnPCToDevice) ON_BN_CLICKED(IDC_EXITAPP, OnExitapp) ON_BN_CLICKED(IDC_DEVICETOPC, OnDeviceToPC) ON_WM_DESTROY() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CRapiTestDlg message handlers BOOL CRapiTestDlg::OnInitDialog() { CDialog::OnInitDialog(); ///////////////////////////////////// CEdit *pDesktop = (CEdit *)GetDlgItem(IDC_DESKTOP_FILE); CEdit *pCE = (CEdit *)GetDlgItem(IDC_CE_FILE); CButton *pToDevice = (CButton *)GetDlgItem(IDC_PCTODEVICE); CButton *pToPC = (CButton *)GetDlgItem(IDC_DEVICETOPC); pDesktop->SetWindowText(_T("F:\\NAVoice.exe")); pDesktop->EnableWindow(FALSE); pCE->SetWindowText(_T("\\NAVoice.exe")); pCE->EnableWindow(FALSE); pToDevice->EnableWindow(FALSE); pToPC->EnableWindow(FALSE); ///////////////////////////////////// return TRUE; // return TRUE unless you set the focus to a control } void CRapiTestDlg::OnSysCommand(UINT nID, LPARAM lParam) { CDialog::OnSysCommand(nID, lParam); } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CRapiTestDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CRapiTestDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CRapiTestDlg::OnConnect() { gbInitRAPI = rapi.InitRapi(); //打开rapi.dll,导出API if(TRUE == gbInitRAPI) { BOOL bSuccess = rapi.RapiConnectDevice(); //连接设备 if(FALSE == bSuccess) { TRACE("==连接设备错误!\n"); } else { CEdit *pDesktop = (CEdit *)GetDlgItem(IDC_DESKTOP_FILE); CEdit *pCE = (CEdit *)GetDlgItem(IDC_CE_FILE); CButton *pToDevice = (CButton *)GetDlgItem(IDC_PCTODEVICE); CButton *pToPC = (CButton *)GetDlgItem(IDC_DEVICETOPC); pDesktop->EnableWindow(TRUE); pCE->EnableWindow(TRUE); pToDevice->EnableWindow(TRUE); pToPC->EnableWindow(TRUE); } } } /* *在设备连接成功后,进行文件传输 */ void CRapiTestDlg::OnPCToDevice() { CEdit *pDesktop = (CEdit *)GetDlgItem(IDC_DESKTOP_FILE); CEdit *pCEDevice = (CEdit *)GetDlgItem(IDC_CE_FILE); CString csDesktopFile; CString csCEFile; pDesktop->GetWindowText(csDesktopFile); pCEDevice->GetWindowText(csCEFile); if(csCEFile.GetLength() > 1 && csDesktopFile.GetLength() > 1) { CString strOut; if(TRUE == rapi.CopyFiletoWinCE(csDesktopFile, csCEFile)) { strOut.Format(_T("File %s was transferred to WinCE as %s:"), csDesktopFile, csCEFile); AfxMessageBox(strOut); } else { strOut.Format(_T("文件打开失败!")); AfxMessageBox(strOut); } } else { AfxMessageBox(_T("Problem with filename's.... \nTry Again!!!!")); pDesktop->SetWindowText(_T("")); pCEDevice->SetWindowText(_T("")); pDesktop->SetFocus(); } } void CRapiTestDlg::OnExitapp() { // TODO: Add your control notification handler code here PostQuitMessage(0); } void CRapiTestDlg::OnDeviceToPC() { // TODO: Add your control notification handler code here CEdit *pDesktop = (CEdit *)GetDlgItem(IDC_DESKTOP_FILE); CEdit *pCEDevice = (CEdit *)GetDlgItem(IDC_CE_FILE); CString csDesktopFile; CString csCEFile; pDesktop->GetWindowText(csDesktopFile); pCEDevice->GetWindowText(csCEFile); if(csCEFile.GetLength() > 1 && csDesktopFile.GetLength() > 1) { CString strOut; if(TRUE == rapi.CopyFiletoPC(csCEFile,csDesktopFile)) { strOut.Format(_T("File %s was transferred to PC as %s:"),csCEFile,csDesktopFile); AfxMessageBox(strOut); } else { strOut.Format(_T("文件打开失败!")); AfxMessageBox(strOut); } } else { AfxMessageBox(_T("Problem with filename's.... \nTry Again!!!!")); pDesktop->SetWindowText(_T("")); pCEDevice->SetWindowText(_T("")); pDesktop->SetFocus(); } } void CRapiTestDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: Add your message handler code here if(TRUE == gbInitRAPI) { rapi.CeRapiUninit(); } } //DEL void CRapiTestDlg::OnButton1() //DEL { //DEL // TODO: Add your control notification handler code here //DEL BOOL bRet = FALSE; //DEL //DEL bRet = rapi.CeCopyFile(L"\\CELongPress.txt",L"\\CELongPress2.txt",FALSE); //DEL if(FALSE == bRet) //DEL { //成功 //DEL TRACE("==CeCopyFile failure 1!\n"); //DEL } //DEL //DEL bRet = rapi.CeCopyFile(L"F:\\CELongPress.txt",L"\\CELongPress3.txt",FALSE); //DEL if(FALSE == bRet) //DEL { //失败:3 - 系统找不到指定的路径。 //DEL TRACE("==CeCopyFile failure 2!\n"); //DEL } //DEL //DEL bRet = rapi.CeCopyFile(L"\\CELongPress.txt",L"F:\\CELongPress2.txt",FALSE); //DEL if(FALSE == bRet) //DEL { //失败:3 - 系统找不到指定的路径。 //DEL TRACE("==CeCopyFile failure 3!\n"); //DEL } //DEL }