如何实现一个控件继承另一个控件的方法 AstaClientdataset已有AstaClientdataset.refresh,但我不满意这个控件的refresh方法的效果,我想要用Clientdataset.refresh方法代替AstaClientdataset.refresh。。请问我该怎么做呢? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 简单参考fixvcl的方式,替代即可 可以用Clientdataset.refresh方法写到AstaClientdataset.refresh中去,需要重新编译控件,安装。 继承一个,重新overload该方法,不行吗? type myds =class(TClientDataSet) public procedure Refresh;overload; end;然后实现这个访求就可以 type myds =class(AstaClientdataset) public procedure Refresh;overload; end; procedure myds.Refresh;begin //inherited; 注释这句//这里不需要继承原来的方法 补上你自己的代码即可end; overload不会有inherited;这句 对,是OVERRIDE重写,OVERLOAD是重载 是override 眼神不好使,没改过来 我测试了,不行哟type myds =class(TAstaClientdataset) public procedure Refresh;override; //这里编译通不过 提示 E2170 Cannot override a non-virtual method end; 這是我之前玩的,目的是在不修改控件的情況下,使rzDBNumericEdit能觸發OnGetText的功能。代碼如下:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Mask, RzDBEdit, db, RzEdit, Grids, DBGrids, ADODB;type TJumpOfs = Integer; PPointer = ^Pointer; PXRedirCode = ^TXRedirCode; TXRedirCode = packed record Jump: Byte; Offset: TJumpOfs; end; PWin9xDebugThunk = ^TWin9xDebugThunk; TWin9xDebugThunk = packed record PUSH: Byte; Addr: Pointer; JMP: TXRedirCode; end; PAbsoluteIndirectJmp = ^TAbsoluteIndirectJmp; TAbsoluteIndirectJmp = packed record OpCode: Word; //$FF25(Jmp, FF /4) Addr: PPointer; end; TMyNumericEdit = class(TRzDBNumericEdit) public procedure NewDataChanged; end; TForm1 = class(TForm) ADOConnection1: TADOConnection; ADOTable1: TADOTable; DBGrid1: TDBGrid; DataSource1: TDataSource; RzDBNumericEdit1: TRzDBNumericEdit; ADOTable1BS01001: TStringField; ADOTable1BS01002: TStringField; ADOTable1BS01003: TStringField; ADOTable1BS01035: TFloatField; ADOTable1BS01036: TIntegerField; ADOTable1BS01037: TIntegerField; ADOTable1BS01038: TIntegerField; ADOTable1BS01995: TAutoIncField; ADOTable1BS01996: TStringField; ADOTable1BS01997: TStringField; ADOTable1BS01998: TDateTimeField; ADOTable1BS01999: TDateTimeField; ADOTable1BS01063: TStringField; ADOTable1BS01064: TStringField; ADOTable1BS01065: TStringField; ADOTable1BS01066: TStringField; ADOTable1BS01067: TStringField; ADOTable1BS01068: TStringField; ADOTable1BS01069: TIntegerField; ADOTable1BS01070: TIntegerField; procedure ADOTable1BS01037GetText(Sender: TField; var Text: String; DisplayText: Boolean); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1; BackupDataChanged : TXRedirCode;implementation{$R *.dfm}function GetActualAddr(Proc: Pointer): Pointer; function IsWin9xDebugThunk(AAddr: Pointer): Boolean; begin Result := (AAddr <> nil) and (PWin9xDebugThunk(AAddr).PUSH = $68) and (PWin9xDebugThunk(AAddr).JMP.Jump = $E9); end;begin if Proc <> nil then begin if (Win32Platform <> VER_PLATFORM_WIN32_NT) and IsWin9xDebugThunk(Proc) then Proc := PWin9xDebugThunk(Proc).Addr; if (PAbsoluteIndirectJmp(Proc).OpCode = $25FF) then Result := PAbsoluteIndirectJmp(Proc).Addr^ else Result := Proc; end else Result := nil;end;procedure HookProc(Proc, Dest: Pointer; var BackupCode: TXRedirCode);var n: DWORD; Code: TXRedirCode;begin Proc := GetActualAddr(Proc); Assert(Proc <> nil); if ReadProcessMemory(GetCurrentProcess, Proc, @BackupCode, SizeOf(BackupCode), n) then begin Code.Jump := $E9; Code.Offset := PAnsiChar(Dest) - PAnsiChar(Proc) - SizeOf(Code); WriteProcessMemory(GetCurrentProcess, Proc, @Code, SizeOf(Code), n); end;end;procedure UnhookProc(Proc: Pointer; var BackupCode: TXRedirCode);var n: Cardinal;begin if (BackupCode.Jump <> 0) and (Proc <> nil) then begin Proc := GetActualAddr(Proc); Assert(Proc <> nil); WriteProcessMemory(GetCurrentProcess, Proc, @BackupCode, SizeOf(BackupCode), n); BackupCode.Jump := 0; end;end;{ TMyNumericEdit }procedure TMyNumericEdit.NewDataChanged;begin if Field <> nil then begin if AllowBlank and Field.IsNull then Text := '' else begin Value := strtofloat(DataLink.Field.Text); Text := FormatText( Value ); end; end else begin if csDesigning in ComponentState then EditText := Name else EditText := ''; end;end;procedure TForm1.ADOTable1BS01037GetText(Sender: TField; var Text: String; DisplayText: Boolean);begin ShowMessage(Text);end;procedure TForm1.FormCreate(Sender: TObject);begin ADOTable1.Active := True;end;initialization HookProc(@TMyNumericEdit.DataChanged, @TMyNumericEdit.NewDataChanged, BackupDataChanged);finalization UnhookProc(@TMyNumericEdit.DataChanged, BackupDataChanged);end.另外,hook的方法會受到封裝級別的限制(private,protected....)。當然,是否為虛方法,做法也不同。只要熟悉rtti,這些不是問題. 楼上是给出了相关重载的方法,具体自己可以去实现,参考一下Clientdataset.refresh 的写法。 你使用不了ClientdataSet的Refresh的方法,因为Refresh的方法是在TDataSet类中定义的,并且该方法不是虚拟或动态的方法,不能被override的; 有个非常简单的问题想请教大家!! 如何用adoquery配合sql删除数据表中的所有数据? 在TTreeView中,怎样取得选中节点的根节点。 Delphi的指数函数X的Y次方是什么? 西安某软件公司拖欠我工资三个月,可到年底,把最后一个月给没收了,气愤,想要告它! 一个关于OLE的弱弱的问题!---后台运行. AVI 资源问题,见者有分??? 如何将文件内容读入StringStream中 如何将delphi 中的数据库,转换成orancle 数据库? 查询结果赋值给变量出错 delphi 增删改查写在一个类里面,增删改可以,查询没反应 写网络桌面程序,我应该用那些组件啊?
需要重新编译控件,安装。
myds =class(TClientDataSet)
public
procedure Refresh;overload;
end;然后实现这个访求就可以
myds =class(AstaClientdataset)
public
procedure Refresh;overload;
end;
procedure myds.Refresh;
begin
//inherited; 注释这句//这里不需要继承原来的方法
补上你自己的代码即可
end;
overload不会有inherited;这句
对,是OVERRIDE重写,OVERLOAD是重载
眼神不好使,没改过来
myds =class(TAstaClientdataset)
public
procedure Refresh;override; //这里编译通不过 提示 E2170 Cannot override a non-virtual method
end;
代碼如下:unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Mask, RzDBEdit, db, RzEdit, Grids, DBGrids, ADODB;type
TJumpOfs = Integer;
PPointer = ^Pointer; PXRedirCode = ^TXRedirCode;
TXRedirCode = packed record
Jump: Byte;
Offset: TJumpOfs;
end; PWin9xDebugThunk = ^TWin9xDebugThunk;
TWin9xDebugThunk = packed record
PUSH: Byte;
Addr: Pointer;
JMP: TXRedirCode;
end; PAbsoluteIndirectJmp = ^TAbsoluteIndirectJmp;
TAbsoluteIndirectJmp = packed record
OpCode: Word; //$FF25(Jmp, FF /4)
Addr: PPointer;
end; TMyNumericEdit = class(TRzDBNumericEdit) public
procedure NewDataChanged;
end; TForm1 = class(TForm)
ADOConnection1: TADOConnection;
ADOTable1: TADOTable;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
RzDBNumericEdit1: TRzDBNumericEdit;
ADOTable1BS01001: TStringField;
ADOTable1BS01002: TStringField;
ADOTable1BS01003: TStringField;
ADOTable1BS01035: TFloatField;
ADOTable1BS01036: TIntegerField;
ADOTable1BS01037: TIntegerField;
ADOTable1BS01038: TIntegerField;
ADOTable1BS01995: TAutoIncField;
ADOTable1BS01996: TStringField;
ADOTable1BS01997: TStringField;
ADOTable1BS01998: TDateTimeField;
ADOTable1BS01999: TDateTimeField;
ADOTable1BS01063: TStringField;
ADOTable1BS01064: TStringField;
ADOTable1BS01065: TStringField;
ADOTable1BS01066: TStringField;
ADOTable1BS01067: TStringField;
ADOTable1BS01068: TStringField;
ADOTable1BS01069: TIntegerField;
ADOTable1BS01070: TIntegerField;
procedure ADOTable1BS01037GetText(Sender: TField; var Text: String;
DisplayText: Boolean);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
BackupDataChanged : TXRedirCode;
implementation{$R *.dfm}
function GetActualAddr(Proc: Pointer): Pointer; function IsWin9xDebugThunk(AAddr: Pointer): Boolean;
begin
Result := (AAddr <> nil) and
(PWin9xDebugThunk(AAddr).PUSH = $68) and
(PWin9xDebugThunk(AAddr).JMP.Jump = $E9);
end;begin
if Proc <> nil then
begin
if (Win32Platform <> VER_PLATFORM_WIN32_NT) and IsWin9xDebugThunk(Proc) then
Proc := PWin9xDebugThunk(Proc).Addr;
if (PAbsoluteIndirectJmp(Proc).OpCode = $25FF) then
Result := PAbsoluteIndirectJmp(Proc).Addr^
else
Result := Proc;
end
else
Result := nil;
end;procedure HookProc(Proc, Dest: Pointer; var BackupCode: TXRedirCode);
var
n: DWORD;
Code: TXRedirCode;
begin
Proc := GetActualAddr(Proc);
Assert(Proc <> nil);
if ReadProcessMemory(GetCurrentProcess, Proc, @BackupCode, SizeOf(BackupCode), n) then
begin
Code.Jump := $E9;
Code.Offset := PAnsiChar(Dest) - PAnsiChar(Proc) - SizeOf(Code);
WriteProcessMemory(GetCurrentProcess, Proc, @Code, SizeOf(Code), n);
end;
end;procedure UnhookProc(Proc: Pointer; var BackupCode: TXRedirCode);
var
n: Cardinal;
begin
if (BackupCode.Jump <> 0) and (Proc <> nil) then
begin
Proc := GetActualAddr(Proc);
Assert(Proc <> nil);
WriteProcessMemory(GetCurrentProcess, Proc, @BackupCode, SizeOf(BackupCode), n);
BackupCode.Jump := 0;
end;
end;
{ TMyNumericEdit }procedure TMyNumericEdit.NewDataChanged;begin
if Field <> nil then
begin
if AllowBlank and Field.IsNull then
Text := ''
else
begin
Value := strtofloat(DataLink.Field.Text);
Text := FormatText( Value );
end;
end
else
begin
if csDesigning in ComponentState then
EditText := Name
else
EditText := '';
end;
end;procedure TForm1.ADOTable1BS01037GetText(Sender: TField; var Text: String;
DisplayText: Boolean);
begin
ShowMessage(Text);
end;procedure TForm1.FormCreate(Sender: TObject);
begin
ADOTable1.Active := True;
end;initialization
HookProc(@TMyNumericEdit.DataChanged, @TMyNumericEdit.NewDataChanged, BackupDataChanged);
finalization
UnhookProc(@TMyNumericEdit.DataChanged, BackupDataChanged);
end.另外,hook的方法會受到封裝級別的限制(private,protected....)。當然,是否為虛方法,做法也不同。只要熟悉rtti,這些不是問題.
楼上是给出了相关重载的方法,具体自己可以去实现,参考一下Clientdataset.refresh 的写法。