Einzelnen Beitrag anzeigen

RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#6

AW: Generischen Typ "merken" zur späteren Verwendung

  Alt 20. Jun 2012, 12:18
Ah, der Kern deiner Idee ist also folgender: Die asynchron aufzurufende Methode mit generischen Parametern wird in eine parameterlose anonyme Funktion verpackt, die nichts anderes tut, als die asynchron aufzurufende Methode mit den passenden Parametern aufzurufen. Im Kontext dieser parameterlosen anonymen Funktion sind die tatsächlichen Typen der generischen Parameter der asynchron aufzurufenden Methode bekannt und deshalb kann sie auch aufgerufen werden. Beim Empfang der Windows-Message brauche ich die Infos über die generischen Typen gar nicht, da ich nur die anonyme Funktion aufrufe (im "alten" Kontext).

Mein angepasster Quelltext:
Delphi-Quellcode:
  TAsync = class
  public
    type
      TAsyncProc = reference to procedure;
      TAsyncProc1<T1> = reference to procedure(P1: T1);
    class procedure Call(Proc: TAsyncProc); overload;
    class procedure Call<T1>(Proc: TAsyncProc1<T1>; P1: T1); overload;
  private
    const
      WM_ASYNCCALLINVOKE = WM_USER + $4df8;
    class function AsyncCallInvoke(var m: TMessage): Boolean;
  end;

...

implementation

...


class function TAsync.AsyncCallInvoke(var m: TMessage): Boolean;
var
  PProc: ^TAsyncProc;
begin
  case m.Msg of
    WM_ASYNCCALLINVOKE:
      begin
        Result := True;
        case m.WParam of
          0:
            begin
              PProc := Pointer(m.LParam);
              try
                PProc^.Invoke;
              finally
                Dispose(PProc);
              end;
            end;
        end;
      end;
    else
      Result := False;
  end;
end;

class procedure TAsync.Call(Proc: TAsyncProc);
var
  PProc: ^TAsyncProc;
begin
  MessageDistributor.RegisterMessageHandlerMethod(TAsync.AsyncCallInvoke);
  New(PProc);
  PProc^ := Proc;
  PostMessage(MessageDistributor.Handle, WM_ASYNCCALLINVOKE,
              0, Integer(PProc));
end;

class procedure TAsync.Call<T1>(Proc: TAsyncProc1<T1>; P1: T1);
var
  PProc: ^TAsyncProc;
begin
  MessageDistributor.RegisterMessageHandlerMethod(TAsync.AsyncCallInvoke);
  New(PProc);
  PProc^ := procedure
    begin
      Proc(P1);
    end;
  PostMessage(MessageDistributor.Handle, WM_ASYNCCALLINVOKE,
              0, Integer(PProc));
end;
Vielen Dank für diese Idee!
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."
  Mit Zitat antworten Zitat