Home page Home page Home page Home page
Pixel
Pixel Header R1 C1 Pixel
Pixel Header R2 C1 Pixel
Pixel Header R3 C1 Pixel
Pixel
By Captain C | Monday 7 September 2009 08:28 | 0 Comments
In the previous post on this topic we looked at how to find the proper exported function name when dealing with DLL functions that can take ANSI or Unicode (UTF-16) strings. We also looked at the "TEXT string" type that Windows uses when defining these dual interface functions and what it actually means when we need to use it with OpenInsight. This time we're going to look at actually passing Basic+ string variables to the function so that they are correctly encoded.

(Note: This article assumes you are familiar with the basics of DLL prototyping in OpenInsight. If not please consult the OpenInsight on-line help for more details)

Passing Basic+ variables as string parameters - The Easy Way

By far the easiest way to pass a string to a Windows API function is to let OpenInsight handle the details for you - You simply pass your variable to the DLL function as you would to any normal Basic+ function.

All you have to do is define your string variable types in the OpenInsight prototype record as one of the following:

  • LPASTR if you are passing an ANSI string (for "A" functions)
  • LPWSTR if you are passing a Unicode string (for "W" functions)

For example - if you wanted to use the Unicode SetWindowText function which is documented by Microsoft as:

   BOOL SetWindowText( HWND hwnd, LPCTSTR lpString ); 

From Part 1 we know the Unicode version is really defined in the Windows API as:

   BOOL SetWindowTextW( HWND hwnd, LPCWSTR lpString ); 

And so we create the following User32 DLL prototype record entry in OpenInsight:

   INT STDCALL SetWindowTextW( HANDLE, LPWSTR ) 

This means that we can use the function in Basic+ like so:

0001     declare function SetWindowTextW
0002     
0003     hwnd = get_Property( @window, "HANDLE" )
0004     text = "New Window text"
0005     cch = SetWindowTextW( hwnd, text ) 


And that's all there is to it!

Using this method OpenInsight ensures that:

  1. The string is in the correct format. i.e. if it's internally held as a number (in binary format) it's converted to a string first.
  2. The string is null-terminated.
  3. The string is automatically converted into the correct encoding (ANSI or Unicode) regardless of your application's UTF8 mode.

Here's a summary of how you should translate the Windows string type to a OpenInsight string prototype:

Windows TypeOpenInsight Type
LPTSTRLPASTR for an ANSI ("A") function
LPWSTR for a Unicode ("W") function
LPCTSTRLPASTR for an ANSI ("A") function
LPWSTR for a Unicode ("W") function
LPSTRLPASTR
LPCSTRLPASTR
LPWSTRLPWSTR
LPCWSTRLPWSTR


What about the OpenInsight LPSTR prototype?

You may have seen some string arguments for Windows API functions already prototyped in OpenInsight as LPSTR, e.g.

   INT STDCALL SetWindowTextA( HANDLE, LPSTR )
   INT STDCALL GetWindowTextA( HANDLE, LPSTR, INT )


In this case OpenEngine does NO encoding for you at at all, i.e. step (3) from the list above is not performed. In this case you are responsible for encoding the string to the proper format before invoking the DLL function.

I would highly recommend that you do NOT use LPSTR when prototyping - rather be explicit and use LPASTR or LPWSTR as appropriate.

What about the OpenInsight LPCHAR prototype?

Back in the ancient days of versions 2.x and 3.x OpenInsight didn't support a LPASTR, LPWSTR or even a LPSTR prototype. It did however have a LPCHAR prototype which passed a variable as a string in a similar manner as the LPSTR prototype mentioned above, e.g.

   INT STDCALL SetWindowTextA( HANDLE, LPCHAR )
   INT STDCALL GetWindowTextA( HANDLE, LPCHAR, INT )


However - there's one important difference here - it didn't null-terminate the string it passed for you. It remained your responsibility to null-terminate the string (i.e. append a Char(0) to it) before you passed it to the DLL function.

OpenInsight still supports the LPCHAR prototype but again I suggest you avoid it and use LPASTR/LPWSTR so you're assured of the null termination.

So that's the easy way - what's next?

Next time we'll be looking at a more complex way of passing strings to a Windows API function for those instances where the easy way isn't sufficient...

Labels: , , ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]



<< Home

Pixel
Pixel Footer R1 C1 Pixel
Pixel
Pixel
Pixel