- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've been using the following code:
type(T_OPENFILENAME) ofn character(*),parameter :: filter_spec = & "All Files"C//"*.*"C//""C character(512) :: file_spec = ""C lnth = Strlen (myBuffer) if (lnth < 2) Then file_spec = "TempFile.txt"C else file_spec = myBuffer end if lDlg = gdlg hwDlg = gdlg%HWND call getcwd(cdir) cd2 = trim(cdir) ofn%lStructSize = SIZEOF(ofn) ofn%hwndOwner = ghWndMain ofn%hInstance = ghInst 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 = loc(cd2) ofn%lpstrTitle = loc(""C) ofn%Flags = ior(OFN_PATHMUSTEXIST, OFN_NOVALIDATE) ofn%lpstrDefExt = loc("txt"C) ofn%lpfnHook = NULL ofn%lpTemplateName = NULL file_spec = Trim(AdjustL(myBuffer)) // ""C lnth = StrLen(file_spec) bret = GetSaveFileName(ofn) !<===== BOMB
in ivf 2016 with no problems. But now with 2017 r2 I get a break when calling it. This an x84 application and it is single threaded. I'm running in debug mode and my system has 32GB of RAM. My processor is an Intel i7-4770 running at 3.4GHz. I'm running within MS vs2013 Community Edition and my OS is Win 10 x64. I am using the Intel Parralel Studio XE Composer Edition.
Anyone have any ideas?
Thanks,
Brooks
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is not a complete source. I suggest you try to construct a reproducer by starting with the GETOPENFILENAME sample (it's pretty clear your code is based on that), and gradually tweak it to match your current code. There's stuff you have left out that might be relevant, I tested the GETOPENFILENAME sample and it works fine.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The snippet isn't compilable, so there may be other issues, but the parameter associated with the current working directory is not null terminated. Different versions of the compiler will lay things out in memory in different ways, which means things like a missing null termination will result in different behaviour. Perhaps `cd2 = trim(cdir) // ACHAR(0)` instead of your line 16.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Don't know much about this, but a couple of things I would try are:
- Don't use an initializer for file_spec, rather set its value with an assignment statement. This only matters if the procedure is invoked twice. Hmm... there is some contradictory logic involving file_spec, so maybe this is irrelevant.
- As a named constant, filter_spec doesn't necessarily have a LOC. You might want to assign a variable with filter_spec and use the LOC of the variable.
- Hopefully you have checked that cd2 has something valid in it.
- I would set lpstrFileTitle to NULL rather than LOC(""C) and anyhow I would give the LOC of a variable rather than that of a literal.
- All of the above probably will have no effect, but certainly I would use keyword syntax to construct the structure in one statement. That way you know that all members are set to some known value. Some of them might have been set to zero in previous environments but are now set to garbage. This really could cause a crash.
I assume that you mean that the program crashes at that last line so you can't use GetLastError or CommDlgExtendedError to investigate the cause of the problem.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Complete subroutine:
Subroutine Browse (myBuffer) !$=Browse !$ !$ !$ Browse is invoked by: !$ Dlgchanged Saveall !$ !$ Browse invokes: !$ Func Adjustl Func Char Module Comdlg32 Module Gdi32 !$ Subr Getcwd Func Getsavefilena Module Ifwin Func Index !$ Func Ior Module Kernel32 Func Loc Module Mstrlen !$ Module Pearsonglobal Func Sizeof Func Strlen Func Trim !$ Module User32 Module Xtransf !$ !$=Browse use ifwin use user32 use gdi32 use kernel32 use comdlg32 use mStrLen Implicit None Character(*),Intent(inout):: myBuffer integer(4):: ilen, lnth Integer(bool):: bret character(512):: cdir, cd2 type(T_OPENFILENAME) ofn character(*),parameter :: filter_spec = & "All Files"C//"*.*"C//""C character(512) :: file_spec = ""C lnth = Strlen (myBuffer) ! lnth = 10 myBuffer = "Sample.Txt"C if (lnth < 2) Then file_spec = "TempFile.txt"C else file_spec = myBuffer end if call getcwd(cdir) ! ok cd2 = trim(cdir) ! cd2 = 'C:\Users\Brooks\Desktop\Projects\Pearson\Pearson ' ofn%lStructSize = SIZEOF(ofn) ! = 152 ofn%hwndOwner = NULL ofn%hInstance = NULL 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 = loc(cd2) ofn%lpstrTitle = NULL ofn%Flags = OFN_PATHMUSTEXIST ofn%lpstrDefExt = loc("txt"C) ofn%lpfnHook = NULL ofn%lpTemplateName = NULL bret = GetSaveFileName(ofn) if (bret == 0) then return end if ilen = INDEX(file_spec,CHAR(0)) myBuffer = file_spec(1:ilen-1) return End Subroutine Browse
I tested the getopenfilename sample and it works fine for a console app. This subroutine is part of a large app that has 70+ subroutines and a winmain program. I then added it to generic and it works, so I don't know what to do. I guess I have a lot of debugging before I can resolve this, but thank to all for your comments.
Brooks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In your original post you said this was an "x84 application". Did you mean x86 or x64? If x86, did you try building it as x64?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As I said, I would try filling in all structure members first:
module mStrLen use ISO_C_BINDING implicit none private public StrLen interface function StrLen(str) bind(C,name='strlen') import implicit none integer(C_SIZE_T) StrLen character(KIND=C_CHAR), intent(in) :: str(*) end function StrLen end interface end module mStrLen Subroutine Browse (myBuffer) !$=Browse !$ !$ !$ Browse is invoked by: !$ Dlgchanged Saveall !$ !$ Browse invokes: !$ Func Adjustl Func Char Module Comdlg32 Module Gdi32 !$ Subr Getcwd Func Getsavefilena Module Ifwin Func Index !$ Func Ior Module Kernel32 Func Loc Module Mstrlen !$ Module Pearsonglobal Func Sizeof Func Strlen Func Trim !$ Module User32 Module Xtransf !$ !$=Browse use ifwin use mStrLen use ifport Implicit None Character(*),Intent(inout):: myBuffer integer(4):: ilen, lnth Integer(bool):: bret character(512):: cdir, cd2 type(T_OPENFILENAME) ofn character(*),parameter :: Pfs = & "All Files"C//"*.*"C//""C character(len(Pfs)) :: filter_spec = Pfs character(*), parameter :: Pfx = 'txt'//achar(0) character(len(Pfx)) :: lpstrDefExt = Pfx character(512) :: file_spec file_spec = achar(0) lnth = Strlen (myBuffer) ! lnth = 10 myBuffer = "Sample.Txt"C if (lnth < 2) Then file_spec = "TempFile.txt"C else file_spec = myBuffer end if cdir = '' bret = getcwd(cdir) ! ok cd2 = trim(cdir)//achar(0) ! cd2 = 'C:\Users\Brooks\Desktop\Projects\Pearson\Pearson ' ofn = T_OPENFILENAME( & lStructSize = SIZEOF(ofn), & ! = 152 hwndOwner = NULL, & hInstance = NULL, & lpstrFilter = loc(filter_spec), & lpstrCustomFilter = NULL, & nMaxCustFilter = 0, & nFilterIndex = 1, & ! Specifies initial filter value lpstrFile = loc(file_spec), & nMaxFile = len(file_spec), & lpstrFileTitle = NULL, & nMaxFileTitle = 0, & lpstrInitialDir = loc(cd2), & lpstrTitle = NULL, & Flags = OFN_PATHMUSTEXIST, & nFileOffset = 0, & nFileExtension = index(file_spec,'.',BACK=.TRUE.), & lpstrDefExt = loc(lpstrDefExt), & lCustData = NULL, & lpfnHook = NULL, & lpTemplateName = NULL, & pvReserved = NULL, & dwReserved = 0, & FlagsEx = 0) bret = GetSaveFileName(ofn) if (bret == 0) then return end if ilen = INDEX(file_spec,CHAR(0)) myBuffer = file_spec(1:ilen-1) return End Subroutine Browse
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Repeat Offender,
Thanks for the code. I tried it but still it didn't help. Here is what vs2013 debugger says after I hit continue, enter the directory and filer that I want and click save:
'PDC.exe' (Win32): Unloaded 'C:\Windows\System32\xmllite.dll'
The thread 0x23f4 has exited with code 0 (0x0).
7376 0000000000000000 ENTER: DllCanUnloadNow
ShellStreams: Detach
=======================================
VERIFIER STOP 0000000000000900: pid 0x256C: A heap allocation was leaked.
0000025B216DAA10 : Address of the leaked allocation. Run !heap -p -a <address> to get additional information about the allocation.
0000025B08F56570 : Address to the allocation stack trace. Run dps <address> to view the allocation stack.
0000025B1F3F6FCC : Address of the owner dll name. Run du <address> to read the dll name.
00007FFCC4D70000 : Base of the owner dll. Run .reload <dll_name> = <address> to reload the owner dll. Use 'lm' to get more information about the loaded and unloaded modules.
=======================================
This verifier stop is continuable.
After debugging it use `go' to continue.
=======================================
PDC.exe has triggered a breakpoint.
The program '[9580] PDC.exe' has exited with code 0 (0x0).
Debug looks fine before and within subroutine Browse before the break. I've got everything turned on in debug checking, like zeroing arrays and array bounds checking but I haven't figured it out yet.
Brooks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Also, I'm on x64 not x86.
Brooks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have found using the T_OPENFILENAME structure a bit like swimming in mud. There are many options and permutations and also the behaviour varies dependent on which version of windows is running. Just as a matter of interest does it work if you set lpstrInitialDir=NULL?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Andrew, done it both ways. Same resul;t.
Brooks
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page