PDA

View Full Version : Moving to UniCode WinAPI



raveens
2-Mar-2020, 10:37 PM
Hi DAW,

We are in the midst of moving our ANSI WINAPI interface to UniCode, below is an example:



#IF (!@ > 191)
External_Function GetClassName "GetClassNameW" User32.dll Handle hWnd Pointer lpsClassName Integer cbText Returns Integer
#ELSE
External_Function GetClassName "GetClassNameA" User32.dll Handle hWnd Pointer lpsClassName Integer cbText Returns Integer
#ENDIF


Function WinClassName Global Handle hWnd Returns String
Integer iVoid
#IF (!@ > 191)
WString sClassName
#ELSE
String sClassName
#ENDIF
Move (Repeat(Character(0), 60)) to sClassName
Move (GetClassName(hWnd,AddressOf(sClassName),60)) to iVoid
Function_Return (CString(sClassName))
End_Function




Is the above code the right way (best practise) or should we be using the examples in WinUser.pkg where a string to converted to a widestring pointer using the StringToWide procedure ?

Thanks.

Harm Wibier
3-Mar-2020, 02:29 AM
I'd do it like this. To be completely honest, the tWide struct was how we where planning to do it before we decided to implement the WString in the runtime. If we were to do it all again we'd likely wouldn't have used it in our packages.

starzen
4-Mar-2020, 06:34 AM
here is my idea for our classes. We do a similar thing for VPE where the parameter type has changed from one rev to another



#IF (!@ > 191)
Define szxString for WString
#ELSE
Define szxString for String
#ENDIF


#IF (!@ > 191)
External_Function GetClassName "GetClassNameW" User32.dll Handle hWnd Pointer lpsClassName Integer cbText Returns Integer
#ELSE
External_Function GetClassName "GetClassNameA" User32.dll Handle hWnd Pointer lpsClassName Integer cbText Returns Integer
#ENDIF

Function WinClassName Global Handle hWnd Returns String
Integer iVoid
szxString sClassName
Move (Repeat(Character(0), 60)) to sClassName
Move (GetClassName(hWnd,AddressOf(sClassName),60)) to iVoid
Function_Return (CString(sClassName))
End_Function



and then of course there could be a new macro hat allows you to do this



External_FunctionAW GetClassName "GetClassNameA" "GetClassNameW" User32.dll Handle hWnd Pointer lpsClassName Integer cbText Returns Integer


but the macro seems overkill

Focus
4-Mar-2020, 06:57 AM
Especially as is this not a relatively temporary situation ?

If a developer is looking to upgrade to DF20 then one assume they are a fairly regular updater (or really want Unicode support) and will stop using 19.1 and prior when DF21 arrives if not before ?

So at that point all these compiler directives and extra code can be removed again

Since going to DF20 requires changing of SQL column types to NCHAR and NVARCHAR to take advantage of Unicode, then whilst you can still read the data in 19.1 so long as those columns don't include Unicode data, I would have thought that a common code base between 19.1 and 20.0 projects has a relatively short shelf life ?

starzen
4-Mar-2020, 07:05 AM
and of course this is very different for most developers compared to us

We create a lot of libraries and classes. They are still used in all versions including VDF7 so we need to make them compatible as much as possible

obviously a developer moving to DF20 without any need to go back is a bit different but i still like the type because there is only one place for compiler directives vs multiple and they really do not look great.

wila
4-Mar-2020, 07:22 AM
Yep, I also have the problem of backward compatibility with older versions.
Sometimes though I'd say it is OK to retire a particular version of a library and if the developer/customer needs to use the library with an older version of then they can use the retired version.
Obviously that has the downside of not receiving new features anymore.


i still like the type because there is only one place for compiler directives vs multiple and they really do not look great.

They really don't look great and make code harder to read.
Perhaps I should try and add it as a code collapse feature ;) (that's harder than it seems, the reason why I don't offer code collapse on compiler directives in The Hammer)

What I have tried was to use different header files in the vWin32fh library.
Not really ecstatic about that option either.



Use windows.pkg
Use Dll.pkg
#IF (!@ < 200)
Use vWin32fhA.pkg // WinAPI ANSI legacy interface
#ELSE
Use vWin32fhW.pkg // WinAPI Unicode version
#ENDIF


It keeps the code much cleaner that way, but hmm.. don't know.

--
Wil