|
Post by ronald on Oct 21, 2019 9:32:11 GMT -5
LS,
I tried the following DLL call:
calldll #comdlg32, "GetOpenFileNameA", ofn as struct
I read in Alyce's API reference book that this would call up an extended file dialog. (Of course I first initialized the ofn struct).
However, I get an non-continuable protection violation as a result.
What could I be doing wrong, and how can this be fixed?
|
|
|
Post by Rod on Oct 21, 2019 13:21:51 GMT -5
This is usually about the exact details of the data types you have used. So show us the exact code.
|
|
|
Post by Chris Iverson on Oct 21, 2019 13:46:57 GMT -5
GetOpenFileName() has a return value that you're ignoring, and is possibly causing LB to mess up the memory management.
CallDLL #comdlg32, "GetOpenFileNameA", ofn as struct, ret as long
Try that. If that still doesn't work, then as Rod said, post your code, or at least a fully working example, so we can see where the issue is.
|
|
|
Post by ronald on Oct 22, 2019 5:25:43 GMT -5
Thanks for the reactions. I added the "ret as long" as suggested, and I am now one step further. The program doesn't crash anymore, but the dialog window still doesn't show, and the value of ret is 0.
Underneath the initialisation code:
sub ExtendedFileDialog struct ofn,_ lStructSize as ulong,_ 'size of struct hwndOwner as ulong,_ 'owner window, can be null hInstance as ulong,_ 'instance handle, can be null lpstrFilter$ as ptr,_ 'filter strings lpstrCustomFilter$ as ptr,_ 'user's filter string choice nMaxCustFilter as ulong,_ 'length of lpstrCustomFilter$ nFilterIndex as ulong,_ 'index of currently selected filter lpstrFile$ as ptr,_ 'filename used to initialize nMaxFile as ulong,_ 'length of lpstrFile$ lpstrFileTitle$ as ptr,_ 'buffer to receive filename without path nMaxFileTitle as ulong,_ 'length of lpstrFileTitle$ lpstrInitialDir$ as ptr,_ 'initial file directory, or null for current directory lpstrTitle$ as ptr,_ 'Titlebar string for dialog flags as ulong,_ 'initialization flags nFileOffset as word,_ '0-based offset to filename in lpstrFile$ nFileExtension as word,_ '0-based offset to extension in lpstrFile4 lpstrDefExt$ as ptr,_ 'default extension if none is typed lCustData as ulong,_ 'not used here lpfnHook as long,_ 'hook procedure, not used here lpTemplateName as long 'template name, not used here
ofn.lStructSize.struct=len(ofn.struct) Filter$="All files" + chr$(0) +"*.*" + chr$(0) + chr$(0) ofn.lpstrFilter$.struct = Filter$ ofn.lpstrCustomFilter$.struct = space$(260) + chr$(0) ofn.nMaxCustFilter.struct = 260 ofn.nFilterIndex.struct = 1 ofn.lpstrFile$.struct= chr$(0) + space$(260) + chr$(0) ofn.nMaxFile.struct=260 ofn.lpstrFileTitle$.struct=space$(260) + chr$(O) ofn.nMaxFileTitle.struct=260 ofn.lpstrInitialDir$.struct = "C:\" + chr$(0) ofn.lpstrTitle$.struct="Select files" + chr$(0) ofn.lpstrDefExt$.struct="" + chr$(0) ofn.flags.struct = _OFN_PATHMUSTEXIST or _OFN_FILEMUSTEXIST or _OFN_ALLOWMULTISELECT
calldll #comdlg32, "GetOpenFileNameA", ofn as struct, ret as long
|
|
|
Post by Brandon Parker on Oct 22, 2019 6:33:14 GMT -5
Here is a working example from a few years ago when everyone was looking at the path length issue. This one is from Stefan, so credit goes to him for the polished code; I just happen to remember I had it sitting around. This should help get you pointed in the correct direction. Dig through it and see if you can determine where you might have an issue in your code.
'API_FileDialog.bas 'Author: Stefan Pendl 'Date: 10.04.11
' Information used from: ' ' Bay Six Software ' Converting C types to LB types ' http://www.b6sw.com/forum/content.php?mode=hints&t=235 ' ' MSDN: ' OPENFILENAME Structure ' http://msdn.microsoft.com/en-us/library/ms646839%28VS.85%29.aspx ' ' GetOpenFileName Function ' http://msdn.microsoft.com/en-us/library/ms646927%28VS.85%29.aspx ' ' GetSaveFileName Function ' http://msdn.microsoft.com/en-us/library/ms646928%28VS.85%29.aspx ' ' CommDlgExtendedError Function ' http://msdn.microsoft.com/en-us/library/ms646916%28VS.85%29.aspx
struct tagOFN,_ lStructSize as uLong,_ ' length of the structure, fill with LEN(tagOFN.struct) hwndOwner as uLong,_ ' must be _NULL hInstance as uLong,_ ' must be _NULL lpstrFilter as Ptr,_ ' file filter in the format {name}\0{pattern}\0\0, can be _NULL lpstrCustomFilter as uLong,_ ' must be _NULL nMaxCustFilter as uLong,_ ' must be 0 nFilterIndex as uLong,_ ' must be 0 lpstrFile as Ptr,_ ' buffer for selected files, must be _MAX_PATH for single file or 32kB for multiple files nMaxFile as uLong,_ ' size of the lpstrFile buffer, must be LEN(tagOFN.lpstrFile.struct) lpstrFileTitle as uLong,_ ' must be _NULL nMaxFileTitle as uLong,_ ' must be 0 lpstrInitialDir as Ptr,_ ' initial path, can be _NULL lpstrTitle as Ptr,_ ' dialog title, can be _NULL Flags as uLong,_ ' OFN_FILEMUSTEXIST; OFN_ALLOWMULTISELECT must be used with OFN_EXPLORER (0x00080000) nFileOffset as Word,_ ' start of file name nFileExtension as Word,_ ' start of extension lpstrDefExt as uLong,_ ' must be _NULL lCustData as uLong,_ ' must be _NULL lpfnHook as uLong,_ ' must be _NULL lpTemplateName as uLong ' must be _NULL
WindowWidth = DisplayWidth WindowHeight = 400 UpperLeftX = 1 UpperLeftY = 1
nomainwin
statictext #m.status, "Status", 10, 10, WindowWidth - 40, 20 statictext #m.error, "Errors", 10, 40, WindowWidth - 40, 40
stylebits #m.file, _WS_VSCROLL, _ES_AUTOHSCROLL, 0, 0 textbox #m.file, 10, 90, WindowWidth - 40, 220
button #m.browse, "Browse", [browse], ul, 10, 320 button #m.save, "Save", [save], ul, 100, 320
open "API FileDialog Test" for dialog as #m #m "trapclose [quit]" StartDir$ = DefaultDir$ wait
[browse] gosub [InitSelection]
'call APIfiledialog chr$(0) + "Open", StartDir$ + "\*.*", FileName$ 'call APIfiledialog chr$(0) + "Open", StartDir$ + "\*.log;*.txt", FileName$ call APIfiledialog "", "", FileName$
gosub [DisplaySelection] wait
[save] gosub [InitSelection]
'call APIfiledialog chr$(0) + "Save", StartDir$ + "\*.*", FileName$ 'call APIfiledialog chr$(0) + "Save", "*.bas", FileName$ call APIfiledialog chr$(0) + "Save", "", FileName$
gosub [DisplaySelection] wait
[quit] close #m end
[InitSelection] #m.status "" #m.error "" #m.file "" return
[DisplaySelection] Count = Count + 1
#m.file FileName$; chr$(13); chr$(10);_ "Path length "; len(FileName$); chr$(13); chr$(10);_ "Attempt "; Count
if FileName$ <> "" then StartDir$ = FileName$
while right$(StartDir$, 1) <> "\" StartDir$ = left$(StartDir$, len(StartDir$) - 1) wend StartDir$ = left$(StartDir$, len(StartDir$) - 1) end if return
sub APIfiledialog Title$, Template$, ByRef Filepath$ ' This procedure displayes a file dialog to allow the user to select a file ' It is similar to the FILEDIALOG command with three exceptions: ' 1) it allows selecting paths longer than 128 characters ' 2) it makes sure the selected file exists on open ' 3) it prompts the user for confirmation to overwrite an existing file ' ' Usage: CALL APIfiledialog TitleString, TemplateString, ReceiverVariable ' ' TitleString ........ the caption for the dialog, if it includes the word "save" ' the dialog to save a file is displayed instead of the open dialog ' ' TemplateString ..... the file filter pattern, like "*.txt" or "*.log;*.txt" ' if a path is included it will be used as the initial folder ' ' ReceiverVariable ... the string variable to receive the selected file
BufferSize = _MAX_PATH + 1 OFN.EXPLORER = 524288
' check if we need the save dialog if instr(lower$(Title$), "save") > 0 then Flags = _OFN_OVERWRITEPROMPT else Flags = _OFN_FILEMUSTEXIST Or _OFN_ALLOWMULTISELECT Or OFN.EXPLORER end if
' extract the initial folder, if any if instr(Template$, "\") > 0 then InitialDir$ = Template$
while right$(InitialDir$, 1) <> "\" InitialDir$ = left$(InitialDir$, len(InitialDir$) - 1) wend end if
' extract the file filter FileFilter$ = mid$(Template$, len(InitialDir$) + 1)
' common settings tagOFN.lStructSize.struct = len(tagOFN.struct) tagOFN.lpstrFilter.struct = FileFilter$; chr$(0); FileFilter$; chr$(0); chr$(0) tagOFN.lpstrFile.struct = chr$(0); space$(BufferSize); chr$(0) tagOFN.nMaxFile.struct = BufferSize tagOFN.lpstrInitialDir.struct = InitialDir$; chr$(0) tagOFN.lpstrTitle.struct = Title$; chr$(0) tagOFN.Flags.struct = Flags
' display the file dialog if instr(lower$(Title$), "save") > 0 then calldll #comdlg32, "GetSaveFileNameA",_ tagOFN as struct,_ result as Long else calldll #comdlg32, "GetOpenFileNameA",_ tagOFN as struct,_ result as Long end if
' check for errors calldll #comdlg32, "CommDlgExtendedError",_ ErrorCode as uLong
' return the selected path on success if result <> 0 and ErrorCode = 0 then Selected$ = winstring(tagOFN.lpstrFile.struct) else Selected$ = "" end if
Filepath$ = Selected$ end sub
{:0)
Brandon Parker
|
|
|
Post by ronald on Oct 22, 2019 8:35:32 GMT -5
Thanks Brandon. I made the appropriate changes, and it now indeed works. I can now select multiple files, and parse the result with the WinString function. But if I want to select both files and folders (multiple), is this also possible with GetOpenFileNameA, or do I then need a different API function?
|
|