GetOpenFile not working in 64Bit Windows 11 under MSAccess 2021 (1 Viewer)

Dippies

New member
Local time
Today, 12:15
Joined
May 21, 2020
Messages
14
Good day all,

Please help,

My MSAccess version 2010 originally coded on Windows 7 Professional has a problem runing under windoes 11 MSaccess 2021.

The following event procedure does react when clicked. The dialog box does not open.
It seems the code is "disabled?"

Private Sub Voorblad_Click()
Me![Phvoorblad] = GetOpenFile_CLT("C:\", "Select the Coin Picture File")
Me![Phvoorblad] = LCase(Me![Phvoorblad])
Me!imgvoorblad.Picture = Me!Phvoorblad
End Sub

I appreciate your answers.
Blessings
 

theDBguy

I’m here to help
Staff member
Local time
Today, 03:15
Joined
Oct 29, 2018
Messages
21,489
Hi. Can you show us the code for GetOpenFile_CLT()?
 

moke123

AWF VIP
Local time
Today, 06:15
Joined
Jan 11, 2013
Messages
3,926
Have you converted the code to run under 64 bit access? It appears to be a windows API for file dialog.
 

Dippies

New member
Local time
Today, 12:15
Joined
May 21, 2020
Messages
14
Hi. Can you show us the code for GetOpenFile_CLT()?
Hi there,
Herewith the code as it appears in the event procedure.

Private Sub Voorblad_Click()
Me![Phvoorblad] = GetOpenFile_CLT("C:\", "Select the Coin Picture File")
Me![Phvoorblad] = LCase(Me![Phvoorblad])
Me!imgvoorblad.Picture = Me!Phvoorblad
End Sub
 

Dippies

New member
Local time
Today, 12:15
Joined
May 21, 2020
Messages
14
Have you converted the code to run under 64 bit access? It appears to be a windows API for file dialog.
I have only edited 3 Declare statements that was in error.
I am not aufait with any "conversion" so to speak
 

moke123

AWF VIP
Local time
Today, 06:15
Joined
Jan 11, 2013
Messages
3,926
Local time
Today, 12:15
Joined
Feb 27, 2023
Messages
43
Found the "secret" Code for GetOpenFile_CLT. If you adapt it correct for x64 VBA (see How to convert Windows API declarations in VBA for 64-bit), it works, but what's wrong with Application.FileDialog (as moke had asked above)?

Working x64 Code for GetOpenFile_CLT (only tested with standard settings GetOpenFile_CLT "C:\", "Select a File To Open")

Code:
Option Compare Database
Option Explicit

' Declarations for Windows Common Dialogs procedures
Private Type CLTAPI_OPENFILE
  strFilter As String             ' Filter string
  intFilterIndex As Long          ' Initial Filter to display.
  strInitialDir As String         ' Initial directory for the dialog to open in.
  strInitialFile As String        ' Initial file name to populate the dialog with.
  strDialogTitle As String        ' Dialog title
  strDefaultExtension As String   ' Default extension to append to file if user didn't specify one.
  lngFlags As Long                ' Flags (see constant list) to be used.
  strFullPathReturned As String   ' Full path of file picked.
  strFileNameReturned As String   ' File name of file picked.
  intFileOffset As Integer        ' Offset in full path (strFullPathReturned) where the file name (strFileNameReturned) begins.
  intFileExtension As Integer     ' Offset in full path (strFullPathReturned) where the file extension begins.
End Type

Const ALLFILES = "All Files"

Private Type CLTAPI_WINOPENFILENAME
  lStructSize As Long
  hwndOwner As LongPtr
  hInstance As LongPtr
  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 LongPtr
  lpfnHook As LongPtr
  lpTemplateName As String
  pvReserved As LongPtr
  dwReserved As Long
  FlagsEx As Long
End Type

Const OFN_ALLOWMULTISELECT = &H200
Const OFN_CREATEPROMPT = &H2000
Const OFN_EXPLORER = &H80000
Const OFN_FILEMUSTEXIST = &H1000
Const OFN_HIDEREADONLY = &H4
Const OFN_NOCHANGEDIR = &H8
Const OFN_NODEREFERENCELINKS = &H100000
Const OFN_NONETWORKBUTTON = &H20000
Const OFN_NOREADONLYRETURN = &H8000
Const OFN_NOVALIDATE = &H100
Const OFN_OVERWRITEPROMPT = &H2
Const OFN_PATHMUSTEXIST = &H800
Const OFN_READONLY = &H1
Const OFN_SHOWHELP = &H10

Declare PtrSafe Function CLTAPI_GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" _
  (pOpenfilename As CLTAPI_WINOPENFILENAME) _
As Boolean

Declare PtrSafe Function CLTAPI_GetSaveFileName Lib "comdlg32.dll" Alias "GetSaveFileNameA" _
  (pOpenfilename As CLTAPI_WINOPENFILENAME) _
As Boolean

Function GetOpenFile_CLT(strInitialDir As String, strTitle As String) As String
  ' Comments  : Simple file open routine. For additional options, use GetFileOpenEX_CLT()
  ' Parameters: strInitialDir - path for the initial directory, or blank for the current directory
  '             strTitle - title for the dialog
  ' Returns   : string path, name and extension of the file selected
  '
  Dim fOK As Boolean
  Dim typWinOpen As CLTAPI_WINOPENFILENAME
  Dim typOpenFile As CLTAPI_OPENFILE
  Dim strFilter As String

  On Error GoTo PROC_ERR

  ' Set defaults for the structure
  strFilter = CreateFilterString_CLT("All Files (*.*)", "*.*", "Database Files (*.MDB)", "*.MDB")

  If strInitialDir <> "" Then
    typOpenFile.strInitialDir = strInitialDir
  Else
    typOpenFile.strInitialDir = CurDir()
  End If

  If strTitle <> "" Then
    typOpenFile.strDialogTitle = strTitle
  End If

  typOpenFile.strFilter = strFilter
  typOpenFile.lngFlags = OFN_HIDEREADONLY Or OFN_SHOWHELP

  ' Convert the CLT structure to a Win structure
  ConvertCLT2Win typOpenFile, typWinOpen

  ' Call the Common dialog
  fOK = CLTAPI_GetOpenFileName(typWinOpen)

  ' Convert the Win structure back to a CLT structure
  ConvertWin2CLT typWinOpen, typOpenFile

  GetOpenFile_CLT = typOpenFile.strFullPathReturned
     
PROC_EXIT:
  Exit Function

PROC_ERR:
  GetOpenFile_CLT = ""
  Resume PROC_EXIT

End Function

Sub ConvertCLT2Win(CLT_Struct As CLTAPI_OPENFILE, Win_Struct As CLTAPI_WINOPENFILENAME)
  ' Comments  : Converts the passed CLTAPI structure to a Windows structure
  ' Parameters: CLT_Struct - record of type CLTAPI_OPENFILE
  '             Win_Struct - record of type CLTAPI_WINOPENFILENAME
  ' Returns   : Nothing
  '
  Dim strFile As String * 512

  On Error GoTo PROC_ERR

  Win_Struct.hwndOwner = Application.hWndAccessApp
  Win_Struct.hInstance = 0

  If CLT_Struct.strFilter = "" Then
    Win_Struct.lpstrFilter = ALLFILES & Chr$(0) & "*.*" & Chr$(0)
  Else
    Win_Struct.lpstrFilter = CLT_Struct.strFilter
  End If
  Win_Struct.nFilterIndex = CLT_Struct.intFilterIndex

  Win_Struct.lpstrFile = String(512, 0)
  Win_Struct.nMaxFile = 511

  Win_Struct.lpstrFileTitle = String$(512, 0)
  Win_Struct.nMaxFileTitle = 511

  Win_Struct.lpstrTitle = CLT_Struct.strDialogTitle
  Win_Struct.lpstrInitialDir = CLT_Struct.strInitialDir
  Win_Struct.lpstrDefExt = CLT_Struct.strDefaultExtension

  Win_Struct.flags = CLT_Struct.lngFlags

  Win_Struct.lStructSize = LenB(Win_Struct)

PROC_EXIT:
  Exit Sub

PROC_ERR:
  Resume PROC_EXIT
 
End Sub

Sub ConvertWin2CLT(Win_Struct As CLTAPI_WINOPENFILENAME, CLT_Struct As CLTAPI_OPENFILE)
  ' Comments  : Converts the passed CLTAPI structure to a Windows structure
  ' Parameters: Win_Struct - record of type CLTAPI_WINOPENFILENAME
  '             CLT_Struct - record of type CLTAPI_OPENFILE
  ' Returns   : Nothing
  '
  On Error GoTo PROC_ERR
     
  CLT_Struct.strFullPathReturned = Left(Win_Struct.lpstrFile, InStr(Win_Struct.lpstrFile, vbNullChar) - 1)
  CLT_Struct.strFileNameReturned = RemoveNulls_CLT(Win_Struct.lpstrFileTitle)
  CLT_Struct.intFileOffset = Win_Struct.nFileOffset
  CLT_Struct.intFileExtension = Win_Struct.nFileExtension

PROC_EXIT:
  Exit Sub

PROC_ERR:
  Resume PROC_EXIT

End Sub

Function CreateFilterString_CLT(ParamArray varFilt() As Variant) As String
  ' Comments  : Builds a Windows formatted filter string for "file type"
  ' Parameters: varFilter - parameter array in the format:
  '                          Text, Filter, Text, Filter ...
  '                         Such as:
  '                          "All Files (*.*)", "*.*", "Text Files (*.TXT)", "*.TXT"
  ' Returns   : windows formatted filter string
  '
  Dim strFilter As String
  Dim intCounter As Integer
  Dim intParamCount As Integer

  On Error GoTo PROC_ERR

  ' Get the count of paramaters passed to the function
  intParamCount = UBound(varFilt)

  If (intParamCount <> -1) Then
   
    ' Count through each parameter
    For intCounter = 0 To intParamCount
      strFilter = strFilter & varFilt(intCounter) & Chr$(0)
    Next
   
    ' Check for an even number of parameters
    If (intParamCount Mod 2) = 0 Then
      strFilter = strFilter & "*.*" & Chr$(0)
    End If
   
  End If

  CreateFilterString_CLT = strFilter

PROC_EXIT:
  Exit Function

PROC_ERR:
  CreateFilterString_CLT = ""
  Resume PROC_EXIT

End Function

Function RemoveNulls_CLT(strIn As String) As String
  ' Comments  : Removes terminator from a string
  ' Parameters: strIn - string to modify
  ' Return    : modified string
  '
  Dim intChr As Integer

  intChr = InStr(strIn, Chr$(0))

  If intChr > 0 Then
    RemoveNulls_CLT = Left$(strIn, intChr - 1)
  Else
    RemoveNulls_CLT = strIn
  End If

End Function
I added PtrSafe, correct Type-Declaration for OPENFILENAME and fixed the length computation of OPENFILENAME (LenB(), not Len()!), hth
 

Users who are viewing this thread

Top Bottom