Visual Fortran / PowerStation

使用 Win32 的開啟舊檔與另存新檔對話盒


在 Windows 95/98/NT 中,大多數的軟體在開啟舊檔或另存新檔時,多半會使用系統內建的對話盒,在 Fortran 中要如何使用呢?本網頁經璉璉整理後,提供網友一方便的解決方案。

要使用系統內建的對話盒,即是使用 comdlg32.lib 或 comdlg32.dll 的內建 GetOpenFileName 與 GetSaveFileName 兩個函數,但這兩個函數的引數均為結構引數,細觀 dfwinty.f90 內該結構相關資料為:

type T_OPENFILENAME
 integer lStructSize
 integer hwndOwner
 integer hInstance
 integer lpstrFilter
 integer lpstrCustomFilter
 integer nMaxCustFilter
 integer nFilterIndex
 integer lpstrFile
 integer nMaxFile
 integer lpstrFileTitle
 integer nMaxFileTitle
 integer lpstrInitialDir
 integer lpstrTitle
 integer Flags
 integer(2) nFileOffset
 integer(2) nFileExtension
 integer lpstrDefExt
 integer lCustData
 integer lpfnHook
 integer lpTemplateName
end type T_OPENFILENAM

所有的參數全為整數,可以猜得相關字串引數均靠指標 (Pointer) 傳遞,因此配合 MSDN 內的相關說明進行測試,詳細測試敘述說明未來有空再打字。

測試程式如下:

program Main

Character*1024 myGetOpenFileName, myGetSaveFileName

write(*,*) myGetSaveFileName('另存新檔 - 使用 Visual Fortran 5.0c'C,'文字檔 (*.txt)\0*.txt\0所有檔案 (*.*)\0*.*\0\0'C,''C,'Test'C,0)
write(*,*) myGetOpenFileName('開啟舊檔 - 使用 Visual Fortran 5.0c'C, '所有檔案 (*.*)\0*.*\0\0'C, ''C, ''C, 0)

end

由於呼叫的原始函數使用 Char(0) 來作為換行判斷條件,因此以 \0 及 C 為關鍵字,另外因為我暫時無法清除所有的記憶體空間,因此 myGetOpenFileName 與 myGetSaveFileName 不能像上述程式碼同時共用,必須分開使用。

myGetOpenFileName 與 myGetSaveFileName 引數相同,因此一起介紹:

引數 說明
hTitle 對話盒的標題列
hFilter 使用檔案類型
DefaultDir 預設目錄
DefaultFileName 預設檔名
hFlags 對話盒旗標

比較複雜的引數是 hFilter,是以兩兩為一組,先提供檔案類型的說明,再填入檔案類型,以另存新檔為例,第一部份為 '文字檔 (*.txt)' 後以 \0 隔開,第二部份為 '*.txt' 後以 \0 隔開,最後以 '\0\0' 作為終結。

檔案類型的說明 檔案類型
文字檔 (*.txt) *.txt
所有檔案 (*.*) *.*

以上例來說, hFilter 為 '文字檔 (*.txt)\0*.txt\0所有檔案 (*.*)\0*.*\0\0'C

另外本函數需引用已包裝完成的 OpenFile.f90Window.f90 兩個檔案並一同編譯。除此之外也要設定引用的程式庫,如下圖,內定引用的程式庫為 kernel32.lib ,自行設定引用的程式庫 comdlg32.lib , user32.lib 。

設定引用的程式庫

在 myGetOpenFileName 與 myGetSaveFileName 中需要 hWnd 的引數,因此利用 GetActivateWindow (此函數位於 user32.lib) ,取得正在作用中的視窗代碼 (hWnd)

執行畫面:

另存新檔對話盒

開啟舊檔對話盒

上圖在開啟舊檔對話盒的背景,即為上面主程式的測試碼執行結果,出現的字串 'C:\My Documents\Test.txt' 為

write(*,*) myGetSaveFileName('另存新檔 - 使用 Visual Fortran 5.0c'C,'文字檔 (*.txt)\0*.txt\0所有檔案 (*.*)\0*.*\0\0'C,''C,'Test'C,0)

執行結果!


福傳語言