已生成N个按一不规则的panel,如何用鼠标控制它,双击左键放大,再次双击缩小回原状态 ( 积分: 200 )

  • 主题发起人 主题发起人 rzqcjwrz
  • 开始时间 开始时间
R

rzqcjwrz

Unregistered / Unconfirmed
GUEST, unregistred user!
var
PanelW : array[0..63] of TPanel;
i,n,k,x,m,iWidth,iHeight,chanelnum : Integer;//5*4
s,temp:string;
begin
chanelnum:=24;//通道数
if chanelnum <= 4 then
x:=4
else if chanelnum<9 then
x:=9
else if chanelnum<=16 then
x:=16
else if chanelnum <= 25 then
x:=25
else if chanelnum<=36 then
x:=36
else if chanelnum<=49 then
x:=49
else if chanelnum<=64 then
x:=8;

Str(Sqrt(x):5:0, Temp);

S :=temp;
k:=strtoint(s);
m:=k;
n:=k;
iWidth:=352 div n;
iHeight:=288 div m;
for i := 0 to m*n-1 do
begin
PanelW:=TPanel.Create(self);
PanelW.Parent:=Self;//self为父级控件
PanelW.Width:=iWidth;
PanelW.Height:=iHeight;
PanelW.Visible:=True;
PanelW.Top:=(i div n)*iHeight;
PanelW.Left:=(i mod n)*iwidth;
PanelW.Caption:=inttostr(i);
end;
end;
 
将所有的Panel挂同一个OnClick事件

------------------------------------------------------
http://www.waibaoinfo.com 外包信息网
 
...
...
...
PanelW.Left:=(i mod n)*iwidth;
PanelW.Caption:=inttostr(i);
PanelW.OnDblClick := PanelDblClick;
end;


procedure TForm1.PanelDblClick(Sender: TObject);
begin
with TPanel(Sender) do
if Tag = 0 then
begin
Tag := 1;
SetBounds(Left - Width div 2, Top - Height div 2, Width * 2, Height * 2); //中心固定
//SetBounds(Left, Top, Width * 2, Height * 2); //左上角固定
end
else begin
Tag := 0;
SetBounds(Left + Width div 4, Top + Height div 4, Width div 2, Height div 2);
//SetBounds(Left, Top, Width div 2, Height div 2);
end;
end;
 
大概的思路是:
1. 需要标识新创建的Panel,所以需要用Name或Tag来标识;
2. 需要保存原来的大小和位置信息,以及其它信息;
因此:
定义一个结构
TNewPanelMgr=record
ID: integer;
Name: string;
OrgLeft: integer //保存原始位置
...
end;
NewPanelMgr=array[0..63] of TNewPanelMgr; //当然你可以动态,想要多少就多少
procedure OnNewPanelDblClick(Sender: TObject) of Object; //双击事件处理函数
大概的创建代码:
var
obj: TPanel;
begin
obj:=TPanel.Create;
obj.name:='NewPanel'+int(1); //当前是第几个,保存总共有几个
obj.OnDBClient:=OnNewPanelDblClick;
......
end;
后面的就不用说了吧
 
还是弄不出,可能我太笨了,请再进一步示例.
 
其实弄明白了,利用自身属性也很容易做到(这是我最常用也最喜欢用的),
以下土办法可仅供参考:

主要是要记忆两点:
1.是要放大还是要缩小:可以用Tag属性的0和1来记忆
2.放大或缩小前后各个位置大小:
可以利用属性Hints:= [Left:Top;Width:Height][Left:Top;Width:Height]来记忆,
里面用冒号隔开或怎么隔就随便你了,strtoint()与inttostr()......
3.所有panel一定要共用一个鼠标双击事件,这个事件里用个
for i:= 0 to ...ControlCount-1 do 的形式查找所有panel
最好是写个递归查找法来查找panel,因为有可能你的panel是嵌套的,双击事件里直接传入self作初始参数为递归调用,若有必要,属性Hints可加入其它特殊标识以表示是你要操作的panel
 
对你们讲很简单,但对我来讲很复杂,能否就4*4的格式,也就是通道数为:ChanelNum:=4的情况,完整示范一下双击事件,并通过击恢复原状.
 
各位可能我没有讲清楚,应该是:以屏幕左上角为基点,双击改变,再次双击恢复原位置.
 
unit Unit1;

interface

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

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
procedure PanelDblClick(Sender: TObject);
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.PanelDblClick(Sender: TObject);
begin
with TPanel(Sender) do
begin
BringToFront;
if Tag = 0 then
begin
Tag := 1;
//SetBounds(Left - Width div 2, Top - Height div 2, Width * 2, Height * 2); //中心固定
SetBounds(Left, Top, Width * 2, Height * 2); //左上角固定
end
else begin
Tag := 0;
//SetBounds(Left + Width div 4, Top + Height div 4, Width div 2, Height div 2);
SetBounds(Left, Top, Width div 2, Height div 2);
end;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
PanelW : array[0..63] of TPanel;
i,n,k,x,m,iWidth,iHeight,chanelnum : Integer;//5*4
s,temp:string;
begin
chanelnum:=24;//通道数
if chanelnum <= 4 then
x:=4
else if chanelnum<9 then
x:=9
else if chanelnum<=16 then
x:=16
else if chanelnum <= 25 then
x:=25
else if chanelnum<=36 then
x:=36
else if chanelnum<=49 then
x:=49
else if chanelnum<=64 then
x:=8;

Str(Sqrt(x):5:0, Temp);

S :=temp;
k:=strtoint(s);
m:=k;
n:=k;
iWidth:=352 div n;
iHeight:=288 div m;
for i := 0 to m*n-1 do
begin
PanelW:=TPanel.Create(self);
PanelW.Parent:=Self;//self为父级控件
PanelW.Width:=iWidth;
PanelW.Height:=iHeight;
PanelW.Visible:=True;
PanelW.Top:=(i div n)*iHeight;
PanelW.Left:=(i mod n)*iwidth;
PanelW.Caption:=inttostr(i);
PanelW.OnDblClick := PanelDblClick;
end;
end;

end.

其实就是链接一下事件,不过觉得你生成Panel的代码挺复杂的
procedure CreatePanels(Num: Integer; Pnt: TWinControl);
var
I, J, W, H, Count: Integer;
begin
W := Pnt.ClientWidth div Num;
H := Pnt.ClientHeight div Num;
Count := 0;
for I := 0 to Num - 1 do
for J := 0 to Num - 1 do
begin
with TPanel.Create(Pnt) do
begin
Parent := Pnt;
Left := J * W;
Top := I * H;
Width := W;
Height := H;
Caption := IntToStr(Count);
OnDblClick := PanelDblClick;
end;
Inc(Count);
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
CreatePanels(5, Self); //在Form1上生成5*5的Panels
end;
当然Num可以用两个变量代替,生成行列不相等的Panel阵列,也可以不用Pnt的Width,Height而用指定的宽高,简单修改下就行了
 
首先谢谢你.
生成panel没有关系,但双击事件有问题.
我的意识是以左上角o号panel为基点,进行放大和缩小.
 
我的意识是以左上角o号panel为基点,进行放大和缩小.
不明白,放到多大呢,我不是左上角固定了吗,Panel0就是在左上角啊
 
矩形界面,分割成N份后,每份均可以左上角:left:=0;top:=0;放大为整个矩形大小,每个的大小一样.width:=352,height:=288.都是以第一个的左上角与最后一个的右下角为对角点放大.
 
var
R: TRect;

procedure TForm1.PanelDblClick(Sender: TObject);
begin
with TPanel(Sender) do
begin
BringToFront;
if Tag = 0 then
begin
Tag := 1;
R := BoundsRect;
SetBounds(0, 0, 352, 288);
end
else begin
Tag := 0;
BoundsRect := R;
end;
end;
end;

仅针对你这个程序而已,双击放大后其它Panel都被遮住,所以可以只用一个TRect来保存当前放大的Panel的位置
 

Similar threads

I
回复
0
查看
763
import
I
I
回复
0
查看
682
import
I
I
回复
0
查看
843
import
I
后退
顶部