Swanman's Horizon

性欲をもてあましつつなんらかの話をするよ。

ShortCutToKey関数を実行時に置き換える。

[twitter:@zendenmushi]さんがFireMonkeyでのショートカットの不具合を何とかする方法を書かれていたので、修正ユニットをusesすれば有効になるようにしてみた。
元記事はこちら: FireMonkey/OSX メニューアイテムのショートカット: 生き物コーディング

unit FMXShortCutFix;

interface

uses
  System.Classes, Macapi.CocoaTypes, Macapi.AppKit, Posix.SysMman, FMX.Platform.Mac;

implementation

procedure ShortCutToKey(ShortCut: TShortCut; var Key: Char; var ModifierMask: NSUInteger);
begin
  // 上記記事からコピペしてね!
end;

procedure HookShortCutToKey;
var
  p, pagebegin, pageend: PByte;
begin
  p := @ActualPlatformClass;
  pagebegin := PByte(Integer(p) and not $FFF);
  pageend := pagebegin + $1000;
  mprotect(pageBegin, $1000, PROT_READ or PROT_WRITE or PROT_EXEC);
  while p < pageend-1 do
  begin
    if PWord(p)^ = $5653 then
    begin
      p^ := $E9;
      PInteger(p + 1)^ := Integer(@ShortCutToKey) - Integer(p) - 5;
      Break;
    end;
    Inc(p);
  end;
end;

initialization
  HookShortCutToKey;
end.

コードとしてはかなりかっこ悪いですが、ShortCutToKey関数のアドレスが直接取れなかったので仕方なく…。
ちなみに動作としては、元の関数の先頭にパッチをあてて強制的に独自関数へジャンプさせてるだけです。