📄 visual c++ 50 编 程 经 验.htm
字号:
MSG Message; DeleteFile(ExitFlag); SetTimer(1,100,NULL);// 设 置 计 时 器 Search=TRUE; while(Search) { if (::PeekMessage(&Message,NULL,0,0,PM_REMOVE)) { ::TranslateMessage(&Message); ::DispatchMessage(&Message); } }// 进 程 结 束 前 后 的 处 理 工 作 DWORDExitCode; if (!GetExitCodeProcess(pro_info.hProcess,&ExitCode)) AfxMessageBox("GetExitCodeProcess is Failed!"); if (!TerminateProcess(pro_info.hProcess,(UINT)ExitCode)) // 终 止 进 程 AfxMessageBox("TerminateProcess is Failed!"); if (!CloseHandle(pro_info.hProcess)) // 释 放 被 终 止 进 程 的 句 柄 AfxMessageBox("CloseHandle is Failed!"); KillTimer(1);// 撤 消 计 时 器 } else AfxMessageBox("Process Is Not Created!"); SetCurrentDirectory(lpBuffer);// 回 复 到 原 来 的 目 录 下}</pre> <ul type="square"> <li>同 时 按 下Ctrl 和W 键 或 直 接 单 击 工 具 条 上 的ClassWizard 按 钮, 打 开ClassWizard 对 话 框。 在 类 名(Class name) 列 表 框 中 选 择 需 要 调 用ARJ.EXE 进 行 压 缩/ 解 压 缩 的 类, 在Object IDs 列 表 框 中 选 择 该 类 的 类 名 后, 在 消 息(Messages) 列 表 框 中 选 择WM_TIMER 消 息 并 双 击 它, 这 时ClassWizard 就 会 在 该 类 中 加 入 一 个OnTimer() 函 数。 该 函 数 将 以 一 定 的 时 间 间 隔 检 查 压 缩/ 解 压 缩 程 序 是 否 已 经 执 行 完 毕, 即 检 查 作 为 标 志 的 临 时 文 件 是 否 已 经 存 在, 并 及 时 修 改 状 态 变 量“Search”, 以 便 通 知RunBat() 函 数 结 束 进 程。 </li> </ul> <pre>void CMyCompress::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default CFile file; CFileException Error; if (file.Open(ExitFlag,CFile::modeRead,&Error)) { Search=FALSE; file.Close(); }}</pre> <h3><font color="#FF0000">自 编 删 除 目 录 及 其 下 属 文 件 的 函 数</font></h3> <h3><font color="#FFFFFF">----</font> 高 版 本 的MS-DOS 和Windows 95 都 提 供 了 一 个 可 以 删 除 一 个 或 多 个 目 录 及 其 下 属 文 件 和 目 录 的 命 令, 即DeleteTree 命 令。 然 而, 无 论 在MFC 类 库 还 是 在Win32 函 数 库 中, 都 没 有 相 应 的 函 数 与 之 对 应。 这 样, 当 我 们 在 自 己 设 计 的 应 用 程 序 中 需 要 用 到DeleteTree 的 功 能 时, 自 然 想 到 的 方 法 是 通 过 进 程 调 用 或 者 系 统 调 用 的 方 式( 正 如 上 面 部 分 所 述 的 那 样) 调 用MD-DOS 或Windows 95 下 的DeleteTree 命 令。 然 而,Win32 函 数 库 已 经 为 我 们 提 供 了 多 种 用 于 文 件 和 目 录 操 作 的 函 数, 利 用 它 们 不 难 设 计 出 自 己 的DeleteTree() 函 数。 </h3> <p><font color="#FFFFFF">----</font> 读 者 读 到 这 里, 也 许 会 感 到 有 些 疑 惑, 为 什 么 第 六 部 分 强 调 进 程 调 用 优 于 自 我 设 计 的 函 数, 而 这 一 部 分 又 反 了 过 来 ? 是 的, 在 通 常 情 况 下, 调 用 应 用 程 序 内 部 的 函 数 比 使 用 进 程 或 者 调 用 外 部 函 数 更 灵 活 并 且 可 以 提 高 执 行 效 率, 也 便 于 修 改。 所 以, 象DeleteTree() 这 样 的 功 能, 利 用 现 有 的 函 数 并 不 难 实 现, 自 然 就 最 好 通 过 内 部 函 数 的 方 式 来 完 成。 然 而, 象 设 计 一 个 压 缩/ 解 压 缩 这 样 的 函 数 的 工 作 量, 并 不 比 通 过 进 程 调 用 来 使 用 现 成 品 的 开 销 更 合 算, 因 为 它 至 少 需 要 我 们 了 解 压 缩/ 解 压 缩 的 复 杂 算 法, 而 且 调 试 和 维 护 它 也 需 要 一 定 代 价。 于 是, 这 个 时 候, 还 是 采 用“ 拿 来 主 义” 为 好。 </p> <p><font color="#FFFFFF">----</font> 下 面, 给 出 我 自 己 设 计 的DeleteTree() 函 数, 仅 供 参 考。 </p> <pre>BOOL DeleteTree(CString DirName){ //成功:返回TRUE;否则,返回FALSE BOOL Result; Result=PreRemoveDirectory(DirName) && RemoveDirectory(DirName); return Result;}BOOL PreRemoveDirectory(CString DirName){//成功:返回TRUE;否则,返回FALSE LPTSTR lpBuffer; UINT uSize; CString fileName; HANDLE hHeap; BOOL result; HANDLE hFindFile; WIN32_FIND_DATA FindFileData; uSize=(GetCurrentDirectory(0,NULL))*sizeof(TCHAR); hHeap=GetProcessHeap(); lpBuffer=(LPSTR)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,uSize); GetCurrentDirectory(uSize,lpBuffer); if (lpBuffer!=DirName) {//调整当前目录 SetCurrentDirectory(DirName); } hFindFile=FindFirstFile("*.*",&FindFileData); CString tFile; if (hFindFile!=INVALID_HANDLE_VALUE) { do { tFile=FindFileData.cFileName; if ((tFile==".")||(tFile=="..")) continue; if (FindFileData.dwFileAttributes== FILE_ATTRIBUTE_DIRECTORY){ if (DirName[DirName.GetLength()-1]!='\\') PreRemoveDirectory(DirName+'\\'+tFile); else PreRemoveDirectory(DirName+tFile); if (!RemoveDirectory(tFile)) result=FALSE; else result=TRUE; } else if (!DeleteFile(tFile)) result=FALSE; else result=TRUE; } while (FindNextFile(hFindFile,&FindFileData)); FindClose(hFindFile); } else { SetCurrentDirectory(lpBuffer); return FALSE; } SetCurrentDirectory(lpBuffer); //回复到原来的目录下 return result;}</pre> <h3><font color="#FF0000">如 何 得 到 并 修 改 各 驱 动 器 的 信 息</font></h3> <h3><font color="#FFFFFF">----</font> 在 设 计 和 文 件 输 入/ 输 出 有 关 的 应 用 程 序 时, 我 们 很 可 能 在 输 入/ 输 出 文 件 前, 需 要 了 解 一 下 源 驱 动 器 或 者 目 标 驱 动 器 的 各 项 信 息, 比 如 是 否 有 磁 盘 在 软 驱 中, 它 是 否 已 打 开 写 保 护, 以 及 现 有 磁 盘 的 容 量 等。 遗 憾 的 是,MFC 类 库 中 没 有 提 供 支 持 这 些 功 能 的 类, 所 以 我 们 只 能 通 过Win32 提 供 的 函 数 来 完 成 我 们 的 要 求。 下 面, 我 根 据 自 己 的 编 程 实 践, 通 过 几 段 程 序, 来 说 明 如 何 利 用Win32 提 供 的 函 数 实 现 对 驱 动 器 的 操 作。 读 者 可 以 根 据 自 己 的 需 要, 把 介 绍 的 函 数 稍 加 修 改 后, 即 可 插 入 到 自 己 设 计 的 应 用 程 序 中 去。 </h3> <ul type="square"> <li>下 面 程 序 的 功 能 是 搜 索 计 算 机 中 所 有 驱 动 器, 选 择 出 其 中 软 盘 驱 动 器 的 驱 动 器 号, 依 次 加 入 到 一 个 下 拉 列 表 框 中。 </li> </ul> <pre>void FindDriverInfo(){ CComboBox* Driver=(CComboBox*)GetDlgItem(IDC_DRIVER); DWORD dwNumBytesForDriveStrings; HANDLE hHeap; LPSTR lp; CString strLogdrive; int nNumDrives=0, nDriveNum; dwNumBytesForDriveStrings=GetLogicalDriveStrings(0,NULL) *sizeof(TCHAR);//实际存储驱动器号的字符串长度 if (dwNumBytesForDriveStrings!=0) { hHeap=GetProcessHeap(); lp=(LPSTR)HeapAlloc(hHeap,HEAP_ZERO_MEMORY, dwNumBytesForDriveStrings);// GetLogicalDriveStrings(HeapSize(hHeap,0,lp),lp); StringBox.SetSize(dwNumBytesForDriveStrings/sizeof(TCHAR)+1); while (*lp!=0) { if (GetDriveType(lp)==DRIVE_REMOVABLE){ Driver->AddString(lp); StringBox[nNumDrives]=lp; nNumDrives++; } lp=_tcschr(lp,0)+1; } } else AfxMessageBox("Can't Use The Function GetLogicalDriveStrings!");}</pre> <ul type="square"> <li>下 面 介 绍 的EmptyDiskSpace() 函 数 主 要 负 责 清 空 指 定 驱 动 器 中 的 磁 盘, 同 时 它 还 负 责 记 录 指 定 驱 动 器 中 磁 盘 的 容 量, 并 得 到 该 磁 盘 的 序 列 号。 在 该 函 数 中, 还 将 调 用 第 七 部 分 提 到 的PreRemoveDirectory() 函 数, 来 完 成 清 空 工 作。 </li> </ul> <pre>BOOL EmptyDiskSpace(CString Driver){ BOOL result=TRUE; DWORDSectorsPerCluster; // address of sectors per cluster DWORDBytesPerSector; // address of bytes per sector DWORDNumberOfFreeClusters; // address of number of free clusters DWORDTotalNumberOfClusters; DWORDTotalBytes; DWORDFreeBytes; int bContinue=1; char DiskVolumeSerialNumber[30]; //存储驱动器内当前磁盘的序列号 LPCTSTRlpRootPathName; // address of root directory of the file system LPTSTRlpVolumeNameBuffer=new char[12]; // address of name of the volume DWORDnVolumeNameSize=12; // length of lpVolumeNameBuffer DWORD VolumeSerialNumber; // address of volume serial number DWORD MaximumComponentLength; // address of system's maximum filename length DWORD FileSystemFlags; // address of file system flags LPTSTRlpFileSystemNameBuffer=new char[10]; // address of name of file system DWORDnFileSystemNameSize=10; // length of lpFileSystemNameBuffer lpRootPathName=Driver; while (1){ if (GetDiskFreeSpace(Driver, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters)) {//驱动器中有磁盘 TotalBytes=SectorsPerCluster*BytesPerSector *TotalNumberOfClusters;//磁盘总容量 FreeBytes=SectorsPerCluster*BytesPerSector *NumberOfFreeClusters;//磁盘空闲空间容量 GetVolumeInformation(lpRootPathName, lpVolumeNameBuffer, nVolumeNameSize, &VolumeSerialNumber, &MaximumComponentLength, &FileSystemFlags, lpFileSystemNameBuffer, nFileSystemNameSize); sprintf(DiskVolumeSerialNumber,"%X",VolumeSerialNumber); //得到驱动器内当前磁盘的序列号 SetmTotalBytes(TotalBytes/1024);//存储指定驱动器中磁盘的容量 if (TotalBytes!=FreeBytes){//当磁盘总容量不等于空闲空间容量时, 应该执行清空操作 while (bContinue) { if ((bContinue==2)||(MessageBox ("在驱动器 "+m_Driver+"中的磁盘尚存有数据. \n您愿意让系统为您删除它们吗?", "提问",MB_YESNO|MB_ICONQUESTION)==IDYES)) if (!PreRemoveDirectory(Driver))//无法执行清空操作 if (MessageBox("因某种原因系统无法删除 在驱动器 "+m_Driver+"中的磁盘上的数据. \n请检查磁盘是否没有关闭写保护. \n您愿意再试一次吗?", "问题",MB_YESNO|MB_ICONERROR)==IDYES) { bContinue=2; continue; } else { bContinue=0; result=FALSE; } else { MessageBox("成功删除磁盘上的数据!", "提示信息",MB_OK|MB_ICONINFORMATION); bContinue=0; result=TRUE; } else {//THE FIRST IF'S ELSE bContinue=0; result=FALSE; } } } else result=TRUE; break; } else { if (MessageBox("没有磁盘在驱动器 "+m_Driver+"中. \n您愿意插入一张磁盘再来一次吗?", "问题",MB_YESNO|MB_ICONASTERISK)==IDYES) continue; else break; } }//END OF WHILE return result;}</pre> <ul type="square"> <li>在MS-DOS 和Windows95 中, 磁 盘 卷 标 最 多 由11 个 字 符 组 成, 并 且 字 母 的 大 小 写 不 加 区 分。 当 需 要 设 定 指 定 驱 动 器 中 磁 盘 的 卷 标 时, 只 要 调 用Win32 的SetVolumeLabel() 函 数 即 可, 并 在 第 一 个 参 数 中 指 明 磁 盘 所 在 的 驱 动 器 号, 在 第 二 个 参 数 中 指 明 新 的 卷 标 号。 例 如,SetVolumeLabel(DriverNum, NewVolumeLabel)。 </li> </ul> <p> </td> </tr></table></center></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -