当前位置:主页>仓库管理软件> 列表

控件数组改变数量出错,怎么办? 找财务记账软件哪个好

销售管理软件版1楼: 在form1 中
var
ary1:tbutton;
a:integer;

a:=12
onshow中SetLength(ary1,A),form显示12个按钮正常
onhide中for i:=0 to 11 do ary1[i].free;也很正常
但我在程序中要改变按钮的数量时,比如改成24个
a:=24
然后再
form1.hide;
form1.show;
系统报内存分配错误,而且form1上的按钮数量只能变多,不能变少,就是说a:=6时,form1上的按钮还是12个.
请高手相助!

2楼: 按钮需要动态生成的吧 如进销存管理系统设计

3楼: var
ary1 : tbutton; //你下面用的是按钮数组,这句话会正确?

把完整的代码贴出来,大家好弄明白具体错在哪。这个问题应该很好解决的

4楼: 当然,在onshow中生成了,用creat方法

5楼: 先释放

6楼: procedure TForm_Main.FormShow(Sender: TObject);
var
Unit_count,Machine_count : SmallInt;
RowTemp,ColTemp,GroupTemp : SmallInt;
begin
RowTemp := 0;
ColTemp := -1;
//机台按钮的创建
for Machine_count:=0 to Machine_Total-1 do begin

ColTemp := ColTemp + 1;


if ColTemp >= Col_Num then begin
ColTemp := 0;
RowTemp := RowTemp + 1;
end;

Bevel_Array[Machine_count]:=tBevel.Create(Self);
Bevel_Array[Machine_count].Parent:=self;
Bevel_Array[Machine_count].Left:=MBtnLeft+ColTemp*MBtnColUnpack-8; //控件位置
Bevel_Array[Machine_count].Top:=MBtnTop+RowTemp*MBtnRowUnpack-10;
Bevel_Array[Machine_count].Width:=BevelWidth; //控件宽,高
Bevel_Array[Machine_count].Height:=BevelHeight;
Bevel_Array[Machine_count].Shape :=bsFrame;

Machine_Array[Machine_count]:=tSpeedButton.Create(Self);
Machine_Array[Machine_count].Parent:=self; //一般将其父控件设置为Self,如果不设置Parent的值,则控件不会在屏幕
Machine_Array[Machine_count].Left:=MBtnLeft+ColTemp*MBtnColUnpack; //控件位置
Machine_Array[Machine_count].Top:=MBtnTop+RowTemp*MBtnRowUnpack;
Machine_Array[Machine_count].Width:=MBtnWidth; //控件宽,高
Machine_Array[Machine_count].Height:=MBtnHeight;
Machine_Array[Machine_count].Caption:=''1''; //控件的标题


//Machine_Array[Machine_count].Glyph:=SpeedButton1.Glyph; //加载图象
Machine_Array[Machine_count].Layout:=blGlyphTop;
Machine_Array[Machine_count].Font.Size:=12; //确定字体大小
Machine_Array[Machine_count].Transparent:=True;
Machine_Array[Machine_count].Flat:=False;
Machine_Array[Machine_count].onclick:=Machine_click; //定义单击事件
end;

GroupTemp :=-1;
RowTemp := 0;
ColTemp := 0;

//机位按钮的创建
for Unit_count:=0 to Unit_Total-1 do begin

GroupTemp := GroupTemp + 1;
if GroupTemp >= Unit_Num then begin
GroupTemp := 0 ;
ColTemp := ColTemp + 1 ;
end;
if ColTemp >= Col_Num then begin
ColTemp := 0;
RowTemp := RowTemp + 1;
end;

Unit_Array[Unit_count]:=tSpeedButton.Create(Self);
Unit_Array[Unit_count].Parent:=self; //一般将其父控件设置为Self,如果不设置Parent的值,则控件不会在屏幕
Unit_Array[Unit_count].Left:=UBtnLeft+ColTemp*UBtnColUnpack+GroupTemp*(UBtnWidth-1); //控件位置
Unit_Array[Unit_count].Top:=UBtnTop++RowTemp*UBtnRowUnpack;
Unit_Array[Unit_count].Width:=UBtnWidth; //控件宽,高
Unit_Array[Unit_count].Height:=UBtnHeight;
Unit_Array[Unit_count].Caption:=''1''; //控件的标题
//Unit_Array[Unit_count].Glyph:=SpeedButton1.Glyph; //加载图象
Unit_Array[Unit_count].Layout:=blGlyphTop;
Unit_Array[Unit_count].Font.Size:=8; //确定字体大小
Unit_Array[Unit_count].Transparent:=True;
Unit_Array[Unit_count].Flat:=False;
Unit_Array[Unit_count].onclick:=Unit_click; //定义单击事件
end;

Form_Main.Width := FormWidth;
Form_Main.Height := FormHeight;

Form_Main.Caption := ''标签打印 - '' + FormTitle;
LabelTitle.Caption := FormTitle;
labelTitle.Left := Trunc(FormWidth/2)-Trunc(labelTitle.Width/2);
labelTitle.Top := 5;
end;

procedure TForm_Main.FormHide(Sender: TObject);
var
Unit_count,Machine_count:SmallInt;
begin
for Unit_count:=0 to Unit_Total-1 do Unit_Array[Unit_count].Free;
for Machine_count:=0 to Machine_Total-1 do Machine_Array[Machine_count].Free;
for Machine_count:=0 to Machine_Total-1 do Bevel_Array[Machine_count].Free;
end;

销售管理软件版7楼: 有些没有定义的变量是全局变量

8楼: 既然在FormHide時有手動釋放,那么在各種控件Create時寫為Create(self),
改為Create(nil)。
或者可先試試這個
for i:= High(ary1) to Low(ary1) do
begin
ary1[i].Free;
ary1[i]:= nil;
end;

9楼: ary1[i].free 改为 freeandnil(ary1[i])看看 是不是你button的数组的引用地址没有清空?

10楼: 先释放所有,再创建

11楼: BrainYang与Avalon大侠的方法我试过了,没用的.
zhlfdm大侠,我的代码贴出来了,你看是不是先创建后释放呢.

12楼: 代码不能写在这
procedure TForm_Main.FormShow(Sender: TObject);
应写在这
procedure TForm_Main.Create(Sender: TObject);
隐藏就这写
procedure TForm_Main.FormHide(Sender: TObject);
....
for Machine_count:=0 to Machine_Total-1 do Machine_Array[Machine_count].visible:=false;
.... 如简单的财务管理软件

13楼: 在窗体中动态创建控件在onshow中也可以的吧


在onhide时 我的本意是要释放按钮数组的.

销售管理软件版14楼: 在form1 中
var
ary1:arry of tbutton;
onshow中SetLength(ary1,A),form显示12个按钮正常
onhide中for i:=low(ary1) to high(ary1) do ary1[i].free;也很正常

15楼: 变量作用域问题吧,那个a是全局还是局部?

16楼: 应该是
var
ary1 : array of tbutton;
...
吧?

17楼: 我試過下面代碼,半點問題也沒有
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Buttons, StdCtrls;

type
Tform_main = class(TForm)
...
private
procedure ButtonClick(Sender:TObject);
public
{ Public declarations }
end;

const
Machine_Total: Integer = 12;
var
form_main: Tform_main;
Machine_Array:Array of TButton;
implementation

{$R *.dfm}

procedure Tform_main.FormShow(Sender: TObject);
var
btn:TButton;
i:integer;
begin
SetLength(Machine_Array,Machine_Total);
for i:=0 to Machine_Total-1 do //這里要減1


begin
btn:=TButton.Create(nil);//這里是nil,如果為self,那么formhide中就不用寫代碼了
with btn do
begin
Parent:=self;
left:=10;
Top:=10+27*i;
Visible:=True;
Enabled:=True;
Caption:=''Button ''+IntToStr(i);
onClick:=ButtonClick;
end;
Machine_Array[i]:=btn;
end;
end;

procedure Tform_main.FormHide(Sender: TObject);
var
i:integer;
begin
for i:=0 to machine_total-1 do //這里要減1
begin
TButton(Machine_Array[i]).OnClick:=nil;
FreeAndNil(Machine_Array[i]);
end;
end;

procedure Tform_main.ButtonClick(Sender:TObject);
begin
if Sender is TButton then
ShowMessage((Sender As TButton).Caption);
end;

end.

18楼: 多谢,问题解决了.

19楼: 怎么解決了。問題出在哪里

20楼: 我这样写的不知道能不能对你有所帮助

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(Application);
Form2.m_Count := StrToInt(Edit1.Text);
Form2.Show;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Form2.m_Count := StrToInt(Edit1.Text);
Form2.Show;
end;

end.


unit Unit2;

interface

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

type
TForm2 = class(TForm)
procedure FormDestroy(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
m_Count: Integer;
m_Buttons: array of TButton;
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormDestroy(Sender: TObject);
begin
Form2 := nil;
end;

procedure TForm2.FormShow(Sender: TObject);
var
v_Count: Integer;
begin
for v_Count := Low(m_Buttons) to High(m_Buttons) do
begin
m_Buttons[v_Count].Free;
m_Buttons[v_Count] := nil;
end;
SetLength(m_Buttons, m_Count);
for v_Count := Low(m_Buttons) to High(m_Buttons) do
begin
m_Buttons[v_Count] := TButton.Create(Self);
m_Buttons[v_Count].Parent := Self;
m_Buttons[v_Count].Height := 20;
m_Buttons[v_Count].Width := 100;
m_Buttons[v_Count].Caption := ''按钮'' + IntToStr(v_Count);
m_Buttons[v_Count].Top := 10 + 30 * (v_Count + 1);
end;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caHide; 《--这里为了效果就不写cafree了
end;

end.

销售管理软件版21楼: onhide中for i:=low(ary1) to high(ary1) do ary1[i].free;

是计数的时候错了,我用了全局变量,setlengh用了A变量,在对话框中改变了A变量,可我释放时还是用A变量来循环,当然错了.我贴上来的代码不全的,所有为难各个了.再次感谢!

还有creat时用self就不用手式释放吗?

22楼: creat时用self不用手式释放。不過這樣的話,隨著show的次數增多,資源消耗會加大。
只有等到form_main關閉后,所有的資源才會釋放。 如财务记账软件哪个好

23楼: creat时nil与self有什么分别,有什么优缺点?

再有,我如何知道点中的数组中哪个控件?

24楼: 如
btn:=TButton.Create(Self);
//是指定控件btn的owner為self,其資源由self(一般是form)來釋放,不用手動釋放
btn:=TButton.Create(nil);
//是不指定btn的Owner,btn所占資源由手動釋放

劉藝有一本《Delphi面向對象編程思想》,有機會的話,把它買下來。


絕對受益菲淺。

如何知道點中的數組中的哪個控件嘛
如:
for i:=0 to Machine_Total-1 do //這里要減1
begin
btn:=TButton.Create(nil);//這里是nil,如果為self,那么formhide中就不用寫代碼了
with btn do
begin
...
tag:=i; //
...
end;
Machine_Array[i]:=btn;
end;

當點擊的時候,根據tag值,就可知道點中的是數組中的哪個button了。

25楼: 呵呵,昨天晚上自己想了个办法.在creat按钮时定义BTN的name,这样查名字就知道了.

26楼: 恭喜恭喜。