Ighn
|
Helix pomatia
|
|
|
|
Рег.: 15.06.2005
|
Сообщений: 383
|
Из: Москва
|
Рейтинг: -10
|
|
Не могу перекрыть базовый метод [Delphi]
18.11.2007 03:24
|
|
|
Хочу перекрыть метод из юнита Classes. Дописываю в конце объявления метода (в Classes) "virtual", сохраняю юнит. В методе класса-наследника дописываю "override". При компиляции говорит, что нельзя перекрыть статический метод. Непонятно. Я же в базовом классе объявил этот метод виртуальным. Что здесь не правильно?
|
Incertus animus dimidium sapientiae est - Сомнение - половина мудрости |
|
Yorik
|
|
|
|
|
Рег.: 01.09.2005
|
Сообщений: 2476
|
Из: Москва
|
Рейтинг: 633
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Ighn]
18.11.2007 13:33
|
|
|
может, потому что В ответ на:
нельзя перекрыть статический метод
? проблема в том, что он статический, а не виртуальный/невиртуальный
|
|
Ighn
|
Helix pomatia
|
|
|
|
Рег.: 15.06.2005
|
Сообщений: 383
|
Из: Москва
|
Рейтинг: -10
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Yorik]
18.11.2007 13:51
|
|
|
Я не совсем понял. А "virtual" тогда для чего дописывают?
|
Incertus animus dimidium sapientiae est - Сомнение - половина мудрости |
|
Basilio
|
GreenOne
|
|
|
|
Рег.: 14.10.2002
|
Сообщений: 13749
|
Из: Москва
|
Рейтинг: 3476
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Ighn]
18.11.2007 14:00
|
|
|
потому что нельзя менять системные исходники. они даны AS IS, так сказать FYI. Если очень надо - переписывай Classes.pas в каталог своего проекта и включай его в проект. Еще лучше - переобзови его как myClasses.pas.
|
|
Basilio
|
GreenOne
|
|
|
|
Рег.: 14.10.2002
|
Сообщений: 13749
|
Из: Москва
|
Рейтинг: 3476
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Basilio]
18.11.2007 14:06
|
|
|
Если нужно серьезное расширение базовых классов, советую посмотреть в сторону JCL - это опенсорсная коллекция библиотек, которые существенно расширяют модули Classes, SysUtils и им подобные.
|
|
Ighn
|
Helix pomatia
|
|
|
|
Рег.: 15.06.2005
|
Сообщений: 383
|
Из: Москва
|
Рейтинг: -10
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Basilio]
18.11.2007 15:21
|
|
|
В ответ на:
потому что нельзя менять системные исходники. они даны AS IS, так сказать FYI. Если очень надо - переписывай Classes.pas в каталог своего проекта и включай его в проект. Еще лучше - переобзови его как myClasses.pas.
Да, я уже понял. Засада, блин. Буду делать свой юнит.
|
Incertus animus dimidium sapientiae est - Сомнение - половина мудрости |
|
Ighn
|
Helix pomatia
|
|
|
|
Рег.: 15.06.2005
|
Сообщений: 383
|
Из: Москва
|
Рейтинг: -10
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Basilio]
18.11.2007 15:23
|
|
|
В ответ на:
Если нужно серьезное расширение базовых классов, советую посмотреть в сторону JCL - это опенсорсная коллекция библиотек, которые существенно расширяют модули Classes, SysUtils и им подобные.
А они идут как надстройка над системными библиотеками или устанавливаются вместо их?
|
Incertus animus dimidium sapientiae est - Сомнение - половина мудрости |
|
Basilio
|
GreenOne
|
|
|
|
Рег.: 14.10.2002
|
Сообщений: 13749
|
Из: Москва
|
Рейтинг: 3476
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Ighn]
18.11.2007 16:01
|
|
|
как отдельные юниты будут. ну и будут называться типа jcClasses, jcStrUtils etc
|
|
Ighn
|
Helix pomatia
|
|
|
|
Рег.: 15.06.2005
|
Сообщений: 383
|
Из: Москва
|
Рейтинг: -10
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Basilio]
18.11.2007 16:36
|
|
|
Понятно. Спасибо. А VCL-то можно перекомпилить. 1. стираешь *.dcu-файл, нужной тебе библиотеки, который лежит в директории Lib. 2. Закидываешь в эту же директорию правленный *.pas той же библиотеки. В программе, использующей эту библиотеку, делаешь "Compile All". Компилятор создаст новый *.dcu. 3. Можешь удалить правленный *.pas из директории Lib. Все. Таким образом мне-таки удалось перекрыть метод NextToken класса TParser, который реализован с ошибкой. Так что "не боги горшки обжигают". Это я к твоему "аффтор...зачем использовать говно 20-давности..." в соседней теме. Откуда тебе знать, зачем я TC использую? Может он и говно, но я его на КПК под Dos гоняю, потому что мне удобно. Такие дела.
|
Incertus animus dimidium sapientiae est - Сомнение - половина мудрости |
|
CROTishka
|
Shai-Hulud
|
|
|
|
Рег.: 09.06.2004
|
Сообщений: 31423
|
Из: - под земли
|
Рейтинг: 3655
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Basilio]
18.11.2007 18:57
|
|
|
исходники подменять нельзя, а вот переопределять классы - влегкую! вот вам пример:
code: 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.
Но гораздо правильнее запихать его в пэкадж, и присвоить какое-нибудь собственное имя.
|
|
|
Ighn
|
Helix pomatia
|
|
|
|
Рег.: 15.06.2005
|
Сообщений: 383
|
Из: Москва
|
Рейтинг: -10
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: CROTishka]
18.11.2007 19:35
|
|
|
В ответ на:
исходники подменять нельзя
В смысле? Перекомпилировать как раз можно. Другое дело, что нежалательно их корректировать.
|
Incertus animus dimidium sapientiae est - Сомнение - половина мудрости |
|
_Seti
|
Добрые руки
|
|
|
|
Рег.: 18.10.2003
|
Сообщений: 3164
|
|
Рейтинг: 2131
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Ighn]
19.11.2007 10:51
|
|
|
А что за задача возникла такая, что надо менять Classes.pas? Напиши, порешаем.
|
|
Basilio
|
GreenOne
|
|
|
|
Рег.: 14.10.2002
|
Сообщений: 13749
|
Из: Москва
|
Рейтинг: 3476
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: _Seti]
19.11.2007 21:16
|
|
|
Скажем так - почему возникло желание перекрывать неперекрываемый метод? Все, что пользователю может взбрести в голову перекрывать - объявлено как virtual. Например, Sort у TStringList-a
|
|
CROTishka
|
Shai-Hulud
|
|
|
|
Рег.: 09.06.2004
|
Сообщений: 31423
|
Из: - под земли
|
Рейтинг: 3655
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Basilio]
20.11.2007 04:30
|
|
|
Не все. примеры что-то не могу уже припомнить. ???например wm_paint у всяких компонентов(нед ide под рукой, завтра мб гляну)
|
|
|
Basilio
|
GreenOne
|
|
|
|
Рег.: 14.10.2002
|
Сообщений: 13749
|
Из: Москва
|
Рейтинг: 3476
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: CROTishka]
20.11.2007 09:32
|
|
|
а зачем wm_paint перекрывать?! если ты рисуешь на компоненте нечто, для чего этот компонент не предназначен - это же бред. для этого есть TImage.
|
|
CROTishka
|
Shai-Hulud
|
|
|
|
Рег.: 09.06.2004
|
Сообщений: 31423
|
Из: - под земли
|
Рейтинг: 3655
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Basilio]
20.11.2007 15:16
|
|
|
имадж - графический компонент. рисую я обычно на контролах.
|
|
|
Basilio
|
GreenOne
|
|
|
|
Рег.: 14.10.2002
|
Сообщений: 13749
|
Из: Москва
|
Рейтинг: 3476
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: CROTishka]
20.11.2007 16:12
|
|
|
почему для этих целей не подходит image? ведь канвас и там и там, а у имаджа еще и перерисовку не надо свою писать...
|
|
CROTishka
|
Shai-Hulud
|
|
|
|
Рег.: 09.06.2004
|
Сообщений: 31423
|
Из: - под земли
|
Рейтинг: 3655
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Basilio]
20.11.2007 17:40
|
|
|
Много чем... Хотя бы тем, что не контролы не могут получать фокус.
|
|
|
CROTishka
|
Shai-Hulud
|
|
|
|
Рег.: 09.06.2004
|
Сообщений: 31423
|
Из: - под земли
|
Рейтинг: 3655
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: Basilio]
20.11.2007 17:40
|
|
|
В ответ на:
перерисовку не надо свою писать...
Еще как надо, а тут - подправил чуток и ок! =)
|
|
|
Basilio
|
GreenOne
|
|
|
|
Рег.: 14.10.2002
|
Сообщений: 13749
|
Из: Москва
|
Рейтинг: 3476
|
|
Re: Не могу перекрыть базовый метод [Delphi]
[re: CROTishka]
20.11.2007 20:26
|
|
|
что-то я тогда не понимаю. можешь привести конкретный пример?
|
|