home *** CD-ROM | disk | FTP | other *** search
- // Xceed Streaming Compression Library - Memory Compress sample
- // Copyright (c) 2001 Xceed Software Inc.
- //
- // [MemoryCompressDlg.cpp]
- //
- // This form module contains the main form's code. It demonstrates how to
- // compress a chunk of memory data using different kinds of compression formats,
- // and decompress a compressed memory data. It specifically uses:
- // - The Compress and Decompress method.
- // - The CompressionFormat property.
- //
- // This file is part of the Xceed Streaming Compression Library sample applications.
- // The source code in this file is only intended as a supplement to Xceed
- // Streaming Compression Library's documentation, and is provided "as is", without
- // warranty of any kind, either expressed or implied.
-
- #include "stdafx.h"
- #include "MemoryCompress.h"
- #include "MemoryCompressDlg.h"
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // CAboutDlg dialog used for App About
-
- class CAboutDlg : public CDialog
- {
- public:
- CAboutDlg();
-
- // Dialog Data
- //{{AFX_DATA(CAboutDlg)
- enum { IDD = IDD_ABOUTBOX };
- //}}AFX_DATA
-
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CAboutDlg)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
-
- // Implementation
- protected:
- //{{AFX_MSG(CAboutDlg)
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- };
-
- CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
- {
- //{{AFX_DATA_INIT(CAboutDlg)
- //}}AFX_DATA_INIT
- }
-
- void CAboutDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CAboutDlg)
- //}}AFX_DATA_MAP
- }
-
- BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
- //{{AFX_MSG_MAP(CAboutDlg)
- // No message handlers
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CMemoryCompressDlg dialog
-
- CMemoryCompressDlg::CMemoryCompressDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CMemoryCompressDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CMemoryCompressDlg)
- m_lCompressionFormat = -1;
- m_sCompressedSize = _T("");
- m_sOriginalSize = _T("");
- m_sDecompressed = _T("");
- m_sToCompress = _T("");
- //}}AFX_DATA_INIT
- // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
- }
-
- void CMemoryCompressDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CMemoryCompressDlg)
- DDX_Control(pDX, IDC_CBO_COMPRESSIONFORMAT, m_cboCompressionFormat);
- DDX_CBIndex(pDX, IDC_CBO_COMPRESSIONFORMAT, m_lCompressionFormat);
- DDX_Text(pDX, IDC_LBL_COMPRESSEDSIZE, m_sCompressedSize);
- DDX_Text(pDX, IDC_LBL_ORIGINALSIZE, m_sOriginalSize);
- DDX_Text(pDX, IDC_TXT_DECOMPRESSED, m_sDecompressed);
- DDX_Text(pDX, IDC_TXT_TOCOMPRESS, m_sToCompress);
- //}}AFX_DATA_MAP
- }
-
- BEGIN_MESSAGE_MAP(CMemoryCompressDlg, CDialog)
- //{{AFX_MSG_MAP(CMemoryCompressDlg)
- ON_WM_SYSCOMMAND()
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- ON_EN_CHANGE(IDC_TXT_TOCOMPRESS, OnChangeTxtTocompress)
- ON_BN_CLICKED(IDC_CMD_COMPRESS, OnCmdCompress)
- ON_BN_CLICKED(IDC_CMD_DECOMPRESS, OnCmdDecompress)
- ON_BN_CLICKED(IDQUIT, OnQuit)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CMemoryCompressDlg message handlers
-
- BOOL CMemoryCompressDlg::OnInitDialog()
- {
- //
- // Set default values for the text to compress
- //
- m_sToCompress = "This is a little test to show you how the memory compression works.\r\n"
- "And it is very easy to use.\r\n"
- "And there is some repeating \r\n"
- "repeating repeating repeating repeating repeating repeating repeating text.";
-
- CDialog::OnInitDialog();
-
- // Add "About..." menu item to system menu.
-
- // IDM_ABOUTBOX must be in the system command range.
- ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
- ASSERT(IDM_ABOUTBOX < 0xF000);
-
- CMenu* pSysMenu = GetSystemMenu(FALSE);
- if (pSysMenu != NULL)
- {
- CString strAboutMenu;
- strAboutMenu.LoadString(IDS_ABOUTBOX);
- if (!strAboutMenu.IsEmpty())
- {
- pSysMenu->AppendMenu(MF_SEPARATOR);
- pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
- }
- }
-
- // Set the icon for this dialog. The framework does this automatically
- // when the application's main window is not a dialog
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
-
- //----------------------------------------------------------------------------------
- // Initialize the size labels and fill the 2 combo boxes
- //----------------------------------------------------------------------------------
-
- // Fill the combo boxes
- m_cboCompressionFormat.AddString( "BZip2" );
- m_cboCompressionFormat.AddString( "GZip" );
- m_cboCompressionFormat.AddString( "Standard" );
- m_cboCompressionFormat.AddString( "Zip3" );
- m_cboCompressionFormat.AddString( "ZLib" );
- m_cboCompressionFormat.AddString( "BurrowsWheeler" );
- m_cboCompressionFormat.AddString( "Deflate" );
- m_cboCompressionFormat.AddString( "Store" );
-
- m_cboCompressionFormat.SetItemData( 0, cfBZip2 );
- m_cboCompressionFormat.SetItemData( 1, cfGZip );
- m_cboCompressionFormat.SetItemData( 2, cfStandard );
- m_cboCompressionFormat.SetItemData( 3, cfZip3 );
- m_cboCompressionFormat.SetItemData( 4, cfZLib );
- m_cboCompressionFormat.SetItemData( 5, cfBWT );
- m_cboCompressionFormat.SetItemData( 5, cfDeflate );
- m_cboCompressionFormat.SetItemData( 5, cfStore );
-
- m_cboCompressionFormat.SetCurSel( cfBZip2 );
-
- OnChangeTxtTocompress();
-
- return TRUE; // return TRUE unless you set the focus to a control
- }
-
- void CMemoryCompressDlg::OnSysCommand(UINT nID, LPARAM lParam)
- {
- if ((nID & 0xFFF0) == IDM_ABOUTBOX)
- {
- CAboutDlg dlgAbout;
- dlgAbout.DoModal();
- }
- else
- {
- 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 CMemoryCompressDlg::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 CMemoryCompressDlg::OnQueryDragIcon()
- {
- return (HCURSOR) m_hIcon;
- }
-
- //====================================================================================
- //
- // EVENTS - triggered by the form and its controls
- //
- //====================================================================================
-
- void CMemoryCompressDlg::OnChangeTxtTocompress()
- {
- if( UpdateData( TRUE ) )
- {
- m_sOriginalSize.Format( "%d", m_sToCompress.GetLength() );
- UpdateData( FALSE );
- }
- }
-
- //------------------------------------------------------------------------------------
- // Do the compression of the text
- //------------------------------------------------------------------------------------
- void CMemoryCompressDlg::OnCmdCompress()
- {
- if( UpdateData( TRUE ) )
- {
- CWaitCursor xWaitCursor;
-
- COleException* pExcept = new COleException;
- DXceedStreamingCompression xCompressor;
- COleVariant vaToCompress;
-
- try
- {
- // Create an instance of the XceedStreamingCompression class.
- if( !xCompressor.CreateDispatch( "Xceed.StreamingCompression", pExcept ) )
- {
- throw pExcept;
- }
-
- // Create and prepare the compression format (BZip2, GZip, ZLib, ...)
- // This function can throw an exception that will be caught here.
- PrepareCompressionFormat( xCompressor );
-
- // Store in the variant to compress the content of the text box
- // as an ANSI String. We could have used a BSTR representation
- // of the string but it would have unnecessarily doubled the string
- // size, and slightly affect the compression ratio. The Variant will
- // report containing a VT_BSTR, but the actual data and size will
- // reflect the Ansi string format.
- vaToCompress.SetString( m_sToCompress, VT_BSTRT );
-
- // Compress the string in a single call (bEndOfData is TRUE).
- m_vaCompressed = xCompressor.Compress( vaToCompress, TRUE );
-
- // We assign an value of 0 as a default compressed size.
- m_sCompressedSize = "0";
-
- // We check that the compressed variant is really a byte array. For instance,
- // it won't be if there was no characters to compress (empty string).
- if( m_vaCompressed.vt == ( VT_ARRAY | VT_UI1 ) )
- {
- LONG lHigh;
- LONG lLow;
-
- // We extracts the upper bound and the lower bound of the
- // byte array.
- SafeArrayGetUBound( m_vaCompressed.parray, 1, &lHigh );
- SafeArrayGetLBound( m_vaCompressed.parray, 1, &lLow );
-
- // We display the compressed size
- m_sCompressedSize.Format( "%d", lHigh - lLow + 1 );
- }
-
- // Update mainly the compressed size label
- UpdateData( FALSE );
- }
- catch( COleDispatchException* pEx )
- {
- pEx->ReportError();
- pEx->Delete();
- }
- catch( COleException* pEx )
- {
- pEx->ReportError();
- pEx->Delete();
- }
- catch( CException* pEx )
- {
- pEx->ReportError();
- pEx->Delete();
- }
-
- pExcept->Delete();
- }
- }
-
- //------------------------------------------------------------------------------------
- // Do the decompression of the compressed byte array
- //------------------------------------------------------------------------------------
- void CMemoryCompressDlg::OnCmdDecompress()
- {
- // If the user did not performed a compression first, refuse to Decompress
- if( m_vaCompressed.vt == VT_EMPTY )
- return;
-
- if( UpdateData( TRUE ) )
- {
- CWaitCursor xWaitCursor;
-
- COleException* pExcept = new COleException;
- DXceedStreamingCompression xCompressor;
- COleVariant vaDecompressed;
-
- try
- {
- // Create an instance of the Xceed Streaming Compression
- if( !xCompressor.CreateDispatch( "Xceed.StreamingCompression", pExcept ) )
- {
- throw pExcept;
- }
-
- // Create and prepare the compression format (BZip2, GZip, ZLib, ...)
- // This function can throw an exception that will be caught here.
- PrepareCompressionFormat( xCompressor );
-
- // Decompress the compressed byte array in a single call
- // (bEndOfData is TRUE).
- vaDecompressed = xCompressor.Decompress( m_vaCompressed, TRUE );
-
- // We assign an empty string as a default decompressed value.
- m_sDecompressed = "";
-
- // We check that the decompressed variant is really a byte array.
- if( vaDecompressed.vt == ( VT_ARRAY | VT_UI1 ) )
- {
- LONG lHigh;
- LONG lLow;
-
- // We extracts the upper bound and the lower bound of the
- // byte array.
- SafeArrayGetUBound( vaDecompressed.parray, 1, &lHigh );
- SafeArrayGetLBound( vaDecompressed.parray, 1, &lLow );
-
- // This pointer will contain the address of the byte array
- char* pszDecompressed = NULL;
-
- // We get a pointer on the actual data in the safe array.
- SafeArrayAccessData( vaDecompressed.parray, ( void** )&pszDecompressed );
-
- // We display the decompressed string by assigning this Ansi string
- // to the CString member, using the constructor accepting a char* and a size.
- m_sDecompressed = CString( pszDecompressed, lHigh - lLow + 1 );
-
- // We release the lock on the safe array
- SafeArrayUnaccessData( vaDecompressed.parray );
- }
-
- // Let's say we want to check format-specific properties. In this sample, when
- // compressing using the GZip format, we add a comment. Let's get it back!
- switch( m_lCompressionFormat )
- {
- case cfGZip:
- {
- DXceedGZipCompressionFormat xGZip = xCompressor.GetCompressionFormat();
-
- m_sDecompressed += "\r\nThe comment is: ";
- m_sDecompressed += xGZip.GetComment();
- break;
- }
- }
-
- // Update mainly the decompressed text box
- UpdateData( FALSE );
- }
- catch( COleDispatchException* pEx )
- {
- pEx->ReportError();
- pEx->Delete();
- }
- catch( COleException* pEx )
- {
- pEx->ReportError();
- pEx->Delete();
- }
- catch( CException* pEx )
- {
- pEx->ReportError();
- pEx->Delete();
- }
-
- pExcept->Delete();
- }
- }
-
- //------------------------------------------------------------------------------------
- // Quit the sample application
- //------------------------------------------------------------------------------------
- void CMemoryCompressDlg::OnQuit()
- {
- EndDialog( IDOK );
- }
-
- //====================================================================================
- //
- // FUNCTIONS
- //
- //====================================================================================
-
- //------------------------------------------------------------------------------------
- // Prepare the compression format according to the user selection
- //------------------------------------------------------------------------------------
- void CMemoryCompressDlg::PrepareCompressionFormat( DXceedStreamingCompression& xCompressor )
- {
- // To simplify the matter here, we use a generic compression format object data type
- // (xGenericOleDispatch is of type COleDispatchDriver)
-
- // If you need to set some properties on your compression format object, you'll need
- // to use the specific data type you create. This is demonstrated with the cfGZip case.
- COleDispatchDriver xGenericOleDispatch;
-
- if( UpdateData( TRUE ) )
- {
- COleException* pEx = new COleException;
-
- switch( m_lCompressionFormat )
- {
- case cfBZip2 :
- {
- if( !xGenericOleDispatch.CreateDispatch( "Xceed.BZip2CompressionFormat", pEx ) )
- {
- throw pEx;
- }
- break;
- }
-
- case cfGZip :
- {
- // Let's say we want to set some properties on our format object. We use
- // a specific DXceedGZipCompressionFormat variable instead of the generic one.
- DXceedGZipCompressionFormat xGZip;
-
- if( !xGZip.CreateDispatch( "Xceed.GZipCompressionFormat", pEx ) )
- {
- throw pEx;
- }
-
- xGZip.SetComment( "This is my comment" );
-
- // We make sure xGenericOleDispatch does point to this format object instance!
- // Simply transfert the responsability of this IDispatch interface reference.
- xGenericOleDispatch.AttachDispatch( xGZip.DetachDispatch() );
- break;
- }
-
- case cfStandard :
- {
- if( !xGenericOleDispatch.CreateDispatch( "Xceed.StandardCompressionFormat", pEx ) )
- {
- throw pEx;
- }
- break;
- }
-
- case cfZip3 :
- {
- if( !xGenericOleDispatch.CreateDispatch( "Xceed.Zip3CompressionFormat", pEx ) )
- {
- throw pEx;
- }
- break;
- }
-
- case cfZLib :
- {
- if( !xGenericOleDispatch.CreateDispatch( "Xceed.ZLibCompressionFormat", pEx ) )
- {
- throw pEx;
- }
- break;
- }
-
- // The next three items are not compression formats. They are compression
- // methods. They still can be assigned to the CompressionFormat property of the
- // XceedStreamingCompression object. In these cases, the resulting compressed
- // streams will have no formating (no header, footer, checksum, ...)
- case cfBWT :
- {
- if( !xGenericOleDispatch.CreateDispatch( "Xceed.BWTCompression", pEx ) )
- {
- throw pEx;
- }
- break;
- }
-
- case cfDeflate :
- {
- if( !xGenericOleDispatch.CreateDispatch( "Xceed.DeflateCompression", pEx ) )
- {
- throw pEx;
- }
- break;
- }
-
- case cfStore :
- {
- // Using Store as the compression format will produce an output
- // compressed stream identical to the original text!
- if( !xGenericOleDispatch.CreateDispatch( "Xceed.StoreCompression", pEx ) )
- {
- throw pEx;
- }
- break;
- }
- }
-
- if( xGenericOleDispatch.m_lpDispatch )
- {
- // Simply set the CompressionFormat property of our main XceedStreamingCompression instance
- xCompressor.SetRefCompressionFormat( xGenericOleDispatch.m_lpDispatch );
- }
-
- pEx->Delete();
- }
- }
-
-