Thema: Delphi Objekt Kommunikation

Einzelnen Beitrag anzeigen

Benutzerbild von peschai
peschai

Registriert seit: 15. Feb 2004
Ort: Göppingen
270 Beiträge
 
Delphi XE5 Professional
 
#7

Re: Objekt Kommunikation

  Alt 4. Jul 2009, 17:40
Hallo Delphianer,

Das Problem war komplizierter als erwartet.
Eure Vorschläge hatte ich im Prinzip schon teilweise ausprobiert, war dabei aber auf die Nase gefallen. Es hatte nicht funktioniert, was eigentlich hätte gehen sollen.

Ich hatte aber etwas wesentliches Unterschlagen ...

Ein DataObject soll nämlich auch mehr als ein GUI-Elemente "benachrichtigen". Hier hatte ich den Fehler gemacht, im DataObject pro "Entfernter ObjectMethode" einen 4Byte Zeiger in einer Liste zu speichern.

Das geht so natürlich nicht, da Object-Methoden versteckte DoppelZeiger sind.

Folgende Lösung scheint zu funktionieren.

Delphi-Quellcode:
uData.pas

type
  TOccupiedDataEvent = procedure (Sender: TObject; aODE:integer; const aMessage: string) of Object;

type
  TOccupiedData = Class(TObject)
  ...
  protected
    FOccupiedGrids : TStringList;
    FOccupiedDataEvent: TOccupiedDataEvent;
    procedure OccupiedDataEventSend(aODE:integer; const aMessage: string);
  ...
  public
    function OccupiedDataEventConnect(aODE:TOccupiedDataEvent):integer;
    function OccupiedDataEventDisconnect(aODE:TOccupiedDataEvent):integer;

function TOccupiedData.OccupiedDataEventConnect { >>>>>>>>>>>>>>>>>>>>>>>>>>>> }
         (aODE:TOccupiedDataEvent):integer;
var
  i1:integer;
  p2:^TOccupiedDataEvent;
  p3:^TMethod;
begin
  // local init
  Result := 0;
  i1 := 0;
  p2 := Nil;
  p3 := Nil;
  // local main
  if Assigned(aODE) then
    begin
      // Suchen ob GUI-Element bereits verlinkt ist
      For i1 := 0 to FOccupiedGrids.Count-1 do
        begin
          p3 := Pointer(FOccupiedGrids.Objects[i1]);
          if (p3<>NIL) then
            begin
              if (p3^.Code = TMethod(aODE).Code) and (p3^.Data = TMethod(aODE).Data) then
                begin
                  // bereits vorhanden
                  p2 := @aODE;
                  break;
                end;
            end;
        end;
      if (p2=Nil) then
        begin
          New(p3);
          p3^ := TMethod(aODE);
          FOccupiedGrids.AddObject('S',TObject(p3));
          aODE(Self, odeConnected, 'Connected');
        end;
    end;
end; { <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< }

function TOccupiedData.OccupiedDataEventDisconnect { >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> }
         (aODE:TOccupiedDataEvent):integer;
var
  i1:integer;
  p2:^TOccupiedDataEvent;
  p3:^TMethod;
begin
  // local init
  Result := 0;
  i1 := 0;
  p2 := Nil;
  p3 := Nil;
  // local main
  if Assigned(aODE) then
    begin
      // Suchen ob GUI-Element bereits verlinkt ist
      For i1 := FOccupiedGrids.Count-1 downto 0 do
        begin
          p3 := Pointer(FOccupiedGrids.Objects[i1]);
          if (p3<>NIL) then
            begin
              if (p3^.Code = TMethod(aODE).Code) and (p3^.Data = TMethod(aODE).Data) then
                begin
                  // gefunden!
                  // ... aus liste entfernen
                  FOccupiedGrids.Delete(i1);
                  // ... dynamischen speicher wieder freigeben
                  Dispose(p3);
                  p3 := NIL;
                  // notification an ODE senden
                  aODE(Self, odeDisConnected, 'DisConnected');
                  break;
                end;
            end;
        end;
    end;
end; { <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< }

procedure TOccupiedData.OccupiedDataEventSend { >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> }
          (aODE:integer; const aMessage: string);
var
  i1:integer;
  p2:^TOccupiedDataEvent;
  p3:^TMethod;
begin
  // local init
  i1 := 0;
  p2 := Nil;
  p3 := Nil;
  // local main

  // Entfernte ObjectMethode aufrufen
  For i1 := 0 to FOccupiedGrids.Count-1 do
    begin
      p3 := Pointer(FOccupiedGrids.Objects[i1]);
      if (p3<>NIL) then
        begin
          Pointer(p2) := p3;
          p2^(Self, aODE,aMessage);
        end;
    end;
end; { <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< }
...

Delphi-Quellcode:
uGui.pas
...
DataObject.OccupiedDataEventConnect(OccupiedDataEvent);
...
procedure TOccupiedGrid.OccupiedDataEvent { >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> }
          (Sender: TObject; aODE:integer; const aMessage: string);
begin
  CASE aODE of
    odeDataLoaded :begin
                        if Assigned(FGrid) then
                          begin
                            FGrid.Invalidate;
                          end;
                      end;
  END;

end; { <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< }
Peter Schaible
  Mit Zitat antworten Zitat