Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi virtuelle funktion (https://www.delphipraxis.net/149877-virtuelle-funktion.html)

JnZn558 1. Apr 2010 13:21


virtuelle funktion
 
Delphi-Quellcode:
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;
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?
vielen dank fuer hilfen

Namenloser 1. Apr 2010 13:45

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.

JnZn558 1. Apr 2010 16:59

Re: virtuelle funktion
 
Zitat:

Zitat von NamenLozer
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.

Wie Bitte. Versteh dich nicht, PWindowBase ist ein Pointer von WindowBase

PWindowBase = ^WindowBase

ich weiss das mit T. nun eine Loesung fuer den Crash?

dominikkv 1. Apr 2010 17:15

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.

Namenloser 1. Apr 2010 18:49

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.

JnZn558 1. Apr 2010 22:54

Re: virtuelle funktion
 
erstmal danke fuers antworten, aber so sei eure Antworten sehr trocken, ein bisschen korrektur code waere viel besser verstaendlicher.

Namenloser 1. Apr 2010 23:01

Re: virtuelle funktion
 
Gut, eine Zeile Code sagt manchmal mehr als tausend Worte:
Delphi-Quellcode:
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;
Hoffe, ich hab nichts übersehen.

JnZn558 2. Apr 2010 17:41

Re: virtuelle funktion
 
Zitat:

Zitat von NamenLozer
Gut, eine Zeile Code sagt manchmal mehr als tausend Worte:
Delphi-Quellcode:
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;
Hoffe, ich hab nichts übersehen.


danke sehr, dies sieht sehr uebersichtlich aus, very n1. werde es sofort testen

JnZn558 2. Apr 2010 22:44

Re: virtuelle funktion
 
Delphi-Quellcode:
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;
bin ein bisschen verwirrt, kann mir das jemand erklaeren? versteh momentan die logik nicht

Namenloser 2. Apr 2010 23:39

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 19:46 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz