如果在form1中点击鼠标,然后在form1内松开鼠标,则可以轻松根据TForm1.FormMouseUp知道鼠标已松开。但是当在form1按住鼠标不放,然后移动后form1以外的区域再松开鼠标,这时候就不能触发TForm1.FormMouseUp了。在这种情况下,请问要怎么办才能知道鼠标是否已松开呢?望请解答,谢谢!!!

解决方案 »

  1.   

    P:TPoint;
    P:=image1.clienttoscreen(point(x,y));  //坐标转换
      

  2.   

    那是比如说你点击了image,然后拖动鼠标到form外,然后释放,就是用坐标转换的,看看行不行?
      

  3.   

    函数功能:该函数综合鼠标击键和鼠标动作。    函数原型:VOID mouse_event(DWORD dwFlags,DWORD dx,DWORD dwFlags,OWORD dx,DWORD dy, DWORD dwData, DWORD dwExtralnfo);    参数:    dwFlags:标志位集,指定点击按钮和鼠标动作的多种情况。此参数里的各位可以是下列值的任何合理组合:    MOOSE_EVENTF_ABSOLOTE:表明参数dX,dy含有规范化的绝对坐标。如果不设置此位,参数含有相对数据:相对于上次位置的改动位置。此标志可被设置,也可不设置,不管鼠标的类型或与系统相连的类似于鼠标的设备的类型如何。要得到关于相对鼠标动作的信息,参见下面备注部分。    MOOSEEVENTFMOVE:表明发生移动。    M00SEEVENTF_LEFTDOWN:表明接按下鼠标左键。    M00SEEVENTF_LEFTUP:表明松开鼠标左键。    MOOSEEVENTF_RIGHTDOWN:表明按下鼠标右键。    MOOSEEVENTF_RIGHTUP:表明松开鼠标右键。    MOOSEEVENTF_MIDDLEDOWN:表明按下鼠标中键。    MOOSEEVENTF_MIDDLEUP:表明松开鼠标中键。    MOOSEEVENTF_WHEEL:在Windows NT中如果鼠标有一个轮,表明鼠标轮被移动。移动的数量由dwData给出。    dx:指定鼠标沿x轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOOSEEVENTF_ABSOLOTE的设置。给出的绝对数据作为鼠标的实际X坐标;给出的相对数据作为移动的mickeys数。一个mickey表示鼠标移动的数量,表明鼠标已经移动。    dy:指定鼠标沿y轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOOSEEVENTF_ABSOLVTE的设置。给出的绝对数据作为鼠标的实际y坐标,给出的相对数据作为移动的mickeys数。    dwData:如果dwFlags为MOOSEEVENTF_WHEEL,则dwData指定鼠标轮移动的数量。正值表明鼠标轮向前转动,即远离用户的方向;负值表明鼠标轮向后转动,即朝向用户。一个轮击定义为WHEEL_DELTA,即120。    如果dwFlagsS不是MOOSEEVENTF_WHEEL,则dWData应为零。    dwExtralnfo:指定与鼠标事件相关的附加32位值。应用程序调用函数GetMessgeExtrajnfo来获得此附加信息。    返回值:无。    备注:如果鼠标被移动,用设置MOUSEEVENTF_MOVE来表明,dX和dy保留移动的信息。给出的信息是绝对或相对整数值。    如果指定了MOWSEEVENTF_ABSOLOTE值,则dX和dy含有标准化的绝对坐标,其值在0到65535之间。事件程序将此坐标映射到显示表面。坐标(0,0)映射到显示表面的左上角,(6553,65535)映射到右下角。    如果没指定MOWSEEVENTF_ABSOLOTE,dX和dy表示相对于上次鼠标事件产生的位置(即上次报告的位置)的移动。正值表示鼠标向右(或下)移动;负值表示鼠标向左(或上)移动。    鼠标的相对移动服从鼠标速度和加速度等级的设置,一个最终用户用鼠标控制面板应用程序来设置这些值,应用程序用函数SystemParameterslnfo来取得和设置这些值。    在应用加速时系统对指定相对鼠标移动提供了两个测试。如果指定的沿X轴y轴的距离比第一个鼠标阈值大,并且鼠标的加速等级非零,则操作系统将距离加倍。如果指定的沿X轴或y轴的距离比第二个鼠标阈值大,并且鼠标的加速等级为2,则操作系统将从第一个阈测试得来的距离加倍。这样就允许操作系统将指定鼠标沿X轴或y轴的相对位移加到4倍。    一旦应用了加速,系统用期望的鼠标速度换算合成的值。鼠标速度的范围是从1(最慢)到20(最快),并代表基于鼠标移动的距离指示符移动的数量。缺省值是10,表示对鼠标的移动设有附加的修改。    函数mouse_event需要用的应用程序用来合成鼠标事件。也被应用程序用来取得鼠标位置和鼠标按键状态之外的鼠标信息。例如,如果输入板制造商想将基于画笔的信息传给自己的应用程序,可以写一个直接与输入板硬件通信的动态键接库(DLL),获得附加的信息,并保存到一个队列中。DLL然后调用mouse_event,用标准按键和x/y位置数据,并在参数dwExtralnfo设置排列的附加信息的指针或索引。当应用程序需要附加信息时,调用DLL(连同存贮在dwEXtralnfo中的指针或索引),则DLL返回附加信息。    Windows CE:Windows CE不支持参数 dwFlags取MOOSE EVENTF WHEEL常数。    速查: Windows NT: 3.1及以上版本; Windows:95及以上版本;Windows CE:不支持;头文件:winuser.h;输入库:user32.lib。
      

  4.   

    我这移到外边也好使
    不知你的怎么回事
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TMainForm = class(TForm)
        Label1: TLabel;
        procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      MainForm: TMainForm;implementation{$R *.dfm}procedure TMainForm.FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      Label1.Caption := 'Mouse Down';
    end;procedure TMainForm.FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      Label1.Caption := 'Mouse Up';
    end;end.
      

  5.   

    我试验了一下,
    对于鼠标的左键,窗体的MouseDown和MouseUp事件是能够检测到的,
    而对于鼠标的右键,在移出了窗体后,窗体的MouseUp事件就没用了,
    解决方法是在MouseDown事件中调用SetCapture(Self.Handle),
    同时在MouseUp事件中调用ReleaseCapture。
    这是两个API函数,前一个被调用后,即使当前鼠标不在指定的窗口(此处为Self,即本窗体)上,此窗口也能够捕获到鼠标输入,其它窗口则无法捕获。
    后一个是释放捕获。
      

  6.   

    同意 netatomy(netatomy)地
    原因是在TControl的WMLButtonDown里用了SetCapture
    而在WMRButtonDown没有用SetCapture;procedure TControl.WMLButtonDown(var Message: TWMLButtonDown);
    begin
      SendCancelMode(Self);
      inherited;
      if csCaptureMouse in ControlStyle then MouseCapture := True;
      if csClickEvents in ControlStyle then Include(FControlState, csClicked);
      DoMouseDown(Message, mbLeft, []);
    end;procedure TControl.WMRButtonDown(var Message: TWMRButtonDown);
    begin
      inherited;
      DoMouseDown(Message, mbRight, []);
    end;所以除了象netatomy那样做外还可
    加两个响应WM_RBUTTONUP,WM_RBUTTONDOWN的代码如下procedure TForm1.WMRButtonDown(var Message: TWMRButtonDown);
    begin
      MouseCapture := True;
      Inherited;
    end;procedure TForm1.WMRButtonUp(var Message: TWMRButtonUp);
    begin
      MouseCapture := False;
      Inherited;
    end;