---- CWnd* m_pCWnd= AfxGetMainWnd()
---- 然 后, 再 以 如 下 形 式 调 用SetWindowText() 函 数:
---- SetWindowText(*m_pCWnd, (LPCTSTR) m_WindowText);// m_WindowText 可 以 是 一 个CString 类 的 变 量
---- 如 何 把 多 于256 色 的 位 图 作 为 资 源 加 入 到 应 用 程 序 中
---- 曾 经 使 用 过Visual C++ 进 行 应 用 程 序 开 发 的 同 行 们 都 知 道,Visual C++ 5.0 以 前 版 本 中 自 带 的 位 图 编 辑 器 不 能 浏 览 和 编 辑256 色 以 上 的 位 图, 并 且 资 源 文 件 中 也 不 允 许 嵌 入(Import)256 色 以 上 的 位 图 作 为 资 源( 否 则, 在 应 用 程 序 运 行 时 会 报 错)。 这 一 特 性 使 得 我 们 用Visual C++ 开 发 应 用 程 序 时 不 得 不 使 用 其 他 方 法 来 增 强 界 面 图 画 的 美 观 性, 于 是 就 有 使 用Visual C++ 开 发 应 用 程 序 内 核, 用Visual Basic 开 发 界 面 部 分 的 组 合 方 法。 好 在Visual C++ 5.0 中 这 个 问 题 有 了 改 善。 首 先, 位 图 编 辑 器 可 以 创 建 并 编 辑256 色 的 位 图 了。 另 外,Visual C++ 5.0 允 许 程 序 员 把256 色 以 上 的 位 图 嵌 入 到 资 源 中, 尽 管 仍 然 无 法 在Visual C++ 的 位 图 编 辑 器 中 浏 览, 并 且 还 要 求 必 须 选 择Win32 Release 作 为 编 译 方 式 生 成 可 执 行 的 应 用 程 序。 另 外 一 个 限 制 条 件 是 作 为 资 源 的256 色 以 上 的 位 图 不 能 由 应 用 程 序 内 核 自 动 打 开 和 关 闭。 比 如 说, 在 上 述 那 篇 名 为《Visual C++ 4.0 编 程 经 验 谈》 的 文 章 中 曾 经 提 到 过 一 种 为 对 话 框 加 入 位 图 式 按 钮 的 方 法, 即 由 程 序 开 发 者 为 每 个 按 钮 创 建 四 幅 位 图, 分 别 用 于 表 示 按 钮 的 弹 起 状 态(UP)、 按 下 状 态(DOWN)、 输 入 焦 点 状 态(FOCUS) 和 禁 止 状 态(DISABLE), 并 且 必 须 以 该 按 钮 的 标 题 名 与 上 述 四 种 状 态 之 一 的 组 合 作 为 位 图 的 标 识, 以 便 应 用 程 序 在 绘 制 位 图 按 钮 时, 可 以 自 动 地 找 到 相 应 的 资 源( 即 位 图)。 然 而 这 一 自 动 映 射 只 限 制 于Visual C++ 位 图 编 辑 器 能 够 打 开 的 位 图。 因 此 如 果 选 择256 色 以 上 的 位 图 作 为 位 图 按 钮 的 资 源, 并 也 希 望 达 到 上 述 四 状 态 的 相 互 切 换 的 话, 就 必 须 用 到 下 述 的 函 数 和 程 序 设 计 参 考 模 型。
---- 下 面 给 出 部 分 程 序 代 码, 仅 供 参 考。
void CTESTDlg::OnPaint() { CWnd* pWnd; CDC* pDC; CDC* pDisplayMemDC; CBitmap* pBitmap; pWnd=GetDlgItem(IDC_IMAGE1);//得到指向第一个位图按钮的指针 pDC=pWnd->GetDC();//获得一个窗口设备用于画图 pWnd->Invalidate();//使窗口无效,从而更新它 pWnd->UpdateWindow(); pDisplayMemDC=new CDC; pBitmap=new CBitmap; pDisplayMemDC->CreateCompatibleDC(pDC); if (Change1) {//说明第一个按钮的状态发生了变化 switch (Button1_Status){ case BUTTON_DISABLE: pBitmap->LoadBitmap(IMAGE1_DISABLE);//装入位图 pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(0,0,140,30,pDisplayMemDC,0,0,SRCCOPY); //把位图拷贝到指定区域 break; case BUTTON_UP: pBitmap->LoadBitmap(IMAGE1_UP); pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(0,0,140,30,pDisplayMemDC, 0,0,SRCCOPY); break; case BUTTON_FOCUS: pBitmap->LoadBitmap(IMAGE1_FOCUS); pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(0,0,140,30,pDisplayMemDC,0,0,SRCCOPY); break; case BUTTON_DOWN: pBitmap->LoadBitmap(IMAGE1_DOWN); pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(0,0,140,30,pDisplayMemDC,0,0,SRCCOPY); break; } } delete pDisplayMemDC; delete pBitmap; pWnd=GetDlgItem(IDC_IMAGE2); pDC=pWnd->GetDC(); pWnd->Invalidate(); pWnd->UpdateWindow(); pDisplayMemDC=new CDC; pBitmap=new CBitmap; pDisplayMemDC->CreateCompatibleDC(pDC); if (Change2) {//说明第二个按钮的状态发生了变化 switch (Button2_Status){ case BUTTON_DISABLE: pBitmap->LoadBitmap(IMAGE2_DISABLE); pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(0,0,140,30,pDisplayMemDC,0,0,SRCCOPY); break; case BUTTON_UP: pBitmap->LoadBitmap(IMAGE2_UP); pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(0,0,140,30,pDisplayMemDC,0,0,SRCCOPY); break; case BUTTON_FOCUS: pBitmap->LoadBitmap(IMAGE2_FOCUS); pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(0,0,140,30,pDisplayMemDC,0,0,SRCCOPY); break; case BUTTON_DOWN: pBitmap->LoadBitmap(IMAGE2_DOWN); pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(0,0,140,30,pDisplayMemDC,0,0,SRCCOPY); break; } } delete pDisplayMemDC; delete pBitmap; CDialog::OnPaint(); } void CTESTDlg::OnMouseMove(UINT nFlags, CPoint point) { CRect rect=CRect(0,0,1,1); CRgn rgn1,rgn2;//记录各位图按钮所占据的矩形区域 rgn1.CreateRectRgnIndirect(m_rect1); //rgn1记录第一个位图按钮所占据的矩形区域 if (rgn1.PtInRegion(point)) {//鼠标当前是否已落入第一个位图按钮所占据的矩形区域 if ( (Button1_Status!=BUTTON_FOCUS) && (Button1_Status!=BUTTON_DISABLE) ) { //如果位图按钮的当前状态不是输入焦点状态并且也不是禁止状态 Button1_Status= BUTTON_FOCUS; Change1=true; InvalidateRect(rect,FALSE); } if ( (Button2_Status!=BUTTON_UP) && (Button2_Status!=BUTTON_DISABLE) ) { Button2_Status= BUTTON_UP; Change2=true; InvalidateRect(rect,FALSE); } } else{ rgn2.CreateRectRgnIndirect(m_rect2); if (rgn2.PtInRegion(point)){ if ( (Button2_Status!=BUTTON_FOCUS) && (Button2_Status!=BUTTON_DISABLE) ) { Button2_Status= BUTTON_FOCUS; Change2=true; InvalidateRect(rect,FALSE); } if ( (Button1_Status!=BUTTON_UP) && (Button1_Status!=BUTTON_DISABLE) ) { Button1_Status= BUTTON_UP; Change1=true; InvalidateRect(rect,FALSE); } } } CDialog::OnMouseMove(nFlags, point); } void CTESTDlg::OnLButtonUp(UINT nFlags, CPoint point) { CRect rect=CRect(0,0,1,1); CRgn rgn1,rgn2; rgn1.CreateRectRgnIndirect(m_rect1); if (rgn1.PtInRegion(point)){ if ( (Button1_Status!=BUTTON_UP) && (Button1_Status!=BUTTON_DISABLE) ) { Button1_Status=BUTTON_UP; Change1=true; InvalidateRect(rect,FALSE); } } else{ rgn2.CreateRectRgnIndirect(m_rect2); if (rgn2.PtInRegion(point)){ if ( (Button2_Status!=BUTTON_UP) && (Button2_Status!=BUTTON_DISABLE) ) { Button2_Status=BUTTON_UP; Change2=true; InvalidateRect(rect,FALSE); } } } CDialog::OnLButtonUp(nFlags, point); } void CTESTDlg::OnLButtonDown(UINT nFlags, CPoint point) { CRect rect=CRect(0,0,1,1); CRgn rgn1,rgn2; rgn1.CreateRectRgnIndirect(m_rect1); if (rgn1.PtInRegion(point)){ if ( (Button1_Status!=BUTTON_DOWN) && (Button1_Status!=BUTTON_DISABLE) ) { Button1_Status=BUTTON_DOWN; Change1=true; InvalidateRect(rect,FALSE); } if ( (Button2_Status!=BUTTON_UP) && (Button2_Status!=BUTTON_DISABLE) ) { Button2_Status=BUTTON_UP; Change2=true; InvalidateRect(rect,FALSE); } } else{ rgn2.CreateRectRgnIndirect(m_rect2); if (rgn2.PtInRegion(point)){ if ( (Button2_Status!=BUTTON_DOWN) && (Button2_Status!=BUTTON_DISABLE) ) { Button2_Status=BUTTON_DOWN; Change2=true; InvalidateRect(rect,FALSE); } if ( (Button1_Status!=BUTTON_UP) && (Button1_Status!=BUTTON_DISABLE) ) { Button1_Status=BUTTON_UP; Change1=true; InvalidateRect(rect,FALSE); } } } CDialog::OnLButtonDown(nFlags, point); }
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; //在此处开始加注释符号 /* if (!m_wndToolBar.Create(this) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) { TRACE0("Failed to create status bar\n"); return -1; // fail to create } // TODO: Remove this if you don't want tool tips or a resizeable toolbar m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); // TODO: Delete these three lines if you don't want the toolbar to be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); 在处结束注释*/ return 0; }
BOOL CYourMainApp::InitInstance() { //.....此处略去一部分无关语句 CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( NULL, //IDR_MAINFRAME, //用NULL替换IDR_MAINFRAME RUNTIME_CLASS(CNoBarDoc), RUNTIME_CLASS(CMainFrame), // main SDI frame window RUNTIME_CLASS(CNoBarView)); AddDocTemplate(pDocTemplate); //.....此处略去一部分无关语句 }
---- 至 此, 我 们 就 得 到 了 不 含 菜 单、 工 具 条 和 状 态 条 结 构 的 应 用 程 序。
CModel::CModel(CWnd* pParent /*=NULL*/) : CDialog(CModel::IDD, pParent) { m_pParent=pParent; m_nID=CModel::IDD; //{{AFX_DATA_INIT(CModel) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT } BOOL CModel::Create() { return CDialog::Create(m_nID,m_pParent); }
void CModel::PostNcDestroy() { // TODO: Add your specialized code here and/or call the base class delete this; CDialog::PostNcDestroy(); }
if (m_Dlg==NULL) {//如果当前没用提示对话框在活动,就创建一个 m_Dlg = new CModel(this); m_Dlg->Create(); GetDlgItem(IDC_EXPORT)->EnableWindow(FALSE); } else//否则就激活它 m_Dlg->SetActiveWindow(); 另外,再在要关闭提示对话框的地方,加入如下语句: m_Dlg->DestroyWindow(); m_Dlg=NULL;
---- 至 此, 您 已 经 拥 有 了 自 己 的 过 程 操 作 提 示 对 话 框。 不 过, 它 还 不 具 有 动 画 和 随 时 取 消 操 作 的 功 能。 您 不 妨 尝 试 着 加 入 这 些 功 能。 另 外, 笔 者 也 曾 尝 试 过 用 下 面 介 绍 的 方 法 实 现 过 程 操 作 提 示 对 话 框。 两 种 方 法 比 较, 可 谓 各 有 千 秋。 如 果 您 希 望 上 面 设 计 的 过 程 提 示 对 话 框 能 够 被 多 个 应 用 程 序 共 享, 那 么 最 好 把 提 示 对 话 框 作 为 独 立 的 进 程 来 调 用。 但 是, 当 您 还 希 望 在 提 示 对 话 框 与 调 用 者 之 间 传 输 数 据 的 话, 似 乎 这 一 部 分 介 绍 的 实 现 方 法 更 简 洁 且 更 有 效。
void CMyCompress:: CreateBat(CString BatPath,CString ArjPath, CString BatName,CString ArjFileName, CString TempPath,CString ExitFlag,BOOL out) { LPTSTR lpBuffer; UINT uSize; HANDLE hHeap; uSize=(GetCurrentDirectory(0,NULL))*sizeof(TCHAR); hHeap=GetProcessHeap(); lpBuffer=(LPSTR)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,uSize); GetCurrentDirectory(uSize,lpBuffer); //得知当前目录信息,以便根据需要变换目录 if (lpBuffer!=BatPath) //diferent dir SetCurrentDirectory(BatPath); CStdioFile f; CFileException e; if (!f.Open( BatName, CFile::modeCreate|CFile::modeWrite, &e)) //以BatName的内容创建一个批处理文件 { AfxMessageBox("不能创建文件"+BatName); return ; } char density[6]; sprintf(density,"%d",mTotalBytes);
---- //mTotalBytes 是 由 其 他 函 数 设 定 的 变 量, 用 于 记 录 用 于 拷 入 或 拷 出 文 件 的 磁 盘 所 具 有 的 最 大 可 用 空 间
CString Density=density; CString string; if (out)//说明是生成做压缩工作的批处理文件 string="arj a -v"+Density; else //说明是生成做解压缩工作的批处理文件 string="arj e -v"+Density; string+=" ..\\"+ArjPath+"\\"+ArjFileName+" "; if (out) string=string+"..\\"+TempPath+"\\*.* -y -jm\n"; else string=string+"..\\"+TempPath+"\\ -y -jm\n"; f.WriteString(string); string="dir >"+ExitFlag+"\n"; f.WriteString(string); f.Close(); SetCurrentDirectory(lpBuffer);//回复到原来的目录下 }
---- 该 函 数 执 行 后, 将 生 成 一 个 批 处 理 文 件, 内 容 大 致 是:
---- ARJ A -V1440 压 缩 后 文 件 的 路 径 名+ 文 件 名 被 压 缩 文 件 的 路 径 名+ 文 件 名 -Y -JM
---- DIR > 临 时 文 件 名
---- 或 者 是:
---- ARJ E -V1440 被 解 压 缩 文 件 的 路 径 名+ 文 件 名 解 压 缩 后 文 件 的 路 径 名+ 文 件 名 -Y -JM
---- DIR > 临 时 文 件 名
void CMyCompress::RunBat(CString BatPath,CString fileName,CString ExitFlag) { CString lpApplicationName=BatPath+"\\"+fileName; // 进 程 执 行 的 应 用 程 序 的 完 全 路 径 名 STARTUPINFO StartupInfo;// 创 建 进 程 所 需 的 信 息 结 构 变 量 GetStartupInfo(&StartupInfo); StartupInfo.lpReserved=NULL; StartupInfo.lpDesktop=NULL; StartupInfo.lpTitle=NULL; StartupInfo.dwX=0; StartupInfo.dwY=0; StartupInfo.dwXSize=200; StartupInfo.dwYSize=300; StartupInfo.dwXCountChars=500; StartupInfo.dwYCountChars=500; StartupInfo.dwFlags=STARTF_USESHOWWINDOW; StartupInfo.wShowWindow=SW_HIDE; // 说 明 进 程 将 以 隐 藏 的 方 式 在 后 台 执 行 StartupInfo.cbReserved2=0; StartupInfo.lpReserved2=NULL; StartupInfo.hStdInput=stdin; StartupInfo.hStdOutput=stdout; StartupInfo.hStdError=stderr; LPTSTR lpBuffer; UINT uSize; HANDLE hHeap; uSize=(GetCurrentDirectory(0,NULL))*sizeof(TCHAR); hHeap=GetProcessHeap(); lpBuffer=(LPSTR)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,uSize); GetCurrentDirectory(uSize,lpBuffer); // 得 知 当 前 目 录 信 息, 以 便 根 据 需 要 变 换 目 录 if (lpBuffer!=BatPath) //diferent dir SetCurrentDirectory(BatPath); // 创 建 进 程 if (CreateProcess(lpApplicationName,NULL,NULL, NULL,FALSE,CREATE_DEFAULT_ERROR_MODE, NULL,NULL,&StartupInfo,&pro_info)) { 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);// 回 复 到 原 来 的 目 录 下 }
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(); } }
---- 读 者 读 到 这 里, 也 许 会 感 到 有 些 疑 惑, 为 什 么 第 六 部 分 强 调 进 程 调 用 优 于 自 我 设 计 的 函 数, 而 这 一 部 分 又 反 了 过 来 ? 是 的, 在 通 常 情 况 下, 调 用 应 用 程 序 内 部 的 函 数 比 使 用 进 程 或 者 调 用 外 部 函 数 更 灵 活 并 且 可 以 提 高 执 行 效 率, 也 便 于 修 改。 所 以, 象DeleteTree() 这 样 的 功 能, 利 用 现 有 的 函 数 并 不 难 实 现, 自 然 就 最 好 通 过 内 部 函 数 的 方 式 来 完 成。 然 而, 象 设 计 一 个 压 缩/ 解 压 缩 这 样 的 函 数 的 工 作 量, 并 不 比 通 过 进 程 调 用 来 使 用 现 成 品 的 开 销 更 合 算, 因 为 它 至 少 需 要 我 们 了 解 压 缩/ 解 压 缩 的 复 杂 算 法, 而 且 调 试 和 维 护 它 也 需 要 一 定 代 价。 于 是, 这 个 时 候, 还 是 采 用“ 拿 来 主 义” 为 好。
---- 下 面, 给 出 我 自 己 设 计 的DeleteTree() 函 数, 仅 供 参 考。
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; }
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!"); }
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; }