2013-04-10 71 views
2

我已将图像(TImage)作为按钮放入我的程序中。我想添加一些额外的效果,所以在OnMouseMove(每当用户在图像移动他的鼠标)的图像被另一图像为了给额外的效果改为:如何检测鼠标何时不在控件中?

procedure TForm1.Image4MouseMove(Sender: TObject; Shift: TShiftState; X, 
    Y: Integer); 
var 
    Path, Destination: String; 
begin 
    Path := ParamStr(0); 
    Destination := Extractfilepath(Path) + 'Images\Image2.bmp'; 
    Image4.Picture.LoadFromFile(Destination); 
end; 

但是每当用户将他将鼠标移开(当他离开图像时),它不会撤消所做的事情(改回Image1)。我该怎么做?没有OnMouseLeave事件。我正在使用德尔福7.

+1

您知道'destination'是'source'的反义词吗? – 2013-04-10 19:20:20

回答

8

首先,你的问题的代码是可怕的!每次光标移动图像控件内的像素时,它都会(重新)加载位图!这太浪费CPU时间了!

无论如何,在Delphi的现代版本中,您只需使用OnMouseEnterOnMouseLeave事件。我不认为这在Delphi 7存在,所以你必须做这样的事情:

TImage = class(ExtCtrls.TImage) 
protected 
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER; 
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE; 
end; 

其中

{ TImage } 

procedure TImage.CMMouseEnter(var Message: TMessage); 
begin 
    // Do something 
end; 

procedure TImage.CMMouseLeave(var Message: TMessage); 
begin 
    // Do something else 
end; 

这个例子需要一个中介类的形式,当然你可能更好地进行适当的分类控制。

+0

如果你不想派生一个新类,你可以选择继承'TImage.WindowProc'属性来捕获相同的消息。 – 2013-04-10 19:43:23

0

如果您在图像控件中加载另一张图片,则先前加载的图片不见了:您必须重新加载。当鼠标移动到图像的容器上时,你可以做到这一点,大概是形式本身。

但是,加载图片在鼠标移动事件处理程序是可怕的,因为安德烈亚斯already explained

我可以提出一个替代方案吗?创建两个图像控件并将它们放置在相同的位置。然后添加以下处理程序:

procedure TForm1.Image4AMouseMove(Sender: TObject; Shift: TShiftState; X, 
    Y: Integer); 
begin 
    Image4B.BringToFront; 
    Image4B.Tag := 1; 
end; 

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, 
    Y: Integer); 
begin 
    if Image4B.Tag = 1 then 
    begin 
    Image4B.Tag := 0; 
    Image4A.BringToFront; 
    end; 
end; 
+1

如果图片周围没有空闲空间(或非常狭窄的区域),该怎么办?尽管如此,我甚至会关心自己的实现,因为如果图像与表单的某个边界对齐,那么光标可以保留整个表单而不会使图像“重置”。 – 2013-04-10 19:52:44

+0

@AndreasRejbrand,但除了InstallLLMouseHook – bummi 2013-04-10 20:26:05

+0

@Andreas OnMouseLeave'将会触发,即使当控件与表单边界或其他控件对齐时,会发生什么。 – NGLN 2013-04-10 20:35:41

相关问题