views:

112

answers:

3

Hello.

Can you please tell me HOW the following symbols are declared in Windows.pas for newer Delphi versions?

  • LONG_PTR = ?
  • WNDPROC = ?

I want that my code is compatible with Delphi 2006 and I do not just want to write "Integer" or "Pointer", instead the "correct" and official declaration.

Can you please also tell me in which Delphi version the functions

  • GetWindowLongPtr
  • SetWindowLongPtr

were officially added? (According to http://qc.embarcadero.com/wc/qcmain.aspx?d=48771 it seems that in Delphi 11 (2007) this issue was active and in Delphi 12 (2009) the issue was solved)

A: 

I don't know the exact version that introduced Get/SetWindowLongPtr, but Delphi 2006 doesn't define either.

The below declarations all come from Delphi 2006.

WNDPROC's probably a TFNWndProc, in Windows.pas:

TFarProc = Pointer;
TFNWndProc = TFarProc;

Classes.pas' StdWndProc's signature looks like this in Delphi 2006:

function StdWndProc(Window: HWND; Message, WParam: Longint;
  LParam: Longint): Longint; stdcall; assembler;

MSHTML.pas defines LONG_PTR as:

LONG_PTR = Integer;

This definition is the only mention of LONG_PTR in Delphi 2006's source directory.

Frank Shearar
Thanks for your answer. Probably WNDPROC = TFNWndProc, now I need to be sure that it is the official declaration. But LONG_PTR = Integer is probably wrong. (Maybe just a local declaration for MSHTML.pas) Otherwise function SetWindowLongPtr(hWnd: HWND; nIndex: Integer; dwNewLong: LONG_PTR): LONG_PTR; stdcall; would not be correct, since no Pointer can be passe for last argument.
Daniel Marschall
@Daniel I suspect you're right. It's the only declaration that appears in the source subdirectory though.
Frank Shearar
LONG_PTR probably should be PTRINT (INTPTR) in delphi and ULONG_PTR PTRUINT (UINTPTR in delphi). The Delphi headers are not entirely updated for 64-bit, but the FPC ones are, and they define it to scale with pointer type.
Marco van de Voort
No, `LONG_PTR` is `Longint` in Delphi, as it defined in Delphi 2010 `Windows.pas` and also JEDI API Library `JwaWinType.pas`. @Marco, AFAIK, Delphi didn't recognize neither `PtrInt` nor `IntPtr` (correct me if I'm wrong). IIRC, `PtrInt` exists in FPC only.
Vantomex
It's safe to say TFnWndProc is the official declaration. It's the type used elsewhere in Windows.pas like CallWindowProc and TWndClass. Anywhere other API code uses WNDPROC, your Delphi code should use TFnWndProc.
Rob Kennedy
Vantomex: it is longint in Delphi and jedi headers, but MSDN (http://msdn.microsoft.com/en-us/library/aa383751%28VS.85%29.aspx) says it shouldn't be, which is what I mean with that the Delphi (and Jedi) headers haven't been properly fixed for 64-bit. Afaik either D2009 or D2010 defines (u)intptr instead of FPC's ptr(u)int. The first "in delphi" should also have been in parentheses, maybe that caused the confusion
Marco van de Voort
I see, so LONG_PTR was Longint in 32-bit Delphi, and supposing 64-bit Delphi will have been released in the future, LONG_PTR should be Int64.
Vantomex
Correct. Jedi API has some 64-bit fixes though, some were propagated back from FPC. In my (FPC) copy of Jedi, long_ptr _IS_ aliased to PtrInt.
Marco van de Voort
Thanks @Marco, and thanks @Rob for your note, I'll update my answer in the previous topic.
Vantomex
A: 

GetWindowLongPtr and SetWindowLongPtr both appear in the windows unit of Delphi 2009 (version 12 of the compiler).

{$EXTERNALSYM GetWindowLongPtr}
function GetWindowLongPtr(hWnd: HWND; nIndex: Integer): LONG_PTR; stdcall;
{$EXTERNALSYM SetWindowLongPtr}
function SetWindowLongPtr(hWnd: HWND; nIndex: Integer; dwNewLong: LONG_PTR): LONG_PTR; stdcall;

The Ansi and Wide versions of the API are also declared, although there is no difference except in name and calls aren't diverted like with many other API functions where the "unadorned" version of a MyApiFunction is redirected to either the MyApiFunctionA (pre D2009) or the MyApiFunctionW (D2009+) function. As in:

function MyApiFunction; external advapi32 name 'MyApiFunctionW';
function MyApiFunctionA; external advapi32 name 'MyApiFunctionA';
function MyApiFunctionW; external advapi32 name 'MyApiFunctionW';

If D2006 doesn't define them as @Frank Shearer says, and the issue was open in QC for D2007 and closed for version 12 (D200(), I guess D2009 is indeed the version in which these declaration were added.

Please note that you can always add the declaration of a Windows API yourself if it isn't provided by the Delphi version you are using. And as always with API functions it is wise to know from which Windows version on they exist so you don't call API's that do not exist on the platform on which your program is running.

Marjan Venema
Instead of adding declarations yourself you could also use the Jedi Windows Apilib (Jwa): http://blog.delphi-jedi.net/jedi-api-headers/
Remko
@Remko: yes indeed you can. I use it myself, but there are those who want as few as possible dependencies on libraries and/or components
Marjan Venema
+1  A: 

When working with VCL controls (TControl descendants which includes TCustomForm) you don't have to use the SetWindowLongPtr API to replace the window procedure; you can set WindowProc property to achieve the same result. I've posted an example here.

TOndrej