Search code examples
vbams-accessms-office32bit-64bitdllimport

Access x64 VBA - Getting ERROR_RESOURCE_DATA_NOT_FOUND when trying to load string from user32.dll


I am trying to load the localized button captions in Access 2016 x64, which are found in user32.dll.

The strange thing is, on another machine with Access 2010 x86 installed, the code works perfectly.

The code is the following:

Option Compare Database
Option Explicit

Private Declare PtrSafe Function LoadString Lib "user32" Alias "LoadStringA" ( _
    ByVal hInstance As Long, _
    ByVal uID As Long, _
    ByVal lpBuffer As String, _
    ByVal nBufferMax As Long) _
    As Long

Private Declare PtrSafe Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" ( _
    ByVal lpFileName As String) _
    As Long

Private Enum CAPTION
    OK_CAPTION = 800
    CANCEL_CAPTION = 801
    ABORT_CAPTION = 802
    RETRY_CAPTION = 803
    IGNORE_CAPTION = 804
    YES_CAPTION = 805
    NO_CAPTION = 806
    CLOSE_CAPTION = 807
    HELP_CAPTION = 808
    TRYAGAIN_CAPTION = 809
    CONTINUE_CAPTION = 810
End Enum

Private Const lPath As String = "user32.dll"
Private Const BufferMax As Long = 256
Private Const cIndex As Long = CAPTION.OK_CAPTION

Private Sub cmdGetCaptionById_Click()
    Dim Buffer As String * BufferMax
    Dim Instance As Long
    Dim sLen As Long
    Instance = LoadLibrary(lPath)
    sLen = LoadString(Instance, cIndex, Buffer, BufferMax)
    If sLen <> 0 Then
        Caption = Left(Buffer, sLen)
        MsgBox Caption, vbInformation
    Else
        MsgBox "No caption found, error " & Err.LastDllError, vbCritical
    End If
End Sub

I can't manage to get into the if block, it's like he doesn't find the stringtable.
The detailed error:

ERROR_RESOURCE_DATA_NOT_FOUND
1812 (0x714)
The specified image file did not contain a resource section.

Expected string output, based on cIndex (In this case, OK_CAPTION, which has ID = 800):

Caption = "Ok"

Help is very appreciated!


Solution

  • LoadLibrary should return a LongPtr instead of Long.
    Therefore, ByVal hInstance As LongPtr instead of ByVal hInstance As Long
    and finally Dim Instance As LongPtr instead of Dim Instance As Long.
    Hope that will help somebody!