控件开发:关于组合控件的mousedown。 (100分)

吴辽

Unregistered / Unconfirmed
GUEST, unregistred user!
我需要开发一个具有阴影的一个按钮控件,我用了两个panel 重叠,就象ghost6。0中
的那种按钮,外面一个用亮色,里面一个用暗色(表示阴影),当我在外面panel按下mouse时时,
我将两个控件重合,当松开mouse时,恢复原状。
请教各位及格问题:
1.我是继承自tpanel,进行开发,还是twincontrol开发。
2.我如何写mousedown事件,现在是这样的情况:
我写出来的那个onmousedown事件,然后我用一个程序来测试该组件,我发现我如果
不在测试程序中该按钮的mousedown写一句语句(随便什么语句,比如showmessage(''aa)之类的)
这个组件的setOnMousedown过程不执行,如果写一条语句,那么你还没点击该按钮时,这个过程就
执行了,这是怎么会事,我把程序代码贴出来,大家帮帮忙。谢谢了!!!
unit ShadowButton;

interface

uses
Windows, Messages, SysUtils,StdCtrls, Classes, Controls, ExtCtrls,Graphics;

type
TShadowButton = class(twincontrol)

private
FPanelOutside:tpanel;
FpanelInside:tpanel;
{ Private declarations }
protected
procedure wmsize(var message:twmsize);message wm_size;
function GetOnMousedown:tmouseevent;
procedure SetOnMousedown(value :tmouseevent);
{ Protected declarations }
public
constructor create(Aowner:tcomponent);override;
destructor destroy;override;
{ Public declarations }
published
property Onmousedown:tmouseevent read getonmousedown write setonmousedown;
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Standard', [TShadowButton]);
end;

constructor Tshadowbutton.create(Aowner:tcomponent);
begin
inherited create(aowner);
bevelouter:=bvnone;

fpaneloutside:=tpanel.Create(self);
fpanelinside:=tpanel.Create(self);

with fpanelinside do
begin
Parent:=self;
Color :=clblack;
bevelouter:=bvNone;
Left :=fpaneloutside.Left +8;
top:=fpaneloutside.Top +8;
width:=fpaneloutside.Width;
height:=fpanelinside.Height ;
end;

fpaneloutside.Parent:=self;
fpaneloutside.Color :=clblue;
fpaneloutside.bevelouter:=bvNone;
width:=fpaneloutside.Width;
height:=fpanelinside.Height ;
end;

procedure tshadowbutton.wmsize(var message:twmsize);
begin
inherited;
fpaneloutside.Width :=message.Width-15;
fpaneloutside.Height :=message.Height-15;
fpanelinside.Width :=message.Width-15;
fpanelinside.Height :=message.Height-15;
end;

destructor tshadowbutton.destroy;
begin
fpanelinside.Free;
fpaneloutside.Free;
inherited destroy;
end;

function tshadowbutton.GetOnMousedown:tmouseevent;
begin
result :=fpaneloutside.OnMouseDown;
end;
//就在这个过程里面里出问题。
procedure tshadowbutton.setOnMousedown(value:tmouseevent);
begin
fpaneloutside.OnMouseDown :=value;
fpaneloutside.Left :=fpanelinside.Left;
fpaneloutside.top :=fpanelinside.top;
end;

 
你可以重载MouseDown函数来处理,
没必要搞的这么复杂。
interface
procedure tshadowbutton.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); override;

implementation
procedure tshadowbutton.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer;
begin
fpaneloutside.Left :=fpanelinside.Left;
fpaneloutside.top :=fpanelinside.top;
end;

 
to 鲁小班 ,我第一次就是使用的你这种方法,但是问题就是当我点击在fpaneloutside上
不触发这个mousedown事件,只有点击在除了fpaneloutside,和fpanelinside时,才触发
mousedown事件。
恳请大家帮忙。
 
建议你从TCustomPanel继承下来,而且只需要一个Panel类成员,这个成员是前景,
而控件本身是背景,另外你也不要重载MouseDown方法而是直接重载WM_LButtonDown消息。
 
现在可以了,不过有点复杂,不知道有什么更简单的办法.

unit ShadowButton;

interface

uses
Windows, Messages, SysUtils,StdCtrls, Classes, Controls, ExtCtrls,Graphics;

type
TShadowButton = class(twincontrol)

private
FPanelOutside:tpanel;
FpanelInside:tpanel;
{ Private declarations }
protected
procedure wmsize(var message:twmsize);message wm_size;[red]
procedure wmlbuttondown( var message:TWMLButtonDown);message wm_lbuttondown;
procedure wmlbuttonup( var message:TWMLButtonup);message wm_lbuttonup;
procedure mousedown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure mouseup(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);[/red]

// function GetOnMousedown:tmouseevent;
// procedure SetOnMousedown(value :tmouseevent);
{ Protected declarations }
public
constructor create(Aowner:tcomponent);override;
destructor destroy;override;
{ Public declarations }
published
// property Onmousedown:tmouseevent read getonmousedown write setonmousedown;
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Standard', [TShadowButton]);
end;

constructor Tshadowbutton.create(Aowner:tcomponent);
begin
inherited create(aowner);
bevelouter:=bvnone;

fpaneloutside:=tpanel.Create(self);
fpanelinside:=tpanel.Create(self);
fpaneloutside.OnMouseDown := mousedown;
fpanelinside.OnMouseDown := mousedown;
fpaneloutside.OnMouseUp := mouseup;
fpaneloutside.OnMouseUp := mouseup;
with fpanelinside do
begin
Parent:=self;
Color :=clblack;
bevelouter:=bvNone;
Left :=fpaneloutside.Left +8;
top:=fpaneloutside.Top +8;
width:=fpaneloutside.Width;
height:=fpanelinside.Height ;
end;

fpaneloutside.Parent:=self;
fpaneloutside.Color :=clblue;
fpaneloutside.bevelouter:=bvNone;
width:=fpaneloutside.Width;
height:=fpanelinside.Height ;
end;

procedure tshadowbutton.wmsize(var message:twmsize);
begin
inherited;
fpaneloutside.Width :=message.Width-15;
fpaneloutside.Height :=message.Height-15;
fpanelinside.Width :=message.Width-15;
fpanelinside.Height :=message.Height-15;
end;

destructor tshadowbutton.destroy;
begin
fpanelinside.Free;
fpaneloutside.Free;
inherited destroy;
end;
{
function tshadowbutton.GetOnMousedown:tmouseevent;
begin
result :=fpaneloutside.OnMouseDown;
end;
//¾ÍÔÚÕâ¸ö¹ý³ÌÀïÃæÀï³öÎÊÌâ¡£
procedure tshadowbutton.setOnMousedown(value:tmouseevent);
begin
fpaneloutside.OnMouseDown :=value;
fpaneloutside.Left :=fpanelinside.Left;
fpaneloutside.top :=fpanelinside.top;
end;
}
[red]procedure tshadowbutton.wmlbuttondown(var message:TWMLButtonDown);
begin
inherited;
fpaneloutside.Left :=fpanelinside.Left;
fpaneloutside.top :=fpanelinside.top;

end;
procedure tshadowbutton.wmlbuttonup(var message:tWmlbuttonup);
begin
inherited;
fpaneloutside.Left :=fpanelinside.Left-8;
fpaneloutside.top :=fpanelinside.top-8;

end;
procedure tshadowbutton. mousedown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if button = mbLeft then
begin
sendmessage(self.Handle,wm_lbuttondown,0,0);
end;
end;
procedure tshadowbutton. mouseup(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if button = mbLeft then
begin
sendmessage(self.Handle,wm_lbuttonup,0,0);
end;
end;[/red]
end.


 
谢谢各位:to aizb,一开始,我也和你一样想,但是如果只中一个panel,然后控件本身
那个panel做阴影,因为两个panel的left一样,所以效果为里面一个框,外面一个框,没有立体感觉
,但是你提的第二点我觉得应该有用,我试一下,谢谢先。
to xeen, 非常感谢你,辛苦你了,也很感谢大富翁,你的代码我马上试一下。
 
接受答案了.
 
顶部