Не могу перекрыть базовый метод [Delphi]
может, потому что
проблема в том, что он статический, а не виртуальный/невиртуальный
нельзя перекрыть статический метод?
проблема в том, что он статический, а не виртуальный/невиртуальный
Я не совсем понял. А "virtual" тогда для чего дописывают?
потому что нельзя менять системные исходники. они даны AS IS, так сказать FYI.
Если очень надо - переписывай Classes.pas в каталог своего проекта и включай его в проект. Ещё лучше - переобзови его как myClasses.pas.
Если очень надо - переписывай Classes.pas в каталог своего проекта и включай его в проект. Ещё лучше - переобзови его как myClasses.pas.
Если нужно серьёзное расширение базовых классов, советую посмотреть в сторону JCL - это опенсорсная коллекция библиотек, которые существенно расширяют модули Classes, SysUtils и им подобные.
потому что нельзя менять системные исходники. они даны AS IS, так сказать FYI.Да, я уже понял. Засада, блин. Буду делать свой юнит.
Если очень надо - переписывай Classes.pas в каталог своего проекта и включай его в проект. Ещё лучше - переобзови его как myClasses.pas.
Если нужно серьёзное расширение базовых классов, советую посмотреть в сторону JCL - это опенсорсная коллекция библиотек, которые существенно расширяют модули Classes, SysUtils и им подобные.А они идут как надстройка над системными библиотеками или устанавливаются вместо их?
как отдельные юниты будут.
ну и будут называться типа jcClasses, jcStrUtils etc
ну и будут называться типа jcClasses, jcStrUtils etc
Понятно. Спасибо. А VCL-то можно перекомпилить.
1. стираешь *.dcu-файл, нужной тебе библиотеки, который лежит в директории Lib. 2. Закидываешь в эту же директорию правленный *.pas той же библиотеки. В программе, использующей эту библиотеку, делаешь "Compile All". Компилятор создаст новый *.dcu. 3. Можешь удалить правленный *.pas из директории Lib. Всё. Таким образом мне-таки удалось перекрыть метод NextToken класса TParser, который реализован с ошибкой.
Так что "не боги горшки обжигают". Это я к твоему "аффтор...зачем использовать говно 20-давности..." в соседней теме. Откуда тебе знать, зачем я TC использую? Может он и говно, но я его на КПК под Dos гоняю, потому что мне удобно. Такие дела.
1. стираешь *.dcu-файл, нужной тебе библиотеки, который лежит в директории Lib. 2. Закидываешь в эту же директорию правленный *.pas той же библиотеки. В программе, использующей эту библиотеку, делаешь "Compile All". Компилятор создаст новый *.dcu. 3. Можешь удалить правленный *.pas из директории Lib. Всё. Таким образом мне-таки удалось перекрыть метод NextToken класса TParser, который реализован с ошибкой.Так что "не боги горшки обжигают". Это я к твоему "аффтор...зачем использовать говно 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
Всё, что пользователю может взбрести в голову перекрывать - объявлено как virtual. Например, Sort у TStringList-a
Не всё.
примеры что-то не могу уже припомнить.
?например wm_paint у всяких компонентов(нед ide под рукой, завтра мб гляну)
примеры что-то не могу уже припомнить.
?например wm_paint у всяких компонентов(нед ide под рукой, завтра мб гляну)
а зачем wm_paint перекрывать?!
если ты рисуешь на компоненте нечто, для чего этот компонент не предназначен - это же бред. для этого есть TImage.
если ты рисуешь на компоненте нечто, для чего этот компонент не предназначен - это же бред. для этого есть TImage.
имадж - графический компонент.
рисую я обычно на контролах.
рисую я обычно на контролах.
почему для этих целей не подходит image?
ведь канвас и там и там, а у имаджа ещё и перерисовку не надо свою писать...
ведь канвас и там и там, а у имаджа ещё и перерисовку не надо свою писать...
Много чем...
Хотя бы тем, что не контролы не могут получать фокус.
Хотя бы тем, что не контролы не могут получать фокус.
перерисовку не надо свою писать...Ещё как надо, а тут - подправил чуток и ок! =)
что-то я тогда не понимаю.
можешь привести конкретный пример?
можешь привести конкретный пример?
Например - выше в теме эдит с прозрачным фоном.
Оставить комментарий
dimon72
Хочу перекрыть метод из юнита Classes. Дописываю в конце объявления метода (в Classes) "virtual", сохраняю юнит. В методе класса-наследника дописываю "override". При компиляции говорит, что нельзя перекрыть статический метод. Непонятно. Я же в базовом классе объявил этот метод виртуальным. Что здесь не правильно?