| 實現操作過程提示對話方塊 在使用Windows 95進行檔案拷貝或刪除操作時,使用者一定見到過那種具有飛行檔案動畫的操作過程提示對話方塊。這一功能的加入不僅使我們能夠在操作過程中隨時取消操作,而且也使檔案拷貝或刪除操作變得生動活潑。其實,在使用Visual C++進行應用程式設計時,我們也可以使用下述方法在適當位置加入自己的操作過程提示對話方塊,步驟如下。 1. 為每一個操作過程提示對話方塊建立一個對話方塊類。為敘述方便,我們只假設應用程式需要一個操作過程提示對話方塊並以“CModel”作為對應的對話方塊類的名字。 2. 使用Visual C++提供的資源編輯器編輯提示對話方塊,比如加入一些文字說明和動畫等。 3. 在CModel類的標頭檔(Model.h)中,首先加入兩個成員變數: CWnd* m_pParent; //指向調用該提示對話方塊的架構類(或對話方塊類), 即它的“父類” int m_nID;//記錄該提示對話方塊的ID號 其次再加入下面兩個成員函數: CModel(CWnd* pParent = NULL); //捨棄原有的建構函式,或者把原函數修改成這種 無強制回應對話方塊的建構函式 BOOL Create(); //該函數將調用建立基類的Create()函數建立對話 框 4. 在Model.cpp檔案中,加入相應函數的實現部分: 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); } 5. 同步選取Ctrl和W鍵或直接單擊工具條上的ClassWizard按鈕,開啟ClassWizard對話方塊。在類名(Class name)列表框中選擇該提示對話方塊類,在Object IDs列表框中選擇該類的類名後,在訊息(Messages)列表框中選擇PostNcDestroy訊息並雙擊它,這時ClassWizard就會在該對話方塊類中加入一個PostNcDestroy()函數。該函數在對話方塊視窗消失後,由OnNcDestroy()函數調用。因此,可以在該函數中加入一些掃尾工作,例如資料傳送、釋放指標空間等。 void CModel::PostNcDestroy() { // TODO: Add your specialized code here and/or call the base class delete this; CDialog::PostNcDestroy(); } 6. 在要調用提示對話方塊類的標頭檔中,先包含(#include)CModel類的標頭檔,再聲明一個指向CModel類的對象的指標,如m_Dlg,並在該類的建構函式中,加入“m_Dlg = NULL;”。然後,在開啟和關閉提示對話方塊的函數中加入如下一段程式: 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; 至此,我們已經擁有了自己的過程操作提示對話方塊。不過,它還不具有動畫和隨時取消操作的功能,讀者不妨嘗試著加入這些功能。 應用進程對其他應用程式的調用 在我們設計的應用程式中,很可能會用到其他應用程式來完成某一特定功能。例如,當我們為了便於資料的傳輸而對諸多檔案進行壓縮和解壓縮時,一種做法是我們自己設計一個這樣的壓縮/解壓縮程式,然後以動態連結程式庫(DLL)或者函數庫的形式由主應用程式調用。但更方便而且高效的做法是利用這方面現有的優秀軟體,如ARJ.EXE等,並以進程的形式調用它,再在適當時候關閉它。下面將以此為例,具體介紹後一種方法的實現過程。 1. 在需要調用ARJ.EXE進行壓縮/解壓縮的類中,建立一個成員函數,不妨稱作CreateBat(),其作用是產生一個批次檔。由該批次檔調用ARJ.EXE,並給出具體壓縮/解壓縮參數。然後,利用MS-DOS的DIR命令產生一個臨時檔案,以作為壓縮/解壓縮工作完成的標誌。 編者註:Createbat原始碼發表http://www.computerworld.com.cn/98/skill/default.htm。下同。歡迎訪問! 該函數執行後,將產生一個批次檔,內容大致是: ARJ A -V1440 壓縮後檔案的路徑名+檔案名稱 被壓縮檔的路徑名+檔案名稱 -Y -JM DIR >臨時檔案名稱 或者是: ARJ E -V1440 被解壓縮檔案的路徑名+檔案名稱 解壓縮後檔案的路徑名+檔案名稱 -Y -JM DIR >臨時檔案名稱 2. 在需要調用ARJ.EXE進行壓縮/解壓縮的類中,再建立一個成員函數,不妨稱作RunBat(),其作用是建立和執行進程來運行上述所產生的批次檔,並在適當時候撤消進程。 3. 同步選取Ctrl和W鍵或直接單擊工具條上的ClassWizard按鈕,開啟ClassWizard對話方塊。在類名(Class name)列表框中選擇需要調用ARJ.EXE進行壓縮/解壓縮的類,在Object IDs列表框中選擇該類的類名,在訊息(Messages)列表框中選擇WM_TIMER訊息並雙擊它,這時ClassWizard就會在該類中加入一個OnTimer()函數。該函數將以一定的時間間隔檢查壓縮/解壓縮程式是否已經執行完畢,即檢查作為標誌的臨時檔案是否已經存在,並及時修改狀態變數“Search”,以便通知RunBat()函數結束進程。 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(); } } 得到並修改各磁碟機資訊 在設計與檔案輸入/輸出有關的應用程式時,我們需要在輸入/輸出檔案前,瞭解一下來源磁碟機或者目的地磁碟機的各項資訊,比如是否有磁碟在軟碟機中、它是否已開啟防寫保護、現有磁碟的容量等。遺憾的是,MFC類庫中沒有提供支援這些功能的類,所以我們只能通過Win32 提供的函數來完成我們的要求。下面,筆者根據自己的編程實踐,通過幾段程式,來說明如何利用Win32提供的函數實現對磁碟機的操作。讀者可以根據自己的需要,把介紹的函數稍加修改後,即可插入到自己設計的應用程式中去。 *S FindDriverInfo()函數的功能是搜尋電腦中所有磁碟機,選擇出其中軟碟機的磁碟機代號,依次加入到一個下拉式清單方塊中。 *S EmptyDiskSpace()函數主要負責清空指定磁碟機中的磁碟,同時它還負責記錄指定磁碟機中磁碟的容量,並得到該磁碟的序號。在該函數中,還將調用上文中的DeletTree()的PreRemoveDirectory()函數,來完成清空工作。 *S 在MS-DOS和Windows95中,磁碟卷標最多由11個字元組成,並且字母的大小寫不加區分。當需要設定指定磁碟機中磁碟的卷標時,只要調用Win32的SetVolumeLabel()函數即可,在第一個參數中指明磁碟所在的磁碟機代號,在第二個參數中指明新的卷標號,例如:SetVolumeLabel(DriverNum, NewVolumeLabel)。 自編刪除目錄及其下屬檔案的函數 高版本的MS-DOS和Windows 95都提供了一個可以刪除一個或多個目錄及其下屬檔案和目錄的命令,即DeleteTree命令。然而,無論在MFC類庫還是在Win32函數庫中,都沒有相應的函數。這樣,當我們在自己設計的應用程式中需要用到DeleteTree的功能時,自然想到的方法是通過進程調用或者系統調用的方式(如上文所述)調用MD-DOS或Windows 95下的DeleteTree命令。但實際上,Win32函數庫已經為我們提供了其它的用於檔案和目錄操作的函數,利用它們不難設計出自己的DeleteTree()函數。 讀者也許會感到有些疑惑,為什麼前文強調進程調用優於自我設計的函數,而這裡又反了過來?是的,在通常情況下,調用應用程式內部的函數比使用進程或者調用外部函數更靈活並且可以提高執行效率,也便於修改,DeleteTree()就是這種情況。然而,像設計壓縮/解壓縮這樣的函數工作量大、演算法複雜,而且調試和維護也需要一定代價,於是這時候還是採用“拿來主義”為好。 本文給出筆者設計的DeleteTree()函數,僅供參考。 |