Struck a snag converting 32bit to 64 bit

AlexanderBB

Well-known Member
Joined
Jul 1, 2009
Messages
1,835
Office Version
  1. 2019
  2. 2016
Platform
  1. Windows
I don't really understand what this does as stepping through shows no code, it just "happens"
Code:
Private Function MatchSpec( _
  filename As String, _
  FileSpec As String) As Boolean
  MatchSpec = PathMatchSpec(StrPtr(filename), StrPtr(FileSpec))
End Function

In Excel 32bit
filename is "100_1829.JPG 1 6"
StrPtr(filename) is 1740372

FileSpec is "*.wav"
StrPtr(FileSpec) is 220909268

and MatchSpec=False

But Debug-Compile in 64bit highlights StrPtr and advises "Type mismatch"

The definition for PathMatchSpec shows
Code:
Private Declare Function PathMatchSpec _
  Lib "shlwapi" Alias "PathMatchSpecW" ( _
  ByVal pszFileParam As Long, _
  ByVal pszSpec As Long) As Long
I had to change this to Private Declare PtrSafe Function...

Any help fixing this appreciated.
 

Excel Facts

What is the shortcut key for Format Selection?
Ctrl+1 (the number one) will open the Format dialog for whatever is selected.
Have you properly declared:

Private Declare PtrSafe Function PathMatchSpec Lib "shlwapi" Alias "PathMatchSpecW" (ByVal pszFileParam As LongPtr, ByVal pszSpec As LongPtr) As Boolean
 
Upvote 0
Have you properly declared:

Private Declare PtrSafe Function PathMatchSpec Lib "shlwapi" Alias "PathMatchSpecW" (ByVal pszFileParam As LongPtr, ByVal pszSpec As LongPtr) As Boolean

No, I didn't know to do that. Now working. Many thanks. (Should returns a Long, not Boolean. Will find out... still compiling)
 
Upvote 0
Hello AlexanderBB,

The Windows API code is written in the "C" language. If you're not familiar with "C" then translating from "C" to VBA can be difficult or impossible.

The API can sometimes have two flavors of a function: A or W. These suffixes indicate the string data type the function expects. "A" is for ANSI and "W" is for Wide Character, the C name for Unicode. So unless you are creating code that needs to handle Unicode glyphs, just use the "A" version of the function.

Now, the prefix "psz" in C indicates the variable is a pointer (memory address) to a zero terminated string. If the string in C is Unicode it will have the prefix "pwzs" for pointer to wide string zero terminated. Standard C strings do not have a length byte as do VBA strings. Strings that use a length byte as known as Basic Strings, abbreviated BSTR. C starts with the first byte and continues to read memory sequentially until a string terminator is encountered, one byte for ANSI or two bytes for Unicode. The terminating byte(s) must be zero - no bits set.

The confusion about the variable being typed as Long happens because C only needs a starting address for the string. But, VBA handles strings differently. A VBA string is pointer to a pointer. The first pointer is the name of the string variable and the second is to the first byte of the string's data.

For example, say I declare myStr as a String and assign the value "ABCD" to it in VBA. When the code is compiled, VBA sees MyStr and returns the address for the variable name MyStr. Next since this variable was typed as a String, the compiler knows to use the address held in this variable to retrieve the first byte of the BSTR buffer. A BSTR has three parts: a header, a buffer, and a terminator. The Header is four bytes and holds the string's byte count. The buffer holds the characters assigned to the string, in this case ABCD, which is 8 bytes and the terminator, 2 bytes, contains ANSI character 0 (zero).

You may be wondering why an ANSI string, single byte characters, is stored as double byte characters. In Windows all strings are store internally as Unicode. Windows does the conversion back to ANSI automatically when needed.

In conclusion, your code can be written two ways:

ANSI Version
Rich (BB code):
Private Declare PtrSafe Function PathMatchSpec Lib "shlwapi.dll" Alias "PathMatchSpecA" (ByVal pszFileParam As String, ByVal pszSpec As String) As Long


Sub TestA()


    Dim ret  As Long
    Dim StrA As String
    Dim StrB As String
    
        ' // ANSI version "A"
        StrA = "100_1829.JPG"
        StrB = "*.jpg"


        ret = PathMatchSpec(StrA, StrB)
        
End Sub

Wide Version
Rich (BB code):
Private Declare PtrSafe Function PathMatchSpec Lib "shlwapi.dll" Alias "PathMatchSpecW" (ByVal pszFileParam As String, ByVal pszSpec As String) As Long


Sub TestA()


    Dim ret  As Long
    Dim StrA As String
    Dim StrB As String


        
        ' // Wide Character version "W" - Unicode strings
        ' // Convert VBA string from ANSI to UNicode format

        StrA = StrConv("100_1829.JPG", vbUnicode)
        StrB = StrConv("*.jpg", vbUnicode)
        
        ret = PathMatchSpec(StrA, StrB)
        
End Sub
 
Upvote 0
Thank you Leith, that was super informative. And no, I've never used "C".
 
Upvote 0

Forum statistics

Threads
1,214,416
Messages
6,119,386
Members
448,891
Latest member
tpierce

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top