home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 September / Chip_2002-09_cd1.bin / zkuste / vbasic / Data / Utils / XZipComp.exe / XceedCompression.Cab / F112873_MemoryCompressDlg.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-05-11  |  16.9 KB  |  553 lines

  1. // Xceed Streaming Compression Library - Memory Compress sample
  2. // Copyright (c) 2001 Xceed Software Inc.
  3. //
  4. // [MemoryCompressDlg.cpp]
  5. //
  6. // This form module contains the main form's code. It demonstrates how to
  7. // compress a chunk of memory data using different kinds of compression formats,
  8. // and decompress a compressed memory data. It specifically uses:
  9. //  - The Compress and Decompress method.
  10. //  - The CompressionFormat property.
  11. //
  12. // This file is part of the Xceed Streaming Compression Library sample applications.
  13. // The source code in this file is only intended as a supplement to Xceed
  14. // Streaming Compression Library's documentation, and is provided "as is", without
  15. // warranty of any kind, either expressed or implied.
  16.  
  17. #include "stdafx.h"
  18. #include "MemoryCompress.h"
  19. #include "MemoryCompressDlg.h"
  20.  
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26.  
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CAboutDlg dialog used for App About
  29.  
  30. class CAboutDlg : public CDialog
  31. {
  32. public:
  33.     CAboutDlg();
  34.  
  35. // Dialog Data
  36.     //{{AFX_DATA(CAboutDlg)
  37.     enum { IDD = IDD_ABOUTBOX };
  38.     //}}AFX_DATA
  39.  
  40.     // ClassWizard generated virtual function overrides
  41.     //{{AFX_VIRTUAL(CAboutDlg)
  42.     protected:
  43.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  44.     //}}AFX_VIRTUAL
  45.  
  46. // Implementation
  47. protected:
  48.     //{{AFX_MSG(CAboutDlg)
  49.     //}}AFX_MSG
  50.     DECLARE_MESSAGE_MAP()
  51. };
  52.  
  53. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  54. {
  55.     //{{AFX_DATA_INIT(CAboutDlg)
  56.     //}}AFX_DATA_INIT
  57. }
  58.  
  59. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  60. {
  61.     CDialog::DoDataExchange(pDX);
  62.     //{{AFX_DATA_MAP(CAboutDlg)
  63.     //}}AFX_DATA_MAP
  64. }
  65.  
  66. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  67.     //{{AFX_MSG_MAP(CAboutDlg)
  68.         // No message handlers
  69.     //}}AFX_MSG_MAP
  70. END_MESSAGE_MAP()
  71.  
  72. /////////////////////////////////////////////////////////////////////////////
  73. // CMemoryCompressDlg dialog
  74.  
  75. CMemoryCompressDlg::CMemoryCompressDlg(CWnd* pParent /*=NULL*/)
  76.     : CDialog(CMemoryCompressDlg::IDD, pParent)
  77. {
  78.     //{{AFX_DATA_INIT(CMemoryCompressDlg)
  79.     m_lCompressionFormat = -1;
  80.     m_sCompressedSize = _T("");
  81.     m_sOriginalSize = _T("");
  82.     m_sDecompressed = _T("");
  83.     m_sToCompress = _T("");
  84.     //}}AFX_DATA_INIT
  85.     // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  86.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  87. }
  88.  
  89. void CMemoryCompressDlg::DoDataExchange(CDataExchange* pDX)
  90. {
  91.     CDialog::DoDataExchange(pDX);
  92.     //{{AFX_DATA_MAP(CMemoryCompressDlg)
  93.     DDX_Control(pDX, IDC_CBO_COMPRESSIONFORMAT, m_cboCompressionFormat);
  94.     DDX_CBIndex(pDX, IDC_CBO_COMPRESSIONFORMAT, m_lCompressionFormat);
  95.     DDX_Text(pDX, IDC_LBL_COMPRESSEDSIZE, m_sCompressedSize);
  96.     DDX_Text(pDX, IDC_LBL_ORIGINALSIZE, m_sOriginalSize);
  97.     DDX_Text(pDX, IDC_TXT_DECOMPRESSED, m_sDecompressed);
  98.     DDX_Text(pDX, IDC_TXT_TOCOMPRESS, m_sToCompress);
  99.     //}}AFX_DATA_MAP
  100. }
  101.  
  102. BEGIN_MESSAGE_MAP(CMemoryCompressDlg, CDialog)
  103.     //{{AFX_MSG_MAP(CMemoryCompressDlg)
  104.     ON_WM_SYSCOMMAND()
  105.     ON_WM_PAINT()
  106.     ON_WM_QUERYDRAGICON()
  107.     ON_EN_CHANGE(IDC_TXT_TOCOMPRESS, OnChangeTxtTocompress)
  108.     ON_BN_CLICKED(IDC_CMD_COMPRESS, OnCmdCompress)
  109.     ON_BN_CLICKED(IDC_CMD_DECOMPRESS, OnCmdDecompress)
  110.     ON_BN_CLICKED(IDQUIT, OnQuit)
  111.     //}}AFX_MSG_MAP
  112. END_MESSAGE_MAP()
  113.  
  114. /////////////////////////////////////////////////////////////////////////////
  115. // CMemoryCompressDlg message handlers
  116.  
  117. BOOL CMemoryCompressDlg::OnInitDialog()
  118. {
  119.   //
  120.   // Set default values for the text to compress
  121.   //
  122.   m_sToCompress = "This is a little test to show you how the memory compression works.\r\n"
  123.                   "And it is very easy to use.\r\n"
  124.                   "And there is some repeating \r\n"
  125.                   "repeating repeating repeating repeating repeating repeating repeating text.";
  126.  
  127.   CDialog::OnInitDialog();
  128.  
  129.     // Add "About..." menu item to system menu.
  130.  
  131.     // IDM_ABOUTBOX must be in the system command range.
  132.     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  133.     ASSERT(IDM_ABOUTBOX < 0xF000);
  134.  
  135.     CMenu* pSysMenu = GetSystemMenu(FALSE);
  136.     if (pSysMenu != NULL)
  137.     {
  138.         CString strAboutMenu;
  139.         strAboutMenu.LoadString(IDS_ABOUTBOX);
  140.         if (!strAboutMenu.IsEmpty())
  141.         {
  142.             pSysMenu->AppendMenu(MF_SEPARATOR);
  143.             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  144.         }
  145.     }
  146.  
  147.     // Set the icon for this dialog.  The framework does this automatically
  148.     //  when the application's main window is not a dialog
  149.     SetIcon(m_hIcon, TRUE);            // Set big icon
  150.     SetIcon(m_hIcon, FALSE);        // Set small icon
  151.     
  152.   //----------------------------------------------------------------------------------
  153.   // Initialize the size labels and fill the 2 combo boxes
  154.   //----------------------------------------------------------------------------------
  155.  
  156.   // Fill the combo boxes
  157.     m_cboCompressionFormat.AddString( "BZip2" );
  158.     m_cboCompressionFormat.AddString( "GZip" );
  159.     m_cboCompressionFormat.AddString( "Standard" );
  160.     m_cboCompressionFormat.AddString( "Zip3" );
  161.     m_cboCompressionFormat.AddString( "ZLib" );
  162.     m_cboCompressionFormat.AddString( "BurrowsWheeler" );
  163.     m_cboCompressionFormat.AddString( "Deflate" );
  164.     m_cboCompressionFormat.AddString( "Store" );
  165.  
  166.   m_cboCompressionFormat.SetItemData( 0, cfBZip2 );
  167.   m_cboCompressionFormat.SetItemData( 1, cfGZip );
  168.   m_cboCompressionFormat.SetItemData( 2, cfStandard );
  169.   m_cboCompressionFormat.SetItemData( 3, cfZip3 );
  170.   m_cboCompressionFormat.SetItemData( 4, cfZLib );
  171.   m_cboCompressionFormat.SetItemData( 5, cfBWT );
  172.   m_cboCompressionFormat.SetItemData( 5, cfDeflate );
  173.   m_cboCompressionFormat.SetItemData( 5, cfStore );
  174.  
  175.   m_cboCompressionFormat.SetCurSel( cfBZip2 );
  176.  
  177.   OnChangeTxtTocompress();
  178.     
  179.     return TRUE;  // return TRUE  unless you set the focus to a control
  180. }
  181.  
  182. void CMemoryCompressDlg::OnSysCommand(UINT nID, LPARAM lParam)
  183. {
  184.     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  185.     {
  186.         CAboutDlg dlgAbout;
  187.         dlgAbout.DoModal();
  188.     }
  189.     else
  190.     {
  191.         CDialog::OnSysCommand(nID, lParam);
  192.     }
  193. }
  194.  
  195. // If you add a minimize button to your dialog, you will need the code below
  196. //  to draw the icon.  For MFC applications using the document/view model,
  197. //  this is automatically done for you by the framework.
  198.  
  199. void CMemoryCompressDlg::OnPaint() 
  200. {
  201.     if (IsIconic())
  202.     {
  203.         CPaintDC dc(this); // device context for painting
  204.  
  205.         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  206.  
  207.         // Center icon in client rectangle
  208.         int cxIcon = GetSystemMetrics(SM_CXICON);
  209.         int cyIcon = GetSystemMetrics(SM_CYICON);
  210.         CRect rect;
  211.         GetClientRect(&rect);
  212.         int x = (rect.Width() - cxIcon + 1) / 2;
  213.         int y = (rect.Height() - cyIcon + 1) / 2;
  214.  
  215.         // Draw the icon
  216.         dc.DrawIcon(x, y, m_hIcon);
  217.     }
  218.     else
  219.     {
  220.         CDialog::OnPaint();
  221.     }
  222. }
  223.  
  224. // The system calls this to obtain the cursor to display while the user drags
  225. //  the minimized window.
  226. HCURSOR CMemoryCompressDlg::OnQueryDragIcon()
  227. {
  228.     return (HCURSOR) m_hIcon;
  229. }
  230.  
  231. //====================================================================================
  232. //
  233. // EVENTS - triggered by the form and its controls
  234. //
  235. //====================================================================================
  236.  
  237. void CMemoryCompressDlg::OnChangeTxtTocompress() 
  238. {
  239.   if( UpdateData( TRUE ) )
  240.   {
  241.     m_sOriginalSize.Format( "%d", m_sToCompress.GetLength() );
  242.     UpdateData( FALSE );
  243.   }
  244. }
  245.  
  246. //------------------------------------------------------------------------------------
  247. // Do the compression of the text
  248. //------------------------------------------------------------------------------------
  249. void CMemoryCompressDlg::OnCmdCompress() 
  250. {
  251.   if( UpdateData( TRUE ) )
  252.   {
  253.     CWaitCursor xWaitCursor;
  254.  
  255.     COleException* pExcept = new COleException;
  256.     DXceedStreamingCompression xCompressor;
  257.     COleVariant vaToCompress;
  258.  
  259.     try
  260.     {
  261.       // Create an instance of the XceedStreamingCompression class.
  262.       if( !xCompressor.CreateDispatch( "Xceed.StreamingCompression", pExcept ) )
  263.       {
  264.         throw pExcept;
  265.       }
  266.  
  267.       // Create and prepare the compression format (BZip2, GZip, ZLib, ...)
  268.       // This function can throw an exception that will be caught here.
  269.       PrepareCompressionFormat( xCompressor );
  270.  
  271.       // Store in the variant to compress the content of the text box 
  272.       // as an ANSI String. We could have used a BSTR representation
  273.       // of the string but it would have unnecessarily doubled the string 
  274.       // size, and slightly affect the compression ratio. The Variant will 
  275.       // report containing a VT_BSTR, but the actual data and size will 
  276.       // reflect the Ansi string format.
  277.       vaToCompress.SetString( m_sToCompress, VT_BSTRT );
  278.  
  279.       // Compress the string in a single call (bEndOfData is TRUE).
  280.       m_vaCompressed = xCompressor.Compress( vaToCompress, TRUE );
  281.  
  282.       // We assign an value of 0 as a default compressed size.
  283.       m_sCompressedSize = "0";
  284.  
  285.       // We check that the compressed variant is really a byte array. For instance,
  286.       // it won't be if there was no characters to compress (empty string).
  287.       if( m_vaCompressed.vt == ( VT_ARRAY | VT_UI1 ) )
  288.       {
  289.         LONG lHigh;
  290.         LONG lLow;
  291.  
  292.         // We extracts the upper bound and the lower bound of the
  293.         // byte array.
  294.         SafeArrayGetUBound( m_vaCompressed.parray, 1, &lHigh );
  295.         SafeArrayGetLBound( m_vaCompressed.parray, 1, &lLow );
  296.  
  297.         // We display the compressed size
  298.         m_sCompressedSize.Format( "%d", lHigh - lLow + 1 );
  299.       }
  300.  
  301.       // Update mainly the compressed size label
  302.       UpdateData( FALSE );
  303.     }
  304.     catch( COleDispatchException* pEx )
  305.     {
  306.       pEx->ReportError();
  307.       pEx->Delete();
  308.     }
  309.     catch( COleException* pEx )
  310.     {
  311.       pEx->ReportError();
  312.       pEx->Delete();
  313.     }
  314.     catch( CException* pEx )
  315.     {
  316.       pEx->ReportError();
  317.       pEx->Delete();
  318.     }
  319.  
  320.     pExcept->Delete();
  321.   }
  322. }
  323.  
  324. //------------------------------------------------------------------------------------
  325. // Do the decompression of the compressed byte array
  326. //------------------------------------------------------------------------------------
  327. void CMemoryCompressDlg::OnCmdDecompress() 
  328. {
  329.   // If the user did not performed a compression first, refuse to Decompress
  330.   if( m_vaCompressed.vt == VT_EMPTY )
  331.     return; 
  332.  
  333.   if( UpdateData( TRUE ) )
  334.   {
  335.     CWaitCursor xWaitCursor;
  336.  
  337.     COleException* pExcept = new COleException;
  338.     DXceedStreamingCompression xCompressor;
  339.     COleVariant vaDecompressed;
  340.  
  341.     try
  342.     {
  343.       // Create an instance of the Xceed Streaming Compression
  344.       if( !xCompressor.CreateDispatch( "Xceed.StreamingCompression", pExcept ) )
  345.       {
  346.         throw pExcept;
  347.       }
  348.  
  349.       // Create and prepare the compression format (BZip2, GZip, ZLib, ...)
  350.       // This function can throw an exception that will be caught here.
  351.       PrepareCompressionFormat( xCompressor );
  352.  
  353.       // Decompress the compressed byte array in a single call
  354.       // (bEndOfData is TRUE).
  355.       vaDecompressed = xCompressor.Decompress( m_vaCompressed, TRUE );
  356.  
  357.       // We assign an empty string as a default decompressed value.
  358.       m_sDecompressed = "";
  359.  
  360.       // We check that the decompressed variant is really a byte array.
  361.       if( vaDecompressed.vt == ( VT_ARRAY | VT_UI1 ) )
  362.       {
  363.         LONG lHigh;
  364.         LONG lLow;
  365.  
  366.         // We extracts the upper bound and the lower bound of the
  367.         // byte array.
  368.         SafeArrayGetUBound( vaDecompressed.parray, 1, &lHigh );
  369.         SafeArrayGetLBound( vaDecompressed.parray, 1, &lLow );
  370.  
  371.         // This pointer will contain the address of the byte array
  372.         char* pszDecompressed = NULL;
  373.  
  374.         // We get a pointer on the actual data in the safe array.
  375.         SafeArrayAccessData( vaDecompressed.parray, ( void** )&pszDecompressed );
  376.  
  377.         // We display the decompressed string by assigning this Ansi string
  378.         // to the CString member, using the constructor accepting a char* and a size.
  379.         m_sDecompressed = CString( pszDecompressed, lHigh - lLow + 1 );
  380.  
  381.         // We release the lock on the safe array
  382.         SafeArrayUnaccessData( vaDecompressed.parray );
  383.       }
  384.  
  385.       // Let's say we want to check format-specific properties. In this sample, when
  386.       // compressing using the GZip format, we add a comment. Let's get it back!
  387.       switch( m_lCompressionFormat )
  388.       {
  389.         case cfGZip:
  390.         {
  391.           DXceedGZipCompressionFormat xGZip = xCompressor.GetCompressionFormat();
  392.  
  393.           m_sDecompressed += "\r\nThe comment is: ";
  394.           m_sDecompressed += xGZip.GetComment();
  395.           break;
  396.         }
  397.       }
  398.  
  399.       // Update mainly the decompressed text box
  400.       UpdateData( FALSE );
  401.     }
  402.     catch( COleDispatchException* pEx )
  403.     {
  404.       pEx->ReportError();
  405.       pEx->Delete();
  406.     }
  407.     catch( COleException* pEx )
  408.     {
  409.       pEx->ReportError();
  410.       pEx->Delete();
  411.     }
  412.     catch( CException* pEx )
  413.     {
  414.       pEx->ReportError();
  415.       pEx->Delete();
  416.     }
  417.  
  418.     pExcept->Delete();
  419.   }
  420. }
  421.  
  422. //------------------------------------------------------------------------------------
  423. // Quit the sample application
  424. //------------------------------------------------------------------------------------
  425. void CMemoryCompressDlg::OnQuit() 
  426. {
  427.   EndDialog( IDOK );
  428. }
  429.  
  430. //====================================================================================
  431. //
  432. // FUNCTIONS
  433. //
  434. //====================================================================================
  435.  
  436. //------------------------------------------------------------------------------------
  437. // Prepare the compression format according to the user selection
  438. //------------------------------------------------------------------------------------
  439. void CMemoryCompressDlg::PrepareCompressionFormat( DXceedStreamingCompression& xCompressor )
  440. {
  441.   // To simplify the matter here, we use a generic compression format object data type
  442.   // (xGenericOleDispatch is of type COleDispatchDriver)
  443.  
  444.   // If you need to set some properties on your compression format object, you'll need
  445.   // to use the specific data type you create. This is demonstrated with the cfGZip case.
  446.   COleDispatchDriver xGenericOleDispatch;
  447.  
  448.   if( UpdateData( TRUE ) )
  449.   {
  450.     COleException* pEx = new COleException;
  451.  
  452.     switch( m_lCompressionFormat )
  453.     {
  454.       case cfBZip2 :
  455.       {
  456.         if( !xGenericOleDispatch.CreateDispatch( "Xceed.BZip2CompressionFormat", pEx ) )
  457.         {
  458.           throw pEx;
  459.         }
  460.         break;
  461.       }
  462.  
  463.       case cfGZip :
  464.       {
  465.         // Let's say we want to set some properties on our format object. We use
  466.         // a specific DXceedGZipCompressionFormat variable instead of the generic one.
  467.         DXceedGZipCompressionFormat xGZip;
  468.  
  469.         if( !xGZip.CreateDispatch( "Xceed.GZipCompressionFormat", pEx ) )
  470.         {
  471.           throw pEx;
  472.         }
  473.  
  474.         xGZip.SetComment( "This is my comment" );
  475.  
  476.         // We make sure xGenericOleDispatch does point to this format object instance!
  477.         // Simply transfert the responsability of this IDispatch interface reference.
  478.         xGenericOleDispatch.AttachDispatch( xGZip.DetachDispatch() );
  479.         break;
  480.       }
  481.  
  482.       case cfStandard :
  483.       {
  484.         if( !xGenericOleDispatch.CreateDispatch( "Xceed.StandardCompressionFormat", pEx ) )
  485.         {
  486.           throw pEx;
  487.         }
  488.         break;
  489.       }
  490.  
  491.       case cfZip3 :
  492.       {
  493.         if( !xGenericOleDispatch.CreateDispatch( "Xceed.Zip3CompressionFormat", pEx ) )
  494.         {
  495.           throw pEx;
  496.         }
  497.         break;
  498.       }
  499.  
  500.       case cfZLib :
  501.       {
  502.         if( !xGenericOleDispatch.CreateDispatch( "Xceed.ZLibCompressionFormat", pEx ) )
  503.         {
  504.           throw pEx;
  505.         }
  506.         break;
  507.       }
  508.  
  509.       // The next three items are not compression formats. They are compression
  510.       // methods. They still can be assigned to the CompressionFormat property of the
  511.       // XceedStreamingCompression object. In these cases, the resulting compressed 
  512.       // streams will have no formating (no header, footer, checksum, ...)
  513.       case cfBWT :
  514.       {
  515.         if( !xGenericOleDispatch.CreateDispatch( "Xceed.BWTCompression", pEx ) )
  516.         {
  517.           throw pEx;
  518.         }
  519.         break;
  520.       }
  521.  
  522.       case cfDeflate :
  523.       {
  524.         if( !xGenericOleDispatch.CreateDispatch( "Xceed.DeflateCompression", pEx ) )
  525.         {
  526.           throw pEx;
  527.         }
  528.         break;
  529.       }
  530.  
  531.       case cfStore :
  532.       {
  533.         // Using Store as the compression format will produce an output
  534.         // compressed stream identical to the original text!
  535.         if( !xGenericOleDispatch.CreateDispatch( "Xceed.StoreCompression", pEx ) )
  536.         {
  537.           throw pEx;
  538.         }
  539.         break;
  540.       }
  541.     }
  542.  
  543.     if( xGenericOleDispatch.m_lpDispatch )
  544.     {
  545.       // Simply set the CompressionFormat property of our main XceedStreamingCompression instance
  546.       xCompressor.SetRefCompressionFormat( xGenericOleDispatch.m_lpDispatch );
  547.     }
  548.  
  549.     pEx->Delete();
  550.   }
  551. }
  552.  
  553.