📄 huffmandlg.cpp
字号:
// HuffmanDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Huffman.h"
#include "HuffmanDlg.h"
#include "dialog1Dlg.h"
#include "Dialog2.h"
#include "Afxcmn.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CHuffmanDlg dialog
int CHuffmanDlg::n=0;
huffnode * CHuffmanDlg::m_data=0;
CHuffmanDlg::CHuffmanDlg(CWnd* pParent /*=NULL*/)
: CDialog(CHuffmanDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CHuffmanDlg)
m_input = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CHuffmanDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CHuffmanDlg)
DDX_Control(pDX, IDC_EDIT2, m_edit2);
DDX_Text(pDX, IDC_EDIT1, m_input);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CHuffmanDlg, CDialog)
//{{AFX_MSG_MAP(CHuffmanDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_COMMAND(ID_SHOW_MENU, OnShowMenu)
ON_COMMAND(ID_EXIT_MENU, OnExitMenu)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
ON_COMMAND(ID_ABOUT_MENU, OnAboutMenu)
ON_EN_CHANGE(IDC_EDIT1, OnChangeEdit1)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
// ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHuffmanDlg message handlers
BOOL CHuffmanDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 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
z=0;
q=0;
// GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);
m_data=(huffnode*)malloc(256*sizeof(huffnode));
cdl=NULL;
return TRUE; // return TRUE unless you set the focus to a control
}
// 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 CHuffmanDlg::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 CHuffmanDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CHuffmanDlg::OnButton1()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
char ch,c[9];
int i=0,j=0,k,l,g;
CString x="";
char a[10]={0};
int m;
n=0;
m_data=(huffnode*)malloc(256*sizeof(huffnode));
for(i=0;i<=255;i++)
{
m_data[i].weight=m_data[i].start=0;
m_data[i].parent=-1;
m_data[i].left=m_data[i].right=-1;
}
m=m_input.GetLength();
num=m;
for( i=0;i<m;i++)
{
ch=m_input[i];
++m_data[ch].weight==1?n++:n;
}
m_data=(huffnode*)realloc(m_data,(n-1+256)*sizeof(huffnode));
for(i=0;i<n-1;i++)//初始化
{
m_data[256+i].weight=m_data[256+i].start=0;
m_data[256+i].parent=-1;
m_data[256+i].left=m_data[256+i].right=-1;
}
Creatree();
Coding_1();
z++;
// GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
if(cdl!=NULL)
{
j=0;
cdl->m_list.DeleteAllItems();
for(i=0;i<256;i++)
if(m_data[i].weight!=0)
{
l=0;
x.Format("%c",(char)i);
cdl->m_list.InsertItem(j,x);//插入行
x.Format("%d",m_data[i].weight);
cdl->m_list.SetItemText(j,1,x);//设置该行的不同列的显示字符
for(g=m_data[i].start;g<10;g++)
a[l++]=m_data[i].code[g];
a[l]='\0';
x=a;
cdl->m_list.SetItemText(j,2,x);
j++;
UpdateData(FALSE);
}
}
m_edit2.SetSel(0,-1);
for(i=0;i<m;i++)
{
l=0;
ch=m_input[i];
for( k=m_data[ch].start;k<10;k++)
c[l++]=m_data[ch].code[k];
c[l]='\0';
m_edit2.ReplaceSel(c);
}
UpdateData(FALSE);
}
void CHuffmanDlg::Creatree()
{
int m1,m2,l,r;
for(int i=256;i<256+n-1;i++)
{
m1=m2=32767;
l=r=0;
for(int k=0;k<=i-1;k++)
if(m_data[k].weight!=0&&m_data[k].parent==-1)
if(m_data[k].weight<m1)
{
m2=m1;
r=l;
m1=m_data[k].weight;
l=k;
}
else if(m_data[k].weight<m2)
{
m2=m_data[k].weight;
r=k;
}
m_data[l].parent=i;
m_data[r].parent=i;
m_data[i].weight=m_data[l].weight+m_data[r].weight;
m_data[i].left=l;
m_data[i].right=r;
}
}
void CHuffmanDlg::Coding_1()
{
int k,c,i,f;
for(i=0;i<256;i++)
if(m_data[i].weight!=0)
{//从叶结点开始逆向求编码
k=10;
c=i;
f=m_data[i].parent;
while(f!=-1)
{
if(m_data[f].left==c)
m_data[i].code[--k]='0';
else
m_data[i].code[--k]='1';
c=f;
f=m_data[f].parent;
}
m_data[i].start=k;
}
}
void CHuffmanDlg::OnShowMenu()
{
// TODO: Add your command handler code here
if(++q%2==1)
{
cdl=new Cdialog1Dlg;
cdl->Create(IDD_DIALOG1,this);
cdl->ShowWindow(SW_SHOW);
}
else
cdl->ShowWindow(SW_HIDE);
int i=0,j=0,k,l;
CString x;
char c[10];
cdl->m_list.InsertColumn(1,"字 符",LVCFMT_CENTER,105,0);//设置列
cdl->m_list.InsertColumn(1,"权 值",LVCFMT_CENTER,105,1);
cdl->m_list.InsertColumn(2,"编 码",LVCFMT_CENTER,105,2);
if(z>=1)
for(;i<256;i++)
if(m_data[i].weight!=0)
{
l=0;
x.Format("%c",(char)i);
cdl->m_list.InsertItem(j,x);//插入行
x.Format("%d",m_data[i].weight);
cdl->m_list.SetItemText(j,1,x);//设置该行的不同列的显示字符
for(k=m_data[i].start;k<10;k++)
c[l++]=m_data[i].code[k];
c[l]='\0';
x=c;
cdl->m_list.SetItemText(j,2,x);
j++;
}
}
void CHuffmanDlg::OnExitMenu()
{
// TODO: Add your command handler code here
OnOK();
}
void CHuffmanDlg::Coding_2()
{
}
void CHuffmanDlg::OnButton2()
{
// TODO: Add your control notification handler code
int m=0,p=1;
int t,j=0;
t=254+n;
UpdateData(TRUE);
m=m_input.GetLength();
CString s="",d="";
for(int i=0;i<m;i++)
if(m_data[t].left!=-1)
{
if(m_input[i]=='0')
t=m_data[t].left;
else if(m_input[i]=='1')
t=m_data[t].right;
else
{
AfxMessageBox("译码错误,请输入2进制代码!");
return;
}
}
else
{
s.GetBuffer(num)[j++]=(char)t;
t=254+n;
i--;
}
z++;
m_edit2.SetSel(0,-1);
m_edit2.ReplaceSel(s);
UpdateData(FALSE);
}
void CHuffmanDlg::OnAboutMenu()
{
// TODO: Add your command handler code here
Dialog2 ps;
ps.DoModal();
}
void CHuffmanDlg::OnChangeEdit1()
{
// TODO: If this is a RICHEDIT control, the control will not
// if(z%2==1)
// GetDlgItem(IDC_BUTTON2)->EnableWindow(SW_SHOW);
// else
// {
// GetDlgItem(IDC_BUTTON1)->EnableWindow(SW_SHOW);
// GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);
// }
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
// TODO: Add your control notification handler code here
}
void CHuffmanDlg::OnFileOpen()
{
// TODO: Add your command handler code here
CFileDialog openBox(TRUE,NULL,"",OFN_HIDEREADONLY,"ALL Files(*.*)|*.*||",GetDlgItem(IDD_HUFFMAN_DIALOG));
openBox.m_ofn.lpstrTitle="打开要编码/译码文件";
openBox.DoModal();
CFile mFile;
if(mFile.Open(openBox.GetFileName(),CFile::modeRead)==0)
{
return;
}
ASSERT(mFile.GetPosition() == 0);
DWORD nFileSize = mFile.GetLength();
CArchive ar(&mFile,CArchive::load);
ar.Read((void *)m_input.GetBuffer(nFileSize), nFileSize);
GetDlgItem(IDC_EDIT1)->SetWindowText(m_input);
UpdateData(FALSE);
// ar.Close();
// mFile.Close();
}
void CHuffmanDlg::OnFileSaveAs()
{
// TODO: Add your command handler code here
CFileDialog SaveBox(FALSE,NULL,"",OFN_HIDEREADONLY,"ALL Files(*.*)|*.*||",NULL);
SaveBox.m_ofn.lpstrTitle="文件另存为";
SaveBox.DoModal();
UpdateData(TRUE);
CFile mFile;
CString x;
if(mFile.Open(SaveBox.GetFileName(),CFile::modeCreate|CFile::modeReadWrite)==0)
{
return;
}
ASSERT(mFile.GetPosition() == 0);
m_edit2.GetWindowText(x);
CArchive ar(&mFile,CArchive::store);
ar.WriteString(x);
UpdateData(FALSE);
// ar.Close();
// mFile.Close();
}
void CHuffmanDlg::Serialize(CArchive& ar)
{
// if (ar.IsStoring())
// {
// ar<<m_input;// storing code
// }
// else
// {
// ar>>m_input;// loading code
// }
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -