MFC制作的文件打包工具

时间:2021-07-21 18:38:58
MFC制作的文件打包工具
由于个人以前对VC6.0比较熟悉,当然也尝试使用VS2008,还是感觉VC6.0比较简单明了!!!
1.编译工具:VC6.0
新建工程:新建->弹出框->工程->MFC AppWizarp(exe)->填上工程名
2.图形使用:基本控件如按钮、编辑框、标签等都是可以通过拉取来布局,右键属性修改一些设置如ID,名称等,双击生成函数会提示函数名命名。
3.按钮控件:在生成的函数里,就是按钮按下所要执行的事件。
4.编辑框:SetDlgItemText(IDC_FILEPATH_EDIT,filename);//在一个地址为IDC_FILEPATH_EDIT的editbox中显示文件名
5.CFile类的使用:CFileDialog opendlg (TRUE,_T("*"),NULL,OFN_OVERWRITEPROMPT, _T("所有文件(*.*;)|*.*||"),NULL);   
if (opendlg.DoModal()==IDOK)
{
filename=opendlg.GetPathName();   
  CFileDialog Dlg( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL );
    各个参数的意义说明如下:
    bOpenFileDialog 为TRUE则显示打开文件对话框,为FALSE则显示保存文件对话框。 
    lpszDefExt 指定默认的文件扩展名。 
    lpszFileName 指定默认的文件名。 
    dwFlags 指明一些特定风格。 
    lpszFilter 是最重要的一个参数,它指明可供选择的文件类型和相应的扩展名。

5.新建自己的类
插入->类->选择类的类型下的generic class->填上名字确定即可
6.文件的打包解包
直接上代码:
class packFile  
{
public:
packFile();
virtual ~packFile();
int OpenMasFile(const char* path, const byte onlyOpen);
int WriteFileToPak(const char* path);
int ReadFileFromPak(const FilesMsg msg, byte* _dst);
int GetFileMessage( const char* path, FilesMsg* msg);
int CloseMasFile( void );
};
// 打开包文件  
int packFile::OpenMasFile(const char* path, const byte onlyOpen) 
{   
uint       uWriteCount;       // 写入文件信息次数  
byte       bIsNew = 0;        // 是否新建的  
MaseHeader header;            // 文件头结构定义  
FilesMsg   msg;               //文件信息结构定义 
g_pMasFile = fopen(path, "rb");  //用来判断是否存在  
if (g_pMasFile == NULL)      
{   
 if (onlyOpen == 1)            // 只打开不新建  
 return -1;  
 bIsNew = 1;   
 g_pMasFile = fopen(path, "wb"); 
 if (g_pMasFile == NULL) 
  return -1; 
}   


 //先关闭,然后在用"rb+"方式打开  二进制读写打开文件 
fclose( g_pMasFile );   
g_pMasFile = fopen(path, "rb+"); 
if(g_pMasFile == NULL)
return -1; 
if(bIsNew == 1)// 新建的文件  
{   
header.uFileFlag = 'ESAM'; 
   header.uFileCount= 0;   
header.uFileListOfs  = sizeof(MaseHeader); //紧跟着就是文件列表  
header.uMaxFileCount = MAX_FILE_COUNT;   
header.uFileSize     = sizeof(MaseHeader)+(MAX_FILE_COUNT * sizeof(FilesMsg)); 
//写入头信息  
fwrite(&header, sizeof(MaseHeader), 1, g_pMasFile);
memset(&msg, 0, sizeof(FilesMsg)); 
uWriteCount = MAX_FILE_COUNT;   
    //写入文件列表用0占位  
while(uWriteCount--) 
 fwrite(&msg, sizeof(FilesMsg), 1, g_pMasFile); 
  


}   
else//文件存在  
{   
//则读取头文件信息  
fread(&header, sizeof(MaseHeader), 1, g_pMasFile); 
}   
 //检查文件头标记  
if (header.uFileFlag != 'ESAM') 
{   
 fclose(g_pMasFile);  
 printf("文件头标记不对,错误!\n");
 return -1; 
}   


//检查数据是否完整  
if (header.uMaxFileCount != MAX_FILE_COUNT) 
{   
 fclose(g_pMasFile);   
 printf("数据不完整,错误!\n");
 return -1; 
}  
return 0; 
}   


//写文件到包里  
int packFile::WriteFileToPak(const char* path) 
{   
FilesMsg   fileMsg;      //此文件的文件信息结构  
MaseHeader header;       //包文件头结构定义  
uint       uFileSize;   
uint       uFileListEndOfs;   
byte*      pBuff;   
FILE*      pFile = NULL; 
if (g_pMasFile == NULL) 
     return -1; 
memset(&fileMsg, 0, sizeof(FilesMsg)); 
fseek(g_pMasFile, 0, SEEK_SET);    //定位到文件头,读取头文件信息 


//则读取头文件信息  
fread(&header,sizeof(MaseHeader), 1, g_pMasFile); 
uFileListEndOfs = header.uFileCount * sizeof(FilesMsg) + header.uFileListOfs; 
pFile = fopen(path, "rb"); 
if(pFile == NULL) 
return -1; 
fseek(pFile, 0, SEEK_END);   
uFileSize = ftell(pFile);   
fseek(pFile, 0, SEEK_SET);   
//文件名长度不能超过260  
strcpy(fileMsg.szFileName,path);   
fileMsg.uFileOfs  = header.uFileSize;   
fileMsg.uFileSize = uFileSize;   
// 写入文件信息  
// 将文件指针定位到uFileListEndOfs处,以便写入新的文件信息结构  
fseek(g_pMasFile, uFileListEndOfs, SEEK_SET);   
fwrite(&fileMsg,sizeof(FilesMsg),1,g_pMasFile); 
// 申请空间  
pBuff = (byte*)malloc(uFileSize);   
fread(pBuff,uFileSize,1,pFile);   
// 写数据到包文件里  
fseek(g_pMasFile,header.uFileSize,SEEK_SET);   
fwrite(pBuff, uFileSize, 1, g_pMasFile);   
// 释放内存  


free(pBuff);   
//重新填充header  
header.uFileCount += 1;   
header.uFileSize  += uFileSize;   
fseek( g_pMasFile,0,SEEK_SET);   
// 重新写入包文件头  
fwrite(&header,sizeof(MaseHeader),1,g_pMasFile); 
return 0; 
}   


//从包文件里读数据  
int packFile::ReadFileFromPak(const FilesMsg msg, byte* _dst) 
{   
if ( g_pMasFile == NULL ) 
return -1; 
fseek(g_pMasFile, msg.uFileOfs,SEEK_SET);   
fread(_dst, msg.uFileSize, 1, g_pMasFile);   
return 0; 
}   


//获取包中某个文件的信息  
int packFile::GetFileMessage( const char* path, FilesMsg* msg) 
{   
FilesMsg   fileMsg;      // 此文件的文件信息结构  
MaseHeader header;       // 包头结构  
uint       uFileCount;   // 文件个数  
if ( g_pMasFile == NULL || msg == NULL ) 
return -1; 
// 则读取头文件信息  
fseek(g_pMasFile, 0, SEEK_SET);   
fread(&header, sizeof(MaseHeader), 1, g_pMasFile); 
uFileCount = header.uFileCount;   
while (uFileCount--) 
{   
fread(&fileMsg, sizeof(FilesMsg), 1,g_pMasFile); 
// 判断是否是要获取的文件  
if (stricmp(fileMsg.szFileName, path) == 0 ) 
{               
*msg = fileMsg;   
return 0; 
}   
}   
return -1; 
}   


   
// 关闭包文件  
int packFile::CloseMasFile( void ) 
{   
    if ( g_pMasFile == NULL );
     return -1; 
fclose( g_pMasFile );   
g_pMasFile = NULL;   
return 0; 
}  
调用
void CPackToolDlg::OnSelectFile() 
{
// TODO: Add your control notification handler code here
//ifstream fin(filename); 
//ofstream fout("a.txt"); 
//CString filename;//保存路径


CFileDialog opendlg (TRUE,_T("*"),NULL,OFN_OVERWRITEPROMPT, _T("所有文件(*.*;)|*.*||"),NULL);   
if (opendlg.DoModal()==IDOK)
{
filename=opendlg.GetPathName();   
SetDlgItemText(IDC_FILEPATH_EDIT,filename);//在一个地址为IDC_FILEPATH_EDIT的editbox中显示文件名

    
}


void CPackToolDlg::OnPack() 
{
// TODO: Add your control notification handler code here
int ret; 
packFile *packTemp;
char changName[100]="";
if(filename=="")
{
    INT_PTR nRes;   
  
// 显示消息对话框   
nRes = MessageBox(_T("没有选择文件"), _T("警告"), MB_OK | MB_ICONWARNING);   
// 判断消息对话框返回值。如果为IDCANCEL就return,否则继续向下执行   
return;   
}
sprintf(changName,"%s.dat",filename);
ret = packTemp->OpenMasFile(changName,0); 
     if ( ret == -1 ) 
     goto __exit;    
//WriteFileToPak( "E:\\珍贵.jpg" ); 
//WriteFileToPak( "E:\\123.docx" ); 
packTemp->WriteFileToPak(filename); 
MessageBox(_T("打包完成"), _T("提醒"), MB_OK | MB_ICONINFORMATION);   
// 判断消息对话框返回值。如果为IDCANCEL就return,否则继续向下执行   
return;   
__exit:   
packTemp->CloseMasFile();  
MessageBox(_T("打包失败"), _T("警告"), MB_OK | MB_ICONWARNING); 
return;
}


void CPackToolDlg::OnUnpack() 
{
// TODO: Add your control notification handler code here
packFile *packTemp;
byte*       pBuff;   
FILE*       pOutFile; 
FilesMsg    getFileMsg;   
int         ret; 
char changName[100]="";
int len=0;
      if(filename=="")
{
    INT_PTR nRes;   
  
// 显示消息对话框   
nRes = MessageBox(_T("没有选择文件"), _T("警告"), MB_OK | MB_ICONWARNING);   
// 判断消息对话框返回值。如果为IDCANCEL就return,否则继续向下执行   
return;   
}
sprintf(changName,"%s",filename);
len = strlen(changName);
if (changName[len - 4] == '.') changName[len - 4] = '\0';
ret = packTemp->OpenMasFile(filename, 1); 
if (ret == -1) 
goto __exit; 
ret = packTemp->GetFileMessage(changName, &getFileMsg); 
if(ret == -1) 
goto __exit; 
pBuff = (byte*)malloc(getFileMsg.uFileSize);   
ret = packTemp->ReadFileFromPak(getFileMsg, pBuff);   
if(ret == -1) 
goto __exit_free; 
pOutFile = fopen(changName, "wb");  // 注意使用的是二进制模式  
if(ret == -1) 
goto __exit_free; 
fwrite( pBuff, getFileMsg.uFileSize, 1, pOutFile );   
fclose( pOutFile );  
MessageBox(_T("解包完成"), _T("提醒"), MB_OK | MB_ICONINFORMATION); 
return;
__exit_free:   
free( pBuff );   
__exit:   
packTemp->CloseMasFile();   
MessageBox(_T("解包失败,可能文件格式不对"), _T("警告"), MB_OK | MB_ICONWARNING); 
   return;
}
7.消息框
              INT_PTR nRes;   
// 显示消息对话框   
nRes = MessageBox(_T("没有选择文件"), _T("警告"), MB_OK | MB_ICONWARNING);   
// 判断消息对话框返回值。如果为IDCANCEL就return,否则继续向下执行   
return;   

8.MFC初始化
BOOL CPackToolDlg::OnInitDialog()
9.MFC获取时间
CTime m_time;  
CString m_strDateTime;
    m_time=CTime::GetCurrentTime();             //获取当前时间日期  
    m_strDateTime=m_time.Format(_T("%Y-%m-%d %H:%M:%S"));   //格式化日期时间  
10.编辑框填入信息与获取信息
SetDlgItemText(IDC_TIME_EDIT,m_strDateTime);
CString version,time,md5;
GetDlgItem(IDC_VERSION_EDIT)->GetWindowText(version); 
 GetDlgItem(IDC_TIME_EDIT)->GetWindowText(time);
  GetDlgItem(IDC_MD5_EDIT)->GetWindowText(md5);
 
11.全局变量的定义
在.cpp文件里的定义全局变量不会报错
附上一张效果图:
MFC制作的文件打包工具
12.main函数传参
int main(int argc, char* argv[])

运行命令为:

hello.exe I  LOVE YOU

那么,argc的值是 4,argv[0]是"hello.exe",argv[1]是"I",argv[2]是"LOVE"