关于控件的wndpro方法的用法:我的想法是“如何用wndproc来屏蔽掉Form上TreeView控件的WM_MOUSEMOVE等全部鼠标消息”


在form上的treeview控件上的一系列鼠标事件(例如onmousemove事件,onmousedown事件,等等)都已经指定了相关的处理过程,我想通过点击一个按钮来屏蔽掉全部的treeview控件上的一系列鼠标事件,然后再点击另外的按钮来恢复Treeview控件上的全部鼠标事件,广义一点讲,就是如何屏蔽掉某个控件上全部的鼠标消息,然后再如何恢复!
  我想通过重写Treeview控件的wndproc过程来截获并屏蔽掉消息,但我不知道在一个窗体中如何来重写这个wndproc过程,望各位高手指点!!!

  注:wndproc过程在TControl中定义并且是保护方法,只有TTreeView类的子类才能重写该方法;

15 个解决方案

#1


那就使用子类化技术啊...
getwindowLong(...)
setWindowLong();

看看menuXP控件,里边用的就是这种技术.

#2


楼主弄错了。。
你不是需要处理wndproc,而是需要处理WindowProc

TWinControl.WindowProc(指针)---->TWinControl.WndProc(实现的函数)

你可以让它这样:

TWinControl.WindowProc(指针)--->你的MOUSE拦截处理--->TWinControl.WndProc(实现的函数)


其实对于VCL架构,还有好些地方可以处理的,比如:
http://community.csdn.net/Expert/topic/3439/3439310.xml?temp=.832348

#3


谢谢,halfdream(哈欠)  和 hydonlee(青山情) 的关注

hydonlee(青山情) :你所说的“子类化”能不能再说说具体思路啊,很想学习学习;

halfdream(哈欠):控件windowproc属性我也想到过,但是给TTreeview.windowproc的wndproc如何写呢?只有TTreeview的子类才能重写其父类的wndproc方法啊,难道我要继承TTreeView再写个子类TmyTreeView,然后再子类中重写wndproc,再把这个重写的wndproc过程名称赋给窗体上的treeview1嘛?(treeview1.windowproc:=mytreeview.wndproc),望指点

#4


楼主补充:
  我只想截获并屏蔽掉form1中treeview1上的所有事件(或者是所有鼠标事件),这样的要求大家能不能给给思路呢?

  我的想法:我知道可以通过重写TTreeView类wndproc方法来截获消息,但因wndproc为保护方法,所以之后定义一个TTreeView子类TMyTreeView,然后在TMyTreeView类中重写wndproc,但是窗体中的treeview1的类型是TTreeView类型啊,我重写的这个wndproc是TMyTreeView中,只能截获TMyTreeView类型的消息。不知所措中,望大家给给思路!!!

#5


看来楼主压根就没有仔细看我写的,
包括那个例子也没有看。

自己脑袋一点不用吗?


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;

#6


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;

望再次指点,不胜感谢

#7


^_^

#8


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当然就会消失了

#9


谢谢各位了,尤其是:fj218(洞庭风) ( ),halfdream(哈欠)  二位,

  我还有个疑问,如果我想通过重写控件本身的wndproc方法来截获并处理消息呢,是不是就是“子类化”的问题了,我的对子类化的理解是:写出自己的一套类,在其中重写某些函数,来完成自己想要实现的功能,不知道是不是这个意思,知道“子类化”技术的朋友指点一下!!!

#10


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,消息的分派有了更多灵活的处理,大多数时候,不用那种子类化.

#11


学习

#12


重写控件本身的wndproc方法来截获并处理消息呢,是不是就是“子类化”的问题了
这不是子类化,但可以看作是基于VCL控件模拟“子类化”。Windows所说的子类化是针对有句柄地窗口,通过Setwindowlong函数替换原有的窗口回调函数,来拦截消息,扩展功能。而重写Wndproc只要是Tcontrol控件就能适用。就有句柄地控件而言,无论是效率还是级别Setwindowlong都要优先于重写Wndproc。

#13


to fj218(洞庭风) , halfdream(哈欠):
  太感谢二位的帮助了,以后还要多向二位请教了!再过两天结贴了,再次感谢各位的关注与帮助,友人帮助解惑的感觉真好!

#14


UP.

#15


to  deepWATERblue(深水蓝):
  别up一下就完事啊,说说自己的看法啊:)
智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告