Recent

Author Topic: setwindowshookex Incompatible type for arg (SOLVED)  (Read 1325 times)

TheLastCayen

  • New Member
  • *
  • Posts: 46
setwindowshookex Incompatible type for arg (SOLVED)
« on: November 14, 2019, 12:47:17 am »
Hi

I am using:
 - Windows 7 64 bit
 - Lazarus 2.0.6
 - FPC 3.0.4

I am using this function from windows:
  kHook := setwindowshookex(WH_KEYBOARD,@LowLevelKeybdHookProc,0,GetCurrentThreadID());

This is my function:
  function LowLevelKeybdHookProc(nCode: LongInt; WPARAM: WPARAM; lParam : LPARAM) : LRESULT; stdcall;

This is my error message:

Error: Incompatible type for arg no. 2: Got "<procedure variable type of function(LongInt;Int64;Int64):Int64 of object;StdCall>", expected "<procedure variable type of function(LongInt;Int64;Int64):Int64;StdCall>"


I found this function on that post:
https://forum.lazarus.freepascal.org/index.php?topic=24023.0

but also from many other sources on the web. Anyone know why it's not working anymore and how can I fix it?

Thank you
« Last Edit: November 16, 2019, 05:21:01 am by TheLastCayen »

440bx

  • Hero Member
  • *****
  • Posts: 1259
Re: setwindowshookex Incompatible type for arg
« Reply #1 on: November 14, 2019, 01:47:31 am »
This is my error message:

Error: Incompatible type for arg no. 2: Got "<procedure variable type of function(LongInt;Int64;Int64):Int64 of object;StdCall>", expected "<procedure variable type of function(LongInt;Int64;Int64):Int64;StdCall>"
The error message indicates that you are passing the address of a class method (indicated by "of object".)  The hook procedure _cannot_ be a class method, it _must_ be a normal function.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

jamie

  • Hero Member
  • *****
  • Posts: 2140
Re: setwindowshookex Incompatible type for arg
« Reply #2 on: November 14, 2019, 03:14:23 am »
I believe a CLASS PROCEDURE or FUNCTION will also work if the compiler will accept the STDCALL attached on the end of it  :D
Number 1 at blue screen app creations!

GetMem

  • Hero Member
  • *****
  • Posts: 3515
Re: setwindowshookex Incompatible type for arg
« Reply #3 on: November 14, 2019, 05:31:24 am »
@TheLastCayen
Replace {$mode objfpc}{$H+} with {$mode delphi}. Check the following thread for more details:
https://forum.lazarus.freepascal.org/index.php/topic,37049.0.html

Thaddy

  • Hero Member
  • *****
  • Posts: 9276
Re: setwindowshookex Incompatible type for arg
« Reply #4 on: November 14, 2019, 06:04:29 am »
I believe a CLASS PROCEDURE or FUNCTION will also work if the compiler will accept the STDCALL attached on the end of it  :D
with the static modifier. and yes, stdcall will be accepted.
« Last Edit: November 15, 2019, 09:56:55 am by Thaddy »
also related to equus asinus.

PascalDragon

  • Hero Member
  • *****
  • Posts: 700
  • Compiler Developer
Re: setwindowshookex Incompatible type for arg
« Reply #5 on: November 14, 2019, 09:14:13 am »
@TheLastCayen
Replace {$mode objfpc}{$H+} with {$mode delphi}. Check the following thread for more details:
https://forum.lazarus.freepascal.org/index.php/topic,37049.0.html
That won't make a difference. The problem here is instance method vs. static/global function.

GetMem

  • Hero Member
  • *****
  • Posts: 3515
Re: setwindowshookex Incompatible type for arg
« Reply #6 on: November 14, 2019, 11:09:44 am »
@PascalDragon
Quote
That won't make a difference. The problem here is instance method vs. static/global function.
True. I did not read the error message carefully. Nevertheless the above mentioned thread still has a nice example on hooking(for those who are interested).

TheLastCayen

  • New Member
  • *
  • Posts: 46
Re: setwindowshookex Incompatible type for arg
« Reply #7 on: November 14, 2019, 11:39:04 pm »
Thank you for all those answers.  When I look at LRESULT , it's defined in base.inc :
Line 193 : LRESULT = LONG_PTR; 

LONG_PTR define in base,inc :
Line 89: LONG_PTR = PtrInt;

PtrInt is define in systemh.inc:
Line 338 PtrInt = Int64;

At the end, LRESULT should be an int64, not Int64 of object... I have a hard time understanding what I am doing wrong:( someone can tell me how I can modify this function so it will work?

Thank you
« Last Edit: November 14, 2019, 11:42:20 pm by TheLastCayen »

PascalDragon

  • Hero Member
  • *****
  • Posts: 700
  • Compiler Developer
Re: setwindowshookex Incompatible type for arg
« Reply #8 on: November 15, 2019, 09:10:38 am »
I have a hard time understanding what I am doing wrong:( someone can tell me how I can modify this function so it will work?
Your function LowLevelKeybdHookProc is contained inside a class (probably your form class), thus it is an instance method, but it must not be such. So either move your function to outside of the class into the implementation section of your unit or declare your function as class function LowLevelKeybdHookProc(...): LRESULT; stdcall; static. Please note however that in both cases you can not directly access your class using Self.

Thaddy

  • Hero Member
  • *****
  • Posts: 9276
Re: setwindowshookex Incompatible type for arg
« Reply #9 on: November 15, 2019, 09:51:58 am »
Indeed, and you can pass self  as the lparam. See the documentation on msdn. (maybe in some cases self.handle, i need to check that)
And use PtrUint as the type to keep 32/64 bit compatibility. You are on 64 bit and compiling for 64 bit, it seems.
« Last Edit: November 15, 2019, 09:54:18 am by Thaddy »
also related to equus asinus.

TheLastCayen

  • New Member
  • *
  • Posts: 46
Re: setwindowshookex Incompatible type for arg
« Reply #10 on: November 15, 2019, 11:42:28 pm »
Thank you for your reply.

Programming for windows using windows dll is always a nightmare:( My code is already working well under Linux and I start considering dropping the windows part:(

When I add static, I get that error message:
Error: Directive "STATIC" not allowed here


If I try to write the code for that function over implementation I get
Fatal: Syntax error, "IMPLEMENTATION" expected but "BEGIN" found

I should have mentioned, my lazarus/FPC are also 64bit.

I am getting really desperate here. Any other recommendations?


440bx

  • Hero Member
  • *****
  • Posts: 1259
Re: setwindowshookex Incompatible type for arg
« Reply #11 on: November 16, 2019, 12:22:29 am »
I am getting really desperate here. Any other recommendations?
Yes, post the entire code of your hook function.   That would help figure out why you're having trouble with it.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

lucamar

  • Hero Member
  • *****
  • Posts: 2120
Re: setwindowshookex Incompatible type for arg
« Reply #12 on: November 16, 2019, 12:40:09 am »
If I try to write the code for that function over implementation I get
Fatal: Syntax error, "IMPLEMENTATION" expected but "BEGIN" found

not over implementation but under it. That is, the function body (definition) should be inside the implementation section, as in:

Code: Pascal  [Select]
  1. implementation
  2.  
  3. function LowLevelKeybdHookProc(nCode: LongInt; WPARAM: WPARAM; lParam : LPARAM) : LRESULT; stdcall;
  4. begin
  5.   { Do something }
  6. end;
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

jamie

  • Hero Member
  • *****
  • Posts: 2140
Re: setwindowshookex Incompatible type for arg
« Reply #13 on: November 16, 2019, 01:01:41 am »
This is against my religion but here goes.. ;D

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Windows, Classes, SysUtils, Forms, Controls, Graphics, Dialogs;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     procedure FormCreate(Sender: TObject);
  16.   private
  17.  
  18.   public
  19.   HookHandle:Int64;
  20.   Class Function AHookProc(nCode:LongInt; awParam:WPARAM;aLparam:LParam):LRESULT; StdCall; Static;
  21.   end;
  22.  
  23. var
  24.   Form1: TForm1;
  25.  
  26. implementation
  27.  
  28. {$R *.lfm}
  29.  
  30. procedure TForm1.FormCreate(Sender: TObject);
  31. begin
  32.   HookHandle := SetWindowsHookEx(WH_KEYBOARD, HookPROC(@TForm1.AHookProc),HInstance, GetThreadID);
  33. end;
  34.  
  35. class Function Tform1.AHookProc(nCode:LongInt; awParam:WPARAM;aLparam:LParam):LRESULT; StdCall;
  36. Begin
  37.  // Hit a key...
  38.   Beep;
  39.  Result :=  CallnextHookEx(Form1.HookHandle,nCode,AwParam, ALparam);
  40. end;
  41.  
  42. end.
  43.  
  44.  
Number 1 at blue screen app creations!

TheLastCayen

  • New Member
  • *
  • Posts: 46
Re: setwindowshookex Incompatible type for arg
« Reply #14 on: November 16, 2019, 05:20:43 am »
Thank you for your help everyone.
 
Jamie, with your code I can finally compile without an error message:)