⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 9914.txt

📁 关于编程技术技巧的文章
💻 TXT
📖 第 1 页 / 共 3 页
字号:
===========================================================

                         《编 程 技 术》

               一份属于广大编程爱好者的电子杂志

             这是一份完全关于探讨编程的免费电子杂志
             您可以任意传播本刊,但必须保持它的完整
            本刊承诺绝不向订户发送任何形式的垃圾邮件!
===========================================================     
             第14期 99/06/27          本期发送数: 1859
===========================================================

<本期栏目>
 *刊首语*
 *技术文档*
    用VC++5.0编写文件分割工具
    如何在VC5下实现自己的定制控件
    用VB制作下雪的特技景象
    自己编程实现对CIH病毒的预防
    在VFP中如何自动生成统计图 
 *疑难杂症*

***********************************************************

<刊首语>
    
    嘿嘿,大家好,我的国际顶级域名http://www.yaozheng.net正
式启用了,当然是“免费”注册的,不信您可以试试,想必许多朋友
都已经知道这个秘密了吧。我是不敢独享这么好的事。如果您还不知
道的话,快去www.webprovider.com 看看吧。不仅能得到10M的免费
空间,更酷的是能免费注册到一个国际顶级域名。不过我不太清楚他
们这么做有什么“阴谋”,希望大家在注册的时候仔细一点。万一要
你交钱或是别的什么的,我可不负什么责任的哦!(我英语太臭,有
些东东实在看不懂:-) )

***********************************************************
***********************************************************

<技术文档>

                用VC++5.0编写文件分割工具 

                      (天津 房超)

  在实际工作中,经常会遇到一些比较大而自己又非常需要的文件,并且必须
通过软盘来进行转移。这时候就必须对该文件进行分割,然后分盘拷贝,最后再
恢复。如果手头没有相应的分割软件,那就麻烦了。不过,如果您机器里装有
VC++5.0,并具备一定VC++5.0编程的知识,就完全可以编写出自己的分割工
具,还可以根据个人的喜好,设计出具有自己风格的用户界面。
  前不久,笔者就用VC++5.0编写了一个自己的分割软件。通过多次分割试验,
效果还可以,完全可以实现对文件的分割处理。以下就是整个软件的编写过程。
  一. 文件分割的基本原理
  文件之所以能够被分割,是与文件在计算机里的存储方式密切相关的,大家
都知道,所有文件都是以二进制的形式存储于介质(包括硬盘、软盘等外部存储
器)之中。计算机在读取文件时,总是把数据转化成二进制的形式,然后再根据
文件系统的相应规定来分别进行处理。具体的说明可参见相关资料。基于这个道
理,所有文件都可以以二进制的格式进行读写、分割,然后再以二进制的格式把
分割后的文件重新组合起来。这样就实现了对文件的分割和恢复。这里要用到一
个DOS的内部命令——COPY,具体用法如下:
  copy filename1/b+filename2/b+
  …+filenameN/b filename
  这里,开关选项b是指以二进制的形式对文件进行拷贝;filenameN是被分割
成的N个文件;filename是组合后的文件名,一般同原文件名。
  二. 程序编写过程及禅解
  1.先创建一个名为Splite的工程文件,利用AppWizard生成一个基于对话框
的程序框架。对话框具有如图所示的各类控件。其中,编辑框1要求输入要被分割
的文件名,可以通过浏览按钮选择;列表框2能够显示分割后的文件列表;编辑框
3显示分割成的文件数,也就是需要的软盘数;要分割的文件被选择之后,按下分
割按钮,即可进行分割操作。
  2.程序编写
  (1).使用Class Wizard的Member Variables 制表页给编辑框1(ID号为:
IDC_EDIT_FILENAME)添加变量m_fName。
  (2).在SpliteDlg.h里加上下面程序段阴影部分的代码。
  class CSpliteDlg : public CDialog
  {
  // Construction
  public:
   CSpliteDlg(CWnd* pParent = NULL); // standard constructor
   CString SplitFileName[20],FileTitle;
   DWORD FileLength,SingleDisk;
   BOOL FileState;
   int DiskNum;
  // Dialog Data
   //{{AFX_DATA(CSpliteDlg)
   enum { IDD = IDD_SPLITE_DIALOG };
   CString m_fName;
   //}}AFX_DATA
   int SplitDiskNum(CFile &files);
   BOOL SpliteFiletoNum(CFile &file);
  SplitFileName[20]是分割后的文件名数组,这里定义为20个;FileTitle是除
去后缀的文件名;FileLength是要分割的文件长度;布尔量FileState是判断分割
是否成功的标志,成功则在列表框2中显示分割后的文件列表;整型数DiskNum是指
分割后的文件数。
  函数SplitDiskNum(CFile &files)对要分割的文件进行判断,并返回分割后
的文件数(也就是需要的软盘数);函数SpliteFiletoNum(CFile &file)将完成
文件的分割过程,成功则返回TURE,否则返回FALSE。
  (3).打开SpliteDlg.cpp,在SpliteDlg.cpp里添加上述函数和其它功能的实
现代码。如下:
  a.在构造函数中添加以下阴影处代码
   SingleDisk=2048*705; //一张软盘的容量
   FileState=FALSE;
   DiskNum=1;
  b.在OnPaint(CDC *pDC)函数末尾添加以下代码:
  UpdateData(FALSE); //初始化编辑框1的变量
   GotoDlgCtrl(GetDlgItem(IDC_EDIT_FILENAME)); //将光标指定到编辑框1中
   CListBox *pList =(CListBox *) GetDlgItem(IDC_LIST_RESULT); 
  //设置列表框2的ClistBox对象指针
   pList->ResetContent(); //重新设置列表框内容
   if(FileState==TRUE) //文件分割成功
   {
   for(i=0;i<=disknum;i++)
   pList->AddString(SplitFileName[i]); //向列表框中添加分割后的文件名
   }
  c.利用Class Wizard添加“浏览”按钮的响应函数,代码如下:
  void CSpliteDlg::OnButtonBrowse() 
  {
  char Filter[]=“所有文件(*.*)|*.*||";
  CFileDialog dlgOpen(TRUE,0,0,OFN_HIDEREADONLY|OFN_FILEMUSTEXIST,
  (LPCTSTR)Filter,NULL);
  if(dlgOpen.DoModal()==IDOK)
  {
   m_fName=dlgOpen.GetPathName();
   FileTitle=dlgOpen.GetFileName(); //取得要分割的文件名(不包含路径、扩展名)
  }
  else return ;
  SetDlgItemText(IDC_EDIT_FILENAME, (LPCTSTR)m_fName); //在编辑框1中显示文件名
  SetDlgItemText(IDC_EDIT_DISKNUM, _T(“")); //在编辑框3中覆盖前次操作的文件数
  Invalidate(TRUE); //对对话框窗口进行重画
  }
  d.利用Class Wizard添加“分割”按钮的响应函数,代码如下:
  void CSpliteDlg::OnButtonSplite() 
  {
   CFile files;
   CFileException fe;
   if (!files.Open(m_fName, CFile::modeRead | CFile::shareDenyWrite, &fe))
   {
   CString sMsg;
   sMsg.Format(“读取%s文件时发生错误!",m_fName);
   AfxMessageBox(sMsg,MB_OK,0);
   return ;
   }
   int i;
   DiskNum=SplitDiskNum(files);
   CString sMsg;
   if(DiskNum>=2)
   {
   sMsg.Format(“%d",DiskNum);
   SetDlgItemText(IDC_EDIT_DISKNUM, (LPCTSTR)sMsg); //在编辑框3中显示文件数
  进 if(SpliteFiletoNum(files)==0) //调用分割函数行分割操作
   {
   AfxMessageBox(“分割文件失败!",MB_OK,0);
   }
   else 
   {
   AfxMessageBox(“分割文件成功!",MB_OK,0);
   FileState=TRUE; //分割成功,设置成功标志
   Invalidate(TRUE);
   }
   }
   else return;
   files.Close(); //关闭打开的被分割文件
  }
  添加函数SplitDiskNum(CFile &files)代码如下:
  int CSpliteDlg::SplitDiskNum(CFile &files)
  {
   int DiskNum;
   FileLength=files.GetLength(); //取得要分割文件的长度
   if(FileLength<=singledisk)
   {
   AfxMessageBox(“该文件能被一张盘复制,不必分割!",MB_OK,0);
   DiskNum=0;
  }
   else DiskNum=FileLength/SingleDisk+1; //计算分割后的文件数
  return DiskNum;
  }
  添加函数SpliteFiletoNum(CFile &file)代码如下:
  BOOL CSpliteDlg::SpliteFiletoNum(CFile &file)
  {
   BOOL Success=FALSE;
   int i;
   DWORD dwBitsSize=SingleDisk; // dwBitsSize是指写入文件的字节数
   CFile filed;
   CString FileNum;
  //开辟数据缓冲区,大小为一张软盘的容量
   HANDLE filedate;
   filedate = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,SingleDisk);
   unsigned char * imgtemp;
   imgtemp=(unsigned char *)::GlobalLock((HGLOBAL)filedate);
  //对文件进行分割,并写入分割后的文件中
   for(i=1;i<=disknum;i++)
   {
   FileNum.Format(“%d.%d",i,i);
   SplitFileName[i-1]=FileTitle+FileNum;
   if(i==DiskNum) dwBitsSize =FileLength-(DiskNum-1)*SingleDisk;
   file.Seek(SingleDisk*(i-1),CFile::begin);
   if(file.ReadHuge(imgtemp, dwBitsSize)!= dwBitsSize)
   return FALSE;
   filed.Open(SplitFileName[i-1],CFile::modeCreate|CFile::modeWrite,0);
   filed.WriteHuge(imgtemp, dwBitsSize);
   filed.Close();
   }
   if(i==(DiskNum+1)) Success=TRUE; //判断分割是否成功
  //创建合并文件的批处理文件
   FileNum=_T(“.bat");
   SplitFileName[DiskNum]=FileTitle+FileNum;
   filed.Open(SplitFileName[DiskNum],CFile::modeCreate|CFile::modeWrite,0);
   CString BatContent=_T(“copy ");
   CString BatFile[20];
   for(i=0;i    {
   BatFile[i]=SplitFileName[i]+_T(“/b");
   BatContent+=BatFile[i];
   if(i!=DiskNum-1) BatContent+=_T(“+");
   else BatContent+=_T(“ ");
   }
   BatContent+=m_fName;
  //按照“copy filename1/b+filename2/b+…+filenameN/b filename”的顺序写入批处理
   for(i=0;i    {
   unsigned char ch=BatContent[i];
   filed.Write(&ch,1);
   }
   return Success;
  filed.Close();
  }
  以上是该程序的主要代码,在VC++5.0下通过编译后,将生成可执行文件Split.exe。
该程序只是实现了对文件的分割处理,读者也可以根据个人需要,设计出自己喜好的界面
风格,还可以加入其它相关的功能。本文旨在起到抛砖引玉的作用,给广大读者以启发,
希望大家都能编写出功能强大并且属于自己的分割软件。
          
***********************************************************

                   如何在VC5下实现自己的定制控件 

                           (辽宁 宋立波)          

  首先利用应用程序向导AppWizard 生成应用程序框架,如本文的应用程序项目
名称为ctrltest,应用程序根据需要选择其基类,可以是基于对话或文档的,本文
是选择基于文档的,并具有默认的下拉菜单和工具条等功能;然后编辑菜单资源,
设置响应定制功能菜单项名称、ID标识;利用类向导ClassWizard 为菜单项映射命
令和更新消息函数;为定制功能增加所使用的图形资源和对话框等资源;最后为定
制功能增加所需的成员变量和成员函数定义。
  一、如何实现按钮的定制功能
  在定制按钮功能时,定制前必须设计好按钮所在的标准对话及定制按钮在对话
框中所对应的标准按钮,因为定制按钮实际上是标准按钮的一种特殊情况,只是按
钮上显示的信息由用户来定制,而其余的消息映射响应和更新方法均相同,所以定
制按钮实际上也是定制按钮上各种显示信息的过程。
  (一)利用LoadBitmaps函数定制方法
  1、在资源对话窗口中增加按钮所需的按下、抬起和选中状态对应的位图及其
ID标识;
  2、在资源对话窗口中增加按钮所在的对话框和标准按钮及其所对应的各种ID
标识;
  3、利用类向导ClassWizard增加新类CBMTest1Dlg,其基类选择基于对话框
CDialog的类型,并设置其头文件为Bbutton.cpp,但不设置其实现文件名;
  4、在实现文件Bbutton.cpp中进行如下代码完善:
   ......//其它代码
   class CBMTest1Dlg : public CDialog
   {//完善类控制代码
   protected:
   CBitmapButton button1,button2;//定义按钮
   public:
   //{{AFX_DATA(CBMTest1Dlg)
  enum {IDD=IDM_TEST_BITMAP_BUTTON1};//对话框标识
   //}}AFX_DATA
   CBMTest1Dlg(); //类实现文件

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -