各位师兄好啊:
现遇到一个图形界面问题,要用DELPHI实现如下功能:
在窗体中有一个RzPanel(用BitBtn做容器也可以)用来放图片的,一个RzLine组件(用来画直线的),
RzPanel可以放图片(用代码来实现图片的更换),并且RzPanel与RzLine画出来的直线是一体的。也就是说当鼠标拖动RzPanel时,RzLine画出的这条线也会跟着移动。不知道各位听懂在下的意思了吗?以前没有做过这方面的问题,所以不知如何下手,望各位赐教。也可以不用RzPanel或RzLine组件,但要实现上述的功能。顺便说一下,RzPanel和RzLine组件各位用过吗?如何换图片,RzPanel又如何可以用鼠标实现拖动呢?如何用RzLine画直线?谢谢了先,分不是问题。
现遇到一个图形界面问题,要用DELPHI实现如下功能:
在窗体中有一个RzPanel(用BitBtn做容器也可以)用来放图片的,一个RzLine组件(用来画直线的),
RzPanel可以放图片(用代码来实现图片的更换),并且RzPanel与RzLine画出来的直线是一体的。也就是说当鼠标拖动RzPanel时,RzLine画出的这条线也会跟着移动。不知道各位听懂在下的意思了吗?以前没有做过这方面的问题,所以不知如何下手,望各位赐教。也可以不用RzPanel或RzLine组件,但要实现上述的功能。顺便说一下,RzPanel和RzLine组件各位用过吗?如何换图片,RzPanel又如何可以用鼠标实现拖动呢?如何用RzLine画直线?谢谢了先,分不是问题。
// 任意摆布一个控件 ( 拖动、放大、缩小 )******************************************
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 begin SC_MANIPULATE := $F001; Control.Cursor := crSizeWE; end //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 光标在控件的最右侧 ********************************************************** //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (X>=Control.Width-Precision) and (Y>Precision) and (Y<Control.Height-Precision) then begin SC_MANIPULATE := $F002; Control.Cursor := crSizeWE; end //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 光标在控件的最上侧 ********************************************************** //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (X>Precision) and (X<Control.Width-Precision) and (Y<=Precision) then begin SC_MANIPULATE := $F003; Control.Cursor := crSizeNS; end //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 光标在控件的左上角 ********************************************************** //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (X<=Precision) and (Y<=Precision) then begin SC_MANIPULATE := $F004; Control.Cursor := crSizeNWSE; end //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 光标在控件的右上角 ********************************************************** //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (X>=Control.Width-Precision) and (Y<=Precision) then begin SC_MANIPULATE := $F005; Control.Cursor := crSizeNESW ; end //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 光标在控件的最下侧 ********************************************************** //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (X>Precision) and (X<Control.Width-Precision) and (Y>=Control.Height-Precision) then begin SC_MANIPULATE := $F006; Control.Cursor := crSizeNS; end //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 光标在控件的左下角 ********************************************************** //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (X<=Precision) and (Y>=Control.Height-Precision) then begin SC_MANIPULATE := $F007; Control.Cursor := crSizeNESW; end //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 光标在控件的右下角 ********************************************************** //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (X>=Control.Width-Precision) and (Y>=Control.Height-Precision) then begin SC_MANIPULATE := $F008; Control.Cursor := crSizeNWSE; end //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 光标在控件的客户区 ( 移动整个控件 )****************************************** //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else if (X>5) and (Y>5) and (X<Control.Width-5) and (Y<Control.Height-5) 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;然后在panel或button的MouseMove事件中加如下代码:
procedure Tmainform.Button1MouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
ManipulateControl((Sender as TControl), Shift, X, Y, 10);
end;至于RzLine,我想你可以在然后在panel或button的Mouseup事件中更新Pzline的top,left..等属性应该是可以的,你试试吧
-----------------------------------------
TO 回复人: wdswcy(一)
你的函数,我已经采用了。谢谢了。很不错,我只需要其中的拖动功能即可。我试了一下,Mouseup事件中改变Pzline的top,left,但是没有效果,所以我把在
if Shift=[ssLeft] then
begin
ReleaseCapture;
Control.Perform(WM_SYSCOMMAND, SC_MANIPULATE, 0);
RzLine1.top:=control.Top+control.Width-control.Height;///这是新加的好象改得也不对。。
end;
但不知道left要如何改,才能实现当按钮拖动的时候,Pzline跟着移动。
望赐教,你的分肯定少不了。
Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
RzPanel1.Perform(wm_syscommand,$f012,0);
end;然后拖动RzPanel试试看?
Mouseup事件中这样写可以吗,你试试 pzline.left:=pzpanel.left
pzline.top:=pzpanel.top+pzpanel.height+N//N你自已定个数,好看为止
在pzpanel的 Mouseup事件中这样写可以吗,你试试 pzline.left:=pzpanel.left
pzline.top:=pzpanel.top+pzpanel.height+N//N你自已定个数,好看为止
RzLine1.top:=control.Top+round(control.Height/2)-round(RzLine1.Height/2);
RzLine1.Left:=control.Left+control.Width-10;//即可
不过很不好意思。我们更新了一下需求,是要完成这样的功能。界面上有两个BitBtn
中间有一个RzLine连接两个BitBtn的中间。无论是拖动哪一个BitBtn,RzLine始终会连接着两个BitBtn的中间。不知道各位是否明白我的意思?
我在程序中修改如下:
if Shift=[ssLeft] then
begin
ReleaseCapture;
Control.Perform(WM_SYSCOMMAND, SC_MANIPULATE, 0);
if RzLine1.top<BitBtn2.Top+round(BitBtn2.Height/2) then
begin
RzLine1.LineSlope:=lsDown;//方向向下
RzLine1.Height:=BitBtn2.Top+round(BitBtn2.Height/2)-BitBtn1.Top+round(control.Height/2);
RzLine1.Left:=control.Left+control.Width-10;
end
else begin
RzLine1.LineSlope:=lsUp;//方向向上
RzLine1.Height:=control.Top-round(control.Height/2)-BitBtn2.Top-round(BitBtn2.Height/2);
RzLine1.Left:=control.Left+control.Width-10;
end;
end;
仍无法解决问题,嗨,急需高手赐教,谢谢。
X, Y: Integer);
begin
ManipulateControl((Sender as TControl), Shift, X, Y, 10);
end;procedure Tmainform.Bitbtn2MouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
ManipulateControl((Sender as TControl), Shift, X, Y, 10);
end;
如果,pzline在bitbtn1在下面,bitbtn2上面,你用下面方法试试 在bitbtn1的 Mouseup事件中这样写 pzline.left:=pzpanel.left
pzline.top:=pzpanel.top+pzpanel.height+N//N你自已定个数,好看为止
在bitbtn2的 Mouseup事件中这样写 pzline.left:=pzpanel.left
pzline.top:=pzpanel.top-N//N你自已定个数,好看为止你试试,
把代码放在Mouseup事件中没有任何效果的。还有就是可能你没看明白我的意思。我的意思如下:
------------ RzLine1 --------------
| Bitbtn 1 |————————————| Bitbtn 2 |
| | | |
------------ --------------
当拖动任一Bitbtn时,RzLine都会连接着两端的Bitbtn ,说白了,比如你可以拖着Bitbtn2到任意的位置(可远可近,可上可下),而RzLine始终会一边连着Bitbtn2,一边连着Bitbtn 1 。
是不是很有难度啊???
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;type
TForm1 = class(TForm)
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
Label1: TLabel;
procedure BitBtn2MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure BitBtn1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}
// 任意摆布一个控件 ( 拖动、放大、缩小 )******************************************
procedure ManipulateControl(Control: TControl; Shift: TShiftState; X, Y, Precision: integer);var SC_MANIPULATE: Word;begin // 光标在控件的客户区 ( 移动整个控件 )****************************************** //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (X>1) and (Y>1) and (X<Control.Width-1) and (Y<Control.Height-1) 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;procedure TForm1.BitBtn2MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
ManipulateControl((Sender as TControl), Shift, X, Y, 10);//为了好看起见,你可以定义两个全局变量,在form 的show事件中
//如:
// x:=bitbtn2.top-label1.top
// 则:label1.top:=bitbtn2.top-x
label1.Top:=bitbtn2.Top+round(bitbtn2.Height/2);
bitbtn1.Top:=bitbtn2.Top;
bitbtn1.Left:=bitbtn2.Left-label1.Width-bitbtn1.Width;
label1.Left:=bitbtn1.Left+bitbtn1.Width;end;procedure TForm1.BitBtn1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
ManipulateControl((Sender as TControl), Shift, X, Y, 10);
label1.Top:=bitbtn1.Top+round(bitbtn1.Height/2);
bitbtn2.Top:=bitbtn1.Top;
label1.Left:=bitbtn1.Left+bitbtn1.Width+2;
bitbtn2.Left:=bitbtn1.Left+bitbtn1.Width+2+label1.Width;
end;end.
我的QQ是:549711582
我的程序如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, RzLine, ExtCtrls, RzPanel;
type
TForm1 = class(TForm)
RzLine1: TRzLine;
Image1: TImage;
BitBtn1: TBitBtn;
procedure BitBtn1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
procedure ManipulateControl(Control: TControl; Shift: TShiftState; X, Y, Precision: integer);
end;
var
Form1: TForm1;
implementation{$R *.dfm}{ TForm1 }
X, Y, Precision: integer);
var SC_MANIPULATE: Word;
begin
if (X>5) and (Y>5) and (X<Control.Width-5) and (Y<Control.Height-5)
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);//当图标在圆心左边时
if control.left+control.Width<image1.Left then
begin
/////当图标在圆心上方时
if control.Top+control.Height<image1.Top then
begin
RzLine1.ArrowLength:=0;
RzLine1.LineSlope:=lsDown;
// RzLine1.Top:=control.Top+round(control.Height/2);
RzLine1.Top:=control.Top+control.Height;
RzLine1.Left:=control.Left+control.Width;
RzLine1.Width:=image1.Left-RzLine1.Left;
if RzLine1.Width<18 then
RzLine1.Width:=18 ;
RzLine1.Height:=image1.Top-RzLine1.Top;
if RzLine1.Height<image1.Height then
RzLine1.Height:=image1.Height;
exit;
end;
if control.Top+control.Height=image1.Top then ///第一水平线
begin
RzLine1.ArrowLength:=0;
RzLine1.LineSlope:=lsDown;
RzLine1.Top:=control.Top+round(control.Height/2);
RzLine1.Left:=control.Left+control.Width;
RzLine1.Width:=image1.Left-RzLine1.Left;
RzLine1.Height:=round(control.Height/2)+round(image1.Height/2);
if RzLine1.Height<image1.Height then
RzLine1.Height:=image1.Height;
exit;
end;
if (control.Top+control.Height>image1.Top) and (control.Top<=image1.Top+image1.Height) then
begin ////在圆心范围内
RzLine1.ArrowLength:=0;
if control.Top>image1.Top+round(image1.Height/2) then
RzLine1.LineSlope:=lsUp
else
RzLine1.LineSlope:=lsDown;
RzLine1.Top:=image1.Top+round(image1.Height/2);
RzLine1.Left:=control.Left+control.Width;
RzLine1.Width:=image1.Left-RzLine1.Left;
RzLine1.Height:=round(image1.Height/2); exit;
end; if control.Top>image1.Top+image1.Height then
begin ////下方或水平线时
RzLine1.LineSlope:=lsUp;
RzLine1.ArrowLength:=0;
RzLine1.Height:=control.Top-image1.Top-image1.Height;//+round(control.Height/2);
RzLine1.Top:=control.Top-RzLine1.Height;
if RzLine1.Height<18 then
RzLine1.Height:=18;
RzLine1.Top:=control.Top-RzLine1.Height;//+(image1.Top+image1.Height);
RzLine1.Left:=control.Left+control.Width-8;
RzLine1.Width:=image1.Left-RzLine1.Left;
if RzLine1.Width<18 then
RzLine1.Width:=18 ;
exit;
end; end;
if control.Left<image1.Left+image1.Width then
begin ////处于圆心的情况
//showmessage('yes');
if control.Top+control.Height<image1.Top then
begin
RzLine1.ArrowLength:=0;
if control.Left+control.Width<=image1.Left+image1.Width then
begin
RzLine1.LineSlope:=lsDown;
RzLine1.Width:=round(image1.Width/2);
RzLine1.Left:=control.Left+round(control.Width/2);
end
else begin
RzLine1.LineSlope:=lsUp;
RzLine1.Width:=control.Left-RzLine1.Left;
RzLine1.Left:=image1.Left+round(image1.Width/2);
end;
RzLine1.Top:=control.Top+control.Height; if RzLine1.Width<18 then
RzLine1.Width:=18 ; RzLine1.Height:=image1.Top-RzLine1.Top;
if RzLine1.Height<image1.Height then
RzLine1.Height:=image1.Height;
exit;
end
else begin
if control.Left+control.Width>=image1.Left+image1.Width then
begin
RzLine1.LineSlope:=lsDown;
RzLine1.Width:=control.Left-RzLine1.Left;
RzLine1.Left:=image1.Left+round(image1.Width/2);
end
else begin
RzLine1.LineSlope:=lsUp;
RzLine1.Width:=round(control.Width/2);
RzLine1.Left:=control.Left+round(control.Width/2); end;
RzLine1.ArrowLength:=0;
RzLine1.Height:=control.Top-image1.Top-image1.Height;//+round(control.Height/2);
RzLine1.Top:=control.Top-RzLine1.Height;
if RzLine1.Height<18 then
RzLine1.Height:=18;
RzLine1.Top:=control.Top-RzLine1.Height;//+(image1.Top+image1.Height);
// RzLine1.Left:=image1.Left+image1.Width;
// RzLine1.Width:=control.Left-RzLine1.Left;
if RzLine1.Width<18 then
RzLine1.Width:=18 ;
exit;
end; end;
begin ///当图标在圆心右边时
/////当图标在圆心上方时
if control.Top+control.Height<image1.Top then
begin
RzLine1.ArrowLength:=0; RzLine1.LineSlope:=lsUp; RzLine1.Top:=control.Top+control.Height;
RzLine1.Left:=image1.Left+image1.Width;
RzLine1.Width:=control.Left-RzLine1.Left;
if RzLine1.Width<18 then
RzLine1.Width:=18 ;
RzLine1.Height:=image1.Top-RzLine1.Top;
if RzLine1.Height<image1.Height then
RzLine1.Height:=image1.Height;
exit;
end;
if control.Top+control.Height=image1.Top then ///第一水平线
begin
RzLine1.ArrowLength:=0;
RzLine1.LineSlope:=lsUp;
RzLine1.Top:=control.Top+round(control.Height/2);
RzLine1.Left:=image1.Left+image1.Width;
RzLine1.Width:=control.Left-RzLine1.Left;
RzLine1.Height:=round(control.Height/2)+round(image1.Height/2);
if RzLine1.Height<image1.Height then
RzLine1.Height:=image1.Height;
exit;
end;
if (control.Top+control.Height>image1.Top) and (control.Top<=image1.Top+image1.Height) then
begin ////在圆心范围内
RzLine1.ArrowLength:=0;
if control.Top>image1.Top+round(image1.Height/2) then
RzLine1.LineSlope:=lsDown
else
RzLine1.LineSlope:=lsUp;
RzLine1.Top:=image1.Top+round(image1.Height/2);
RzLine1.Left:=image1.Left+image1.Width;
RzLine1.Width:=control.Left-RzLine1.Left;
RzLine1.Height:=round(image1.Height/2); exit;
end; if control.Top>image1.Top+image1.Height then
begin ////下方或水平线时
RzLine1.LineSlope:=lsDown;
RzLine1.ArrowLength:=0;
RzLine1.Height:=control.Top-image1.Top-image1.Height;//+round(control.Height/2);
RzLine1.Top:=control.Top-RzLine1.Height;
if RzLine1.Height<18 then
RzLine1.Height:=18;
RzLine1.Top:=control.Top-RzLine1.Height;//+(image1.Top+image1.Height);
RzLine1.Left:=image1.Left+image1.Width;
RzLine1.Width:=control.Left-RzLine1.Left;
if RzLine1.Width<18 then
RzLine1.Width:=18 ;
exit;
end;
end;
end;
end;
procedure TForm1.BitBtn1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
ManipulateControl((Sender as TControl), Shift, X, Y, 10);
end;