There are quite a few API routines that take a pointer to some variable as a parameter that were translated to var parameters, yet can be specified as nil pointers according to the Windows help files.
As an example, the ChangeDisplaySettings function is declared as:
function ChangeDisplaySettings(var lpDevMode: TDeviceMode; dwFlags: DWORD): Longint; stdcall;
But the Windows help file clearly states that "Passing NULL for the lpDevMode parameter is the easiest way to return to the default mode after a dynamic mode change." The correct translation should have been:
function ChangeDisplaySettings(lpDevMode: PDeviceMode; dwFlags: DWORD): Longint; stdcall;
I'm posting this question and answer to help newbies get around these issues without having to re-declare the functions. I still remember that it was an issue for me in the beginning.
One solution is to re-declare any such functions using pointers in place of the var parameters, but there is an easier solution. Simply cast a dereferenced nil-pointer to the correct type, e.g., for the ChangeDisplaySettings example, use the following to reset the display mode to the default registry settings:
ChangeDisplaySettings(TDeviceMode(nil^), 0);
or
ChangeDisplaySettings(PDeviceMode(nil)^, 0);
This way you are passing a var parameter that just happens to be located at memory address zero - the compiler is happy and you get to pass a nil pointer to the API routine!
Edit: From David Hefferman's comment, it seems that the standard practice is to rather re-declare such routines. Personally, I prefer to use the standard declarations if I can in my own personal units, but for professional work purposes I suggest that developers follow the standard practices.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With