Results 1 to 6 of 6

Thread: [VB6] Code Snippet: Load Language Specific resource String. FindResourceEx

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    [VB6] Code Snippet: Load Language Specific resource String. FindResourceEx

    This came up in another thread.
    A lot of declarations out there for FindResourceEx for VB6 aren't too accurate, probably a relic of people still using APIViewer or the like.

    FindStringResourceEx() was translated from the C routine by Raymond Chen.
    https://blogs.msdn.microsoft.com/old...0-00/?p=40813/

    And Delphi version from this blog.
    https://wiert.me/2014/07/17/delphi-a...pecific-lcids/

    Unicode Compliant.

    Code:
    Option Explicit
    
    Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryW" (ByVal lpLibFileName As Long) As Long
    Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
    Private Declare Function FindResourceEx Lib "kernel32" Alias "FindResourceExW" (ByVal hModule As Long, ByVal lpType As Long, ByVal lpName As Long, ByVal wLanguage As Integer) As Long
    Private Declare Function LoadResource Lib "kernel32" (ByVal hInstance As Long, ByVal hResInfo As Long) As Long
    Private Declare Function LockResource Lib "kernel32" (ByVal hResData As Long) As Long
    Private Declare Function SysReAllocStringLen Lib "oleaut32" (ByVal pBSTR As Long, ByVal psz As Long, ByVal Length As Long) As Long
    Private Declare Function GetMem2 Lib "msvbvm60" (Src As Any, Dst As Any) As Long
    
    Private Function PtrAdd(ByVal Address As Long, ByVal Offset As Long) As Long
    ' unsigned pointer arithmetic, moves overflow by toggling the sign bit
    ' required when using /LARGEADDRESSAWARE on 64bit windows
        Const SIGN_BIT As Long = &H80000000
        PtrAdd = (Address Xor SIGN_BIT) + Offset Xor SIGN_BIT
    End Function
    
    Private Property Get DUInt(ByVal Address As Long) As Long
    ' Compensate for VB's lack of unsigned types
    ' Copies a 16bit Unsigned Integer from a pointer into a Long
        GetMem2 ByVal Address, DUInt
    End Property
    
    ' https://blogs.msdn.microsoft.com/oldnewthing/20040130-00/?p=40813/
    Function FindStringResourceEx(ByVal hInstance As Long, _
                                  ByVal uId As Long, _
                                  ByVal langId As Long _
                                  ) As String
        
        Const STRINGS_PER_BUCKET As Long = 16&
        Const RT_STRING As Long = 6&
        Const WCHAR_SIZE As Long = 2
        
        Dim hResource As Long
        Dim hGlobal As Long
        Dim Ptr As Long, i As Long
        
        hResource = FindResourceEx(hInstance, _
                                   RT_STRING, _
                                   uId \ STRINGS_PER_BUCKET + 1, _
                                   langId)
        If hResource Then
            hGlobal = LoadResource(hInstance, hResource)
            If hGlobal Then
                Ptr = LockResource(hGlobal)
                If Ptr Then
                    For i = 1 To uId And (STRINGS_PER_BUCKET - 1)
                        Ptr = PtrAdd(Ptr, (1 + DUInt(Ptr)) * WCHAR_SIZE)
                    Next
                    SysReAllocStringLen VarPtr(FindStringResourceEx), _
                                        PtrAdd(Ptr, 2), _
                                        DUInt(Ptr)
                End If
            End If
        End If
    End Function
    
    Private Sub Form_Click()
        Const YES_CAPTION = 805
        Const LANG_ID_ENGLISH_US = 1033
    
        Dim hModule As Long
        hModule = LoadLibrary(StrPtr("user32"))
        If hModule Then
            Debug.Print FindStringResourceEx(hModule, _
                                             YES_CAPTION, _
                                             LANG_ID_ENGLISH_US)
            FreeLibrary hModule
        End If
    End Sub
    Last edited by DEXWERX; Dec 7th, 2017 at 08:13 AM. Reason: updated with pointer addition

  2. #2
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: [VB6] Code Snippet: Load Language Specific resource String. FindResourceEx

    Hi,

    Thanks for sharing this code.

    I have adapted your code in order to work in vba x64 and it works great for languages such as english, french and arabic except for Spanish !

    When I pass 1034& (spanish) as the Language ID parameter , I get an empty string.
    Code:
     Debug.Print FindStringResourceEx(hModule, _
                                             YES_CAPTION, _
                                             1034&)

    hResource returns 0 at the following line indicating failure but GetLastError returns : 'The operation completed successfully' !!!!
    Code:
    hResource = FindResourceEx(hInstance, _
                                   RT_STRING, _
                                   uId \ STRINGS_PER_BUCKET + 1, _
                                   LangID)
    sBuffer = Space(256)
    FormatMessage FORMAT_MESSAGE_FROM_SYSTEM, ByVal 0&, GetLastError, LANG_NEUTRAL, sBuffer, 256, ByVal 0&
    Debug.Print RTrim(sBuffer)  '<== Returns the string :  'The operation completed successfully'

    I definitely have the spanish language pack installed in my pc and I am running the code in Windows 10 x64 if that makes a difference.

    Any idea why this won't work for spanish but works for other installed languages ?

    Regards.

    EDIT:
    I have also tried passing the LCID of all other Spanish Sub-Languages but none of them work.
    Last edited by JAAFAR; Sep 26th, 2020 at 10:58 PM.

  3. #3
    Hyperactive Member
    Join Date
    Jun 2016
    Location
    EspaƱa
    Posts
    506

    Re: [VB6] Code Snippet: Load Language Specific resource String. FindResourceEx

    Hello JAAFAR
    In Spanish the code is 3082
    Greetings

  4. #4
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: [VB6] Code Snippet: Load Language Specific resource String. FindResourceEx

    Quote Originally Posted by yokesee View Post
    Hello JAAFAR
    In Spanish the code is 3082
    Greetings
    Thank you yokesee

    Yes, 3082 worked as expected.

    I got the LCIDs from the page in the follwoing link BUT 3082 is not anywhere on the is of LCDIs !!!!!! Instead, the list shows 1034.
    https://www.science.co.il/language/Locale-codes.php
    Last edited by JAAFAR; Sep 27th, 2020 at 12:25 PM.

  5. #5

  6. #6
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: [VB6] Code Snippet: Load Language Specific resource String. FindResourceEx

    Quote Originally Posted by Eduardo- View Post
    Thanks Eduardo,

    It is there:
    3082 Spanish - Spain (Modern Sort) es-ES

    I should have looked for the LCIDs the proper way in the official microsoft site not in the first site that came up.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width