Recent

Author Topic: [SOLVED] Port RegisterHotKey from 32bit to 64bit  (Read 484 times)

tboege

  • New Member
  • *
  • Posts: 16
[SOLVED] Port RegisterHotKey from 32bit to 64bit
« on: October 13, 2022, 11:47:45 am »
I am running Lazarus 2.2.0 on 64 bit Windows. I can compile and run the program below, when I compile in 32-bit mode (Target OS Win32, Target CPU family i386, Target processor (Default), but when I change to 64-bit (Targget OS, Target CPU family, Target processor, alle (Default), then program still runs.
I still get avalue fra HotKeyDebugWindow around 4565 (a relatively low number),
but in  TForm1.OnHotKey Msg.HotKey  is a very high number ( eg 213008903045120), which is not identical to HotKeyDebugWindow.
Can anyone help?



Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Windows;
  9.  
  10. type
  11.   TWMHotKey = packed record
  12.     MSG: cardinal;
  13.     HotKey: PtrInt;
  14.     Unused: PtrInt;
  15.     Result: PtrInt;
  16.   end;
  17.   { TForm1 }
  18.  
  19.   TForm1 = class(TForm)
  20.     procedure FormCreate(Sender: TObject);
  21.   private
  22.     procedure OnHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
  23.  
  24.   public
  25.  
  26.   end;
  27.  
  28. var
  29.   Form1: TForm1;
  30.  
  31. implementation
  32.  
  33. {$R *.lfm}
  34.  
  35. { TForm1 }
  36. var
  37.   HotKeyDebugWindow: NativeInt;
  38.  
  39. procedure TForm1.FormCreate(Sender: TObject);
  40. var
  41.   Result: longbool;
  42. begin
  43.   HotKeyDebugWindow := GlobalAddAtom('Hotkey: SHITCTRLE');
  44.   Result := RegisterHotkey(Handle, HotKeyDebugWindow, MOD_CONTROL + MOD_SHIFT, Ord('E'));
  45.   ShowMessage(BoolToStr(result));
  46. end;
  47.  
  48. procedure TForm1.OnHotKey(var Msg: TWMHotKey);
  49. begin
  50.   if Msg.HotKey = HotKeyDebugWindow then
  51.   begin
  52.     ShowMessage('test');
  53.   end;
  54. end;
  55.  
  56. end.
  57.  
« Last Edit: October 17, 2022, 04:38:06 pm by tboege »

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1174
    • Lebeau Software
Re: Port RegisterHotKey from 32bit to 64bit
« Reply #1 on: October 13, 2022, 10:17:10 pm »
Related: TWMKey(Message) cast doesn't work on Win64

Your TWMHotKey record is not declared correctly for 64bit.  You are removing all alignment padding in between the record's fields, but that padding is actually required to line up the fields correctly.

This is how Delphi declares its own TWMHotKey:

Code: Pascal  [Select][+][-]
  1. type
  2.   TWMHotKey = record
  3.     Msg: Cardinal;
  4.     MsgFiller: TDWordFiller;
  5.     HotKey: WPARAM;
  6.     Unused: LPARAM;
  7.     Result: LRESULT;
  8.   end;

Where TDWordFiller is 0 bytes on 32bit and 4 bytes on 64bit.  I don't know if TDWordFiller was ever incorporated into FPC, but if not then you can try this:

Code: Pascal  [Select][+][-]
  1. type
  2.   TWMHotKey = record
  3.     Msg: Cardinal;
  4. {$ifdef cpu64}
  5.     MsgFiller: Cardinal;
  6. {$endif}
  7.     HotKey: WPARAM;
  8.     KeyData: LPARAM;
  9.     Result: LRESULT;
  10.   end;

Or, you could simply not use TWMHotKey at all:

Code: Pascal  [Select][+][-]
  1. procedure OnHotKey(var Msg: TMessage); message WM_HOTKEY;
  2. ...
  3. procedure TForm1.OnHotKey(var Msg: TMessage);
  4. begin
  5.   if Msg.WParam = HotKeyDebugWindow then
  6.   begin
  7.     ShowMessage('test');
  8.   end;
  9. end;

Also, on a side note: GlobalAddAtom() returns an ATOM, which is a WORD, not a NativeInt.  And RegisterHotKey() takes an Integer id, not a NativeInt id.
« Last Edit: October 13, 2022, 10:36:17 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

tboege

  • New Member
  • *
  • Posts: 16
Re: Port RegisterHotKey from 32bit to 64bit
« Reply #2 on: October 14, 2022, 10:33:10 am »
Thank you, Remy.
That solved my problem. BTW, TDWordFiller is defined in Lazarus, so I just used the

Code: Pascal  [Select][+][-]
  1. type
  2.   TWMHotKey = record
  3.     Msg: Cardinal;
  4.     MsgFiller: TDWordFiller;
  5.     HotKey: WPARAM;
  6.     Unused: LPARAM;
  7.     Result: LRESULT;
  8.   end;
  9.  


I will now dig into GetAdaptersInfo from  JwaIpHlpApi and DhcpRequestParams  JwaDhcpCSdk.
Since I (obviously) not are familiar with Win32 API - can you point me in a direction to learn about Win32 API and FPC?



 

TinyPortal © 2005-2018