Access violation at address 40341575 in module 'dbrtl70.bpl'. Read of address 000000D2.
unit PrefEdDb;
interface
uses WinTypes, WinProcs, Messages, SysUtils, Classes, Controls,
Forms, Graphics, Dbctrls, Windows, ExtCtrls, StdCtrls, Variants;
type
TPrefEdDb = class(TDBEdit)
private
FPre : String;
FSuff : String;
procedure AutoInitialize;
procedure AutoDestroy;
function GetPre : String;
procedure SetPre(Value : String);
function GetSuff : String;
procedure SetSuff(Value : String);
function DoFull:string;
protected
procedure Change; override;
procedure Click; override;
procedure DoExit; override;
procedure KeyPress(var Key : Char); override;
procedure Loaded; override;
public
Full : String;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property OnChange;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property Pre : String read GetPre write SetPre;
property Suff : String read GetSuff write SetSuff;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TPrefEdDb]);
end;
function TPrefEdDb.DoFull:string;
var
s:string;
begin
result:='';
if ((Field.Text<>'') or (Field.Value<>null)) then
begin
s:='';
if FPre<>'' then s:=FPre;
s:=s+field.Text;
if FSuff<>'' then s:=s+FSuff;
Result:=s;
end;
end;
procedure TPrefEdDb.AutoInitialize;
begin
Full := '';
FPre := '';
FSuff := '';
end;
procedure TPrefEdDb.AutoDestroy;
begin
{ No objects from AutoInitialize to free }
end;
function TPrefEdDb.GetPre : String;
begin
Result := FPre;
end;
procedure TPrefEdDb.SetPre(Value : String);
begin
FPre := Value;
end;
function TPrefEdDb.GetSuff : String;
begin
Result := FSuff;
end;
procedure TPrefEdDb.SetSuff(Value : String);
begin
FSuff := Value;
end;
procedure TPrefEdDb.Change;
begin
inherited Change;
if Field.Text<>'' then Full:=DoFull;
end;
procedure TPrefEdDb.Click;
begin
inherited Click;
end;
procedure TPrefEdDb.DoExit;
begin
inherited DoExit;
end;
procedure TPrefEdDb.KeyPress(var Key : Char);
const
TabKey = Char(VK_TAB);
EnterKey = Char(VK_RETURN);
begin
inherited KeyPress(Key);
end;
constructor TPrefEdDb.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
AutoInitialize;
end;
destructor TPrefEdDb.Destroy;
begin
AutoDestroy;
inherited Destroy;
end;
procedure TPrefEdDb.Loaded;
begin
inherited Loaded;
end;
end.
问题是您假设当您引用 Field 时它不是 Nil。
如果连接到您的组件的数据集使用非持久性 TFields,它们的值将
在数据集打开之前为 Nil。
进行如下所示的更改
function TPrefEdDb.DoFull:string;
var
s:string;
begin
result:='';
Assert(Field <> Nil); // MA
if Field = Nil then exit; // MA
if ((Field.Text<>'') or (Field.Value<>null)) then
begin
s:='';
if FPre<>'' then s:=FPre;
s:=s+field.Text;
if FSuff<>'' then s:=s+FSuff;
Result:=s;
end;
end;
procedure TPrefEdDb.Change;
begin
inherited Change;
Assert(Field <> Nil); // MA
if Field = Nil then exit; // MA
if Field.Text<>'' then Full:=DoFull;
end;
procedure TPrefEdDb.Change;
begin
inherited Change;
if Field.Text<>'' then Full:=DoFull;
end;
所以我修改成这个
procedure TPrefEdDb.Change;
begin
inherited Change;
if ((DataSource<>nil) and (DataSource.DataSet.Active=True) and (Field.AsString<>''))
then Full:=DoFull;
end;