Hallo DPler,
wie es der Zufall will, habe ich ein ähnliches Problem wie Himitsu:
Ich möchte in der
Unit <Graphics.pas> die Routine <RequiredState> vom TCanvas ersetzen. Das geht so (und funkt auch - getestet):
Neue
Unit, z.B. UMyCanvas.pas, dort:
eine neue Klasse für den Hack, der Zugriff auf das private Feld <State> ermöglicht:
Delphi-Quellcode:
THackCanvas = class(Graphics.TCanvas)
private
FHandle: HDC;
State : TCanvasState;
end;
Eine neue Klasse, in der die neue Routine definiert wird:
Delphi-Quellcode:
TMyCanvas = class(Graphics.TCanvas)
protected
procedure RequiredStatePatch(ReqState: TCanvasState);
end;
...
implementation
...
procedure TMyCanvas.RequiredStatePatch(ReqState: TCanvasState);
var
NeededState: TCanvasState;
begin
NeededState := ReqState - THackCanvas(Self).State;
end;
Im initialization-Teil wird dann mittels
CodeRedirect
(
von http://chee-yang.blogspot.com/2008/11/hack-into-delphi-class.html) die Adresse der vorhandenen Routine durch die Adresse der neuen Routine ersetzt und die neue Routine wird künftig so verwendet, als ob sie ganz normal zu TCanvas gehören würde:
Delphi-Quellcode:
var
P: TCodeRedirect;
initialization
P := TCodeRedirect.Create(@TMyCanvas.RequiredState, @TMyCanvas.RequiredStatePatch);
finalization
P.Free;
OK.
Das Problem ist: für den Zugriff auf <State> muss ich in
RequiredStatePatch
schreiben:
THackCanvas(Self).State
, damit das Ganze kompiliert; zur Laufzeit aber gilt das nicht mehr, weil sich die Routine - nach dem Umbiegen der Adresse - zu TCanvas zugehörig fühlt und deshalb hier nur
State
stehen dürfte. Irgendwie ein Henne/Ei-Problem.
Wenn zur Laufzeit
THackCanvas(Self).State
abgefragt wird, dann bringt das ein falsches Ergebnis.
War das halbwegs verständlich bzw wer weiss Rat?