📄 lzw_demodlg.cpp
字号:
// LZW_DemoDlg.cpp : implementation file
//
#include "stdafx.h"
#include "LZW_Demo.h"
#include "LZW_DemoDlg.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()
/////////////////////////////////////////////////////////////////////////////
// CLZW_DemoDlg dialog
CLZW_DemoDlg::CLZW_DemoDlg(CWnd* pParent /*=NULL*/)
: CDialog(CLZW_DemoDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CLZW_DemoDlg)
// 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 CLZW_DemoDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CLZW_DemoDlg)
DDX_Control(pDX, IDE_FILE, m_SelFile);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CLZW_DemoDlg, CDialog)
//{{AFX_MSG_MAP(CLZW_DemoDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDB_SELFILE, OnSelectFile)
ON_BN_CLICKED(IDB_ENCODE, OnEncode)
ON_BN_CLICKED(IDB_DECODE, OnDecode)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLZW_DemoDlg message handlers
BOOL CLZW_DemoDlg::OnInitDialog()
{
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
// TODO: Add extra initialization here
this->GetDlgItem (IDB_ENCODE)->EnableWindow (FALSE) ;
this->GetDlgItem (IDB_DECODE)->EnableWindow (FALSE) ;
this->GetDlgItem (IDS_METHOD)->SetWindowText (TEXT("LZW算法")) ;
::SetFocus (this->GetDlgItem (IDC_LZW)->GetSafeHwnd ()) ;
::SendMessage (this->GetDlgItem (IDC_LZW)->GetSafeHwnd (), BM_SETCHECK, BST_CHECKED, 0) ;
m_iMethod = 0 ; // LZW算法
return FALSE ; // return TRUE unless you set the focus to a control
}
void CLZW_DemoDlg::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 CLZW_DemoDlg::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 CLZW_DemoDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
BOOL fooShowFileDialog (HWND hWnd, BOOL bOpen, TCHAR * szFullName,
LPCTSTR szIniDir, LPCTSTR Title, LPCTSTR szFilter)
{
OPENFILENAME ofn ;
TCHAR InitDir[MAX_PATH] ;
if (szFullName == NULL)
return FALSE ;
if (szIniDir)
lstrcpy (InitDir, szIniDir) ;
else
::GetCurrentDirectory (MAX_PATH, InitDir) ;
::ZeroMemory (&ofn, sizeof(OPENFILENAME)) ;
szFullName[0] = TEXT('\0') ;
ofn.lStructSize = sizeof (OPENFILENAME) ;
ofn.hwndOwner = hWnd ;
ofn.hInstance = NULL ;
ofn.lpstrFilter = szFilter ? szFilter : TEXT("All Files (*.*)\0*.*\0\0") ;
ofn.lpstrCustomFilter = NULL ;
ofn.nMaxCustFilter = 0 ;
ofn.nFilterIndex = 0 ;
ofn.nMaxFile = MAX_PATH ;
ofn.nMaxFileTitle = MAX_PATH ;
ofn.lpstrInitialDir = InitDir ;
ofn.lpstrTitle = Title ? Title : (bOpen ? TEXT("Open File") : TEXT("Save File")) ;
ofn.lpstrFile = szFullName ;
ofn.nFileExtension = 0 ;
ofn.lpstrDefExt = TEXT("*") ;
ofn.lCustData = 0 ;
ofn.lpfnHook = NULL ;
ofn.lpTemplateName = NULL ;
ofn.Flags = OFN_ENABLESIZING | (bOpen ? 0 : OFN_OVERWRITEPROMPT) ;
return (bOpen ? (::GetOpenFileName (&ofn) != 0) : (::GetSaveFileName (&ofn) != 0)) ;
}
void fooFormatCommaNumber (DWORD dwNum, TCHAR * szBuffer, int iBufLen)
{
if ((szBuffer != NULL) && (iBufLen > 0))
{
TCHAR num[64] ;
::wsprintf (num, TEXT("%lu"), dwNum) ;
NUMBERFMT nf ;
nf.NumDigits = 0 ;
nf.LeadingZero = FALSE ;
nf.Grouping = 3 ;
nf.lpDecimalSep = TEXT(".") ;
nf.lpThousandSep = TEXT(",") ;
nf.NegativeOrder = 0 ;
::GetNumberFormat (LOCALE_USER_DEFAULT, 0, num, &nf, szBuffer, iBufLen) ;
}
}
void CLZW_DemoDlg::OnSelectFile()
{
// TODO: Add your control notification handler code here
TCHAR szFileName[MAX_PATH] ;
BOOL ret = ::fooShowFileDialog (AfxGetMainWnd()->m_hWnd,
TRUE, szFileName, NULL, TEXT("打开文件"),
"All Files (*.*)\0*.*\0"
"可执行文件 (*.exe;*.dll)\0*.exe;*.dll\0"
"文本文件 (*.txt)\0*.txt\0"
"Bmp Files (*.bmp)\0*.bmp\0"
"foo 压缩Files (*.foo)\0*.foo\0\0") ;
if (ret) // 选择
{
m_SelFile.SetWindowText (szFileName) ;
TCHAR ext[_MAX_EXT] ;
::_tsplitpath (szFileName, NULL, NULL, NULL, ext) ;
BOOL bfooFile = (::lstrcmpi (ext, TEXT(".foo")) == 0) ;
(this->GetDlgItem (IDB_ENCODE))->EnableWindow (!bfooFile) ;
(this->GetDlgItem (IDB_DECODE))->EnableWindow (bfooFile) ;
WIN32_FILE_ATTRIBUTE_DATA file_data ;
::GetFileAttributesEx (szFileName, GetFileExInfoStandard, &file_data) ;
if (bfooFile)
{
this->GetDlgItem (IDC_RLE)->EnableWindow (FALSE) ;
this->GetDlgItem (IDC_LZW)->EnableWindow (FALSE) ;
// foo压缩文件,读取文件信息
FCMemMapFile file ;
BYTE * pStart = (BYTE*)file.ReadFile (szFileName) ;
switch (*(WORD*)&pStart[10])
{
case 0 : m_iMethod = 0 ;
this->GetDlgItem (IDS_METHOD)->SetWindowText (TEXT("LZW算法")) ;
break ;
case 1 : m_iMethod = 1 ;
this->GetDlgItem (IDS_METHOD)->SetWindowText (TEXT("RLE算法")) ;
break ;
case 2 : m_iMethod = 2 ;
this->GetDlgItem (IDS_METHOD)->SetWindowText (TEXT("算术编码")) ;
break ;
case 3 : m_iMethod = 3 ;
this->GetDlgItem (IDS_METHOD)->SetWindowText (TEXT("Huffman编码")) ;
break ;
case 4 : m_iMethod = 4 ;
this->GetDlgItem (IDS_METHOD)->SetWindowText (TEXT("LZSS算法")) ;
break ;
}
TCHAR out[100] ;
::fooFormatCommaNumber (*(DWORD*)&pStart[12], out, 100) ;
this->GetDlgItem (IDS_OLDSIZE)->SetWindowText (out) ;
::fooFormatCommaNumber (file_data.nFileSizeLow, out, 100) ;
this->GetDlgItem (IDS_NEWSIZE)->SetWindowText (out) ;
::fooFormatCommaNumber (file_data.nFileSizeLow*100/(*(DWORD*)&pStart[12]), out, 100) ;
this->GetDlgItem (IDS_RATE)->SetWindowText (out) ;
::fooFormatCommaNumber (*(DWORD*)&pStart[16], out, 100) ;
this->GetDlgItem (IDS_ENCODETIME)->SetWindowText (out) ;
this->GetDlgItem (IDS_DECODETIME)->SetWindowText (TEXT("------")) ;
}
else
{
this->GetDlgItem (IDC_RLE)->EnableWindow (TRUE) ;
this->GetDlgItem (IDC_LZW)->EnableWindow (TRUE) ;
// 非压缩文件,设置文件属性
TCHAR out[100] ;
::fooFormatCommaNumber (file_data.nFileSizeLow, out, 100) ;
this->GetDlgItem (IDS_OLDSIZE)->SetWindowText (out) ;
this->GetDlgItem (IDS_NEWSIZE)->SetWindowText (TEXT("------")) ;
this->GetDlgItem (IDS_RATE)->SetWindowText (TEXT("------")) ;
this->GetDlgItem (IDS_ENCODETIME)->SetWindowText (TEXT("------")) ;
this->GetDlgItem (IDS_DECODETIME)->SetWindowText (TEXT("------")) ;
}
}
}
void CLZW_DemoDlg::OnEncode()
{
TCHAR SrcName[MAX_PATH] ; // 原文件名
TCHAR DestName[MAX_PATH] ; // 压缩文件的name
TCHAR drive[_MAX_DRIVE] ;
TCHAR dir[_MAX_DIR] ;
TCHAR fname[_MAX_FNAME] ;
TCHAR ext[_MAX_EXT] ;
m_SelFile.GetWindowText (SrcName, MAX_PATH) ;
::_tsplitpath (SrcName, drive, dir, fname, ext) ;
// 压缩文件名
::_tmakepath (DestName, drive, dir, fname, TEXT(".foo")) ;
// 文件是否存在
WIN32_FIND_DATA tempFileInfo ;
HANDLE hFind = ::FindFirstFile (DestName, &tempFileInfo) ;
bool bExist = (::GetLastError() != ERROR_FILE_NOT_FOUND) ;
::FindClose (hFind) ;
if (bExist)
if (::MessageBox (NULL, TEXT("目标文件已经存在,是否覆盖?"),
TEXT("文件存在"), MB_YESNO) == IDYES)
{
::SetFileAttributes (DestName, FILE_ATTRIBUTE_ARCHIVE) ;
::DeleteFile (DestName) ;
}
else
return ;
// 获得原文件信息
hFind = ::FindFirstFile (SrcName, &tempFileInfo) ;
::FindClose (hFind) ;
FCMemMapFile flSrc, flDest ;
BYTE * pDest = (BYTE *) flDest.CreateFile (DestName, tempFileInfo.nFileSizeLow * 2 + 2048) ;
ZeroMemory (pDest, tempFileInfo.nFileSizeLow * 2 + 2048) ;
BYTE * pSrc = (BYTE *) flSrc.ReadFile (SrcName) ;
BYTE * pCurr = pDest ;
if ((pDest == NULL) || (pSrc == NULL))
{
::MessageBox (NULL, TEXT("打开文件失败"), TEXT("错误"), MB_OK|MB_ICONSTOP) ;
return ;
}
// 写头
::lstrcpyA ((char*)pDest, "foo2002a") ;
pCurr += 8 ;
* (WORD *) pCurr = 16 ;
pCurr += 2 ;
* (WORD *) pCurr = m_iMethod ;
pCurr += 2 ;
* (DWORD *) pCurr = tempFileInfo.nFileSizeLow ;
pCurr += 4 ;
pCurr += 8 ;
// 文件名
::lstrcat (fname, ext) ;
int ii=::lstrlen (fname);
* (WORD *) pCurr = ::lstrlen (fname) ;
::lstrcpy ((char *)pCurr+2, fname) ;
pCurr += * (WORD *) pCurr + 2 ;
// 压缩
DWORD dwCounter = ::GetTickCount () ;
if (m_iMethod == 0)
{
FCLzw fLzw ;
pCurr += fLzw.LZW_Encode (pSrc, tempFileInfo.nFileSizeLow, pCurr) ;
}
else
{
pCurr = ::RLE_PCX_EncodeLine (pSrc, 8, tempFileInfo.nFileSizeLow, pCurr) ;
}
dwCounter = ::GetTickCount () - dwCounter ;
* (DWORD *) &pDest[16] = dwCounter ;
flDest.SetSize (pCurr - pDest) ;
// 设置
TCHAR out[50] ;
::fooFormatCommaNumber (dwCounter, out, 50) ;
this->GetDlgItem (IDS_ENCODETIME)->SetWindowText (out) ;
::fooFormatCommaNumber (pCurr - pDest, out, 50) ;
this->GetDlgItem (IDS_NEWSIZE)->SetWindowText (out) ;
::fooFormatCommaNumber ((pCurr - pDest)*100/tempFileInfo.nFileSizeLow, out, 50) ;
this->GetDlgItem (IDS_RATE)->SetWindowText (out) ;
}
void CLZW_DemoDlg::OnDecode()
{
TCHAR SrcName[MAX_PATH] ; // 压缩文件名
m_SelFile.GetWindowText (SrcName, MAX_PATH) ;
FCMemMapFile flCurr ;
BYTE * pSrc = (BYTE *) flCurr.ReadFile (SrcName) ;
if (pSrc == NULL)
{
::MessageBox (NULL, TEXT("打开文件失败"), TEXT("错误"), MB_OK|MB_ICONSTOP) ;
return ;
}
// 获得原文件名
TCHAR szOldName[MAX_PATH] ;
ZeroMemory (szOldName, sizeof(TCHAR) * MAX_PATH) ;
CopyMemory (szOldName, &pSrc[26], * (WORD *) &pSrc[24]) ;
// 文件是否存在
WIN32_FIND_DATA tempFileInfo ;
HANDLE hFind = ::FindFirstFile (szOldName, &tempFileInfo) ;
bool bExist = (::GetLastError() != ERROR_FILE_NOT_FOUND) ;
::FindClose (hFind) ;
if (bExist)
if (::MessageBox (NULL, TEXT("目标文件已经存在,是否覆盖?"),
TEXT("文件存在"), MB_YESNO) == IDYES)
{
::SetFileAttributes (szOldName, FILE_ATTRIBUTE_ARCHIVE) ;
::DeleteFile (szOldName) ;
}
else
return ;
// 创建文件
FCMemMapFile flOld ;
DWORD dwOldSize = * (DWORD *) &pSrc[12] ;
BYTE * pDest = (BYTE *) flOld.CreateFile (szOldName, dwOldSize) ;
ZeroMemory (pDest, dwOldSize) ;
if (pDest == NULL)
{
::MessageBox (NULL, TEXT("打开文件失败"), TEXT("错误"), MB_OK|MB_ICONSTOP) ;
return ;
}
// 解码
DWORD dwCounter = ::GetTickCount () ;
if (* (WORD *) &pSrc[10] == 0)
{
pSrc += 26 + (* (WORD *) &pSrc[24]) ;
FCLzw lzw ;
lzw.LZW_Decode (pSrc, pDest) ;
}
else
{
pSrc += 26 + (* (WORD *) &pSrc[24]) ;
::RLE_PCX_DecodeLine (pSrc, 8, dwOldSize, pDest) ;
}
dwCounter = ::GetTickCount () - dwCounter ;
flOld.SetSize (dwOldSize) ;
TCHAR out[50] ;
::fooFormatCommaNumber (dwCounter, out, 50) ;
this->GetDlgItem (IDS_DECODETIME)->SetWindowText (out) ;
}
BOOL CLZW_DemoDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
switch (LOWORD(wParam))
{
case IDC_LZW : m_iMethod = 0 ;
this->GetDlgItem (IDS_METHOD)->SetWindowText (TEXT("LZW算法")) ;
break ;
case IDC_RLE : m_iMethod = 1 ;
this->GetDlgItem (IDS_METHOD)->SetWindowText (TEXT("RLE算法")) ;
break ;
case IDC_ARITH : m_iMethod = 2 ;
this->GetDlgItem (IDS_METHOD)->SetWindowText (TEXT("算术编码")) ;
break ;
case IDC_HUFFMAN : m_iMethod = 3 ;
this->GetDlgItem (IDS_METHOD)->SetWindowText (TEXT("Huffman编码")) ;
break ;
case IDC_LZSS : m_iMethod = 4 ;
this->GetDlgItem (IDS_METHOD)->SetWindowText (TEXT("LZSS算法")) ;
break ;
}
return CDialog::OnCommand(wParam, lParam);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -