概要
TXPStyleMenuItem から継承するいくつかのプロシージャをオーバーライドしています。これは、TActionMainMenuBar を使用するときにメニューがどのように表示されるかを変更できるようにするためです。
例:
TMyXPStyleMenuItem = class(TXPStyleMenuItem)
protected
procedure DrawBackground(var PaintRect: TRect); override;
end;
TActionMainMenuBar から派生した独自のコンポーネントを作成し、GetControlClass メソッドで をvar ControlClass: TCustomActionControlClass
TMyXPStyleMenuItem に設定しました。
これまでのところ、うまく機能していますが、明らかに上記の例よりも完全です-質問の目的のために、できるだけ短くシンプルに保ちました。
スタイラー コンポーネント
基本的に公開されたプロパティの集まりにすぎない非ビジュアル スタイラー コンポーネントを作成しました。このスタイラー コンポーネントは、いくつかのコントロールに割り当てることができます。この場合は、私の子孫の TActionMainMenuBar です。
コントロールにスタイラー コンポーネントが割り当てられている場合、コントロールはプロパティの値を読み取り、その値に基づいてペイントします。スタイラー コンポーネントが割り当てられていない場合は、デフォルトを使用してコントロールの描画方法を決定します。
簡単な例は、私のカスタム TEdit の 1 つです。割り当てられたスタイラー値に応じて色を変更できます。
TMyEdit = class(TCustomEdit)
private
FStyler: TMyStyler;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
if Assigned(FStyler) then
begin
Color := FStyler.Color;
end;
問題
私が直面している問題は、 のオーバーライドされた手順にありますTMyXPStyleMenuItem = class(TXPStyleMenuItem)
。
スタイラー コンポーネントの値を読み取る必要がありますが、TMyXPStyleMenuItem は実際にはメニュー コンポーネントの一部ではないため、どこFStyler
から来たのか (たとえば、TActionMainMenuBar のどのインスタンスに割り当てられたのか)を知る方法がありません。
通常、FStyler は私のメニュー クラスから次のように設定されます。
private
FStyler: TMyStyler;
procedure SetStyler(const Value: TMyStyler);
published
property Styler: TMyStyler read FStyler write SetStyler;
..
procedure TMyMenu.SetStyler(const Value: TMyStyler);
begin
if Value <> FStyler then
begin
FStyler := Value;
end;
end;
しかし、からのそれらの手順TMyXPStyleMenuItem
は上記について知りません。
宣言が基本クラスと異なるため機能しないため、オーバーライドされたプロシージャに新しいパラメーターを含めることはできません。例:
procedure DrawBackground(var PaintRect: TRect; AStyler: TMyStyler); override;
ほとんどありました
私が得た最も近いものは、実装部分の上にグローバル変数を作成したメニューコンポーネントのユニットでした:
var
FStyler: TMyStyler;
implementation
次に、オーバーライドされた DrawBackground プロシージャで、次のようにしました。
procedure TMyXPStyleMenuItem.DrawBackground(var PaintRect: TRect);
procedure _DrawBackground(AStyler: TMyStyler);
begin
// handle all the painting from here
// using the values from AStyler.
end;
begin
if Assigned(FStyler) then
_DrawBackground(FStyler);
end;
動作していると思っていたのと同じように、すぐに動作していないことに気付きました。セカンダリ メニュー、または別のフォームのメニューがあるとすぐに、どのメニューをどのスタイラーの値を使用して描画する必要があるかについて混乱します。これは、理論上、私のメニュー コンポーネントのすべてのインスタンスがグローバル FStyler 変数を使用するためです。
私ができると思ったもう 1 つのことは、オーバーロード ディレクティブでプロシージャをマークすることでした。これにより、追加のパラメーターを追加できるようになりましたが、正しいメニュー コンポーネントを参照しているかどうかはまだわかりません。
私は基本的にコンポーネントの作成などに慣れてきているので、完全に明白な何かを見落としていたら許してください。それが単純な場合、私はそれを完全に見逃しています - 正直に言うと、これは今私をかなり混乱させています!