2012年9月24日月曜日

HotKeyStyleHook

皆さんご存じの通り、Vcl.ComCtrls.THotKey を使うと簡単にホットキーを設定したりできます。
THotKey を実際に貼ってみると下図のように、簡単にホットキーが表示できます。



だが!しかし!
VCL スタイルを設定していると下図のように白く浮いてしまうわけです!





かっこわるい!

これは、THotKey に専用の StyleHook が用意されていないために起きています(THotKey の StyleHook は TEditStyleHook が指定されています)。


Win32 の HotKey コントロールは自動的にホットキーを表示してくれますが、背景モードが OPAQUE になっています。
そのため、テキストの描画で、背景が塗りつぶされてしまうのです。

そこで、次の API を呼んでやります。

SetBkMode(Canvas.Handle, TRANSPARENT);

SetBkMode で TRANSPARENT に設定することで、テキストを描画したときに背景を塗りつぶさなくなります。

描画時に SetBkMode を呼ぶような Custom Style Hook の例が↓です。

unit uHotKeyStyleHook;

(略)

procedure THotKeyStyleHook.Paint(Canvas: TCanvas);
var
  Text: String;
  Shift: TShiftState;
  Key: Word;
begin
  // 表示する文字列を作成
  ShortCutToKey(THotKey(Control).HotKey, Key, Shift);

  if (ssAlt in Shift) then
    Text := Text + 'Alt + ';

  if (ssCtrl in Shift) then
    Text := Text + 'Ctrl + ';

  if (ssShift in Shift) then
    Text := Text + 'Shift + ';

  Text := Text + ShortCutToText(Key);
  
  // 背景モードを指定
  SetBkMode(Canvas.Handle, TRANSPARENT);

  // フォントカラーを StyleServices から取得
  Canvas.Font.Color := StyleServices.GetStyleFontColor(sfEditBoxTextNormal);

  // テキストを描画
  Canvas.TextOut(0, 0, Text);
end;

initialization
begin
  TCustomStyleEngine.RegisterStyleHook(THotKey, THotKeyStyleHook);
end;

end.

ここで、一点。
RegisterStyleHook を initialization 節に書いていますが、本来は StyleHook を適用したいコントロールの class constructor に書きます。
そうすると、そのコントロールを使わない限り、StyleHook が読み込まれることもありません。
しかし、THotKey は VCL で提供されているコントロールのため、THotKey のコードを書き換えるのは憚られます。
そのため、StyleHook 側の initialization 節に書いてみました。

この THotKeyStyleHook を使うために必要なコードは、たったこれだけです。

uses
  uHotKeyStyleHook;


uHotKeyStyleHook を組み込んだアプリは↓こちら。
ちゃんとスタイルが適用されました!!







ちなみに、このソースでは自分で文字列を組み立てて表示してますが、本当は


というインターフェースから、ホットキーの組み合わせ文字列を取得できるみたいです。
僕は上手くできなかったので、どなたかお願いいたします!

0 件のコメント:

コメントを投稿