Не могу перекрыть базовый метод [Delphi]
нельзя перекрыть статический метод?
проблема в том, что он статический, а не виртуальный/невиртуальный
Я не совсем понял. А "virtual" тогда для чего дописывают?
Если очень надо - переписывай Classes.pas в каталог своего проекта и включай его в проект. Ещё лучше - переобзови его как myClasses.pas.
Если нужно серьёзное расширение базовых классов, советую посмотреть в сторону JCL - это опенсорсная коллекция библиотек, которые существенно расширяют модули Classes, SysUtils и им подобные.
потому что нельзя менять системные исходники. они даны AS IS, так сказать FYI.Да, я уже понял. Засада, блин. Буду делать свой юнит.
Если очень надо - переписывай Classes.pas в каталог своего проекта и включай его в проект. Ещё лучше - переобзови его как myClasses.pas.
Если нужно серьёзное расширение базовых классов, советую посмотреть в сторону JCL - это опенсорсная коллекция библиотек, которые существенно расширяют модули Classes, SysUtils и им подобные.А они идут как надстройка над системными библиотеками или устанавливаются вместо их?
ну и будут называться типа jcClasses, jcStrUtils etc
Так что "не боги горшки обжигают". Это я к твоему "аффтор...зачем использовать говно 20-давности..." в соседней теме. Откуда тебе знать, зачем я TC использую? Может он и говно, но я его на КПК под Dos гоняю, потому что мне удобно. Такие дела.
вот вам пример:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
const
TMWM__SpecialInvalidate = WM_USER + 1111;
type
TEdit = class(StdCtrls.TEdit)
private
FClarity : Boolean;
procedure SetClarity(const Value: Boolean);
{ Private declarations }
protected
{ Protected declarations }
procedure CMEraseBkgnd (var Message: TWMEraseBkgnd); Message WM_ERASEBKGND;
procedure WMSetText (var Message: TWMSetText);
procedure SpecialInvalidate(var Message: TMessage); message TMWM__SpecialInvalidate;
procedure CNCTLCOLOREDIT (var Message: TWMCTLCOLOREDIT); message CN_CTLCOLOREDIT;
procedure WMKeyDown (var Message: TWMKeyDown); message WM_KEYDOWN;
procedure WMKillFocus (Var Message: TWMKillFocus); Message WM_KillFocus;
procedure WMLButtonDown (Var Message: TWMLButtonDown); Message WM_LButtonDown;
procedure WMMove (Var Message: TWMLButtonDown); Message WM_Move;
procedure WMMouseMove (Var Message: TWMMouseMove); Message WM_MouseMove;
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
procedure Invalidate; override;
property Clarity:Boolean read FClarity write SetClarity default True;
end;
TForm1 = class(TForm)
Edit1: TEdit;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TEdit }
procedure TEdit.CMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
if Clarity then
Message.Result := 1;
end;
procedure TEdit.CNCTLCOLOREDIT(var Message: TWMCTLCOLOREDIT);
begin
if Clarity then
with Message do
begin
SetBkMode(ChildDC,Windows.TRANSPARENT);
Result:=GetStockObject(HOLLOW_BRUSH);
end
else inherited;
end;
constructor TEdit.Create(AOwner: TComponent);
begin
inherited create(AOwner);
BorderStyle := bsNone;
BevelKind := bkNone;
Clarity:=true;
end;
procedure TEdit.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
if (CsDesigning in ComponentState) then exit;
with Params do
begin
ExStyle:=ExStyle or WS_EX_TRANSPARENT;
end;
end;
procedure TEdit.CreateWnd;
begin
inherited CreateWnd;
if Clarity then
begin
SetWindowLong(Parent.Handle, GWL_STYLE,
GetWindowLong(Parent.Handle, GWL_STYLE) and not WS_CLIPCHILDREN);
end;
end;
procedure TEdit.Invalidate;
begin
if Clarity then PostMessage(Handle,TMWM__SpecialInvalidate,0,0)
else inherited;
end;
procedure TEdit.SetClarity(const Value: Boolean);
begin
FClarity := Value;
end;
procedure TEdit.SpecialInvalidate(var Message: TMessage);
var
rect:TRect;
begin
if Parent<>nil then
begin
rect:=ClientRect;
rect.TopLeft:=Parent.ScreenToClient(ClientToScreen(rect.TopLeft;
rect.BottomRight:=Parent.ScreenToClient(ClientToScreen(rect.BottomRight;
InvalidateRect(Parent.Handle,@rect,true);
RedrawWindow(Handle,nil,0,RDW_FRAME+RDW_INVALIDATE)
end;
end;
procedure TEdit.WMKeyDown(var Message: TWMKeyDown);
begin
SendMessage(Handle,TMWM__SpecialInvalidate,0,0);
inherited;
PostMessage(Handle,TMWM__SpecialInvalidate,0,0);
end;
procedure TEdit.WMKillFocus(var Message: TWMKillFocus);
begin
inherited;
if not (csDesigning in ComponentState) then
PostMessage(Handle,TMWM__SpecialInvalidate,0,0)
end;
procedure TEdit.WMLButtonDown(var Message: TWMLButtonDown);
begin
inherited;
if not (csDesigning in ComponentState) then
PostMessage(Handle,TMWM__SpecialInvalidate,0,0);
end;
procedure TEdit.WMMouseMove(var Message: TWMMouseMove);
begin
inherited;
if not (csDesigning in ComponentState) then
PostMessage(Handle,TMWM__SpecialInvalidate,0,0);
end;
procedure TEdit.WMMove(var Message: TWMLButtonDown);
begin
inherited;
//if not (csDesigning in ComponentState) then
PostMessage(Handle,TMWM__SpecialInvalidate,0,0);
end;
procedure TEdit.WMSetText(var Message: TWMSetText);
begin
inherited;
if not (csDesigning in ComponentState) then
PostMessage(Handle,TMWM__SpecialInvalidate,0,0);
end;
end.
Но гораздо правильнее запихать его в пэкадж, и присвоить какое-нибудь собственное имя.
исходники подменять нельзяВ смысле? Перекомпилировать как раз можно. Другое дело, что нежалательно их корректировать.
А что за задача возникла такая, что надо менять Classes.pas? Напиши, порешаем.
Всё, что пользователю может взбрести в голову перекрывать - объявлено как virtual. Например, Sort у TStringList-a
примеры что-то не могу уже припомнить.
?например wm_paint у всяких компонентов(нед ide под рукой, завтра мб гляну)
если ты рисуешь на компоненте нечто, для чего этот компонент не предназначен - это же бред. для этого есть TImage.
рисую я обычно на контролах.
ведь канвас и там и там, а у имаджа ещё и перерисовку не надо свою писать...
Хотя бы тем, что не контролы не могут получать фокус.
перерисовку не надо свою писать...Ещё как надо, а тут - подправил чуток и ок! =)
можешь привести конкретный пример?
Например - выше в теме эдит с прозрачным фоном.
Оставить комментарий
dimon72
Хочу перекрыть метод из юнита Classes. Дописываю в конце объявления метода (в Classes) "virtual", сохраняю юнит. В методе класса-наследника дописываю "override". При компиляции говорит, что нельзя перекрыть статический метод. Непонятно. Я же в базовом классе объявил этот метод виртуальным. Что здесь не правильно?