GetPrivateProfileString - API - Unicode Version (1 Viewer)

darbid

Registered User.
Local time
Today, 20:58
Joined
Jun 26, 2008
Messages
1,428
Referring to my general thread here
http://www.access-programmers.co.uk/forums/showthread.php?t=164073
I hinted at a problem which I thought dealt with Access Generally. The problem seems to be my API call thus this new thread.

How to call this function for unicode and NOT ANSI
Code:
Public Declare Function GetPrivateProfileString _
                            Lib "kernel32" Alias "GetPrivateProfileStringW" _
                           (ByVal lpApplicationName As String, _
                             ByVal lpKeyName As Any, _
                             ByVal lpDefault As String, _
                             ByVal lpReturnedString As String, _
                             ByVal nSize As Long, _
                             ByVal lpFileName As String) As Long
The only thing I can find in this forum is this http://www.access-programmers.co.uk/forums/showthread.php?t=33283&highlight=unicode+api

which may provide some method.

If I understand my issue properly VBA is converting my strings to ANSI which means that when it searches a text file in Unicode it finds nothing.

I have read the StrPtr() could also help here, pointing to the place where my string is kept instead of passing the string to the API Call.

Usually I am happy to read about this but this time I really need some spoonfeeding here on how to do this because it is beyond me.

Following my theory on StrPtr I thought the following would be the solution but if finds nothing.

Code:
 Public Function ProfileGetItem(sSection As String, _
                                sKeyName As String, _
                                sDefValue As String, _
                                sInifile As String) As String

  'retrieves a value from an ini file
  'corresponding to the section and
  'key name passed.

   Dim dwSize As Long
   Dim nBuffSize As Long
   Dim buff As String

  'Call the API with the parameters passed.
  'nBuffSize is the length of the string
  'in buff, including the terminating null.
  'If a default value was passed, and the
  'section or key name are not in the file,
  'that value is returned. If no default
  'value was passed (""), then dwSize
  'will = 0 if not found.
  '
  'pad a string large enough to hold the data
   buff = Space$(2048)
   nBuffSize = Len(buff)
   dwSize = GetPrivateProfileString(StrPtr(sSection), _
                                    StrPtr(sKeyName), _
                                    sDefValue, _
                                    buff, _
                                    nBuffSize, _
                                    sInifile)

   If dwSize > 0 Then
      ProfileGetItem = Left$(buff, dwSize)
   End If

End Function
 

darbid

Registered User.
Local time
Today, 20:58
Joined
Jun 26, 2008
Messages
1,428
Well for anyone interested - you probably know that VBA (although it stores strings in unicode) sends strings to the API in ANSI and gets it back the same way. This means that a Unicode Call is all stuffed up.

The solution is to make sure that VBA passes unicode to the API call AND that you set up an array for the result so that you can extract what is retreived back out.

Code:
Public Declare Function GetPrivateProfileString _
                            Lib "Kernel32" Alias "GetPrivateProfileStringW" _
                            (ByVal lpApplicationName As String, _
                             ByVal lpKeyName As String, _
                             ByVal lpDefault As String, _
                             lpReturnedString As Any, _
                             ByVal nSize As Long, _
                             ByVal lpFileName As String) As Long

Global Const sDefValue = "oops...data not in the file"
Global sInifile As String
'
'
'
 Public Function ProfileGetItem(sSection As String, _
                                sKeyName As String, _
                                sDefValue As String, _
                                sInifile As String) As String




Dim retval As Long
Dim cSize As Long
Dim Buf() As Byte

ReDim Buf(254)
cSize = 255


retval = GetPrivateProfileString(StrConv(sSection, vbUnicode), _
                                    StrConv(sKeyName, vbUnicode), _
                                    StrConv(sDefValue, vbUnicode), _
                                    Buf(0), _
                                    cSize, _
                                    StrConv(sInifile, vbUnicode))

If retval > 0 Then
      ProfileGetItem = Left(Buf, retval)
End If

End Function
You will see that I have deleted one of the ByVal's and changed the type to "ANY" above as well - this kind of stuff is beyond me but I was copying this article http://support.microsoft.com/kb/145727

The second source (although I have literally spent hours on this and there are many pages I looked at) was http://www.informit.com/articles/article.aspx?p=366892&seqNum=3
which had this
Although VBA stores strings internally as Unicode, it always converts them to ANSI when passing them to API functions. This is usually sufficient, and it is quite rare to find examples of VB or VBA calling the Unicode versions. In some cases, however, we need to support the full Unicode character set and can work around VBA's conversion behavior by calling the Wversion of the API function and using StrConv to do an extra ANSI-to-Unicode conversion within our API function calls:
Declare Function FindWindow Lib "user32" Alias "FindWindowW" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long

ApphWnd = FindWindow(StrConv("XLMAIN", vbUnicode), _
StrConv(Application.Caption, vbUnicode))
 

Users who are viewing this thread

Top Bottom