本人作了一个界面,上有 label和edit,我想用鼠标可以托动他的位置,选中控件之后,让他变色(以示被选中),用CTRL+ARROW(方向键),也可以移动他(微调)
另外一个我不明白
   drag 和 DOCK  的区别?
还有以下不太明白:
onstartdrag
onstartdock
ondockdrop
ondockover
ondragover
ondragdrop
onenddock
onenddrag
                    ongetsiteinfo
onmousedown
onmousemove
onmouseup
onstartdock
onstartdrag
onundock

解决方案 »

  1.   

    新建一个工程,在窗体体上放一个Panel组件和一个Label组件,然后分别设置他们的DragMode属性为dmAutomatic,然后定义全局变量 xpanel,ypanel,xlabel,ylabel:Integer;
    在Label的MouseMove和EndDrag事件,在Panel1的DragOver事件中键入下面的代码:
    procedure TForm1.Label1MouseMove(Sender: TObject; Shift: TShiftState; X,
    Y: Integer);
    begin
    xlabel:=x;
    ylabel:=y;
    end;procedure TForm1.Label1EndDrag(Sender, Target: TObject; X, Y: Integer);
    begin
    Label1.Left:=xpanel-xlabel;
    Label1.Top:=ypanel-ylabel;
    end;procedure TForm1.Panel1DragOver(Sender, Source: TObject; X, Y: Integer;
    State: TDragState; var Accept: Boolean);
    begin
    xpanel:=x;
    ypanel:=y;
    end;
      

  2.   

    Delphi中停靠技术的实现 
    作者:  评价:  上站日期: 2002-05-22  
    内容说明:  
    来源:  --------------------------------------------------------------------------------随着软件技术的不断进步,软件界面也越来越美观,操作也越来越方便。综观市面上比较专业的各种软件,我们会发现大部分都提供窗体停靠的功能,特别象工具软件,基本上都或多或少有停靠功能。自然,Delphi也支持停靠,而且她和VCL紧密结合,对于广大的Delphi程序员来说更是一大福音。让我们省去枯燥的编码时间。把注意力集中在核心程序的构思上。 先让我们来复习一下VCL的结构,在TWinControl类中有一个DockSite属性(boolean),它的作用是是否允许别的控件停靠在它的上面,在TControl类中有一个DragKind属性,如果要这个控件能停靠在别的控件上,就把DragKind属性设成dkDock。就这么简单,只要设置一下属性,一个支持停靠的程序就完成了。当然,上面说的只是最最基本的步骤,有了以上两步,我们就可以继续编写代码实现更复杂的功能。一般的支持停靠的程序都可以在主窗口的上下左右停靠,也就是说在主窗口的边上放上能被停靠的控件比较好(只要是从TWinControl继承的都行),一般我们都选择TPanel,为了便于读者理解,我们可以假定主窗口的左边可以停靠,所以在主窗口上放一个Align属性为alLeft的Panel,取名为LeftDockPanel,宽度为0,DockSite属性为True,当然我们的LeftDockPanel应该是可以改变大小的,所以在它右边再放一个TSplitter,取名为LeftSplitter,Align属性为alLeft。接下来就是停靠控件了,一般的程序停靠控件都是窗体,所以我们也建一个窗体,取名叫DockableForm,DragKind属性设成dkDock,DragMode属性设为dmAutomatic(自动停靠)。现在我们可以运行这个程序了,什么?效果不好?停靠的窗体停靠停靠进去后就不见了! 哦,我差点忘了,当停靠窗体停靠时Delphi会产生一些事件,他们分别是1.OnDockOver(Sender: TObject; Source: TDragDockObject;      X, Y: Integer; State: TDragState; var Accept: Boolean);2.OnDockDrop(Sender: TObject; Source: TDragDockObject;      X, Y: Integer);3.OnGetSiteInfo(Sender: TObject; DockClient: TControl;      var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);4.OnStartDock(Sender: TObject;      var DragObject: TDragDockObject);5.OnEndDock(Sender, Target: TObject; X, Y: Integer);6.OnUnDock(Sender: TObject; Client: TControl;      NewTarget: TWinControl; var Allow: Boolean);哇,这么多,别急,让我细细道来:先让我们来看看第一个事件OnDockOver是在停靠控件(DockableForm)掠过被停靠控件(LeftDockPanel)时触发的。Source包含了停靠—拖动操作的信息,其中有一个重要的属性是Control,就是DockableForm,另一个重要的属性是DockRect,就是停靠的位置;X,Y是鼠标的位置,State的状态有dsDragEnter, dsDragLeave, dsDragMove,分别表示拖动进入,拖动离开,拖动移动;Accept是是否同意停靠的意思。OnDockOver事件主要作用是控制停靠窗体的预览位置,下面我们来加入以下代码:procedure TMainForm.LeftDockPanelDockOver(Sender: TObject;  Source: TDragDockObject; X, Y: Integer; State: TDragState;  var Accept: Boolean);var  ARect: TRect;begin  Accept := Source.Control is TDockableForm;  if Accept then  begin//修改预览停靠位置    ARect.TopLeft := LeftDockPanel.ClientToScreen(Point(0, 0));    ARect.BottomRight := LeftDockPanel.ClientToScreen(      Point(Self.ClientWidth div 3, LeftDockPanel.Height));    Source.DockRect := ARect;  end;end; 现在再运行程序,当你把DockableForm拖动到主窗口左边时,已经出现了预览停靠位置,也就是虚线包含的范围。怎么?窗体又不见了?那当然了,我们只是讲了OnDockOver,还没详细讲解OnDockDrop呢,它才是决定停靠窗体在哪里出现的罪魁祸首:OnDockDrop(Sender: TObject;  Source: TDragDockObject; X, Y: Integer);参数和OnDockOver差不多,只是少了State: TDragState和var Accept: Boolean它是在停靠窗体进入被停靠控件时发生的,作用是控制停靠窗体的最终位置。下面添加如下代码:procedure TMainForm.LeftDockPanelDockDrop(Sender: TObject;  Source: TDragDockObject; X, Y: Integer);Begin  LeftDockPanel.Width := ClientWidth div 3;  LeftSplitter.Left := LeftDockPanel.Width + LeftSplitter.Width;End;现在再运行程序,哇塞,成功了。出现了一个和Delphi的IDE完全一样的停靠窗体,上面是两条横线,用来把它拖出来,右上角有一个小X是用来关闭的。不过好景不长,当我们把它关闭时,装载DockableForm的LeftDockPanel不能还原,还是霸占着主窗口的客户区,怎么办?嘻嘻,忘了告诉你们了,其实Delphi早就为我们作好了一切。请打开DockableForm的关闭事件,你会发现原来当你点击右上角那个小X关闭DockableForm时,它会触发DockableForm的OnClose事件,在OnClose事件中把LeftDockPanel的宽度设为0就行了。procedure TDockableForm.FormClose(Sender: TObject;  var Action: TCloseAction);begin  MainForm.LeftDockPanel.Width := 0;  Action := caHide;end; 
      
      

  3.   

    以上所讲的是如何在主窗口上停靠窗体,原代码都通过测试。同理,我们可以在主窗口的右边,下边,上边都实现停靠功能。对了,刚才我们只介绍了OnDockOver和OnDockDrop,忘了介绍别的事件,下面简单介绍一下:3.OnGetSiteInfo(Sender: TObject; DockClient: TControl;      var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);这个事件是在窗体移动时触发的,所以经常触发,它里面的DockClient就是TDockableForm,有一个引用参数叫CanDock,和OnDockOver中的Accept差不多,都是询问是否允许停靠。在这里可以不写,CanDock默认就是True,也可以写上CanDock := DockClient is TDockableForm; 4.OnStartDock(Sender: TObject;      var DragObject: TDragDockObject);5.OnEndDock(Sender, Target: TObject; X, Y: Integer);6.OnUnDock(Sender: TObject; Client: TControl;      NewTarget: TWinControl; var Allow: Boolean);这三个事件都是在DockableForm上面有用,意思分别是停靠开始,停靠结尾,不停靠(也就是被拖出来时)。OnStartDock和OnEndDock经常会被触发,OnUnDock只在停靠窗体变成浮动时触发  讲了那么多,大家有没有被搞糊涂?那好,我来做一下总结:在Delphi中只要是从TWinControl继承的控件都支持被停靠(如上面的LeftDockPanel),也就是有DockSite这个属性;所有从TControl继承的控件都支持停靠(如上面的DockableForm),也就是有DragKind这个属性.所以支持被停靠的控件都支持停靠,支持停靠的控件不一定支持被停靠,道理很简单,因为TWinControl继承于TControl。OnDockOver事件是控制停靠窗体的预览位置;OnDockDrap事件是控制停靠窗体的最终位置;OnGetSiteInfo是询问是否可以停靠;OnStartDock是停靠开始,OnEndDock是停靠结尾,OnUnDock是不停靠(也就是被拖出来时)。 想必Delphi用的熟的大虾都知道在Delphi的可停靠窗体间可以相互停靠,而且花样还很多,可以停靠成并排的,也可以停靠成PageControl样式的,两个可停靠窗体合并后的窗体又可以再和别的可停靠窗体合并,形成树状。下面来介绍这方面的技术:说道这里,我们不得不介绍一下CM_DOCKCLIENT消息和TCMDockClient结构,CM_DOCKCLIENT消息和TCMDockClient结构是相互对应的,TCMDockClient的结构是:  TCMDockClient = packed record    Msg: Cardinal;    DockSource: TDragDockObject;    MousePos: TSmallPoint;    Result: Integer;  end;其中DockSource包含了停靠—拖动操作的信息,前面已经提到过;MousePos是鼠标的位置。CM_DOCKCLIENT事件在停靠和被停靠控件都可以捕获,因为它是TWinControl类发出的,代码如下:procedure TWinControl.DockDrop(Source: TDragDockObject; X, Y: Integer);begin  if (Perform(CM_DOCKCLIENT, Integer(Source), Integer(SmallPoint(X, Y))) > = 0)    and Assigned(FOnDockDrop) then    FOnDockDrop(Self, Source, X, Y);end; 可以看出,TWinControl是先发送DOCKCLIENT消息,再触发OnDockDrop事件的。为了演示可停靠窗体之间相互停靠,我们先创建一个宿主窗体,取名叫TiledHost,把它的DockSite设成True。它的作用是用来装载两个DockableForm的。首先在DockableForm中捕获DOCKCLIENT消息,在里面完成两个窗体的相互停靠声明:privateprocedure CMDockClient(var Message: TCMDockClient); message CM_DOCKCLIENT;end; 实现:procedure TDockableForm.CMDockClient(var Message: TCMDockClient);var  Host: TForm;begin  if Message.DockSource.Control is TDockableForm then  beginHost := TTiledHost.Create(Application);    Host.BoundsRect := Self.BoundsRect;    Self.ManualDock(Host, nil, alNone);    Self.DockSite := False;    Message.DockSource.Control.ManualDock(Host, nil, alNone);    TDockableForm(Message.DockSource.Control).DockSite := False;    Host.Visible := True;End;end;先解释一下上面的代码,首先创建TTiledHost的实例,然后用ManualDock函数把自己停靠到TTiledHost,把Message.DockSource.Control也停靠到TTiledHost,这样就完成了窗体的相互停靠,当然,要是我们要程序产生停靠的预览效果,就在DockableForm的OnDockOver事件里加入代码:procedure TDockableForm.FormDockOver(Sender: TObject;  Source: TDragDockObject; X, Y: Integer; State: TDragState;  var Accept: Boolean);var  ARect: TRect;begin  Accept := Source.Control is TDockableForm;  if Accept then  begin    ARect.TopLeft := ClientToScreen(Point(0, 0));    ARect.BottomRight := ClientToScreen(      Point(ClientWidth div 2, ClientHeight));    Source.DockRect := ARect;  end;end; 怎么样,效果还可以吧。对了,需要注意的是,用ManualDock函数可以安全的完成停靠功能,不要用Dock函数。ManualDock函数有一些参数:function ManualDock(NewDockSite: TWinControl; DropControl: TControl = nil; ControlSide: TAlign = alNone): Boolean;NewDockSite:要被停靠的窗体;DropControl:已经存在于NewDockSite的TControl,在这里可以把它设成nil;ControlSide: 停靠的位置,可以是上,下,左,右,全部等。 当然,我们也可以让TiledHost也具有和LeftDockPanel一样有被停靠的功能,只要把TiledHost看成前面的LeftDockPanel,添加一些属性和事件;把TiledHost看成DockableForm,就可以有停靠的功能了。具体的做法这里不再阐述了,相信对VCL有深刻研究的大虾都知道怎么做了。
      

  4.   

    创建一个 Panel,再创建一个Label,通过编程使控件 Lable 可以在 Panel 中被拖放到任
    意位置。以下是具体实现过程:
      1. 首先做一下准备工作,运行Delphi,进入集成开发环境,在 File 菜单中选择New 
    Application 。
      2. 在Form1中创建对象 Panel1,并在 Panel1 中创建另一对象 Label1。
      3. 选中Label1,修改其下列属性的值: 
                 属性值:
                 Caption    :标签移动测试!
                 Cursor     :crHandPoint
                 DragCursor:crDrag
                 DragMode   :dmAutomatic
      4.在程序的开头部分声明全局变量 x_panel,y_panel,x_label,y_label,其中,x_panel,y_panel :
    鼠标在Panel1上的坐标;x_label,y_label :鼠标在label1上的坐标。
      注:这里分别获取在Panel1和Label1上的坐标是为了更精确地计算出Label1实际的移动距离。
      5.在Panel1的OnDragOver 和OnMouseMove 事件中添加如下代码:
         x_panel:=X;
        y_panel:=Y;
       注:该操作是获得 mouse 在Panel1上的坐标。
      6.在Label1的OnMouseMove 事件中添加如下代码:
         x_Labell:=X;
         y_Label1:=Y;
         注:该操作是获得 mouse 在Label1上的坐标。 
      7.在Label1的OnEndDrag 事件中添加如下代码:
         label1.left :=x_panel-x_label;
         label1.top :=y_panel-y_label; 
         说明:两者相减是为了求得 label1 实际的移动距离。 
      8.创建一个对象 Button1 ,并在其 OnClick 事件中添加如下代码:
         close; //用以关闭应用程序。
      好了,现在运行程序,测试一下结果。
      以下是程序源代码,在Delphi3.0、Windows9598中测试通过。
    unit test_move;
    interface
    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, ExtCtrls;
    type
      TForm1 = class(TForm)
      Panel1: TPanel;
      Label1: TLabel;
      Button1: TButton;
      procedure Button1Click(Sender: TObject);
      procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
      procedure Panel1DragOver(Sender, Source: TObject; X, Y: Integer;
                State: TDragState; var Accept: Boolean);
      procedure Label1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
      procedure Label1EndDrag(Sender, Target: TObject; X, Y: Integer);
    private
      { Private declarations }
    public
      { Public declarations }
      x_panel,y_panel,x_label,y_label:integer;
    end;
    var
      Form1: TForm1;
    implementation
    {$R *.DFM}
    procedure TForm1.Button1Click(Sender: TObject);
    begin
       close;
    end;
    procedure FTorm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState;X,Y: Integer);
    begin
       x_panel:=X;
       y_panel:=Y;
    end;
    procedure TForm1.Panel1DragOver(Sender, Source: TObject; X, Y: Integer;
              State: TDragState; var Accept: Boolean);
    begin
       x_panel:=X;
       y_panel:=Y;
    end;
    procedure TForm1.Label1MouseMove(Sender: TObject; Shift: TShiftState;X,Y: Integer);
    begin
       x_label:=X;
       y_label:=Y;
    end;
    procedure TForm1.Label1EndDrag(Sender, Target: TObject; X, Y: Integer);
    begin
      label1.left :=x_panel-x_label; 
      label1.top:=y_panel-y_label; 
    end;
    end.
      

  5.   

    在应用程序的开发中,常常要将某些控件对象(如标签)用鼠标选中后进行拖动操作,用以改变控件的位置,在Delphi中如何实现这一功能呢?笔者想了一个方法:通过在 public 中定义全局变量用以跟踪 鼠标在移动和拖动控件时的坐标,然后在拖动结束时将鼠标的坐标值赋给控件的 TOP和LEFT属性,以达到拖动的目的。
      举例如下:创建一个 Panel,再创建一个Label,通过编程使控件 Lable 可以在 Panel 中被拖放到任意位置。以下是具体实现过程:
      1.首先做一下准备工作,运行Delphi3.0,进入集成开发环境,在 File 菜单中选择New Application 。
      2.在Form1中创建对象 Panel1,并在 Panel1 中创建另一对象 Label1。
      3.选中Label1,修改其下列属性的值: 
    属性 值
    Caption : 标签移动测试!
    Cursor : crHandPoint
    DragCursor : crDrag
    DragMode : dmAutomatic
      4.在程序的开头部分声明全局变量 x_panel,y_panel,x_label,y_label
      其中,x_panel,y_panel :鼠标在Panel1上的坐标。
      x_label,y_label :鼠标在label1上的坐标。
      注:这里分别获取在Panel1和Label1上的坐标是为了更精确地计算出Label1实际的移动距离。
      5.在Panel1的OnDragOver 和OnMouseMove 事件中添加如下代码:
      x_panel:=X;
      y_panel:=Y;
      注:该操作是获得 mouse 在Panel1上的坐标。
      6.在Label1的OnMouseMove 事件中添加如下代码:
      x_Labell:=X;
      y_Label1:=Y;
      注:该操作是获得 mouse 在Label1上的坐标。 
      7.在Label1的OnEndDrag 事件中添加如下代码:
      label1.left :=x_panel-x_label;
      label1.top :=y_panel-y_label; 
      说明:两者相减是为了求得 label1 实际的移动距离。 
      8.创建一个对象 Button1 ,并在其 OnClick 事件中添加如下代码:
      close; 用以关闭应用程序。
      好了,现在运行程序,测试一下结果。
      以下是程序源代码,在Delphi3.0、Windows95/98中测试通过。
    unit test_move;
    interface
    uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    StdCtrls, ExtCtrls;
    type
    TForm1 = class(TForm)
    Panel1: TPanel;
    Label1: TLabel;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
    procedure Panel1DragOver(Sender, Source: TObject; X, Y: Integer;
    State: TDragState; var Accept: Boolean);
    procedure Label1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
    procedure Label1EndDrag(Sender, Target: TObject; X, Y: Integer);
    private
    { Private declarations }
    public
    { Public declarations }
    x_panel,y_panel,x_label,y_label:integer;
    end;
    var
    Form1: TForm1;
    implementation
    {$R *.DFM}
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    close;
    end;
    procedure FTorm1.Panel1MouseMove
    (Sender: TObject; Shift: TShiftState; 
    X,Y: Integer);
    begin
    x_panel:=X;
    y_panel:=Y;
    end;
    procedure TForm1.Panel1DragOver(Sender, Source: TObject; X, Y: Integer;
    State: TDragState; var Accept: Boolean);
    begin
    x_panel:=X;
    y_panel:=Y;
    end;
    procedure TForm1.Label1MouseMove(Sender: TObject; Shift: TShiftState;
    X,Y: Integer);
    begin
    x_label:=X;
    y_label:=Y;
    end;
    procedure TForm1.Label1EndDrag(Sender, Target: TObject; X, Y: Integer);
    begin
    label1.left :=x_panel-x_label; 
    label1.top:=y_panel-y_label; 
    end;
    end.
      

  6.   

    I follow you!
    抄袭就是这样疯狂,原来他是继承了父类的特性,有过之而不及。
    在学校时,你们怎莫考试的!
    等一下结贴
    然我也研究研究!
      

  7.   

    //begin drag
    procedure TFMForm.FileListBox1MouseDown(Sender: TObject;
    Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    begin
      if Button = mbLeft then { drag only if left button pressed }
      with Sender as TFileListBox do { treat Sender as TFileListBox }
      begin
        if ItemAtPos(Point(X, Y), True) >= 0 then { is there an item here? }
        BeginDrag(False); { if so, drag it }
      end;
    end;
      

  8.   

    我手头有个文章,但我按照里面的做法没有成功,不知道怎么搞的!?It's very simple - so don't try to write hundreds of lines to solve this problem just take a look at this small source-snip all what we need to do is to override the dynamic MouseDown method of the TControl-BaseClass and fire an WM_SysCommand event with the magicKey $F012. I hope this article is helpful for you .... for feedback - please rate regards Boris Benjamin Wittfoth {----------------------------------------------------------------------------- 
    hEaDRoOm Development 
    29.10.2002 Unit Name: HREdit 
    Author:    Benjamin Benjamin Wittfoth 
    Purpose: 
    History: 
    -----------------------------------------------------------------------------} 
    unit HREdit; interface uses 
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
      StdCtrls; type 
      THREdit = class(TEdit) 
      private 
        fDragable:Boolean; 
      protected 
        procedure MouseDown(Button: TMouseButton;Shift: TShiftState; X, Y: Integer);override; 
      public 
        Constructor Create(AOwner:TComponent);override; 
        Destructor Destroy;override; 
      published 
        property Dragable:Boolean read fDragable write fDragable; 
      end; procedure Register; implementation procedure Register; 
    begin 
      RegisterComponents('HEADROOM DEVELOPMENT', [THREdit]); 
    end; { THREdit } 
    constructor THREdit.Create(AOwner: TComponent); 
    begin 
      inherited Create(AOwner); 
    end; destructor THREdit.Destroy; 
    begin 
      inherited; 
    end; procedure THREdit.MouseDown(Button: TMouseButton; Shift: TShiftState; X, 
      Y: Integer); 
    const 
      SC_DragMove = $F012; // important key  !! 
    begin 
      inherited; 
      if assigned(onMouseDown)then 
        OnMouseDown(self,Button,Shift,x,y); 
      if fDragable then 
      begin 
        ReleaseCapture; 
        (self as TControl).perform(WM_SysCommand, SC_DragMove, 0); // this is the key ! 
      end; 
    end; end.
      

  9.   

    上面这个代码我是在www.delphi3000.com的文档中心看到的,但我实验以后不起作用首先WM_SYSCOMMAND的消息参数中没有SC_DRAGMOVE,我换成SC_MOVE也不可以!大家看看,解决了告诉偶一声
      

  10.   

    这种东西有很多种实现方法,各有优缺点。
    1、
    releasecapture;
    perform(wm_syscommand, $f012, 0);
    最简单,但是很难实现一些特殊的效果
    2、自己写控制类,通过记录鼠标位置的变化实现移动
    效果折中,要求容器支持canvas。
    3、完全靠自己画图实现
    可以实现各种复杂的效果,但需要自己写很多代码(我的程序中是以着种方法实现移动的)
      

  11.   

    很简单,就需要几行代码,听好了首先定义一个全局变量
    var
      FMouseIsDown: Boolean;然后给你要移动的控件写三个事件处理函数(OnMouseDown, OnMouseUp, OnMouseMove):OnMouseDown中写:
      FMouseIsDown := True;OnMouseUp中写:
      FMouseIsDown := False;OnMouseMove中写:
      if FMouseIsDown and (Sender is TWinControl) then
      begin
        ReleaseCapture;
        SendMessage((Sender as TWinControl).Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
      end;行了,玩去吧!
      

  12.   

    楼上两位朋友,看看我前面发的那个帖子,为什么那个使用MagicKey的方法实现不了?
      

  13.   

    上面这个代码我是在www.delphi3000.com的文档中心看到的,但我实验以后不起作用首先WM_SYSCOMMAND的消息参数中没有SC_DRAGMOVE,我换成SC_MOVE也不可以!大家看看,解决了告诉偶一声
    ----------------------------------------------------------------------------------
    SC_DRAGMOVE是自己定义的一个常量,系统中当然没有。
    const 
      SC_DragMove = $F012; // important key  !! 
    SC_MOVE 是系统定义的常量
    SC_MOVE = $F010;
    WM_SYSCOMMAND可以接受的参数大概有9个(与窗体移动相关),[$F001..$F008, $F012]
      

  14.   

    只要写一个 事件就可以轻松 解决
    procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    const SC_DragMove=$f012;
    begin
    ReleaseCapture;
    Panel1.perform(WM_SysCommand, SC_DragMove, 0); // this is the key !end;我解决了 其实对于所有有perform方法的都可以行得通的 包括窗体
      

  15.   

    onmousedown ->onmouseup 时成对德吗?
      

  16.   

    我已经做成了用键盘方向健空指标单上的控件(10 个label),自由随便移动。就是鼠标以移动,被移动的空件自动跑倒左上角,没办法!
      

  17.   

    你这个问题我也有过,你要把坐标从ScreenToClient才行。
      

  18.   

    这么简单的问题,尽然惹来这么多个?
    而且,一个个都是Copy Code的高手。
      

  19.   

    To DSenhorSoft  有本事你就解决,不要在这里跌凉话!什么叫简单,问题不被思考,不被讨论永远都不会变简单....
      

  20.   

    哎!
    我学delphi的第14天,碰到这样的事!
      

  21.   

    各位大哥,前辈,你们真是大学而小遗啊!看看以下代码吗!
    procedure TForm1.Button3MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
      var SC_MANIPULATE: Word;
      Control: TControl;
    begin
     if (X<Control.Width-5) and (Y<Control.Height)   then
       begin
             SC_MANIPULATE  := $F009;
             Control.Cursor := crSizeAll;
           end
      else begin
             SC_MANIPULATE := $F000;
             Control.Cursor := crDefault;
           end;
     if Shift=[ssLeft] then
      begin
        ReleaseCapture;
        Control.Perform(WM_SYSCOMMAND, SC_MANIPULATE, 0);
      end;
    end;