请教关于动态创建和删除控件的问题

静远 2010-02-25 11:15:16
目的:在一Form上,当点击鼠标左键时动态生成一指定控件,当在生成的控件上点击鼠标右键时,删除该控件。
创建控件我是用的MouseDown事件通过判断鼠标左键实现。
请问该如何解决这个问题?
...全文
251 点赞 收藏 23
写回复
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
火龙岛主 2010-02-25
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private

public
function CreateButton(const x, y: integer): TButton;
procedure ButtonRightClick(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.CreateButton(const x, y: integer): TButton;
begin
result := TButton.Create(nil);
result.Parent := self;
result.Left := x;
result.Top := y;
result.OnMouseDown := ButtonRightClick;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if button = mbLeft then
CreateButton(x, y);
end;

procedure TForm1.ButtonRightClick(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (button = mbRight) and (Sender is TButton) then
FreeAndNil(Sender);
end;

end.
回复
zshsuming 2010-02-25
TMouseButton identifies a mouse button in a mouse-event handler.

Unit

Controls

type TMouseButton = (mbLeft, mbRight, mbMiddle);

Description

The TMouseButton type defines the mouse-button constants used by mouse-event handlers to distinguish which button generated the mouse event.
回复
zshsuming 2010-02-25

public
procedure MyMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); //注意参数要和原有事件过程一样

procedure TForm1.MyMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
begin
if Button=mbLeft then
begin
(Sender as TEdit).Free;
end;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
//创建TEdit的对象实例,之后加上如下代码
Object.OnMouseDown:=MyMouseDown; //自定义一个Mousedown事件,创建组件后,把组件的mousedown事件指向你自定义的事件,然后在自定义的事件中处理删除
end;

回复
bdmh 2010-02-25
自定义一个Mousedown事件,创建组件后,把组件的mousedown事件指向你自定义的事件,然后在自定义的事件中处理删除
回复
静远 2010-02-25
另开帖加分:
http://topic.csdn.net/u/20100225/17/f9714f72-2171-4f2f-b946-c59001505fd0.html
多谢各位的热情帮助!
请各位移驾此贴^_^
回复
静远 2010-02-25
引用 21 楼 avan_lau 的回复:
直接指定不就可以了,为啥还加一个右键判断?


多谢多谢!
原来是这样,把问题弄复杂了~
回复
金卯刀 2010-02-25
直接指定不就可以了,为啥还加一个右键判断?
回复
静远 2010-02-25
引用 18 楼 avan_lau 的回复:
你应该在控件创建完后就指定,即在if Button = mbLeft then判断体内指定

谢谢回复!
嗯,之前我也是把右键判断放在左键判断里面的,但是发现无法执行右键判断(或者说是没有反应)。
回复
静远 2010-02-25
引用 17 楼 harryfin 的回复:
引用 14 楼 eriato 的回复:引用 12 楼 harryfin 的回复: 对于protected下的属性,要用特殊方法才能访问的到。不过一般情况建议尽量不这样用。 Delphi(Pascal) codetype TControlHack= class(TControl);begin TControlHack(YourObject).OnMouseDown := MyMouseDown;end; 多谢! 嗯,这里如果没有别的办法我可以尝试通过判断控件类型,然后再进行转换,再执行后面的OnMouseDown。
不知道你是否看明白了,我的意思不是让你判断控件类型,如果控件类型多的话,是会死人的,且需要写死。只是告诉你一种直接访问TControl的protected属性的取巧方法而已,这样就不用进行类型判断了。


嗯,这是学到的新知识,多谢^_^
就是还有后面提到的问题不知道该如何解决?我开始以为是Newcls.Parent := Self;的原因而使自定义的OnMouseDown事件 被指向了Form,但是后来发觉似乎不是这个原因,因为预先定义的Button1是可以被指向成功的,只是需要多右键一次Form。
回复
金卯刀 2010-02-25
你应该在控件创建完后就指定,即在if Button = mbLeft then判断体内指定
回复
Harryfin 2010-02-25
引用 14 楼 eriato 的回复:
引用 12 楼 harryfin 的回复:
对于protected下的属性,要用特殊方法才能访问的到。不过一般情况建议尽量不这样用。
Delphi(Pascal) codetype
TControlHack= class(TControl);begin
TControlHack(YourObject).OnMouseDown := MyMouseDown;end;

多谢!
嗯,这里如果没有别的办法我可以尝试通过判断控件类型,然后再进行转换,再执行后面的OnMouseDown。

不知道你是否看明白了,我的意思不是让你判断控件类型,如果控件类型多的话,是会死人的,且需要写死。只是告诉你一种直接访问TControl的protected属性的取巧方法而已,这样就不用进行类型判断了。
回复
静远 2010-02-25
引用 15 楼 idwb 的回复:
引用 8 楼 eriato 的回复:引用 6 楼 idwb 的回复:SmallHand的方法完全可行,左键是创建右键是删除,哪里有问题啊?? 但是在我这里鼠标无论怎么点击都没有反应,我刚开始看到他写的也认为是没问题的。不知道是不是版本的问题?

如果创建后没有显示出来,那么可以加上visable:=true;
你调试一下看看到底有没有被创建了
对于不同控件MouseDown定义每种控件的MouseDown方法格式,d2005是否和d7一样我就不清楚了
FreeAndNil(Sender);的作用是调用控件destroy方法并且将控件分配的地址=nil,相当于完全释放该控件


控件是创建成功了的,也可以看到。但是自定义的OnMouseDown事件被指向了当前From,而不是所指定的控件。还发现一个奇怪的问题,如果是直接写预先定义的控件的OnMouseDown事件,如procedure TForm10.Button1MouseDown(),则右键一次即可删除该控件,而如果是通过把自定义事件指向Button1的OnMouseDown则需要先右键一下Form再右键Button1才可以删除。
回复
IDWB 2010-02-25
引用 8 楼 eriato 的回复:
引用 6 楼 idwb 的回复:SmallHand的方法完全可行,左键是创建右键是删除,哪里有问题啊??

但是在我这里鼠标无论怎么点击都没有反应,我刚开始看到他写的也认为是没问题的。不知道是不是版本的问题?


如果创建后没有显示出来,那么可以加上visable:=true;
你调试一下看看到底有没有被创建了
对于不同控件MouseDown定义每种控件的MouseDown方法格式,d2005是否和d7一样我就不清楚了
FreeAndNil(Sender);的作用是调用控件destroy方法并且将控件分配的地址=nil,相当于完全释放该控件
回复
静远 2010-02-25
引用 12 楼 harryfin 的回复:
对于protected下的属性,要用特殊方法才能访问的到。不过一般情况建议尽量不这样用。
Delphi(Pascal) codetype
TControlHack= class(TControl);begin
TControlHack(YourObject).OnMouseDown := MyMouseDown;end;


多谢!
嗯,这里如果没有别的办法我可以尝试通过判断控件类型,然后再进行转换,再执行后面的OnMouseDown。
现在还有个问题就是:对于已经建立的控件,可以直接右键进行删除,但是动态生成的却不行,而是对该控件的Parent(Form)执行操作。请问这该如何解决呢?
回复
静远 2010-02-25
哦,这个等级只能给100分了……
可以另开帖加分,多谢!
回复
Harryfin 2010-02-25
对于protected下的属性,要用特殊方法才能访问的到。不过一般情况建议尽量不这样用。

type
TControlHack = class(TControl);

begin
TControlHack(YourObject).OnMouseDown := MyMouseDown;
end;
回复
静远 2010-02-25
分不够可以再加分,多谢各位指点!
回复
静远 2010-02-25
引用 9 楼 harryfin 的回复:
引用 7 楼 eriato 的回复:这个时候如果Object.OnMouseDown:=MyMouseDown;这样写,就会提示:'Cannot access protected symbol TControl.OnMouseDown';
你的那个Object定义成了什么类型?TControl?


嗯,因为有多个类型的控件。
我试过进行转换,如当为Button时:TButton(object).OnMouseDown:=MyMouseDown;这样写是不会报错,但是有一个新的问题,那就是右键的时候是把Form给Destroy了(但进程还存在,似乎只是隐藏了?)。
我想这应该和前面的Newcls.Parent := Self; 有关。不知道是不是呢?
回复
Harryfin 2010-02-25
引用 7 楼 eriato 的回复:
这个时候如果Object.OnMouseDown:=MyMouseDown;这样写,就会提示:'Cannot access protected symbol TControl.OnMouseDown';

你的那个Object定义成了什么类型?TControl?
回复
静远 2010-02-25
引用 6 楼 idwb 的回复:
SmallHand的方法完全可行,左键是创建右键是删除,哪里有问题啊??


但是在我这里鼠标无论怎么点击都没有反应,我刚开始看到他写的也认为是没问题的。不知道是不是版本的问题?
回复
发动态
发帖子
语言基础/算法/系统设计
创建于2007-08-02

1.6w+

社区成员

Delphi 语言基础/算法/系统设计
申请成为版主
社区公告
暂无公告