![]() |
virtuelle funktion
Delphi-Quellcode:
dabei crash es bei aufruf von Eventhandler wegen virtual, aber eventhandler is fuer override in abgeleitete klassen vorgesehen. daher virtuel wie kann ich dies denn eure meinung nach am besten loesen?
function WndProc(hWindow: HWND; dwMsg: ZDWORD; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var wnd: PWindowBase; msg : TMSG; begin if dwMsg = WM_NCCREATE then begin wnd := PWindowBase(PCreateStruct(nlParam)^.lpCreateParams); SetWindowLongPtr(hWindow, GWL_USERDATA, Integer(wnd)); end; wnd:= PWindowBase(GetWindowLongPtr(hWindow, GWL_USERDATA)); if Assigned(wnd) then begin ZeroMemory(@msg, SizeOf(msg)); msg.hwnd := hWindow; msg.message := dwMsg; msg.wParam := wParam; msg.lParam := lParam; wnd^.EventHandler(msg); // in WindowBase is diese funktion virtuell (hier crash es Exit; end; Result := DefWindowProc(hWindow, dwMsg, nwParam, nlParam); end; WindowBase = class .. public function EventHandler(msg: TMsg): Boolean; virtual; end; vielen dank fuer hilfen |
Re: virtuelle funktion
Warum speicherst du einen Pointer auf das Objekt (PWindowBase)? Das Objekt ist bereits ein Pointer. Außerdem solltest du dich an die Konvention halten, Klassennamen mit einem T zu beginnen.
|
Re: virtuelle funktion
Zitat:
PWindowBase = ^WindowBase ich weiss das mit T. nun eine Loesung fuer den Crash? |
Re: virtuelle funktion
Du rufst die Methode von WindowBase auf, welche eben noch nicht implementiert wurde. Die Instanz, mit der du arbeitest, muss explizit über WindowBaseChild.Create erzeugt werden.
|
Re: virtuelle funktion
Selbst dann wird es noch crashen, aufgrund des Doppelpointers. Dein Pointer, den du speicherst, zeigt nämlich auf die Adresse der lokalen Variable wnd, nicht auf das dahinterliegende Objekt. Da die Variable wnd im nächsten Durchlauf undefiniert ist, wird auf die falsche Adresse zugegriffen, die zufällig an dieser Stelle gespeichert ist.
Das Objekt selbst ist, wie ich schon sagte, bereits ein Pointer - Also caste das Objekt einfach nach Integer und alles wird gut. |
Re: virtuelle funktion
erstmal danke fuers antworten, aber so sei eure Antworten sehr trocken, ein bisschen korrektur code waere viel besser verstaendlicher.
|
Re: virtuelle funktion
Gut, eine Zeile Code sagt manchmal mehr als tausend Worte:
Delphi-Quellcode:
Hoffe, ich hab nichts übersehen.
function WndProc(hWindow: HWND; dwMsg: ZDWORD; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var wnd: TWindowBase; // Geändert msg : TMSG; begin if dwMsg = WM_NCCREATE then begin wnd := TWindowBase.Create(PCreateStruct(nlParam)^.lpCreateParams); // Geändert // (ich habe jetzt einfach mal geraten, dass hier der Konstruktor hin sollte) SetWindowLongPtr(hWindow, GWL_USERDATA, Integer(wnd)); end; wnd := TWindowBase(GetWindowLongPtr(hWindow, GWL_USERDATA)); // Geändert if Assigned(wnd) then begin ZeroMemory(@msg, SizeOf(msg)); msg.hwnd := hWindow; msg.message := dwMsg; msg.wParam := wParam; msg.lParam := lParam; wnd.EventHandler(msg); // Geändert Exit; end; Result := DefWindowProc(hWindow, dwMsg, nwParam, nlParam); end; TWindowBase = class // Umbenannt .. public function EventHandler(msg: TMsg): Boolean; virtual; end; |
Re: virtuelle funktion
Zitat:
danke sehr, dies sieht sehr uebersichtlich aus, very n1. werde es sofort testen |
Re: virtuelle funktion
Delphi-Quellcode:
bin ein bisschen verwirrt, kann mir das jemand erklaeren? versteh momentan die logik nicht
function ZWndProc(hWnd: HWND; dwMsg: ZDWORD; wParam: WPARAM; lParam: LPARAM): LRESULT;
var pWnd : PZWindowBase; pCS : PCreateStruct; nUserData : ZINT; begin if dwMsg = WM_NCCREATE then begin pCS := PCreateStruct(lParam); nUserData := ZINT(pCS.lpCreateParams); SetWindowLongPtr(hWnd, GWL_USERDATA, nUserData ); end; nUserData := GetWindowLongPtr(hWnd, GWL_USERDATA); //pWnd := PZWindowBase(nUserData); // wieso funktionier das hier nicht richtig? fenster geschlossen, app nicht beendet pWnd := PZWindowBase(@nNewData); // wieso funktioniert das? fenster geschlossen und app beendet if Assigned(pWnd) then Result := pWnd^.WndProc(hWnd, dwMsg, wParam, lParam) else Result := DefWindowProc(hWnd, dwMsg, wParam, lParam); end; |
Re: virtuelle funktion
Wieso machst du schon wieder mit Zeigern rum? Noch mal: ein Objekt ist bereits ein Zeiger. Ich habe dir doch schon gezeigt, wie du es machen musst.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:27 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz