Please pay attention to the bug in TB (Unable to load DLL) and fix it
So, I wrote a module in VB6 to open a file selection dialog. It works fine on VB6, but it is buggy in Twin. I ask you to pay attention to this bug of the developers of Twin Basic.
1. In the executable file, the EXE does not behave like in the IDE. It's buggy. An error pops up that allegedly the DLL cannot be loaded. I have Win7.
2. There is some other error with calling the dialog for multiple file selection. I still did not fully understand what and why it does not work there, but as a result it does not give out a list of files that the user has chosen to open.
I'm giving you the whole of my little project. Module:
Code:
Option Explicit
'////////////////////////////////////////////////////
'// A module for calling the file selection dialog //
'// Copyright (c) 08.05.2024 by HackerVlad //
'// e-mail: [email protected] //
'// Version 2.1 //
'////////////////////////////////////////////////////
Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameW" (ByVal pOpenfilename As Long) As Long
Private Declare Function GetSaveFileName Lib "comdlg32.dll" Alias "GetSaveFileNameW" (ByVal pOpenfilename As Long) As Long
Private Const OFN_ALLOWMULTISELECT = &H200
Private Const OFN_EXPLORER = &H80000
Private Const OFN_LONGNAMES = &H200000
Private Const OFN_NODEREFERENCELINKS = &H100000
Private Const OFN_OVERWRITEPROMPT = &H2
Private Const OFN_SHAREAWARE = &H4000
Private Type OPENFILENAME
lStructSize As Long
hwndOwner As Long
hInstance As Long
lpstrFilter As String
lpstrCustomFilter As String
nMaxCustFilter As Long
nFilterIndex As Long
lpstrFile As String
nMaxFile As Long
lpstrFileTitle As String
nMaxFileTitle As Long
lpstrInitialDir As String
lpstrTitle As String
flags As Long
nFileOffset As Integer
nFileExtension As Integer
lpstrDefExt As String
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type
Public Enum OpenFileEnum
OFEOpenForLoad = 1
OFEOpenForSave = 2
End Enum
' The file selection dialog function (open or save) returns the path ALWAYS without a slash at the end
' The array arrFiles is an optional parameter and is used only when selecting multiple files
Public Function GetDialogFileName(OpenMode As OpenFileEnum, ByVal strFilter As String, Optional ByVal hwndOwner As Long, Optional ByVal InitDir As String, Optional ByVal DialogTitle As String, Optional ByVal AllowMultiSelect As Boolean, Optional arrFiles As Variant) As String
Dim ofn As OPENFILENAME
Dim str As String
Dim ret As Long
Dim i As Long
ofn.nMaxFile = 999999 ' The size of the buffer pointed to by lpstrFile, in characters. The buffer must be large enough to store a string or strings of the path and file name, including the terminating NULL character.
ofn.hwndOwner = hwndOwner
If Len(DialogTitle) > 0 Then ofn.lpstrTitle = DialogTitle
ofn.lpstrFile = Space$(999999)
ofn.lStructSize = LenB(ofn)
ofn.lpstrFilter = strFilter
If Len(InitDir) > 0 Then ofn.lpstrInitialDir = InitDir
ofn.flags = OFN_SHAREAWARE Or OFN_LONGNAMES Or OFN_NODEREFERENCELINKS Or OFN_EXPLORER
If OpenMode = OFEOpenForLoad Then
If AllowMultiSelect = True Then ofn.flags = ofn.flags Or OFN_ALLOWMULTISELECT
ret = GetOpenFileName(VarPtr(ofn))
Else
ofn.flags = ofn.flags Or OFN_OVERWRITEPROMPT
ret = GetSaveFileName(VarPtr(ofn))
End If
If ret <> 0 Then
If AllowMultiSelect = True And OpenMode = OFEOpenForLoad Then
i = InStr(1, ofn.lpstrFile, vbNullChar & vbNullChar)
If i Then ofn.lpstrFile = Left$(ofn.lpstrFile, i - 1)
str = Left$(ofn.lpstrFile, ofn.nFileOffset - 1)
ofn.lpstrFile = Right$(ofn.lpstrFile, Len(ofn.lpstrFile) - ofn.nFileOffset)
arrFiles = Split(ofn.lpstrFile, vbNullChar)
If Right$(str, 1) <> "\" Then
GetDialogFileName = str
Else
GetDialogFileName = Left$(str, Len(str) - 1)
End If
Else
i = InStr(1, ofn.lpstrFile, vbNullChar)
If i Then GetDialogFileName = Left$(ofn.lpstrFile, i - 1)
End If
End If
End Function
Re: Please pay attention to the bug in TB (Unable to load DLL) and fix it
That's much better Vlad as a bug report. Still better to raise it on github here: https://github.com/twinbasic/twinbasic/issues
If you can raise them on github it helps Wayne track issues to resolution. It is easy to obtain a github login if you don't have one.
Skillset: VMS,DOS,Windows Sysadmin from 1985, fault-tolerance, VaxCluster, Alpha,Sparc. DCL,QB,VBDOS- VB6,.NET, PHP,NODE.JS, Graphic Design, Project Manager, CMS, Quad Electronics. classic cars & m'bikes. Artist in water & oils. Historian.
By the power invested in me, all the threads I start are battle free zones - no arguing about the benefits of VB6 over .NET here please. Happiness must reign.
Re: Please pay attention to the bug in TB (Unable to load DLL) and fix it
2. There is some other error with calling the dialog for multiple file selection. I still did not fully understand what and why it does not work there, but as a result it does not give out a list of files that the user has chosen to open.
The bug is in assigning a Variant containing an array to a String array when passed as an argument; I've created a minimal reproduction and posted the report here: https://github.com/twinbasic/twinbasic/issues/1961
As a temporary workaround, you can separate the conversion from the argument,
Code:
Dim vFiles As Variant
Dim ArrayFiles() As String
Dim strFileName As String
strFileName = GetDialogFileName(OFEOpenForLoad, "All files" & vbNullChar & "*.*" & vbNullChar & vbNullChar, hWnd, , "Open any file(s)", True, vFiles)
ArrayFiles = vFiles
Re: Please pay attention to the bug in TB (Unable to load DLL) and fix it
With regards to the 'Unable to load DLL' issue, it appears it is something to with the DLL name being 'comdlg32.dll'. If you change it to 'comdlg32', on my Win7 test machine, the compiled EXE then works. I will look into the issue further.
Re: Please pay attention to the bug in TB (Unable to load DLL) and fix it
Originally Posted by WaynePhillipsEA
With regards to the 'Unable to load DLL' issue, it appears it is something to with the DLL name being 'comdlg32.dll'. If you change it to 'comdlg32', on my Win7 test machine, the compiled EXE then works. I will look into the issue further.
Re: Please pay attention to the bug in TB (Unable to load DLL) and fix it
Yes, you're right, I removed the ".dll" and everything worked as it should, the error disappeared. I will need to check the same thing in my CAB archive packaging utility - there was a similar error, I remember.
Re: Please pay attention to the bug in TB (Unable to load DLL) and fix it
Yes, I just checked, with the code "cabinet.dll "the same error occurred. But this is very surprising, because in version 1.0 of my utility, the same code using "cabinet.dll "everything works as it should, for some reason. And here I had to remove the ".dll" and everything worked right away.
Re: Please pay attention to the bug in TB (Unable to load DLL) and fix it
OK, I have investigated further and found the root cause. Changing to "comdlg32" fixed the issue only by chance. The actual problem is that the literal unicode strings that are passed to the LoadLibrary() OS calls are not guaranteed to be aligned correctly in current BETAs of twinBASIC, meaning that the unicode strings could be at an uneven offset in the EXE module (e.g. &H410001) but Win7/8 requires that they are 2-byte aligned (e.g. &H410002), as you would expect unicode strings to be. It's a small but important linker bug that is now fixed in the upcoming release. Thanks for reporting it.
Re: Please pay attention to the bug in TB (Unable to load DLL) and fix it
Originally Posted by fafalone
The bug is in assigning a Variant containing an array to a String array when passed as an argument; I've created a minimal reproduction and posted the report here: https://github.com/twinbasic/twinbasic/issues/1961
As a temporary workaround, you can separate the conversion from the argument,
Code:
Dim vFiles As Variant
Dim ArrayFiles() As String
Dim strFileName As String
strFileName = GetDialogFileName(OFEOpenForLoad, "All files" & vbNullChar & "*.*" & vbNullChar & vbNullChar, hWnd, , "Open any file(s)", True, vFiles)
ArrayFiles = vFiles
Thank you so much for fixing this bug too. I am pleased to see that the new version that I downloaded has already fixed as many as three bugs that I asked to fix. You really don't stand in one place, but you're constantly moving forward and fixing glitches pretty quickly. I am proud of your work.