Using bidi32.dll for Logical-Visual conversion

This code snippet is designated for using in bidirectional systems only (Hebrew and Arabic).
It uses the functions in bidi32.dll (BiDiConvertAnsiToOem and BiDiConvertOemToAnsi) to convert strings from Visual to Logical and from Logical to Visual.



'The following module uses bidi32.dll for Visual/Logical 
'conversion in Hebrew and Arabic versions of windows and office.

'The bidi32.dll is usually installed with bidirectional versions 
'of Microsoft Office.
'
'Be aware that the functions in bidi32.dll 
'(BiDiConvertAnsiToOem and BiDiConvertOemToAnsi) are not officially documented, and

'they don't do the best Visual/Logical conversion.
'
'Written by Nir Sofer.
'Web site: http://nirsoft.mirrorz.com

Declare Function BiDiConvertAnsiToOem Lib "BIDI32.DLL" Alias "#3" _
(lpConvertInfo As CONVERTINFO, ByRef lpStrInfo As STRINFO) As Long
Declare Function BiDiConvertOemToAnsi Lib "BIDI32.DLL" Alias "#2" _
(lpConvertInfo As CONVERTINFO, ByRef lpStrInfo As STRINFO) As Long

Private Type CONVERTINFO
     hWndOwner As Long          'Owner Window
     nOemCP As Long             'OEM code page
     fOemLayout As Long         'OEM text layout
     nWindowsCP As Long         'Windows code page
     fControlChars As Long      'Output string BiDi control characters
     fShowLayout As Long        'Show/hide Layout dialog item
     nUILang As Long            'UI language
End Type

Type STRINFO
     lpStrIn As String          'Input string
     cchIn As Long              'Length of input string
     lpStrOut As String         'Output string buffer
     cchOut As Long             'Length of output string buffer
End Type

'This function receives one argument containing a logical text and returns visual text.
Public Function LogicalToVisual(LogicalStr As String) As String
    Dim ConvInfo        As CONVERTINFO
    Dim StrInfo1        As STRINFO
    Dim Buf             As String * 2000
    
    ConvInfo.nOemCP = 1
    ConvInfo.fOemLayout = 2
    ConvInfo.nWindowsCP = 1255
    ConvInfo.fControlChars = 1
    ConvInfo.nUILang = &H409
    ConvInfo.fShowLayout = 1
    
    StrInfo1.lpStrIn = LogicalStr
    StrInfo1.cchIn = Len(LogicalStr)
    StrInfo1.lpStrOut = Buf
    StrInfo1.cchOut = Len(Buf)
    
    BiDiConvertAnsiToOem ConvInfo, StrInfo1
    LogicalToVisual = Trim(ZeroTrim(StrInfo1.lpStrOut))
End Function

'This function receives one argument containing a visual text and returns logical text.
Public Function VisualToLogical(LogicalStr As String) As String
    Dim ConvInfo        As CONVERTINFO
    Dim StrInfo1        As STRINFO
    Dim Buf             As String * 2000
    
    ConvInfo.nOemCP = 1
    ConvInfo.fOemLayout = 2
    ConvInfo.nWindowsCP = 1255
    ConvInfo.fControlChars = 0
    ConvInfo.nUILang = &H409
    ConvInfo.fShowLayout = 1
    
    StrInfo1.lpStrIn = LogicalStr
    StrInfo1.cchIn = Len(LogicalStr)
    StrInfo1.lpStrOut = Buf
    StrInfo1.cchOut = Len(Buf)
    
    BiDiConvertOemToAnsi ConvInfo, StrInfo1
    VisualToLogical = ZeroTrim(StrInfo1.lpStrOut)
End Function

Private Function ZeroTrim(Str1 As String) As String
    Dim Pos         As Long
    
    Pos = InStr(Str1, Chr(0))
    If Pos > 0 Then
        ZeroTrim = Mid(Str1, 1, Pos - 1)
    Else
        ZeroTrim = Str1
    End If
End Function

Download sample project