Taming GetOpenFileName

Taming GetOpenFileName

I have a large number of directories that are numbered sequentially, and whose names I want to change using the SYSTEM command from within FORTRAN to invoke the REN command in the command line shell. I use GetOpenFileName as implemented in the code sample to get the names of the first and last directories in the sequence.

The REN command works for all the directories in the range except the last, which fails with the diagnostic "The process cannot access the file because it is being used by another process." I get the same diagnostic if I attempt to execute the same REN command from an independent command shell invoked from runnung cmd.exe, with the FORTRAN code paused in debug mode in VS2008. If I terminate the FORTRAN executable, then REN works normally in the independent command shell.

If I hard code the start and finish directories in the sequence, the procedure works as it should and renames all the directories including the last, so it is something that the GetOpenFileName procedure is doing that blocks access to the last directory.

It seems that GetOpenFileName (or one of its components) has got a lock on the last directory that I used it to identify. I can see nothing in the documentation that one can set in GetOpenFileName to release the last directory after it passes its name, and nor have I been able to find a solution on the forums.

The GetOpenFileName code is modified only slightly from the example to allow passing arguments to define the filter and a title for the dialogue box:

subroutine GetPath (file_spec, main_spec, abb_spec,box_title)

use ifwin
use comdlg32
use user32 ! Interface for GetForegroundWindow
implicit none

! Declare structure used to pass and receive attributes
character(512) file_spec, filter_spec
character(60) box_title
character(32) main_spec, abb_spec
integer status,ilen
filter_spec = main_spec(:len_Trim(main_spec))//CHAR(0)//abb_spec(:LEN_trim(abb_spec))//CHAR(0)// &
"All Files"C//"*.*"C//""C
ofn%lStructSize = SIZEOF(ofn)
ofn%hwndOwner = GetForegroundWindow()
ofn%hInstance = NULL ! For Win32 applications, you
! can set this to the appropriate
! hInstance
ofn%lpstrFilter = loc(filter_spec)
ofn%lpstrCustomFilter = NULL
ofn%nMaxCustFilter = 0
ofn%nFilterIndex = 1 ! Specifies initial filter value
ofn%lpstrFile = loc(file_spec)
ofn%nMaxFile = sizeof(file_spec)
ofn%nMaxFileTitle = 0
ofn%lpstrInitialDir = NULL ! Use Windows default directory
ofn%lpstrTitle = loc(box_title(:len_trim(box_title))//CHAR(0))
ofn%lpstrDefExt = loc("txt"C)
ofn%lpfnHook = NULL
ofn%lpTemplateName = NULL

file_spec = ""C

! Call GetOpenFileName and check status
status = GetOpenFileName(ofn)
if (status .eq. 0) then
type *,'No file name specified'
! Get length of file_spec by looking for trailing NUL
ilen = INDEX(file_spec,CHAR(0))
! type *,'Filespec is ',file_spec(1:ilen-1)
! Example of how to see if user said "Read Only"
if (IAND(ofn%flags,OFN_READONLY) /= 0) &
type *,'Readonly was requested'
end if
end subroutine GetPath

2 帖子 / 0 全新

I persevered some more and found a solution on http://www.codeguru.com/forum/archive/index.php/t-379767.html. The forum is for C, so naturally " | OFN_NOCHANGEDIR" does not work, but ".OR. OFN_NOCHANGEDIR" does work. Problem solved.

The MSDN documentation says that "[t]his flag is ineffective in GetOpenFileName." Weird.