How the DesktopRapiInvoker Application Transfers the File

In this lesson, you’ll see how the DesktopRapiInvoker application manages file transfers from the desktopside of a RAPI connection to a CE device. In the CMainFrame member OnDownloadHtml(), you choose a file to transfer to the desktop, initialize the RAPI subsystem, create and open a CE side file, and copy the desktop file to the CE side file.

The first step is to initialize and display the common file dialog to allow the user to choose a file for transfer. Note that this process of file selection is intentionally naïve. You don’t use a filter string to ensure that the file is actually text or HTML, and you don’t check to see whether the CE device has adequate space to accept the transferred file before you send it. In most real-world applications, it would be necessary to take these extra precautions. In this case, they are omitted for the sake of clarity and simplicity, but the techniques for performing these tasks are demonstrated in previous example programs in this series.

The Steps

You create an object of CfileDialog type, passing parameters to the constructor that customize the object for your purposes. Here are the parameters and what they do:

  • Setting the first parameter as TRUE indicates that you are opening rather than saving the file;
  • Setting the second parameter to NULL has the effect of preventing the appending of a default file extension to the name specified by the user;
  • The third parameter sets a flag that prevents read-only files from being displayed in the dialog;
  • The fourth parameter, set to NULL, means that you are not supplying a filter string to control the types of files displayed in the dialog;
  • And the final parameter is the handle to a window that can display error messages for the common file dialog if necessary.
void CMainFrame::OnDownloadHtml()
{
   CString str1;

   CFileDialog dlg( TRUE, NULL, "",
                    OFN_HIDEREADONLY ,
                    NULL, this);

You can modify the appearance and behavior of the dialog by setting members of the OPENFILENAME structure before you actually invoke the dialog with a call to member function DoModal(). This structure is exposed by the CfileDialog class in the data member .m_ofn . In this case, you set the caption of the dialog by loading a string resource and setting dlg.m_ofn.lpstrTitle equal to the string object. Notice that you use _chdir() to set the initial directory to My Documents. You also could have set this string in the m_ofn.lpstrInitialDir member.

   str1.LoadString( IDS_DOWNLOAD_DLG_CAPTION );
   dlg.m_ofn.lpstrTitle = str1;
   _chdir("\My Documents" );

   CString str;
   CString strFileName;
   CFile fileHTML;

/* This is another way to set the initial directory for the dialog
   str.LoadString( IDS_DOWNLOAD_PATH );
   dlg.m_ofn.lpstrInitialDir = str.GetBuffer(str.GetLength());
*/

Next, youwe invoke the dialog, and, if it returns with IDOK, you get the filename the user has chosen. You open the file combining the flags for read only and binary access.

   if( dlg.DoModal() == IDOK )
      {
         strFileName = dlg.GetFileExt();
         strFileName = dlg.GetPathName();
         //open a stream file

         if(    !fileHTML.Open( strFileName.GetBuffer(
                 strFileName.GetLength()),
                 CFile::modeRead | CFile::typeBinary) )
         {
            str1.LoadString( IDS_ERR_FILE_OPEN );
            CWnd::MessageBox( str1, strFileName, MB_ICONHAND |
                              MB_OK );
            return;
         }

      }    //end if(dlg.DoModal() == IDOK )
else
{
   return;
}

Now, you are ready to copy the file to the CE device. First, you initialize the RAPI subsystem. You check the size of the file, allocate a buffer for it, and then read the entire file into memory on the desktop.

// open a file on the CE device
HRESULT hr = CeRapiInit();
if ( hr != ERROR_SUCCESS )
   { return; }

//how big is the desktop file
DWORD dwFileSize = fileHTML.GetLength();

//allocate a buffer
PBYTE pbFileBuff = (PBYTE) LocalAlloc(LPTR, dwFileSize);
if ( !pbFileBuff )
   {
      str1.LoadString( IDS_ALLOCATION_FAILURE );
      CWnd::MessageBox( str1, strFileName, MB_ICONHAND | MB_OK );
      return;
   }

//read it
fileHTML.Read(pbFileBuff, dwFileSize );

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read