一个Panel的拖动问题,无论用OnMouseDown下面写 BeginDrag还是设置DragMode =dmAutomatic
都不能解决。Mouse的次序好像是MouseDown ,MouseClick,MouseUp的次序,我在MouseDown的时候
就已经激发了我的OnStartDrage,然后再OnClick也被屏蔽了,有没有什么办法,让Click发生在前面
先激发Click ,如果用按住鼠标在Panel上拖动一定的位置后,然后再激发BeginDrag ?

解决方案 »

  1.   

    click是mousedown+mouseup后激发的。。你在mousedown事件中写btn.click;
      

  2.   

    设一个全局布尔变量M,
    在MouseDown事件中置M为真,
    在MouseMove事件中,如果M为真,就通过改变Panel的Left与Top来移动
    在MouseUp中置M为假.
      

  3.   

    1.默认panel不可停靠
    2.mousedown事件判断鼠标位置,规定在某一个区域内激活停靠或托拽功能否则就是click,或者mousedown了一定时间激活停靠或拖拽否则就是click 
    3.如果开始停靠或托拽,则在最后onenddrag或onstartdrag事件中再禁止停靠或拖拽。
      

  4.   

    话虽如此,我需要的是实现。 
    我手上有个方法是用"钩子"来实现,太过麻烦。
    2.mousedown事件判断鼠标位置,规定在某一个区域内激活停靠或托拽功能否则就是click,或者mousedown了一定时间激活停靠或拖拽否则就是click 
    3.如果开始停靠或托拽,则在最后onenddrag或onstartdrag事件中再禁止停靠或拖拽。
      

  5.   

    试试这样能不能满足你的需要呢?
    procedure TForm1.Image1Click(Sender: TObject);
    begin
      memo1.Lines.Add('Click');
    end;procedure TForm1.Image1EndDrag(Sender, Target: TObject; X, Y: Integer);
    begin
      memo1.Lines.Add('EndDrag');
      image1.DragMode := dmManual;
    end;procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      image1.DragMode := dmAutomatic;
    end;Image1是被拖运控件,它的DragMode初始设置为dmManual
      

  6.   

    这样呢?
    当MouseDown时记录鼠标的起始位置,在MouseUp时判断是否鼠标还在原位置。如果在原位置,视为Click事件,否则视为拖动事件,处理代码则全部写在MouseUp事件里。
      

  7.   

    谢谢热情的 chenshusc(菜菜) 
    你上办法终非正道,难道没有一个看上去很好的答案?
      

  8.   

    Click是这样才会触发的:MouseDown,MouseUp.
      

  9.   

    >> jinjazz(近身剪(N-P攻略))
    本来可以CTRL拖动的,但是.....我这不是想知道解决办法嘛。
    >>fbysss(独孤求败) (
    OnMouseDown -> OnClick->OnMouseUp
    >> zxydelphi(xiaoyu)
    不是很明白你的意思,可否详细告知?
      

  10.   

    自己手工拖放,不要用自动模式,Down事件里面设置标志,并且纪录鼠标位置,UP事件取消标志,移动事件开始做拖放处理
      

  11.   

    >>快乐老猫(无米下炊) 
    注意我问题的第一句话:(一个Panel的拖动问题,无论用OnMouseDown下面写 BeginDrag还是设置DragMode =dmAutomatic都不能解决。)
      

  12.   

    能不能把需求在说详细一点?你是要实现Click->down->up>
      

  13.   

    tofbysss(独孤求败) ( )
    无关 Click->down->up>
    就像Windows那样。您Click的时候是选中一个文件夹,然后你点住文件夹,拖动鼠标,表示你要drag
    Delphi 中 DragMode =dmAutomatic 则OnClick失效
    如果在OnMouseDown中自己激发BeginDrag(False,-1)的形式,效果依然很差。
    不知道你明白没有,如果没有明白,你可以建立一个Application试验一下,看看效果就知道了
    btw:我在
    procedure TForm1.Button1StartDrag(Sender: TObject;
      var DragObject: TDragObject);
    begin
      //
    end;
    中处理了 拖动半透明阴影的,所以当我click按钮的时候,拖动阴影就出现了。
      

  14.   

    试试看,我刚写的,测试了。unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls;type
      TForm1 = class(TForm)
        Panel1: TPanel;
        Memo1: TMemo;
        procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure Panel1Click(Sender: TObject);
        procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      x1,y1: integer;
      flag: integer = 0;
    implementation{$R *.dfm}procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      //memo1.Lines.Append('MouseDown');
      x1:= X;
      y1:= Y;
      flag:= 1;
    end;procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      //memo1.Lines.Append('MouseUp');
      Panel1.Left := Panel1.Left+X-x1;
      Panel1.Top := Panel1.Top+Y-y1;
      flag:= 0;
    end;procedure TForm1.Panel1Click(Sender: TObject);
    begin
      memo1.Lines.Append('MouseClick');
    end;procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      //memo1.Lines.Append('MouseMove');
      if flag=1 then
      begin
      Panel1.Left := Panel1.Left+X-x1;
      Panel1.Top := Panel1.Top+Y-y1;
      end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      DoubleBuffered:= true;
    end;end.
      

  15.   

    TO: xixuemao(吸血猫) 
    和我的要求相差甚远。 你这是一个Panel跟随鼠标位置。我的拖动阴影是通过继承TDragControlObject来实现了。
    我的MainForm上动态创建了N个(数据库内的记录数)Frame,Fame上有数个Panel,
    panel实现了拖动,这些都没有问题,Panel的Click没法用了。
      

  16.   

    procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      ReleaseCapture;
      Panel1.Perform(WM_SYSCOMMAND,$f012,0);
    end;
      

  17.   

    To :chenylin(陈SIR) 
    这个方法用Delphibbs的离线资料一查大把大把
    而且该方法和我问题无关
      

  18.   

    TO : phy(被爱捶死)
    不晚,问题还没有解决啊
    上面的回答很少有看清我的题意的,大多数都是来混分的。
    简直够呛
      

  19.   

    我证明,确实是先MouseDown,再Click再MouseUp的,实验出来的。*^_^*
    可能我业没有明白楼主的意思,我想可不可以这样,
    procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      Panel1.BeginDrag(false,50); //呵呵,把延迟时间设计的长一些
    end;
      

  20.   

    Starts the dragging of a control.Delphi syntax:procedure BeginDrag(Immediate: Boolean; Threshold: Integer = -1);C++ syntax:void __fastcall BeginDrag(bool Immediate, int Threshold = -1);DescriptionCall BeginDrag to start a drag operation. BeginDrag is called in application code only when the value of the control’s DragMode is dmManual. If DragMode is dmAutomatic, BeginDrag is called automatically.If the Immediate parameter is true, the mouse pointer changes to the value of the DragCursor property and dragging begins immediately. If Immediate is false, the mouse pointer doesn't change to the value of the DragCursor property and dragging doesn't begin until the user moves the mouse pointer the number of pixels specified by the Threshold parameter. If the caller passes a Threshold value less than 0 (such as the default value for this parameter), BeginDrag uses the DragThreshold property of the global Mouse variable.Setting Immediate to false allows the control to accept mouse clicks without beginning a drag-and-drop or drag-and-dock operation.
      

  21.   

    to :fayeflash(我爱阿菲) 
    的确是那样,我 Panel1.BeginDrag(false,100)
    都试过了,结果一样的,因为我加了拖动阴影效果的处理代码(和Windows拖动那样,跟随鼠标
    有一个半透明的选中图标的阴影),所以出现的情况是 : 在 Panel上Click 立刻可以看到一个大大的阴影(如果仅仅使用Delphi默认的拖动效果就不会出现那样的情况),这是我不想出现的效果。
    因为不管你延迟多少秒,最后你还是要调用BeginDrag,还是会激发OnStartDrag,而在StartDrag里面我就会绘制那个拖动阴影。所以出现了这个情况,这个是我不想看到的。不过今天我已经解决了这个问题。谢谢各位关注:我用了一个笨办法解决的 Mouse Down 后 peekMessage ,
    然后 GetCursorPos,判断光标的位移量,如果 + - 5,才开始BegingDrag,否则不Drag ,其实DelphiBBS上早有人问过类似的问题,如果你试验一下就能看到效果。
    var
      StartPoint, CurMouse: TPoint;
      TheMessage: TMSG;
      xInt, yInt: integer;
    begin
      if Button <> mbLeft then Exit;
      GetCursorPos(StartPoint);
      while not peekMessage(theMessage, Handle, WM_LBUTTONUP, WM_LBUTTONUP, PM_NOREMOVE) do
      begin
        GetCursorPos(curMouse);
        xInt := CurMouse.X - StartPoint.X;
        yInt := CurMouse.y - StartPoint.y;
        if ((xInt > 5) or (xInt < -5)) or ((yInt > 5) or (yInt < -5)) then
        begin
          RzPnlInfo.BeginDrag(False, -1);
          Break;
        end else Self.IcoBtn.Click;  end;
    end;
      

  22.   

    TO : Sorder(剑客) 
    谢谢你Copy 帮助文档给我,我想按F1查询我还是可以的!
      

  23.   

    把onclick里面的东西写到onStartDrag里就可以了
      

  24.   

    To :jinjazz(近身剪(N-P攻略)) 
      谢谢关注
      主要是解决拖动阴影,而非Click!故而,不能直接在OnDrag里面Click