Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#11

AW: Callback WndProc innerhalb einer Klassen-Methode... ist das OK?

  Alt 6. Nov 2011, 00:19
Jupp, dort würde dein Win32 Programm ja in einem "virtuellen" 32 Bit-Windows ausgeführt.


Wenn man irre ist, dann kann man auch die möglichkeiten der Klassen ausnutzen.

Di kennst ja bestimmt das Folgendes
Delphi-Quellcode:
procedure WMGestureNotify(var Message: TWMGestureNotify); message WM_GESTURENOTIFY;
procedure CMActivate(var Message: TCMActivate); message CM_ACTIVATE;
procedure WndProc(var Message: TMessage); override;

Würde dann wohl etwa so aussehn ... natürlich in Assembler, da ja das SELF hardcodiert sein müßte.
Delphi-Quellcode:
//type
// TMessage = packed record
// Msg: Cardinal;
// WParam: WPARAM;
// LParam: LPARAM;
// Result: LRESULT;
// end;

function WndProc(Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  Message: TMessage;
begin
  Message.Msg := Msg;
  Message.WParam := wParam;
  Message.LParam := lParam;
  Message.Result := 0;
  TheDispatcher.Dispatch(Message);
  Result := Message.Result;
end;
statt deinem globalen Array könnte man auch gleich alles in diese Klasse verbauen:
Delphi-Quellcode:
type
  TDispatcher = class
  private
    FHandle: HWND;
    FMessage: TMessage;
    FWndProcInfo: TWndProcInfo;
  public
    constructor Create(Window: HWND);
    destructor Destroy;

    property Handle: HWND read FHandle;
  end;

function WndProc(Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  with TheDispatcher do begin
    FHandle := Wnd; // (MethodOwner + 8)^ := Wnd; (sollte +8 sein ... glaub ich)
    FMessage.Msg := Msg; // (MethodOwner + 12)^ := Msg;
    FMessage.WParam := wParam; // (MethodOwner + 16)^ := wParam
    FMessage.LParam := lParam; // (MethodOwner + 20)^ := lParam;
    FMessage.Result := 0; // (MethodOwner + 24)^ := 0;
    Dispatch(Message); // call TObject.Dispatch mit TheDispatcher und MethodOwner als Parameter
    Result := FMessage.Result; // Result := (MethodOwner + 24)^;
  end;
end;
PS: Statt das Self hardzukodieren kannste es uch über SetProp an das Fenster hängen und über GetProp auslesen ... dann könnteste deine deine Proceduren in Pascal schreiben.
Wäre ja nur noch eine Variante nötig wäre, da man keine Werte hardcodiert hätte.

Hat auch den Vorteil, daß man schauen kann kann, ob schon soein Hook an dem Fenster hängt. (PS: so macht es die VCL ... die hängt ihr Self auch einfach überall an)
Es gäbe zwar noch GWL_USERDATA, aber das wäre wohl zu unsicher, da es ja schon belegt sein kann.
SetProp(hWnd, 'Satty67_Dispatcher', THandle(TheDispatcher));
Ach ja, ich hatte FHandle := Wnd immer wieder neu gesetzt .. das könnte man auch nicht machen
- wenn die Klasse nur an einem Fenster hängt, dann ändert sich dieses nicht
- wenn man es veränderbar macht, könnte man mehere Fenster an eine Klasse hängen


[add]
ich seh grade, daß man man bei dem Dispatch ebenfalls nur das SELF zwischen das HWND und MSG schieben müßte, dann bräuchte man das Message nicht kopieren, sondern könnte direkt auf den Stack zeigen und kopiert nach Prozeduraufruf noch nur noh das Result in EAX.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 6. Nov 2011 um 00:26 Uhr)
  Mit Zitat antworten Zitat