home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 September / Chip_2002-09_cd1.bin / zkuste / vbasic / Data / Utils / XZipComp.exe / XceedZip.Cab / F112530_MemoryCompression.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-17  |  7.6 KB  |  220 lines

  1. // Memory Compression.cpp : Defines the entry point for the console application.
  2. //
  3. // This file is part of the Memory Compression sample using 
  4. // The Xceed Zip Compression Library 4
  5. // Copyright (c) 1998-1999 Xceed Software Inc.
  6. //
  7. // This sample shows how to compress a memory buffer and add it to a zip file
  8. // as a regular file entry.
  9.  
  10.  
  11. #include "stdafx.h"         // IMPORTANT: Take a look at this file
  12. #include "zipDispIds.h"     // DISPIDs for methods, properties and events
  13. #include "zipAtlFuncInfo.h" // Event information structures
  14.  
  15.  
  16. // The following line imports the type library from XceedZip.dll, and creates
  17. // wrapper classes for the controls (in XceedZip.tlh and XceedZip.tli).
  18.  
  19. #import "XceedZip.dll" no_namespace named_guids
  20.  
  21.  
  22. // Change these defines to customize the sample
  23.  
  24. #define ZIP_FILENAME        _T( "c:\\test.zip" )
  25.  
  26.  
  27. // This identifies our sink object (can be any id)
  28.  
  29. #define DISPID_ZIP_SINK     1
  30.  
  31.  
  32. // Usually, a sink object derives from IDispEventImpl, which uses type info from the
  33. // event source's typelib to get the funcinfo. But IDispEventImpl::GetUserDefinedType()
  34. // only handles TKIND_ALIAS. In many of our events, we have TKIND_ENUM parameters.
  35. // This is why the sink object derives from IDispEventSimpleImpl, which does not use
  36. // type information. We need to provide a _ATL_FUNC_INFO for each event we want to
  37. // handle. Fortunately, you can get all these informations in "zipAtlFuncInfo.h"
  38.  
  39. class CZipEventSink : public IDispEventSimpleImpl< DISPID_ZIP_SINK, CZipEventSink, &DIID__IXceedZipEvents >
  40. {
  41. public:
  42.   //
  43.   // QueryMemoryFile event: This event is triggered by the XceedZip control as long as
  44.   //                        the bFileProvided is set to true. Each time this is the case
  45.   //                        a new virtual entry is added to the zip file. For each of
  46.   //                        these virtual entries, at least one "ZippingMemoryFile" event
  47.   //                        will be triggered, for you to provide the data to compress.
  48.   void _stdcall QueryMemoryFile( long * lUserTag,
  49.                                  BSTR * sFilename,
  50.                                  BSTR * sComment,
  51.                                  long * lAttributes,
  52.                                  DATE * dtLastModified,
  53.                                  DATE * dtLastAccessed,
  54.                                  DATE * dtCreated,
  55.                                  VARIANT_BOOL * bEncrypted,
  56.                                  BSTR * sPassword,
  57.                                  VARIANT_BOOL * bFileProvided )
  58.   {
  59.     if( m_bMustProvideFile )
  60.     {
  61.       m_bMustProvideFile = false;
  62.  
  63.       // You must realloc the provided pointers!
  64.       SysReAllocString( sFilename, L"UserMessage.txt" );   // Fake file entry
  65.  
  66.       *bFileProvided = VARIANT_TRUE;
  67.     }
  68.     else
  69.     {
  70.       *bFileProvided = VARIANT_FALSE;
  71.     }
  72.  
  73.     // Little internal trick: All calls to QueryMemoryFile happen before the first
  74.     // call to ZippingMemoryFile. We take the opportunity to reset internal flags
  75.     // used in ZippingMemoryFile.
  76.     m_bFirstCall  = true;
  77.   }
  78.  
  79.   //
  80.   // ZippingMemoryFile event: This event is paired with each fake entry specified in the 
  81.   //                          above event. This is where you specify the data to compress.
  82.   //                          If you cannot provide all the data at once (e.g. when
  83.   //                          compreesing a stream oriented provider), you can set the
  84.   //                          bEndOfData parameter to false, and another call to this event
  85.   //                          will be made by XceedZip for the same entry.
  86.   //
  87.   void _stdcall ZippingMemoryFile( long lUserTag,
  88.                                    BSTR sFilename,
  89.                                    VARIANT * vaDataToCompress,
  90.                                    VARIANT_BOOL * bEndOfData )
  91.   {
  92.     if( m_bFirstCall )
  93.     {
  94.       printf( "Please enter the message you want to add to the zip file\n"
  95.               "as the %S entry.\n"
  96.               "Enter \"end\" on a single line to end the message.\n",
  97.               sFilename );
  98.  
  99.       m_bFirstCall  = false;
  100.     }
  101.  
  102.     // Retrieve a line from the console
  103.     char  szLine[ 200 ];
  104.     gets( szLine );
  105.  
  106.     if( !lstrcmpi( szLine, "end" ) )
  107.     {
  108.       // Nothing to compress for the last call of this entry
  109.       // It is legal to empty vaDataToCompress!
  110.       VariantClear( vaDataToCompress );
  111.       *bEndOfData = VARIANT_TRUE;
  112.  
  113.       // Let's reactivate the "first call" flag for next entry!
  114.       m_bFirstCall  = true;
  115.     }
  116.     else
  117.     {
  118.       // gets removed the \n. Add it back!
  119.       lstrcat( szLine, "\n" );
  120.  
  121.       // We create a safearray that will contain the data to be zipped
  122.       long        lSize = lstrlen( szLine );
  123.       SAFEARRAY*  psa   = SafeArrayCreateVector( VT_I1, 0, lSize );
  124.  
  125.       BYTE* pcData;
  126.  
  127.       SafeArrayAccessData( psa, ( void** )&pcData );
  128.  
  129.       // We copy the line in the safe array buffer
  130.       CopyMemory( pcData, szLine, lSize );
  131.  
  132.       SafeArrayUnaccessData( psa );
  133.  
  134.       // We set the variant vaDataToCompress to the safearray we just created.
  135.       vaDataToCompress->vt      = VT_UI1 | VT_ARRAY;
  136.       vaDataToCompress->parray  = psa;
  137.  
  138.       // Since it wasn't the "end" keyword, we tell XceedZip that we did not
  139.       // provide all the data for this entry yet.
  140.       *bEndOfData = VARIANT_FALSE;
  141.     }
  142.  
  143.     // Little trick again: Since a call to this event means no more calls to
  144.     // QueryMemoryFile, we reset the "must provide file" flag for next
  145.     // zipping operation.
  146.     m_bMustProvideFile  = true;
  147.   }
  148.  
  149. // The sink map is used by IDispEventSimpleImpl<>. The map contains information about
  150. // each event handler we want to provide.
  151.  
  152. BEGIN_SINK_MAP( CZipEventSink )   
  153.   SINK_ENTRY_INFO(DISPID_ZIP_SINK, DIID__IXceedZipEvents, XCD_ZIP_DISPID_QUERYMEMORYFILE, QueryMemoryFile, &QueryMemoryFile_Info)
  154.   SINK_ENTRY_INFO(DISPID_ZIP_SINK, DIID__IXceedZipEvents, XCD_ZIP_DISPID_ZIPPINGMEMORYFILE, ZippingMemoryFile, &ZippingMemoryFile_Info)
  155. END_SINK_MAP()
  156.  
  157.   CZipEventSink( void )
  158.   {
  159.     m_bMustProvideFile  = true;
  160.     m_bFirstCall        = true;
  161.   }
  162.  
  163. private:
  164.   bool  m_bMustProvideFile;
  165.   bool  m_bFirstCall;
  166. };
  167.  
  168.  
  169. int main(int argc, char* argv[])
  170. {
  171.   CoInitialize( NULL );
  172.  
  173.   try 
  174.   {
  175.     // Create our instance of the XceedZip control.
  176.     IXceedZipPtr pZip( CLSID_XceedZip );
  177.  
  178.     // Create our event sink that will handle Xceed Zip events, and connect
  179.     // it to our instance of XceedZip
  180.     CZipEventSink xEventSink;
  181.     xEventSink.DispEventAdvise( pZip );
  182.  
  183.     // Xceed Zip never erases a zip file. It updates at most.
  184.     DeleteFile( ZIP_FILENAME );
  185.  
  186.     // Set the zip file we want to work on
  187.     pZip->ZipFilename = ZIP_FILENAME;
  188.  
  189.     // You can zip regular files too! The QueryMemoryFile event is triggered
  190.     // after processing regular files to zip. So you may want to zip regular files
  191.     // and add a "memory" file too. In this sample, we'll only zip a memory buffer,
  192.     // so we leave the FilesToProcess property empty!
  193.     pZip->FilesToProcess  = "";
  194.  
  195.     // And we start a good old zipping operation!
  196.     pZip->Zip();
  197.  
  198.     xEventSink.DispEventUnadvise( pZip );
  199.   }
  200.   catch( const _com_error& xErr ) 
  201.   {
  202.     // The generated wrapper classes throw _com_error exceptions when a COM error
  203.     // occurs.
  204.  
  205.     printf( "\nCOM Error 0x%08X ( %s ).\n", xErr.Error(), xErr.ErrorMessage() );
  206.   }
  207.   catch ( ... ) 
  208.   {
  209.     printf( "\nUnhandled Exception.\n" );
  210.   }
  211.  
  212.   CoUninitialize();
  213.  
  214.   printf( "\nPress any key to quit...\n" );
  215.   getch();
  216.  
  217.     return 0;
  218. }
  219.  
  220.