unit Main;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private
    { Private declarations }  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation
var
      down:boolean=false;
      downpoint:tpoint;
{$R *.dfm}procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);begin
down:=true;
downpoint.X:=x;
downpoint.Y:=y;end;procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
down:=false;
end;procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
if down then
begin  button1.Left:=mouse.CursorPos.X-left-downpoint.X-self.BevelWidth-self.BorderWidth;
  button1.Top:=mouse.CursorPos.Y-top-downpoint.Y-self.BorderWidth-self.BevelWidth;
end;
end;end.////////////////////////////////////////////////
问题:
1。怎样得到窗体的标题栏高度。
2。
鼠标按下的时候只要稍微的挪动一点,button1.left和button1.top就变化很大,但是当托动开始以后,就正常了。self.bothorstyle:=bsnone以后就没问题了,  button1.Left:=mouse.CursorPos.X-left-downpoint.X-self.BevelWidth-self.BorderWidth;
  button1.Top:=mouse.CursorPos.Y-top-downpoint.Y-self.BorderWidth-self.BevelWidth;这两句除了form的标题栏高度以外,我不知道还忘了减去什么。

解决方案 »

  1.   

    1.GetSystemMetrics()
    2.开始时候的定位不准确,注意Screen和Client坐标转化的问题
      

  2.   

    2。开始的时候定位为什么不准确呢?
    我的意思是当鼠标再button上按下的时候纪录鼠标想对于buton坐标系的位置,而
    横纵坐标恰好是buttonmousedown的x,y这是vcl已经转化好的阿。请各位高手copy到自己delphi6上运行一下,谢谢!
    请各位高手copy到自己delphi6上运行一下,谢谢!
    请各位高手copy到自己delphi6上运行一下,谢谢!
    请各位高手copy到自己delphi6上运行一下,谢谢!
      

  3.   

    也许下面的方法来得更为简单直接(关键在于消息$F012):
    procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      ReleaseCapture;
      Button1.Perform(WM_SYSCOMMAND, $F012, 0); //Move Panel
    end;
      

  4.   

    如果你一定要进行坐标变换,那么需要注意:
    (1)窗体的标题有高度(这你已经注意到了)
    (2)窗体的边界也有宽度(你可以跟踪鼠标落下或升起时鼠标、窗体、控件的位置)
    (3)OnMove事件本身是当一定时间内有一定的移动距离时才触发(请参阅MS Win32 SDK),因此当你用坐标变换的方法实现控件拖动特别是快速拖动或者移动量很小的拖动时,你会发现鼠标升起时对于控件的相对位置与原先会有所改变。