?? 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 + -