在窗体中添加组件时出现delphi错误



嗨,我刚刚完成了一个组件,它在编辑框中键入并在下拉dbCtrlGrid中显示结果时实现了表搜索。它编译和安装没有任何问题。但是当放在窗体Delphi(7(上时,我会得到一个Stack Overflow保存您的工作并重新启动Delphi。我无法调试它,因为它不在表单上,所以有人能帮忙吗?

unit QueryPnl;
interface
uses WinTypes, WinProcs, Messages, SysUtils, Classes, Controls,
Forms, Graphics, Extctrls, Eedit, Stdctrls, ABSMain,
Db, DBCtrls, EDBEdit, dbcgrids;
type
TQueryPanel = class(TPanel)
private
Addressmem : TDBMemo;
Display : TDBCtrlGrid;
DsQ1 : TDataSource;
Head : TLabel;
FDbase : TABSDatabase;
FTableName : string;
FOnInTextChange : TNotifyEvent;
procedure AutoInitialize;
procedure AutoDestroy;
protected
InText : TEedit;
NmText : TEDBEdit;
NumText : TEDBEdit;
Q1 : TABSQuery;
procedure InTextChange(Sender : TObject); overload;
procedure DoEnter; override;
procedure DoExit; override;
procedure Click; override;
procedure KeyPress(var Key : Char); override;
procedure Loaded; override;
procedure Paint; override;
function GetFDbase : TABSDatabase;
procedure SetFDbase(Value : TABSDatabase);
function GetFTableName : string;
procedure SetFTableName(Value : string);

public
procedure InTextChange;overload;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnResize;
property DBase : TABSDatabase read FDBase write SetFDBase;
property TableName : String read FTableName write SetFTableName;
property OnInTextChange : TNotifyEvent read FOnInTextChange write FOnInTextChange;

end;

procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Data Controls', [TQueryPanel]);
end;
procedure TQueryPanel.AutoInitialize;
begin
Addressmem.Parent := Display;
with Addressmem do
begin
Left := 2;
Top := 50;
Width := 115;
Height := 50;
DataField := 'Address';
TabOrder := 1;
end;
Display.Parent := Self;
with Display do
begin
DataSource:=DsQ1;
Left := 0;
Top := 54;
Width := 138;
Height := 315;
Color := $00E8DBCE;
PanelHeight := 105;
PanelWidth := 121;
ParentColor := False;
TabOrder := 2;
end;
DsQ1.DataSet:=Q1;
Head.Parent := Self;
with Head do
begin
Left := 1;
Top := 1;
Width := 136;
Height := 13;
Align := alTop;
Alignment := taCenter;
Caption := 'Quick Name Search';
Font.Charset := DEFAULT_CHARSET;
Font.Color := clRed;
Font.Height := -12;
Font.Name := 'MS Sans Serif';
Font.Style := [fsBold];
ParentFont := False;
end;
InText.Parent := Self;
with InText do
begin
Left := 0;
Top := 25;
Width := 121;
Height := 21;
TabOrder := 0;
OnChange := InTextChange;
UpCaseFirst := True;
ColorOnFocus := clYellow;
end;
NmText.Parent := Display;
with NmText do
begin
Left := 2;
Top := 8;
Width := 115;
Height := 21;
DataField := 'Name';
Font.Charset := DEFAULT_CHARSET;
Font.Color := clWindowText;
Font.Height := -11;
Font.Name := 'MS Sans Serif';
Font.Style := [fsBold];
ParentFont := False;
TabOrder := 0;
end;
NumText.Parent := Display;
with NumText do
begin
Left := 1;
Top := 29;
Width := 115;
Height := 21;
DataField := 'Number';
Font.Style := [fsBold];
TabOrder := 2;
end;
Q1.DatabaseName:=FDBase.Name;
Q1.RequestLive:=True;
end;
procedure TQueryPanel.AutoDestroy;
begin
Addressmem.Free;
Display.Free;
DsQ1.Free;
Head.Free;
InText.Free;
NmText.Free;
NumText.Free;
Q1.Free;
end;
procedure TQueryPanel.DoEnter;
begin
inherited DoEnter;
Height := 370;
end;
procedure TQueryPanel.DoExit;
begin
inherited DoExit;
Height := 55;
end;
function TQueryPanel.GetFDbase : TABSDatabase;
begin
Result := FDbase;
end;
procedure TQueryPanel.SetFDBase(Value : TABSDatabase);
begin
FDBase := Value;
// Other code to do when selecting the database
end;
function TQueryPanel.GetFTableName : string;
begin
Result := FTableName;
end;
procedure TQueryPanel.SetFTableName(Value : String);
begin
FTableName := Value;
// Other code to do when selecting the table
end;
procedure TQueryPanel.InTextChange(Sender : TObject);
begin
if Assigned(FOnInTextChange) then
FOnInTextChange(Sender);
Q1.Close;
Q1.SQL.Text:='select * from '+FTableName+' where Name like :nem';
Q1.ParamByName('nem').asString:=InText.Text;
Q1.Open;
end;
procedure TQueryPanel.Click;
begin
inherited Click;
end;
procedure TQueryPanel.KeyPress(var Key : Char);
const
TabKey = Char(VK_TAB);
EnterKey = Char(VK_RETURN);
begin
inherited KeyPress(Key);
end;
constructor TQueryPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Addressmem := TDBMemo.Create(Self);
Display := TDBCtrlGrid.Create(Self);
DsQ1 := TDataSource.Create(Self);
InText := TEedit.Create(Self);
Head := TLabel.Create(Self);
NmText := TEDBEdit.Create(Self);
NumText := TEDBEdit.Create(Self);
Q1 := TABSQuery.Create(Self);
AutoInitialize;
end;
destructor TQueryPanel.Destroy;
begin
inherited Destroy;
end;
procedure TQueryPanel.InTextChange;
begin
//
end;
procedure TQueryPanel.Loaded;
begin
inherited Loaded;
end;
procedure TQueryPanel.Paint;
begin
inherited Paint;
end;
end.

很多时候,StackOverflow错误都是由无限递归引起的
我认为这两个过程的代码导致:

procedure SetDBase(Value : TABSDatabase);
procedure SetTableName(Value : String);

使用类似FDBaseFTableName的字段来存储值(例如(
这两个方法导致Set方法再次被无限调用。

private部分中,添加以下内容:

FDBase : TABSDataBase;
FTableName : String;

published部分中,添加:

property DBase : TABSDataBase read FDBase write SetDBase;
property TableName : String read FTableName write SetTableName;

implementation中,写入:

procedure TQueryPanel.SetDBase(Value : TABSDatabase);
begin
FDBase := Value;
// Other code to do when selecting the database
end;
procedure TQueryPanel.SetTableName(Value : String);
begin
FTableName := Value;
// Other code to do when selecting the table
end;

我在哪里发表评论";其他代码&";,如果没有什么可做的,你根本不需要二传手。

请注意,字段以字母F开头,而属性不以字母F开始。

我跟踪错误-它在TQueryPanel.AutoInitialize中;我想的线路

Q1.DatabaseName:=FDBase.Name;

放错地方了,所以我放了

procedure TQueryPanel.SetDbase(Value : TABSDatabase);
begin
FDbase:= Value;
Q1.DatabaseName:=FDBase.DatabaseName;
end;

现在效果很好。感谢大家的帮助和建议

事实并非如此DBCtrlGrid的第一个面板很好,但显然您必须将DBCtrlGrid.panel作为父面板,该面板是保留的,无法访问。遗憾的是,在有限的空间内,这似乎是一个理想的解决方案。

最新更新