Delphi Tokyo 10.2を使用して、テーマを設定しました。私はフォーム上のコンポーネント、例えばEditTexts、ComboBoxesなどを強調しようとしています。たとえば、ユーザーが無効なデータを入力した場合、コンポーネントを強調表示したいと思います。テーマのあるDelphiアプリケーションのハイライトコントロール
これまでは、コンポーネントの色を赤色にしていましたが、色はサイズ変更/移動/再ペイントを通して一般的に保持されていました。今テーマを設定して、色を表示して持続させるためにもう少し作業をする必要があります。
各コンポーネントのStyleElements [seFont、seClient、seBorder]プロパティを無効にして、色を強制表示しようとしました。これは動作しますが、特に多くのコンポーネントが検証されている場合には、不安定に見えます。また、赤色の要素を単に着色すると、テーマによっては正しく表示されないことがあります。
また、WinAPI SetRop2(..)を使用してコンポーネントの周りに赤い四角形を描画するだけで試してみました。たとえば、hereは巧妙なコードですが、私はTWinControlを取るために微調整し、その周囲には赤い枠を描いています。同様の呼び出しを使って赤いボックスを削除することもできます。これは、
に動作します...しかし、明らかに、再描画を通じて維持されません。カスタムペイントメソッドを追加することは、ここで過度の可能性があるようです。そうでないと、もっと良い方法がありますか?私が検討している
他のもの:
コンポーネントはすべてのパネルの上に座って、そして私は、コンポーネントの周りパネルのキャンバスに赤いrectsを描画するために保護されたハックを使用して考えられますが、再度、複数のカスタムペイントルーチンいます...
私はまた、必要に応じてTShapesを動的に描画することも検討していますが、これは私を馬鹿にします。
同じ状況、例えば古いバージョンのDelphiではうまく機能するデータ入力の検証など、他のものが存在する必要がありますが、テーマを指定するとあまりうまく見えません。テーマを使用するときの最良のアプローチは何ですか? SetRop2(..)アプローチは、最もクリーンなようですが、誰かが色を持続させる簡単な方法を提案することができます。私も他のアイデアを歓迎します。ありがとうございました。
EDIT 無効なレスポンスの周りのTShapesをダイナミックに描画することはそれほど難しくありません。それらは塗り直しを継続し、TWinControlから降下しないので、強調表示されているコントロールの背後に自動的に表示されます。
これは私にとって非常にうまくいくので、他の人にとって参考になることを願っています。赤と青のボックスでHILITEに、このように呼ばれ
//assuming owning control will be free'd properly and
//will in turn free HI_LITE Box.
//
//tantamount to adding an instance variable, TShape, to existing Control,
//since class helpers don't allow. And I don't want to descend
//new controls just to have a hiLiteBox Instance Variable.
procedure HiLiteMe(aControl : TWinControl; HILITE_FLAG : Boolean = TRUE; aColor : TColor = clRed);
const OFFSET = 4; //specify the offset of the border size of the box.
const BOX_NAME_PREFIX = 'HI_LITE_BOX_';
var
hiLiteBox : TShape; //reference created on stack, but object created on the heap,
uniqueBoxName : String; //so use the persistent aControl's owned component list to maintain the reference.
begin
uniqueBoxName := BOX_NAME_PREFIX + aControl.Name; //uniquename for each associated HiLiteBox.
HiLiteBox := aControl.FindComponent(uniqueBoxName) as TShape; //phishing for the HiLiteBox if it was previously created.
if NOT Assigned(hiLiteBox) then //create HiLiteBox and make persist outside this proc.
begin
if NOT HILITE_FLAG then exit; //don't create a box if we're just going to hide it anyway.
hiLiteBox := TShape.Create(aControl); //Create HiLiteBox, setting aControl as owner, quicker retrieval using aControl.findComponent
hiLiteBox.Parent := aControl.Parent; //Render the box on the control's parent, eg, panel, form, etc.
hiLiteBox.Name := uniqueBoxName;
hiLiteBox.Pen.Color := aColor; //Color the Pen
hiLiteBox.Pen.Width := offset-1; //Make the Pen just slightly smaller than the offset.
hiLiteBox.Brush.Color := clWindow; //Choose a brush color, to fill the space between the pen and the Control
hiLiteBox.Left := aControl.Left - offset;
hiLiteBox.Width := aControl.Width + offset*2;
hiLiteBox.Top := aControl.Top - offset;
hiLiteBox.Height := aControl.Height + offset*2;
end;
hiLiteBox.Visible := HILITE_FLAG; //Show/Hide HiLite as appropriate.
end;
... HiLitesを削除するために、次のように呼び出され
begin
HiLiteMe(checkListBox1, TRUE, clRed); //Draw a RedBox around the CheckListBox, eg, Invalid.
HiLiteMe(bitBtn3, TRUE, clBlue); //Draw a Blue Box around the Button, eg, Required.
end;
...
begin
HiLiteMe(checkListBox1, FALSE); //Draw a RedBox around the CheckListBox, eg, Invalid.
HiLiteMe(bitBtn3, FALSE); //Draw a Blue Box around the Button, eg, Required.
end;
VCLスタイルは使用しないでください。ネイティブのWin32形式を使用します。 –
VCLスタイルは、技術的には、まずはハックに似ています。これらは推奨されていません。特に本番ソフトウェア用ではありません。可能な限り、それはどのように動作するのか、全体の性質は薄れており、避けるべきです。別の言い方をすれば、再塗装はあなたの絵を描くと言うでしょう。もちろん、コントロールの 'OnPaint'イベント、または' WM_PAINT' Windowsメッセージの中にペイントしなければ、もちろんそうです。 –
* "同じ状況で他の人がいるはずです" * - おそらく... * .. "古いバージョンではうまく機能したデータ入力の検証..." * - データ入力の検証には、ヒントまたはダイアログを使用してメッセージをポップし、無効なエントリでコントロールにフォーカスを置くことができます。 Andreasのアドバイスと一緒に、それは簡単なアプリケーションになるかもしれません。 –