Is it possible to use Microsoft's Open File Dialog using Intel Visual Fortran Compiler 9.0?
If so, is there a code example somewhere I could see?
I have been using this compiler for several years, but have not found any references or documentation regarding interface with existing Microsoft components.
I found a Compaq Visual Fortran reference that shows an example, but it does not work in the Intel; I assume it's because the Compaq libraries are different than the Intel.
链接已复制
12 回复数
take a look at this:
[fortran]
LOGICAL FUNCTION DlgFileIO (rw_mode, hwndParent, filter, fullpath, extn, path)
IMPLICIT NONE
CHARACTER(LEN=1), INTENT(IN) :: rw_mode ! R for read, W for write
INTEGER(HANDLE), INTENT(IN) :: hwndParent
CHARACTER(LEN=*), INTENT(IN) :: filter
CHARACTER(LEN=*), INTENT(IN) :: extn
CHARACTER(LEN=*), INTENT(INOUT) :: fullpath
CHARACTER(LEN=*), INTENT(INOUT) :: path
INTEGER :: rval
TYPE(T_OPENFILENAME) :: ofn
ofn%lStructSize = SIZEOF(ofn)
ofn%hwndOwner = hwndParent
ofn%hInstance = ghInstance ! global instance for this app, passed via module
ofn%lpstrFilter = LOC(filter)
ofn%nFilterIndex = 0 ! force use of 1st filter entry,
ofn%lpstrCustomFilter = 0 ! restricts to single file type
ofn%lpstrFile = LOC(fullpath)
ofn%nMaxFile = LEN(fullpath)
ofn%lpstrInitialDir = LOC(path)
ofn%lpstrDefExt = LOC(extn)
ofn%nMaxCustFilter = 0
ofn%nMaxFileTitle = 0
ofn%lpstrTitle = loc(""C)
ofn%lpfnHook = NULL
ofn%lpTemplateName = NULL
IF (rw_mode == 'R') THEN
ofn%Flags = MOR(OFN_HIDEREADONLY, OFN_PATHMUSTEXIST, &
OFN_FILEMUSTEXIST, OFN_SHAREAWARE )
DlgFileIO = GetOpenFileName (ofn)
ELSE
ofn%Flags = MOR(OFN_HIDEREADONLY, OFN_CREATEPROMPT, &
OFN_PATHMUSTEXIST, OFN_OVERWRITEPROMPT)
DlgFileIO = GetSaveFileName (ofn)
END IF
END FUNCTION DlgFileIO
[/fortran]
It is implicit in all Windows programming using IVF that Windows constants and types are made available by USEing Ifwinty, which may be done in each routine or more easily in each module (this routine was extracted from a comprehensive module of file i/o routines). One also needs to USE Ifwin, which provides access to interfaces to the WinAPI functions.
When using the Windows API functions you need to convert your strings to C strings by appending char(0) otherwise strange things will happen. Be also aware that the returned file and path names will be C strings and these might not be what you require in your Fortran as LEN_TRIM and TRIM don't recognise the NULL terminator.
O-K.
After using: IFWIN and IFWINTY
I'm down to function "MOR" and "ghInstance" undefined.
Is "mor" simply and-ing the arguments?
Where are: "GetOpenFileName" and "GetSaveFileName" documented?
Where can I find a list of similar functions?
Are these Intel provided functions or Microsoft? I know Microsoft doesn't want you to know about their stuff and they make it very hard to find things...
The GetxxxFileName functions are Microsoft Windows API routines. You can find documentation at msdn.microsoft.com I disagree that they make it hard to find things - Microsoft has some of the best API documentation I have seen. Intel Fortran provides modules such as IFWIN (you don't need IFWINTY if you use IFWIN) that provide declarations for thousands of Windows API routines, types and constants.
ghinstance is usually a variable declared that gets assigned the first argument passed into the WinMain function for a non-console application. You can use NULL here if you want. MOR seems to be some sort of multi-IOR function Paul has created. I have attached our sample, provided in current versions, for this API routine.
Thanks, Steve (it's difficult for me to log on here while away from my office). WinAPI functions use multiple bitflag arguments all the time, and it has proved efficient to create a Multiple-IOR utility for this purpose:
[fortran]
INTEGER FUNCTION MOR (f1, f2, f3, f4, f5, f6, f7, f8)
IMPLICIT NONE
INTEGER,INTENT(IN) :: f1, f2
INTEGER,INTENT(IN),OPTIONAL :: f3, f4, f5, f6, f7, f8
! MultiOR of multiple arguments, as supplied
MOR = IOR(f1, f2)
IF (.NOT.PRESENT(f3)) RETURN
MOR = IOR(MOR,f3)
IF (.NOT.PRESENT(f4)) RETURN
MOR = IOR(MOR,f4)
IF (.NOT.PRESENT(f5)) RETURN
MOR = IOR(MOR,f5)
IF (.NOT.PRESENT(f6)) RETURN
MOR = IOR(MOR,f6)
IF (.NOT.PRESENT(f7)) RETURN
MOR = IOR(MOR,f7)
IF (.NOT.PRESENT(f8)) RETURN
MOR = IOR(MOR,f8)
END FUNCTION MOR
[/fortran]
Thank you very much! I've been wanting to open files using a windows dialog for years...I never have found the windows API documentation you mention. I haven't tried this yet...maybe tomorrow I'll get a chance to try it! My version also has "Quickwin" which, oddly, does not have a file open dialog (for user files); otherwise it would likely do anything I would need to do.
QuickWin does indeed have such a feature, though it is disabled by default. If you set the project option Fortran > Compatibility > Files from command line", and then do an OPEN with an empty filename (FILE=""), then the user will be prompted with a dialog to select a file.
If you are interested in the Windows API, there are numerous good books on the topic. The one by Petzold is usually considered the best reference. But just browsing the categories of functions at MSDN can also be enlightening.
Lastly, please change the "Display Name" for your account here to not be your email address. Click on "Dashboard" toward the top of the page to do that.
Paul Curtis wrote:This function has been obsoleted by the f2008 transformational intrinsic IANY. You can replace MOR(OFN_HIDEREADONLY, OFN_PATHMUSTEXIST, OFN_FILEMUSTEXIST, OFN_SHAREAWARE) with IANY([OFN_HIDEREADONLY, OFN_PATHMUSTEXIST, OFN_FILEMUSTEXIST, OFN_SHAREAWARE]) The advantages are that IANY can be used in constant expressions so that you can create a named constant for a given combination of flags, you don't have to carry around a module for the user-defined function MOR, and IANY works with an array of integers of nondefault kind, as well as not being limited to a fixed upper bound of to the number of inputs.Thanks, Steve (it's difficult for me to log on here while away from my office). WinAPI functions use multiple bitflag arguments all the time, and it has proved efficient to create a Multiple-IOR utility for this purpose:
INTEGER FUNCTION MOR (f1, f2, f3, f4, f5, f6, f7, f8) IMPLICIT NONE INTEGER,INTENT(IN) :: f1, f2 INTEGER,INTENT(IN),OPTIONAL :: f3, f4, f5, f6, f7, f8 ! MultiOR of multiple arguments, as supplied
