怎样移动让程序运行时控件?(200分)

  • 主题发起人 主题发起人 qf0421
  • 开始时间 开始时间
Q

qf0421

Unregistered / Unconfirmed
GUEST, unregistred user!
我想让控件在程序运行时可以被用户用鼠标移动,下面是代码:
procedure WMLBUTTONDOWN(var Msg:TMessage);message WM_LBUTTONDOWN;
procedure WMLBUTTONUP(var Msg:TMessage);message WM_LBUTTONUP;
procedure WMMOUSEMOVE(var Msg:TMessage);message WM_MOUSEMOVE;

implementation

procedure TDataMdl.WMLBUTTONDOWN(var Msg:TMessage);
begin
fmousex:=Msg.LParamLo;
fmousey:=Msg.LParamHi;
fwanttomove:=true;
end;

procedure TDataMdl.WMLBUTTONUP(var Msg:TMessage);
begin
fwanttomove:=false;
nd;

procedure TDataMdl.WMMOUSEMOVE(var Msg:TMessage);
var x,y:integer;
begin
if fwanttomove then
begin
x:=Msg.LParamLo;
y:=Msg.LParamHi;
left:=left+(x-fmousex);
top:=top+(y-fmousey);
end;
end;

可当鼠标移动过快时就移出了控件的客户区,从而使控件接收不到
WM_MOUSEMOVE,导致给人的感觉是移动发滞,我想用SetCapture
可这个控件不是从TWinControl继承的,没有HANDLE.

有那位大虾知道该怎么办?
在下先有礼了!!
 
我把问题提提前
 
现在很多大虾连不进。晚上10点后提前一下效果好
 
把没有HANDLE的控件,比如Label放在一个Panel上。

procedure TForm1.Label1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
Panel1.Perform(WM_SYSCOMMAND,$F012,0);
end;
 
我怎么觉得是你的移动程序有问题?
procedure TDataMdl.WMMOUSEMOVE(var Msg:TMessage);
var x,y:integer;
begin
if fwanttomove then
begin
x:=Msg.LParamLo;
y:=Msg.LParamHi;
left:=left+(x-fmousex);
top:=top+(y-fmousey);
fmousex := x; // 加这两行试试
fmousey := y;
end;
end;
 
有时候会出现这种情况,倒是能拖动了,但, 比如button, 就变成了
一个小窗口, 我用的是drag.
 
supermmx,那是因为BUTTON是从TWINCONTROL继承下来的,有HANDLE。
 
o*o,我的控件是动态生成的,不允许放在有HANDLE的控件上。另外,
我用SPY++发现可以监视诸如TBUTTON类,但没有HANDLE的如TIMAGE
连SPY++也无法监视,可DELPHI中TIMAGE确实可以移动,他到底是
什么办法?
 
我把问题提提前。
 
Delphi 1 的时代就搞定这个问题了,用这个控件 (TStretchHandle) 试试:
ftp://ftp.cdrom.com/pub/delphi_www/ftp/d10free/handles.zip
不仅能移动,还能改变大小呢。
 
我不是说自己写控件,而是让DELPHI里已经有的控件,如:TIMAGE,移动.
 
有什么办法除去吗?
 
我把问题提提前。
 
看你急的。:-)

既然Image是动态生成的,也可以动态生成一个Panel嘛。

Image.Parent:=Panel;
调整Image和Panel的大小,让Image完全覆盖Panel。

在Image的OnMouseDown里:

ReleaseCapture;
(Sender as Timage).Parent.Perform(WM_SYSCOMMAND,$f012,0);
 
qf0421:还是建议您在 Form 上放一个我推荐的 TStretchHandle。
然后您控件的 onMouseDown 事件中写
StretchHandle1.Detach;
StretchHandle1.Attach(TControl(Sender));
 
各位,实不相瞒,我是想编一个做流程图的东西,我从TIMAGE继承编了一个控件用于绘
图,然后在拖动是发生了问题:就是鼠标拖动过快,超出了控件的范围,则不能相应
WM_MOUSEMOVE的消息.
yysun:您推荐的控件我现在还无法下载,老是连不上.
 
o*o的办法很好呀!

做了一个简单的例子,已测试过:

unit Unit61;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
RxGIF, ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject);
procedure MDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.MDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
(Sender as TImage).Parent.Perform(WM_SYSCOMMAND,$F012,0);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
img:TImage;
pan:TPanel;
FN :string;
begin
if OpenDialog1.Execute then
FN := OpenDialog1.FileName
else FN := 'c:/a.bmp';

img := TImage.Create(self);
img.Picture.LoadFromFile(FN);
img.AutoSize := True;
img.OnMouseDown := Form1.MDown;

pan := TPanel.Create(Form1);
pan.Parent := Form1;
pan.Left := 10;
pan.Top := 10;
Pan.Width := img.ClientWidth;
Pan.Height := img.ClientHeight;
Pan.InsertControl(img);
end;

end.
 
每一个TIMAGE都放一个TPANEL,这岂不是太浪费资源?
 
后退
顶部