关于delphi窗体继承问题请教

stephenchern 2016-04-06 11:07:08
假设
父类窗体frmA
通过delphi继承创建窗体的方法继承出frmA1 和 frmA2,frmA中有查询变量Query也同时被继承,然后在frmA基类窗体中的关闭事件上有对Query进行关闭释放操作

代码如下:
type
TfrmA1 = class(TfrmA)

type
TfrmA2 = class(TfrmA)

现在问题是 界面上同时打开了frmA1 和 frmA2
当A1关闭时 A2里面的Query也被关闭了
感觉是共享同一个内存块了
还请指教 这里我要怎么修改其继承方式? 动态? 静态? 在基类窗体中怎么设置? 还请指教 谢谢。。。
...全文
501 点赞 收藏 14
写回复
14 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
stephenchern 2016-09-14
这个问题 还是没解决 郁闷ing、
回复
stephenchern 2016-08-12
继续讨教啊 这个问题 还是最终没解决 嗨。。。。 只能怪自己基础不够扎实 应该是基础哪里错了。
回复
stephenchern 2016-04-23
在类里面的。 很奇怪 现在还没研究透 凑合先用了 继续讨教ing
回复
yuetianbao 2016-04-08
你这个Query会不会是公共资源?肯定的说,理论上不可能出现这种情况!Query应该被包在private、protected或public里面(窗体上拖放的控件属于public),你的Query如果是放在type TForm...end之外,则属于全局变量,另外还有一种可能,你这个Query引的是其它单元的对象(比如DataModule)。
回复
英年渐肥 2016-04-07
应该不会的。另外看了constructor函数。子类不能比父类范围减小,一般不建议这样做。而是采用覆盖或重载。是否需要基础由inherited;控制。另外,变量的构建后一般不需要手动释放;由其owner释放。只要采用类构建实例构建窗体不会出现这种问题的。
回复
stephenchern 2016-04-07
我在基类窗体中 析构函数注释掉对query的free 就没问题 您的意思是说 基类窗体中 无需free query这样的实体变量是吧? 问题很奇怪 我觉得应该是不会影响到 这里还有个细节 是子类a的窗体上 调用子类b b关掉 a会被影响 query也被关了。
回复
stephenchern 2016-04-06
是啊 原本应该是这样 但是就是A2关闭掉后 A1的数据集也被关了 但是在A1上重新点下刷新 又可以出来 父类A里面是有对这个query关闭释放 我做了个实验 把 父类的query关闭释放注释掉 就可以了 但是总觉得不好 应该是我哪里没写好吧 是不是还有什么静态 动态的设置什么的?
回复
怎么可能? 继承了,A2就拥有了自己独立的对象实例,和父类没关系了
回复
stephenchern 2016-04-06
基类单元 unit unt_frmBasicReport; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, unt_frmBasic, RzPanel, RzButton, DateUtils, Vcl.ExtCtrls, cxGraphics, cxControls, cxLookAndFeels, cxLookAndFeelPainters, cxContainer, cxEdit, cxTextEdit, cxMaskEdit, cxDropDownEdit, cxCalendar, unt_UniDACProc, cxStyles, cxCustomData, cxFilter, cxData, cxDataStorage, Data.DB, cxDBData, cxGridLevel, cxClasses, cxGridCustomView, cxGridCustomTableView, Uni, cxGridTableView, cxGridDBTableView, cxGrid, Vcl.Menus, Vcl.StdCtrls, Vcl.ImgList, unt_FTPProc; type TfrmBasicReport = class(TfrmBasic) RzToolbar: TRzToolbar; btnSelect: TRzToolButton; btnExit: TRzToolButton; RzSpacer3: TRzSpacer; dedtBeginDate: TcxDateEdit; dedtEndDate: TcxDateEdit; btnQuery: TRzToolButton; cxGrid: TcxGrid; glEntity: TcxGridLevel; PopupMenu: TPopupMenu; Label1: TLabel; Label2: TLabel; RzSpacer1: TRzSpacer; N1: TMenuItem; N2: TMenuItem; N3: TMenuItem; N4: TMenuItem; N5: TMenuItem; N6: TMenuItem; N7: TMenuItem; N8: TMenuItem; N9: TMenuItem; N10: TMenuItem; btnExport: TRzToolButton; glCommodity: TcxGridLevel; procedure N1Click(Sender: TObject); procedure N2Click(Sender: TObject); procedure btnExitClick(Sender: TObject); procedure N3Click(Sender: TObject); procedure N4Click(Sender: TObject); procedure N5Click(Sender: TObject); procedure N10Click(Sender: TObject); procedure N6Click(Sender: TObject); procedure N7Click(Sender: TObject); procedure N8Click(Sender: TObject); procedure N9Click(Sender: TObject); procedure cxGridDBTableViewCustomDrawIndicatorCell(Sender: TcxGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean); procedure FormDestroy(Sender: TObject); procedure btnExportClick(Sender: TObject); private { Private declarations } public { Public declarations } protected { Protected declarations } EmployeeID, Url: string; UniConnection: TUniConnection; qryEntity, qryCommodity, qryDetail: TUniQuery; dsEntity, dsCommodity, dsDetail: TUniDataSource; constructor Create(Owner: TComponent; EmployeeID, Url: string; UniConnection: TUniConnection); reintroduce; function Check: Boolean; procedure ExportExcel(FileName: string); end; implementation uses unt_DBProc, unt_OtherProc, cxGridExportLink; {$R *.dfm} procedure TfrmBasicReport.btnExitClick(Sender: TObject); begin inherited; Close; end; procedure TfrmBasicReport.btnExportClick(Sender: TObject); begin inherited; ExportExcel(Caption); end; function TfrmBasicReport.Check: Boolean; begin Result := True; if VarIsNullDate(dedtBeginDate.Date) then begin MsgDlg('请制定起始日期', '提示', MB_OK + MB_ICONINFORMATION); dedtBeginDate.SetFocus; Result := False; Exit; end; if VarIsNullDate(dedtEndDate.Date) then begin MsgDlg('请制定截止日期', '提示', MB_OK + MB_ICONINFORMATION); dedtEndDate.SetFocus; Result := False; Exit; end; end; constructor TfrmBasicReport.Create(Owner: TComponent; EmployeeID, Url: string; UniConnection: TUniConnection); begin inherited Create(Owner); Self.EmployeeID := EmployeeID; Self.UniConnection := UniConnection; Self.Url := Url; CreateUniDataSetAndDataSource(qryEntity, dsEntity, UniConnection, Self); CreateUniDataSetAndDataSource(qryCommodity, dsCommodity, UniConnection, Self); CreateUniDataSetAndDataSource(qryDetail, dsDetail, UniConnection, Self); dedtBeginDate.Date := Date - DayOfWeek(Date) + 2; dedtEndDate.Date := dedtBeginDate.Date + 6; glEntity.Active := True; end; procedure TfrmBasicReport.cxGridDBTableViewCustomDrawIndicatorCell( Sender: TcxGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean); var FValue: string; FBounds: TRect; begin//左边显示序号 inherited; if (AViewInfo is TcxGridIndicatorRowItemViewInfo) then begin FValue := IntToStr(TcxGridIndicatorRowItemViewInfo(AViewInfo).GridRecord.Index+1); FBounds := AViewInfo.Bounds; ACanvas.FillRect(FBounds); ACanvas.DrawComplexFrame(FBounds, clBtnHighlight, clBtnShadow, [bBottom, bLeft, bRight], 1); InflateRect(FBounds, -1, -1); ACanvas.Font.Color := clBlack; ACanvas.Brush.Style := bsClear; ACanvas.DrawText(FValue, FBounds, cxAlignCenter or cxAlignTop); ADone := True; end; end; procedure TfrmBasicReport.ExportExcel(FileName: string); begin if not Check then Exit; FileName := dedtBeginDate.Text + ' 至 ' + dedtEndDate.Text + ' ' + FileName + '.xls';//' 个体账面库存汇总表.xls'; if SelectFile('导出另存为', GetSpecialFolder(sfDesktop), 'Excel(*.xls)|.xls|所有文件(*.*)|*.*', 'xls', FileName) then begin ExportGridToExcel(FileName, cxGrid); MsgDlg('导出成功', '提示', MB_OK + MB_ICONINFORMATION); end; end; procedure TfrmBasicReport.FormDestroy(Sender: TObject); begin inherited; qryEntity.Connection.Connected := False; qryEntity.Free; dsEntity.Free; qryCommodity.Connection.Connected := False; qryCommodity.Free; dsCommodity.Free; qryDetail.Connection.Connected := False; qryDetail.Free; dsDetail.Free; end; procedure TfrmBasicReport.N10Click(Sender: TObject); begin inherited; dedtBeginDate.Text := FormatDateTime('yyyy-mm-11', Now); dedtEndDate.Text := FormatDateTime('yyyy-mm-20', Now); end; procedure TfrmBasicReport.N1Click(Sender: TObject); begin inherited; dedtBeginDate.Date := Date; dedtEndDate.Date := dedtBeginDate.Date; end; procedure TfrmBasicReport.N2Click(Sender: TObject); begin inherited; dedtBeginDate.Date := Date - DayOfWeek(Date) + 2; dedtEndDate.Date := dedtBeginDate.Date + 6; end; procedure TfrmBasicReport.N3Click(Sender: TObject); begin inherited; dedtBeginDate.Date := Date - DayOfWeek(Date) - 5; dedtEndDate.Date := dedtBeginDate.Date + 6; end; procedure TfrmBasicReport.N4Click(Sender: TObject); begin inherited; dedtBeginDate.Text := FormatDateTime('yyyy-mm-dd', StartOfTheMonth(Now)); dedtEndDate.Text := FormatDateTime('yyyy-mm-dd', EndOfTheMonth(Now)); end; procedure TfrmBasicReport.N5Click(Sender: TObject); begin inherited; dedtBeginDate.Text := FormatDateTime('yyyy-mm-01', Now); dedtEndDate.Text := FormatDateTime('yyyy-mm-10', Now); end; procedure TfrmBasicReport.N6Click(Sender: TObject); begin inherited; dedtBeginDate.Text := FormatDateTime('yyyy-mm-21', Now); dedtEndDate.Text := FormatDateTime('yyyy-mm-dd', EndOfTheMonth(Now)); end; procedure TfrmBasicReport.N7Click(Sender: TObject); begin inherited; dedtBeginDate.Text := FormatDateTime('yyyy-mm-dd', StartOfTheMonth(IncMonth(Now, -1))); dedtEndDate.Text := FormatDateTime('yyyy-mm-dd', EndOfTheMonth(IncMonth(Now, -1))); end; procedure TfrmBasicReport.N8Click(Sender: TObject); begin inherited; dedtBeginDate.Text := FormatDateTime('yyyy-mm-dd', StartOfTheYear(Now)); dedtEndDate.Text := FormatDateTime('yyyy-mm-dd', EndOfTheYear(Now)); end; procedure TfrmBasicReport.N9Click(Sender: TObject); begin inherited; dedtBeginDate.Text := FormatDateTime('yyyy-mm-dd', StartOfTheYear(IncYear(Now, -1))); dedtEndDate.Text := FormatDateTime('yyyy-mm-dd', EndOfTheYear(IncYear(Now, -1))); end; end.
回复
stephenchern 2016-04-06
子类单元1 unit unt_frmReportBuySummary; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, unt_frmBasicReport, cxGraphics, unt_UniDACProc, cxControls, cxLookAndFeels, cxLookAndFeelPainters, cxContainer, cxEdit, Uni, cxStyles, cxCustomData, cxFilter, cxData, cxDataStorage, Data.DB, cxDBData, Vcl.Menus, cxGridLevel, cxClasses, cxGridCustomView, cxGridCustomTableView, cxGridTableView, cxGridDBTableView, cxGrid, cxTextEdit, cxMaskEdit, unt_FTPProc, cxDropDownEdit, cxCalendar, Vcl.StdCtrls, RzPanel, RzButton, Vcl.ExtCtrls, cxGridBandedTableView, cxGridDBBandedTableView, cxCurrencyEdit, Vcl.ImgList; type TfrmReportBuySummary = class(TfrmBasicReport) gtvEntity: TcxGridDBTableView; gtvEntityColumn1: TcxGridDBColumn; gtvEntityColumn2: TcxGridDBColumn; gtvEntityColumn3: TcxGridDBColumn; gtvEntityColumn4: TcxGridDBColumn; procedure btnQueryClick(Sender: TObject); procedure gtvEntityDblClick(Sender: TObject); private { Private declarations } constructor Create(Owner: TComponent; EmployeeID, Url: string; UniConnection: TUniConnection); reintroduce; public { Public declarations } class procedure ShowForm(Owner: TComponent; EmployeeID, Url: string; UniConnection: TUniConnection); end; implementation uses unt_DBProc, unt_OtherProc, unt_frmReportBuyDetail; {$R *.dfm} { TfrmReportBuySummary } class procedure TfrmReportBuySummary.ShowForm(Owner: TComponent; EmployeeID, Url: string; UniConnection: TUniConnection); begin with TfrmReportBuySummary.Create(Owner, EmployeeID, Url, UniConnection) do begin try Show; except Free; end; end; end; procedure TfrmReportBuySummary.btnQueryClick(Sender: TObject); begin inherited; if not Check then Exit; SqlStr := 'set names gbk;' + 'call p_report_buy_summary_entity(:BeginDate, :EndDate);'; ExecUniQueryWithParam(qryEntity, SqlStr, ['BeginDate', 'EndDate'], [dedtBeginDate.Date, dedtEndDate.Date], [ftDate, ftDate], True); end; constructor TfrmReportBuySummary.Create(Owner: TComponent; EmployeeID, Url: string; UniConnection: TUniConnection); begin inherited Create(Owner, EmployeeID, Url, UniConnection); gtvEntity.DataController.DataSource := dsEntity; end; procedure TfrmReportBuySummary.gtvEntityDblClick(Sender: TObject); begin inherited; if gtvEntity.Controller.SelectedRecordCount > 0 then TfrmReportBuyDetail.ShowForm(Self, GetSFieldValue(qryEntity, 'SupplierID'), dedtBeginDate.Text, dedtEndDate.Text, EmployeeID, Url, UniConnection); end; end.
回复
stephenchern 2016-04-06
我在子类里面 的构造函数 有调用父类里面的构造函数 子类在关闭的时候 也会调用到父类里面的destory函数 我把父类里面的destory下内容注释掉就没问题了 还是有点乱 不知道怎么回事
回复
xiaoyongxiao 2016-04-06
理论上不会有这样的问题,frmA1 和 frmA2没有直接关系,你查查吧,你的frmA1 关闭时肯定对frmA2做了什么
回复
jakefj 2016-04-06
create和destory这两个你要overload一下。不然指定的还是父类
回复
我试了,正常,不管先关闭父类还是先关闭子类,都没影响。 直接用IDE里的窗体继承,也没有选项可选,只有一个 inherited
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, DBGrids, DB, ADODB;

type
  TForm1 = class(TForm)
    qry1: TADOQuery;
    ds1: TDataSource;
    dbgrd1: TDBGrid;
    btn1: TButton;
    btn2: TButton;
    procedure btn1Click(Sender: TObject);
    procedure btn2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
begin
  qry1.Active := not qry1.Active;
end;

procedure TForm1.btn2Click(Sender: TObject);
begin
  if not Assigned(form2) then
    form2:= TForm2.Create(Application);
  try
    Form2.Show;
  except

  end;
end;

end.
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Unit1, DB, ADODB, StdCtrls, Grids, DBGrids;

type
  TForm2 = class(TForm1)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

end.
回复
相关推荐
发帖
Delphi
创建于2007-08-02

4927

社区成员

Delphi 开发及应用
申请成为版主
帖子事件
创建了帖子
2016-04-06 11:07
社区公告
暂无公告