在form上的treeview控件上的一系列鼠标事件(例如onmousemove事件,onmousedown事件,等等)都已经指定了相关的处理过程,我想通过点击一个按钮来屏蔽掉全部的treeview控件上的一系列鼠标事件,然后再点击另外的按钮来恢复Treeview控件上的全部鼠标事件,广义一点讲,就是如何屏蔽掉某个控件上全部的鼠标消息,然后再如何恢复!
我想通过重写Treeview控件的wndproc过程来截获并屏蔽掉消息,但我不知道在一个窗体中如何来重写这个wndproc过程,望各位高手指点!!!
注:wndproc过程在TControl中定义并且是保护方法,只有TTreeView类的子类才能重写该方法;
15 个解决方案
那就使用子类化技术啊...
getwindowLong(...)
setWindowLong();
看看menuXP控件,里边用的就是这种技术.
楼主弄错了。。
你不是需要处理wndproc,而是需要处理WindowProc
TWinControl.WindowProc(指针)---->TWinControl.WndProc(实现的函数)
你可以让它这样:
TWinControl.WindowProc(指针)--->你的MOUSE拦截处理--->TWinControl.WndProc(实现的函数)
其实对于VCL架构,还有好些地方可以处理的,比如:
http://community.csdn.net/Expert/topic/3439/3439310.xml?temp=.832348
谢谢,halfdream(哈欠) 和 hydonlee(青山情) 的关注
hydonlee(青山情) :你所说的“子类化”能不能再说说具体思路啊,很想学习学习;
halfdream(哈欠):控件windowproc属性我也想到过,但是给TTreeview.windowproc的wndproc如何写呢?只有TTreeview的子类才能重写其父类的wndproc方法啊,难道我要继承TTreeView再写个子类TmyTreeView,然后再子类中重写wndproc,再把这个重写的wndproc过程名称赋给窗体上的treeview1嘛?(treeview1.windowproc:=mytreeview.wndproc),望指点
楼主补充:
我只想截获并屏蔽掉form1中treeview1上的所有事件(或者是所有鼠标事件),这样的要求大家能不能给给思路呢?
我的想法:我知道可以通过重写TTreeView类wndproc方法来截获消息,但因wndproc为保护方法,所以之后定义一个TTreeView子类TMyTreeView,然后在TMyTreeView类中重写wndproc,但是窗体中的treeview1的类型是TTreeView类型啊,我重写的这个wndproc是TMyTreeView中,只能截获TMyTreeView类型的消息。不知所措中,望大家给给思路!!!
看来楼主压根就没有仔细看我写的,
包括那个例子也没有看。
自己脑袋一点不用吗?
var
oldproc:TWndMethod;
procedure TForm1.FormCreate(Sender: TObject);
begin
oldproc:=TreeView1.WindowProc;
TreeView1.WindowProc:=MyWndProc;
end;
procedure TForm1.MyWndProc(var Msg: TMessage);
begin
if msg.Msg=WM_MOUSEMOVE then
begin
// ...
end;
oldproc(Msg);
end;
to :halfdream(哈欠)
真的很感谢如此的关注,也许是小弟过于愚笨,或者没有表达清楚,再次把自己想法说明如下:
如果Treeview1的onmousemove中写如下代码“showmessage('Treeview mousemove ')”,要屏蔽掉该事件,用你写的代码不能达到要求啊,
procedure TForm1.MyWndProc(var Msg: TMessage);
begin
if msg.Msg=WM_MOUSEMOVE then
begin
// ...
end;
oldproc(Msg);//此行何意呢?我想要屏蔽treeview的onmousemove事件,此行不是将再次触发嘛
//如果注释掉此行,则窗体中的treeview1控件怎么消失了呢?不解!!!
end;
望再次指点,不胜感谢
var
oldproc:TWndMethod;
procedure TForm1.FormCreate(Sender: TObject);
begin
oldproc:=TreeView1.WindowProc;
TreeView1.WindowProc:=MyWndProc;
end;
procedure TForm1.MyWndProc(var Msg: TMessage);
begin
if flag then //屏蔽参数
begin
if (msg.msg>=WM_MOUSEFIRST) and (msg.msg<=WM_MOUSELAST) then exit;
end
oldproc(Msg);
end;
//如果注释掉此行,则窗体中的treeview1控件怎么消失了呢?不解!!!
WM_paint消息也被拦截了,treeview1当然就会消失了
谢谢各位了,尤其是:fj218(洞庭风) ( ),halfdream(哈欠) 二位,
我还有个疑问,如果我想通过重写控件本身的wndproc方法来截获并处理消息呢,是不是就是“子类化”的问题了,我的对子类化的理解是:写出自己的一套类,在其中重写某些函数,来完成自己想要实现的功能,不知道是不是这个意思,知道“子类化”技术的朋友指点一下!!!
DELPHI帮助的解释subclassing:
In traditional Windows programming, you create custom controls by defining a new window class and registering it with Windows. The window class (which is similar to the objects or classes in object-oriented programming) contains information shared among instances of the same sort of control; you can base a new window class on an existing class, which is called subclassing.
它作用无非是拦截消息,扩展功能.
使用VCL,消息的分派有了更多灵活的处理,大多数时候,不用那种子类化.
重写控件本身的wndproc方法来截获并处理消息呢,是不是就是“子类化”的问题了
这不是子类化,但可以看作是基于VCL控件模拟“子类化”。Windows所说的子类化是针对有句柄地窗口,通过Setwindowlong函数替换原有的窗口回调函数,来拦截消息,扩展功能。而重写Wndproc只要是Tcontrol控件就能适用。就有句柄地控件而言,无论是效率还是级别Setwindowlong都要优先于重写Wndproc。
to fj218(洞庭风) , halfdream(哈欠):
太感谢二位的帮助了,以后还要多向二位请教了!再过两天结贴了,再次感谢各位的关注与帮助,友人帮助解惑的感觉真好!
to deepWATERblue(深水蓝):
别up一下就完事啊,说说自己的看法啊:)