他にも方法があるかも知れませんが、次の3種類について検討してみます。
※色は、clWhiteとclGradientInactiveCaptionを設定しています。
[A] カスタムコンポーネントを作る。
今回、TPanelを拡張したコンポーネントを作ってみました。(最後に、コードを載せています)
一度作ると利用は簡単ですが、いろんなコンポーネントを管理していくのは結構面倒です。
[B] TToolBarの上にTPanelを配置して使う。
左端にラインが表示されますが、とても簡単です。
[C] TPanel+TImage
見た目は問題ないのですが、リサイズ時に少しちらつきます。
リサイズ時の処理だけ書けばよいので、パネルの数が少ない場合には簡単です。
// Image1のグラデーション描画用
uses
GraphUtil;
procedure TForm1.FormResize(Sender: TObject);
var
Rect: TRect;
begin
Image1.Picture := nil;
Rect := Image1.ClientRect;
GradientFillCanvas(Image1.Canvas, clWhite, clGradientInactiveCaption,
Rect, gdVertical);
end;
デザイン時です。
実行するとこんな感じです。
見た目はそう変わらないですね。どれを採用するかはケースバイケースかな?
一度カスタムコンポーネントにしてしまうとそれを使うことが多いんですけど、
きちんと管理していかないと古いバージョンのものを訂正しようとするときに、
○○コンポーネントがない!って言われて、訂正する気力を失うので、要注意です(笑)
今回作ったグラデーションパネルです。
グラデーションを描くためだけに作っているので、かなり適当です。
というか、TToolBarから必要なものを取ってきてるだけという疑惑もあります(笑)
unit HRGadientPanel;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
ExtCtrls, GraphUtil, ComCtrls;
type
THRGadientPanel = class(TPanel)
private
FDrawingStyle: TTBDrawingStyle;
FGradientDirection: TGradientDirection;
FGradientEndColor: TColor;
FGradientStartColor: TColor;
function IsGradientEndColorStored: Boolean;
procedure SetGradientDirection(Value: TGradientDirection);
procedure SetGradientEndColor(Value: TColor);
procedure SetGradientStartColor(Value: TColor);
procedure SetDrawingStyle(Value: TTBDrawingStyle);
protected
procedure Paint; override;
procedure Resize; override;
public
constructor Create(AOwner: TComponent); override;
published
property GradientDirection: TGradientDirection read FGradientDirection
write SetGradientDirection default gdVertical;
property GradientEndColor: TColor read FGradientEndColor
write SetGradientEndColor stored IsGradientEndColorStored;
property GradientStartColor: TColor read FGradientStartColor
write SetGradientStartColor default clWindow;
property DrawingStyle: TTBDrawingStyle read FDrawingStyle
write SetDrawingStyle default dsNormal;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Hiderin', [THRGadientPanel]);
end;
{ THRGadientPanel }
constructor THRGadientPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
GradientStartColor := clWindow;
GradientEndColor := GetShadowColor(clBtnFace, -25);
GradientDirection := gdVertical;
end;
procedure THRGadientPanel.Paint;
const
Alignments: array[TAlignment] of Longint =
(DT_LEFT, DT_RIGHT, DT_CENTER);
VerticalAlignments: array[TVerticalAlignment] of Longint =
(DT_TOP, DT_BOTTOM, DT_VCENTER);
var
Rect: TRect;
Flags: Longint;
begin
if FDrawingStyle = dsGradient then
begin
Rect := GetClientRect;
GradientFillCanvas(Canvas, FGradientStartColor, FGradientEndColor,
Rect, GradientDirection);
with Canvas do
begin
Brush.Style := bsClear;
Font := Self.Font;
Flags := DT_EXPANDTABS or DT_SINGLELINE or
VerticalAlignments[VerticalAlignment] or Alignments[Alignment];
Flags := DrawTextBiDiModeFlags(Flags);
DrawText(Handle, PChar(Caption), -1, Rect, Flags);
end;
end
else
inherited;
end;
procedure THRGadientPanel.SetGradientEndColor(Value: TColor);
begin
if Value <> FGradientEndColor then
begin
FGradientEndColor := Value;
if HandleAllocated then
Repaint;
end;
end;
procedure THRGadientPanel.SetGradientStartColor(Value: TColor);
begin
if Value <> FGradientStartColor then
begin
FGradientStartColor := Value;
if HandleAllocated then
Repaint;
end;
end;
function THRGadientPanel.IsGradientEndColorStored: Boolean;
begin
Result := FGradientEndColor <> GetShadowColor(clBtnFace, -25);
end;
procedure THRGadientPanel.SetGradientDirection(Value: TGradientDirection);
begin
if FGradientDirection <> Value then
begin
FGradientDirection := Value;
if HandleAllocated then
Repaint;
end;
end;
procedure THRGadientPanel.SetDrawingStyle(Value: TTBDrawingStyle);
begin
if Value <> FDrawingStyle then
begin
FDrawingStyle := Value;
if HandleAllocated then
Repaint;
end;
end;
procedure THRGadientPanel.Resize;
begin
inherited Resize;
if (FDrawingStyle = dsGradient) and HandleAllocated then
Repaint;
end;
end.