源码如下:unit uShortcuts;interfaceuses
  ShareMem, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Grids, DBGridEh, DB, ADODB, ComCtrls, StdCtrls, uMainForm,
  Buttons;const
  iHtoH = 20; //行间距
  iWtoW = 10; //列间距
  iPerLine = 6;//每行个数
  iWidth = 80; //按钮宽度
  iHeight =80;//按钮高度type
  TbtnMyButtons =class(TBitBtn)
  public
    Barcode:string;
  end;
  
  TfrmShortcuts = class(TForm)
    pgcGoodsType: TPageControl;
    qryGoods: TADOQuery;
    dsGoodsType: TDataSource;
    qryGoodsType: TADOQuery;
    procedure FormCreate(Sender: TObject);
    procedure qryGoodsTypeAfterScroll(DataSet: TDataSet);
    procedure btnClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    Tabs :array of TTabSheet;
    Buttons:array of TbtnMyButtons;
    { Private declarations }
  public
    { Public declarations }
  end;var
  frmShortcuts: TfrmShortcuts;implementationuses uDMMain;{$R *.dfm}procedure TfrmShortcuts.FormCreate(Sender: TObject);
begin
  top := 128;
  left :=0;
  width := 800;
end;procedure TfrmShortcuts.qryGoodsTypeAfterScroll(DataSet: TDataSet);
begin
  qryGoods.Close;
  qryGoods.Parameters.ParamByName('GoodsTypeID').Value := DataSet.FieldByName('GoodsTypeID').Value;
  qryGoods.Open;
  
end;procedure TfrmShortcuts.btnClick(Sender: TObject);
begin
  frmMainForm.edtEnter.Text := (Sender as TbtnMyButtons).Barcode;
  Close;end;procedure TfrmShortcuts.FormShow(Sender: TObject);
var
  I,J:Integer;
begin
  qryGoodsType.Open;
  qryGoods.Open;
  setlength(Tabs,qryGoodsType.RecordCount);
  SetLength(Buttons,qryGoods.RecordCount * qryGoodsType.RecordCount);
  qryGoodsType.First;  while not qryGoodsType.Eof do
  begin
    J:= qryGoodsType.RecNo;
    I:=0;
    Tabs[J] := TTabSheet.Create(Self);
    Tabs[J].PageControl := pgcGoodsType;
    Tabs[J].Caption := qryGoodsType.FieldByName('GoodsTypeName').AsString;
    Tabs[J].Show;
    qryGoods.First;
    while not qryGoods.Eof do
    begin
      I:=I+1;
      Buttons[I] := TbtnMyButtons.Create(Self);
      Buttons[I].Parent := Tabs[J];
      Buttons[I].Caption := qryGoods.FieldByName('GoodsName').AsString;
      Buttons[I].Barcode := qryGoods.FieldByName('Barcode').AsString;
      Buttons[I].OnClick := btnClick;
      Buttons[I].Width :=iWidth;
      Buttons[I].Height :=iHeight;
      Buttons[I].Font.Color :=clBlack;
      Buttons[I].Top := iHtoH + (iHeight+iHtoH) * (I div iPerLine - integer((I mod iPerLine)=0));
      Buttons[I].Left := iWtoW + (iWidth+iWtoW) * ((I-1) mod iPerLine);
      Buttons[I].Show;
      qryGoods.Next;
    end;
    qryGoodsType.Next;
  end;
  pgcGoodsType.TabIndex :=0;
end;end.
请问是哪儿的问题?先谢谢了

解决方案 »

  1.   

    构造析构没做好吧,还有放在Show里面不好吧,窗体建后,可以执行多次SHOW的.在OnClose里面加上循环,是否为NIL,不为即FREE.
      

  2.   

    show时的代码建议放在别处,在close或closequery事件中处理。。
      

  3.   

    创建的时候最好放在create中,在show中可能会多次创建。
    如果是
    TbtnMyButtons.Create(Self);创建的。Destroy的时候可以操作,
    form会自动帮你释放。
      

  4.   

    楼主这是DLL里面的窗体吧?SHAREMEM写错地方了,应该写在工程文件的第一位,而不是单元文件的第一位。
      

  5.   

    我放在create中创建还是产生一样的问题
      

  6.   

    最后将内存分配加1就没问题了,不太明白为什么,还请高手解答
      setlength(Tabs,qryGoodsType.RecordCount+1);
      SetLength(Buttons,qryGoods.RecordCount * qryGoodsType.RecordCount+1);
      

  7.   

    因为数组是从0开始的,
    而你给数组赋值是从1开始的,
    看这段代码
         J:= qryGoodsType.RecNo;//这里j的最小值是1
        I:=0;
        Tabs[J] := TTabSheet.Create(Self);所以你不加1的话,数组的长度是不够的。
      

  8.   

    就是说你通过setlength设定数组长度为5,数组下标是从0到4
    而你赋值时是从1到5,这样就出问题了,因为tabs[5]不存在啊,虽然数组长度和循环次数都是5