ورود

View Full Version : کامپوننتی برای ساخت دکمه با چند عکس



nicolas1390
دوشنبه 24 تیر 1392, 14:09 عصر
سلام
من تا الان از یک TImage استفاده می کردم و 3 تا عکس درست می کردم و توی حالات مختلف موس اون عکس ها را نمایش می دادم .
یکی برای عادی ، یکی برای وقتی موس روی عکس میره و یکی هم برای زمانی که موس فشرده میشه.

کامپوننتی نیست که این کار ها را انجام بده که دستی انجام ندم ؟

مرسی

یوسف زالی
دوشنبه 24 تیر 1392, 14:18 عصر
سلام.


TU30Button = class(TButton)
private
FBackBeforeHoverColor: TColor;
F_Author: string;
procedure Set_Author(const Value: string);
private
FCanvas: TCanvas;
IsFocused: Boolean;
FBackColor: TColor;
FForeColor: TColor;
FHoverColor: TColor;
procedure SetBackColor(const Value: TColor);
procedure SetForeColor(const Value: TColor);
procedure SetHoverColor(const Value: TColor);
property BackBeforeHoverColor : TColor read FBackBeforeHoverColor write FBackBeforeHoverColor;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure WndProc(var Message : TMessage); override;
procedure SetButtonStyle(Value: Boolean); override;
procedure DrawButton(Rect: TRect; State: UINT);
procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
procedure CNMeasureItem(var Message: TWMMeasureItem); message CN_MEASUREITEM;
procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property _Author: string read F_Author write Set_Author;
published
property BackColor: TColor read FBackColor write SetBackColor default clBtnFace;
property ForeColor: TColor read FForeColor write SetForeColor default clBtnText;
property HoverColor: TColor read FHoverColor write SetHoverColor default clBtnFace;
end;



{ TU30Button }

constructor TU30Button.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCanvas := TCanvas.Create;
BackColor := clBtnFace;
ForeColor := clBtnText;
HoverColor := clBtnFace;
F_Author := 'Yousef Zalli, U3F.Zalli@GMail.Com, Tel = 09123780840';
end;

destructor TU30Button.Destroy;
begin
FCanvas.Free;
inherited Destroy;
end;

procedure TU30Button.WndProc(var Message : TMessage);
begin
if (Message.Msg = CM_MOUSELEAVE) then
begin
BackColor := BackBeforeHoverColor;
invalidate;
end;
if (Message.Msg = CM_MOUSEENTER) then
begin
BackBeforeHoverColor := BackColor;
BackColor := HoverColor;
invalidate;
end;

inherited;
end;

procedure TU30Button.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do Style := Style or BS_OWNERDRAW;
end;

procedure TU30Button.SetButtonStyle(Value: Boolean);
begin
if Value <> IsFocused then
begin
IsFocused := Value;
Invalidate;
end;
end;

procedure TU30Button.CNMeasureItem(var Message: TWMMeasureItem);
begin
with Message.MeasureItemStruct^ do
begin
itemWidth := Width;
itemHeight := Height;
end;
end;

procedure TU30Button.CNDrawItem(var Message: TWMDrawItem);
var
SaveIndex: Integer;
begin
with Message.DrawItemStruct^ do
begin
SaveIndex := SaveDC(hDC);
FCanvas.Lock;
try
FCanvas.Handle := hDC;
FCanvas.Font := Font;
FCanvas.Brush := Brush;
DrawButton(rcItem, itemState);
finally
FCanvas.Handle := 0;
FCanvas.Unlock;
RestoreDC(hDC, SaveIndex);
end;
end;
Message.Result := 1;
end;

procedure TU30Button.CMEnabledChanged(var Message: TMessage);
begin
inherited;
Invalidate;
end;

procedure TU30Button.CMFontChanged(var Message: TMessage);
begin
inherited;
Invalidate;
end;


procedure TU30Button.SetBackColor(const Value: TColor);
begin
if FBackColor <> Value then begin
FBackColor:= Value;
Invalidate;
end;
end;

procedure TU30Button.SetForeColor(const Value: TColor);
begin
if FForeColor <> Value then begin
FForeColor:= Value;
Invalidate;
end;
end;

procedure TU30Button.SetHoverColor(const Value: TColor);
begin
if FHoverColor <> Value then begin
FHoverColor:= Value;
Invalidate;
end;
end;

procedure TU30Button.DrawButton(Rect: TRect; State: UINT);
var
Flags, OldMode: Longint;
IsDown, IsDefault, IsDisabled: Boolean;
OldColor: TColor;
OrgRect: TRect;
begin
OrgRect := Rect;
Flags := DFCS_BUTTONPUSH or DFCS_ADJUSTRECT;
IsDown := State and ODS_SELECTED <> 0;
IsDefault := State and ODS_FOCUS <> 0;
IsDisabled := State and ODS_DISABLED <> 0;

if IsDown then Flags := Flags or DFCS_PUSHED;
if IsDisabled then Flags := Flags or DFCS_INACTIVE;

if IsFocused or IsDefault then
begin
FCanvas.Pen.Color := clWindowFrame;
FCanvas.Pen.Width := 1;
FCanvas.Brush.Style := bsClear;
FCanvas.Rectangle(Rect.Left, Rect.Top, Rect.Right, Rect.Bottom);
InflateRect(Rect, - 1, - 1);
end;

if IsDown then
begin
FCanvas.Pen.Color := clBtnShadow;
FCanvas.Pen.Width := 1;
FCanvas.Brush.Color := clBtnFace;
FCanvas.Rectangle(Rect.Left, Rect.Top, Rect.Right, Rect.Bottom);
InflateRect(Rect, - 1, - 1);
end
else
DrawFrameControl(FCanvas.Handle, Rect, DFC_BUTTON, Flags);

if IsDown then OffsetRect(Rect, 1, 1);

OldColor := FCanvas.Brush.Color;
FCanvas.Brush.Color := BackColor;
FCanvas.FillRect(Rect);
FCanvas.Brush.Color := OldColor;
OldMode := SetBkMode(FCanvas.Handle, TRANSPARENT);
FCanvas.Font.Color := ForeColor;
if IsDisabled then
DrawState(FCanvas.Handle, FCanvas.Brush.Handle, nil, Integer(Caption), 0,
((Rect.Right - Rect.Left) - FCanvas.TextWidth(Caption)) div 2,
((Rect.Bottom - Rect.Top) - FCanvas.TextHeight(Caption)) div 2,
0, 0, DST_TEXT or DSS_DISABLED)
else
DrawText(FCanvas.Handle, PChar(Caption), - 1, Rect,
DT_SINGLELINE or DT_CENTER or DT_VCENTER);
SetBkMode(FCanvas.Handle, OldMode);

if IsFocused and IsDefault then
begin
Rect := OrgRect;
InflateRect(Rect, - 4, - 4);
FCanvas.Pen.Color := clWindowFrame;
FCanvas.Brush.Color := clBtnFace;
DrawFocusRect(FCanvas.Handle, Rect);
end;
end;

procedure TU30Button.Set_Author(const Value: string);
begin
// F_Author := Value;
end;

nicolas1390
دوشنبه 24 تیر 1392, 14:28 عصر
من ساخت کامپوننت تو دلفی کار نکردم ، یک راهنمایی کوچیک می کنید ؟ چرا از کلاس TImage استفاده نکردید ؟!
یک سوال دیگه ، میخوام عکس های مربوط به باتون ها داخل خود فایل exe لود بشه و کنار فایل اجرایی نباشه

یوسف زالی
دوشنبه 24 تیر 1392, 14:53 عصر
من اشتباه کردم.
این کامپوننت فقط رنگ ها رو عوض می کنه.
البته برای عکس هم چندان تفاوتی نداره.
برای ساخت کامپوننت آموزشی رو که گذاشتم مطالعه کنید. در امضای من هست.
دلیل این که از کلاس Image استفاده نشده اینه که بتونید خواصی مثل default,cancel, modalresult, فشرده شدن، رها شدن و ... رو در دسترس داشته باشید و دوباره پیادش نکنید.
البته کامپوننت آماده هم وجود داره که می تونید ازشون استفاده کنید ولی نوشتنش یه چیز دیگس!
موفق باشید.

nicolas1390
سه شنبه 25 تیر 1392, 11:05 صبح
مرسی
اما مشکل زمان هست !
کامپوننت آماده برای این کار چی هست ؟ خوبی TImage اینه عکس png بهش بدی میتونه transparent کنه.

nicolas1390
شنبه 29 تیر 1392, 09:45 صبح
کامپوننت پیدا نکردم مجبور شدم با همین TImage دلفی کار را انجام بدم
فقط یک مشکل ! چجوری میشه همه عکس ها را توی فایل اجرایی ذخیره کرد که دیگه عکس ها کنار فایل اجرایی نباشن ؟ الان در زمان اجرا وقتی عکس ها ی یک دکمه را تغییر میدم باید آدرسش را بدم که کنار فایل اجرایی است . اما میخوام عکس ها کنار فایل اجرایی نباشن و همه داخل فایل اجرایی ذخیره بشن

یوسف زالی
شنبه 29 تیر 1392, 10:27 صبح
ببین خود دلفی برای BitBtn چه کرده. کدش رو بخون و شبیهش رفتار کن، عکست می ره در DFM می شینه.
البته اگر کامپوننت کرده باشید.
در غیر این صورت باید از ریسورس ها استفاده کنید.