我是采取写控件的TOP和LEFT的方法,来做的,还要判断鼠标是上移还是下移,左移或右移,然后加减控件的TOP和LEFT,但我想应该有更好的办法。
  我看了有个onStartDrag 和OnEndDrag, 等事件的,这和移动有些关系吗,这个事件我没用过,手头也没相关资料查询,所以象兄弟们请教了。

解决方案 »

  1.   

    onStartDrag 和OnEndDrag 都是从TControl类派生的!OnStartDrag  发生在用户开始拖动时,向引起拖动操作的组件发送 OnEndDrag    发生在拖动终止时,该事件由启动拖动操作的组件发送 
      

  2.   

    OnStartDrag  发生在用户开始拖动时,向引起拖动操作的组件发送 
    OnEndDrag    发生在拖动终止时,该事件由启动拖动操作的组件发送 
      

  3.   

    举例如下:创建一个 Panel,再创建一个Label,通过编程使控件 Lable 可以在 Panel 中被拖放到任
    意位置。以下是具体实现过程:  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
      

  4.   

    楼上的既给出Delphi代码,我就给出BCB代码:
    界面上有一个按钮和一个Edit
    .h File
    #ifndef movecontrolruningH
    #define movecontrolruningH
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    class TForm1 : public TForm
    {
    __published: // IDE-managed Components
            TEdit *Edit1;
            TButton *Button1;
            void __fastcall Edit1MouseMove(TObject *Sender, TShiftState Shift,
              int X, int Y);
            void __fastcall Button1MouseMove(TObject *Sender,
              TShiftState Shift, int X, int Y);
    private: // User declarations
    public: // User declarations
            __fastcall TForm1(TComponent* Owner);
    };
    extern PACKAGE TForm1 *Form1;
    #endif
    .cpp File
    #include <vcl.h>
    #pragma hdrstop
    #include "movecontrolruning.h"
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    void __fastcall TForm1::Edit1MouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
            WORD SC_DragMove=0xF012;
            ReleaseCapture();
            ((TWinControl*)Sender)->Perform(WM_SYSCOMMAND,SC_DragMove,0);
    }
    void __fastcall TForm1::Button1MouseMove(TObject *Sender,
          TShiftState Shift, int X, int Y)
    {
            WORD SC_DragMove=0xF012;
            ReleaseCapture();
            ((TWinControl*)Sender)->Perform(WM_SYSCOMMAND,SC_DragMove,0);}
      

  5.   

    楼上的既给出Delphi代码,我就给出BCB代码:
    界面上有一个按钮和一个Edit
    .h File
    #ifndef movecontrolruningH
    #define movecontrolruningH
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    class TForm1 : public TForm
    {
    __published: // IDE-managed Components
            TEdit *Edit1;
            TButton *Button1;
            void __fastcall Edit1MouseMove(TObject *Sender, TShiftState Shift,
              int X, int Y);
            void __fastcall Button1MouseMove(TObject *Sender,
              TShiftState Shift, int X, int Y);
    private: // User declarations
    public: // User declarations
            __fastcall TForm1(TComponent* Owner);
    };
    extern PACKAGE TForm1 *Form1;
    #endif
    .cpp File
    #include <vcl.h>
    #pragma hdrstop
    #include "movecontrolruning.h"
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    void __fastcall TForm1::Edit1MouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
            WORD SC_DragMove=0xF012;
            ReleaseCapture();
            ((TWinControl*)Sender)->Perform(WM_SYSCOMMAND,SC_DragMove,0);
    }
    void __fastcall TForm1::Button1MouseMove(TObject *Sender,
          TShiftState Shift, int X, int Y)
    {
            WORD SC_DragMove=0xF012;
            ReleaseCapture();
            ((TWinControl*)Sender)->Perform(WM_SYSCOMMAND,SC_DragMove,0);}
      

  6.   

    //==============================================================================//任意摆布一个控件(拖动、放大、缩小)******************************************//==============================================================================procedure ManipulateControl(Control: TControl; Shift: TShiftState; X, Y, Precision: integer);var SC_MANIPULATE: Word;begin//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//光标在控件的最左侧**********************************************************//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~if (X<=Precision) and (Y>Precision) and (Y<Control.Height-Precision)then beginSC_MANIPULATE := $F001;Control.Cursor := crSizeWE;end//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//光标在控件的最右侧**********************************************************//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~else if (X>=Control.Width-Precision) and (Y>Precision) and (Y<Control.Height-Precision)then beginSC_MANIPULATE := $F002;Control.Cursor := crSizeWE;end//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//光标在控件的最上侧**********************************************************//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~else if (X>Precision) and (X<Control.Width-Precision) and (Y<=Precision)then beginSC_MANIPULATE := $F003;Control.Cursor := crSizeNS;end//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//光标在控件的左上角**********************************************************//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~else if (X<=Precision) and (Y<=Precision)then beginSC_MANIPULATE := $F004;Control.Cursor := crSizeNWSE;end//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//光标在控件的右上角**********************************************************//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~else if (X>=Control.Width-Precision) and (Y<=Precision)then beginSC_MANIPULATE := $F005;Control.Cursor := crSizeNESW ;end//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//光标在控件的最下侧**********************************************************//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~else if (X>Precision) and (X<Control.Width-Precision) and (Y>=Control.Height-Precision)then beginSC_MANIPULATE := $F006;Control.Cursor := crSizeNS;end//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//光标在控件的左下角**********************************************************//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~else if (X<=Precision) and (Y>=Control.Height-Precision)then beginSC_MANIPULATE := $F007;Control.Cursor := crSizeNESW;end//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//光标在控件的右下角**********************************************************//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~else if (X>=Control.Width-Precision) and (Y>=Control.Height-Precision)then beginSC_MANIPULATE := $F008;Control.Cursor := crSizeNWSE;end//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//光标在控件的客户区(移动整个控件)******************************************//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~else if (X>5) and (Y>5) and (X<Control.Width-5) and (Y<Control.Height-5)then beginSC_MANIPULATE := $F009;Control.Cursor := crSizeAll;endelse beginSC_MANIPULATE := $F000;Control.Cursor := crDefault;end;//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~if Shift=[ssLeft] thenbeginReleaseCapture;Control.Perform(WM_SYSCOMMAND, SC_MANIPULATE, 0);end;end;  example://~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~procedure TForm_Main.Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);beginCaption := IntToStr(X) + '/' + IntToStr(Y);ManipulateControl((Sender as TControl), Shift, X, Y, 10);end; 10为精度
      

  7.   

    kingcaiyao(AKing)   您提供的方法我试过了,API是不错,很好用,
    另外要调整控件的大小,包括宽度,高度,有什么简洁的代码吗,BCB的也可以,谢谢。
      

  8.   

    另外 IORILI(眼镜@_@) 提供的代码我也测试了,也可以用,就是移动时,没有一个虚框显示,这样位置不是很确切。 :)
      

  9.   

    以下这段代码是可以用的,但在编辑框的周围多出个方框来,怎么样能够去掉呢
    ::SetWindowLong(Edit1->Handle, GWL_STYLE, dwStyle | WS_SIZEBOX);
    是其中的  WS_SIZEBOX出现周围一个凸出的虚框的,怎么样才能去掉呢,我应该把
    WS_SIZEBOX改成什么才可以,我改了其它的,好象也不行,
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    //修改此单字符串窗口组件性质,可自由缩放大小
    DWORD dwStyle = ::GetWindowLong(Edit1->Handle, GWL_STYLE);
    ::SetWindowLong(Edit1->Handle, GWL_STYLE, dwStyle | WS_SIZEBOX);
    //修正此单字符串窗口组件在Form1上的实际尺寸与范围
    //以便USER直接调整单字符串窗口组件边沿
    ::MoveWindow(Edit1->Handle, Edit1->Left, Edit1->Top,
                 Edit1->Width, Edit1->Height + 1, true);
    }
    //---------------------------------------------------------------------------
    //当鼠标保持箭头图标时,Edit1即可被拖曳
    void __fastcall TForm1::Edit1MouseDown(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y)
    {
    if(Edit1->Cursor == crArrow )
      {//释放原有鼠标捕捉状态,
      //并同时送出鼠标单击位置等同于窗口标题栏可拖曳窗口的属性
      ::ReleaseCapture();
      SNDMSG(Edit1->Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
      }
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Edit1MouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {//鼠标在Edit1上移动时,仍保持箭头图标
    Edit1->Cursor = crArrow;
    }
    //---------------------------------------------------------------------------