如何让让IMAGE支持鼠标的滚轮事件? ( 积分: 50 )

  • 主题发起人 主题发起人 sikaman
  • 开始时间 开始时间
S

sikaman

Unregistered / Unconfirmed
GUEST, unregistred user!
在做一个程序,需要用鼠标控制IMAGE的大小,可是IMAGE是不支持鼠标滚轮事件的,于是查了一些资料,想做一个支持滚轮事件的myimage。先是继承了image,然后......(见代码),可是无法通过,请教高手,我的程序错在哪里了?请指教呀。
unit MyImage;

interface

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

type
TMyImage = class(Timage)

private
{ Private declarations }

fMouseWheel:TMouseWheelEvent;

fMouseWheelUp:TMouseWheelUpDownEvent; //鼠标轮上滚事件

fMouseWheelDown: TMouseWheelUpDownEvent; //鼠标轮下滚事件

protected
{ Protected declarations }
procedure WndProc(var Msg: TMessage);override;

public
{ Public declarations }

published
{ Published declarations }
property OnMouseWheel:TMouseWheelEvent read fMouseWheel write fMouseWheel;

property OnMouseWheelUp:TMouseWheelUpDownEvent read fMouseWheelUp write fMouseWheelUp;

property OnMouseWheelDown:TMouseWheelUpDownEvent read fMouseWheelDown write fMouseWheelDown;
end;

procedure Register;


implementation

procedure Register;
begin
RegisterComponents('Samples', [TMyImage]);
end;

procedure TMyImage.WndProc(var Msg: TMessage);

//  我们在WndProc中捕获鼠标轮的消息,如下:

var

MousePoint:TPoint;

Handled:Boolean;

shift:TShiftState;

begin

if(Msg.Msg=WM_MOUSEWHEEL) then //捕获鼠标轮事件

begin

MousePoint.X:=LOWORD(Msg.lParam);

MousePoint.Y:=HIWORD(Msg.lParam);

Handled:=false;

if(Msg.wParam>0) then //上滚

fMouseWheelUp(self,shift,MousePoint,Handled)

else //下滚

fMouseWheelDown(self,shift,MousePoint,Handled);

fMouseWheel(self,shift,HIWORD(Msg.wParam),MousePoint,Handled);

if Handled then exit;

end;

inherited;

end;

end.
 
在做一个程序,需要用鼠标控制IMAGE的大小,可是IMAGE是不支持鼠标滚轮事件的,于是查了一些资料,想做一个支持滚轮事件的myimage。先是继承了image,然后......(见代码),可是无法通过,请教高手,我的程序错在哪里了?请指教呀。
unit MyImage;

interface

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

type
TMyImage = class(Timage)

private
{ Private declarations }

fMouseWheel:TMouseWheelEvent;

fMouseWheelUp:TMouseWheelUpDownEvent; //鼠标轮上滚事件

fMouseWheelDown: TMouseWheelUpDownEvent; //鼠标轮下滚事件

protected
{ Protected declarations }
procedure WndProc(var Msg: TMessage);override;

public
{ Public declarations }

published
{ Published declarations }
property OnMouseWheel:TMouseWheelEvent read fMouseWheel write fMouseWheel;

property OnMouseWheelUp:TMouseWheelUpDownEvent read fMouseWheelUp write fMouseWheelUp;

property OnMouseWheelDown:TMouseWheelUpDownEvent read fMouseWheelDown write fMouseWheelDown;
end;

procedure Register;


implementation

procedure Register;
begin
RegisterComponents('Samples', [TMyImage]);
end;

procedure TMyImage.WndProc(var Msg: TMessage);

//  我们在WndProc中捕获鼠标轮的消息,如下:

var

MousePoint:TPoint;

Handled:Boolean;

shift:TShiftState;

begin

if(Msg.Msg=WM_MOUSEWHEEL) then //捕获鼠标轮事件

begin

MousePoint.X:=LOWORD(Msg.lParam);

MousePoint.Y:=HIWORD(Msg.lParam);

Handled:=false;

if(Msg.wParam>0) then //上滚

fMouseWheelUp(self,shift,MousePoint,Handled)

else //下滚

fMouseWheelDown(self,shift,MousePoint,Handled);

fMouseWheel(self,shift,HIWORD(Msg.wParam),MousePoint,Handled);

if Handled then exit;

end;

inherited;

end;

end.
 
怎么没有人回答呀?自己顶一下
 
if(Msg.wParam>0) then //上滚

if Assigned(OnMouseWheelUP) then fMouseWheelUp(self,shift,MousePoint,Handled)

else //下滚

if Assigned(OnMouseWheelDown) then fMouseWheelDown(self,shift,MousePoint,Handled);
 
先谢了[:)]
 
晕 chenybin哪有你这样的。。。。

我先copy出去玩玩看~~^_^
 
汗。。。。我试了试,不行,image不能接收CM_MOUSEWHEEL或者WM_MOUSEWHEEL的消息

似乎只有从TWinControl继承出来的控件才能接收到这个消息
而image是从TGraphicControl继承出来的。。。。

我无能为力了,看看别人有没有好办法

不过如果只是单单想获得鼠标滚轮事件,不用重新继承个image,在from上放个ApplicationEvents,在其onmessage事件里截取WM_MOUSEWHEEL消息也行
 
Timage不是从TWinControl继承,所以没有Handle,也就不能接受普通的Windows消息,也就是WM_开头哪些。所以也就没有上面的那个循环。它的消息依靠于它的容器:TForm等。

下面的代码是从网上找的,可能对你有用
unit image1;

interface

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

type
TNewimage = class(TImage)
private
FOnMouseLeave: TNotifyEvent;
FOnMouseEnter: TNotifyEvent;
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
//请自己修改
RegisterComponents('Samples', [TNewimage]);
end;

{ timage1 }

procedure TNewimage.CMMouseEnter(var Message: TMessage);
begin
inherited;
if Assigned(FOnMouseEnter) then
FOnMouseEnter(Self);
end;

procedure TNewimage.CMMouseLeave(var Message: TMessage);
begin
inherited;
if Assigned(FOnMouseLeave) then
FOnMouseLeave(Self);
end;

end.

如果你非要它能成为普通的窗口类那样,用你的函数来处理的话,我加两句话给你

[blue]在类的成员里面放一个FHandle : THandle;
然后在Create里面FHandle := AllocateHWnd(你的消息处理函数)
在Destroy的时候DeallocateHWnd(FHandle );[/blue]
这样就可以了
 
TO chenybin
不行吧。。。。。在类里放
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
我试过了,接收不到这个消息的
 
非常遗憾,小弟不幸收到了,嘿嘿

我在界面上

with TNewImage.Create(nil) do begin
parent := self;
left := 0;
top := 0;
width := 100;
height := 100;
show;
end;

然后把断点设置在上面的那两个地方,就可以了

[blue]不过我后面说的方法应该是没问题的,相当于有了Handle了,不信你看看[/blue]
 
汗。。。。没注意,你写错了
应该是CM_MOUSEWHEEL消息,而不是CM_MOUSEENTER或者CM_MOUSELEAVE,这2个当然能收到
CM_MOUSEWHEEL不行,只有从Twincontrol继承过来的才能收到

那个handle我还没试,不行了,回家睡觉去了 NND 下雨真烦人
 
把你的Image直接放到Form上边。然后覆盖TForm的WndPorc,
if (Mesg.Msg == WM_xxx)
then Inherited ...//在这里加断点,然后一路跟踪,可以得到此消息相应的路径
eles
Inherited.

除非你特别需要透明,否则你可以从TCustomControl继承一个.
 
感谢各位的参与,问题暂时解决了。我的这个程序只用在一处捕获滚轮消息,就用了hs-kill的办法,在from上放个ApplicationEvents,在其onmessage事件里截取WM_MOUSEWHEEL消息。这样来得快,也达到了预期效果。其他朋友的方法不是不能用,我没有时间再试了,等时间宽裕了再试试。
分有点少,还请笑纳。
 
后退
顶部