[fpc-pascal]Win32 API Call

Michalis Kamburelis michalis at camelot.homedns.org
Tue Jun 22 23:38:37 CEST 2004

Jim Wilson wrote:
> At 12:00 AM 6/22/2004, you wrote:
>> You made a few mistakes translating GetCurrentHwProfile to Pascal:
> Figures it was me...  :-)
>> 1. parameter to GetCurrentHwProfile should be TProfileInfo, not 
>> PProfileInfo (using "var" parameter already forces passing HWProfile 
>> by reference)
> That's awfully odd, because according to the Win32 API reference the 
> function GetCurrentHwProfile requires a pointer, which pProfileInfo is 
> (tProfileInfo is just the type definition). Guess I have some more 
> reading to do.

It's true that GetCurrentHwProfile requires a pointer to TProfileInfo. 
But when you declare GetCurrentHwProfile parameter as "var HWProfile: 
TProfileInfo" then compiler understands that "GetCurrentHwProfile 
(Profile);" should pass a *pointer* to Profile variable as 
GetCurrentHwProfile parameter. That's what "var" in "var HWProfile: 
TProfileInfo" means : to pass HWProfile by reference, i.e. by pointer. 
That's why HWProfile should be of type TProfileInfo, not PProfileInfo : 
it will already be passed by pointer, thanks to "var" keyword.

>> 2. result of GetCurrentHwProfile should be LongBool (4 bytes), not 
>> boolean (1 byte)
> But in your code it's still a boolean, but it now works (it returns 
> TRUE). And, when I change "Results : longbool" in the var declaration I 
> get "Hint: Type size mismatch, possible loss of data / range check 
> error" at the "writeln ('Results: ',Results,' - ',GetLastError);" 
> statement (and with either declaration the function returns TRUE, so I 
> assume it's working with both). Does that mean longbool isn't really 
> necessary?
> Guess I have even more reading to do then I thought!

In my code I changed Boolean to LongBool only in declaration of 
GetCurrentHwProfile. It's not needed to change type of "Results" 
variable because FPC will implicitly convert between LongBool and 
Boolean types.

SizeOf(LongBool) = 4, SizeOf(Boolean) = 1. This means that Boolean and 
LongBool have really different representation inside computer memory. So 
GetCurrentHwProfile should really return LongBool, not Boolean. If such 
code runs correctly with "Boolean" instead of "LongBool", you can 
consider it an accident.

>> 3. most important, TProfileInfo.GUID and TProfileInfo.Name are not 
>> AnsiStrings. They are just char arrays, see attached code for correct 
>> declararions.
> Another oddity, because the API reference says they're null-terminated 
> strings. So shouldn't an ansistring work for that too?

They *are* null-terminated strings. But they are not pointers to some 
char arrays. Instead they are just char arrays. msdn calls them "pointer 
to a null-terminated string" because in C pointer to a char can be 
usually considered the same thing as an array of chars.

AnsiString is something completely different: AnsiString is a pointer to 
some null-terminated char array with some additional internal data 
(positioned right before the pointed memory place). As Peter said, 
AnsiString is something that is known only in FPC and Delphi. It's 
completely different than simple "pointer to null-terminated char array" 
that is usually used in C. Such "pointer to null-terminated char array" 
is called PChar in Pascal. *But* TProfileInfo.Name and GUID fields are 
not PChar, they are simply char arrays.

> And where did you get those length numbers from, the ones you used for 
> those const definitions? 

I discovered HW_PROFILE_GUIDLEN and MAX_PROFILE_LEN values by looking at 
C headers distributed with DevCpp. You can use any C compiler 
distributed for Windows to do such thing. Just find a directory inside 
your C compiler with header files for WinAPI (typically this should be a 
directory with "windows.h" file) and there you will find C declarations 
for all WinAPI constants, types, functions, macros...

> I can't seem to find them anywhere, and it 
> appears that in order to get the info to display properly you need to 
> assign specific lengths to those char strings.

I'm sorry but I don't understand this statement. In Pascal you can 
usually use "array[0..<const>]of char" just like it was a "PChar", i.e. 
compiler understands that it's a char array terminated with null character.


More information about the fpc-pascal mailing list