Einzelnen Beitrag anzeigen

Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#5

Re: Zeos-Components, PlugIn-DLL-Forms und AV

  Alt 15. Nov 2008, 12:45
Hallo,

also, die DLL-Plugins haben eine eigene Zeos-Komponente im Formular. In dieser habe ich den Usernamen, pw etc. eingetragen. Genau wie in der MainApp. Diese hat auch eine Zeos-Komponente... Stören die sich?

Ich poste nochmal ein bissl code...moment..

Folgendes Prinzip: Bei Programmstart werden alle PlugIns gesucht, geladen, Menüeinträge erstellt und wieder entladen, damit sie den Speicher nicht zumüllen. Diese Prozedur habe ich auch in anderen Anwendungen benutzt. Daran sollte es nicht liegen:

Delphi-Quellcode:
procedure TForm1.LoadPlugIn(FileName: String);
var
  TempHandle: Cardinal;
  ProcAddr: Pointer;
  LoadPlugInProc: TLadePlugIn;
  TempPlugIn: TProJurisPlugIn;
  Buffer: PChar;
  len: Integer;
  appkey, titel: String;
  addToWrapper: boolean;
  i: Integer;
  Item: TTreeNode;
begin
  TempHandle:=0;
  //Läd PlugIn und schreibt Menü-Eintrag
  TempHandle:=LoadLibrary(PChar(Filename));
  if (TempHandle <> INVALID_HANDLE_VALUE) and (TempHandle <> 0) then
  begin
    ProcAddr:=GetProcAddress(Temphandle, 'LadePlugIn');

    if (ProcAddr = nil) then
    begin
      FreeLibrary(TempHandle);
      MessageDLG('Die Datei '+Filename+' ist kein gültiges PlugIn', mtError, [mbOK], 0);
      Exit;
    end;

    LoadPlugInProc:=TLadePlugIn(ProcAddr);
    try
      TempPlugIn:=Nil;
      LoadPlugInProc(Application.Handle, TempPlugin);
    except
      FreeLibrary(TempHandle);
      MessageDLG('Die Datei '+Filename+' ist kein gültiges PlugIn', mtError, [mbOK], 0);
    end;

    if (TempPlugIn <> nil) then
    begin
      //Appkey holen
      len:=TempPlugin.GetAppKey(nil, 0);
      try
        GetMem(Buffer, len+1);
        len:=TempPlugIn.GetAppKey(Buffer, len+1);
        appkey:=Buffer;
      finally
        FreeMem(Buffer);
      end;

      //Titel holen
      len:=TempPlugin.GetTitel(nil, 0);
      try
        GetMem(Buffer, len+1);
        len:=TempPlugIn.GetTitel(Buffer, len+1);
        titel:=Buffer;
      finally
        FreeMem(Buffer);
      end;

      if (appkey = 'PI-3') then
      begin
        SetLength(PlugIns, Succ(Length(PlugIns)));
        PlugIns[High(PlugIns)].PlugInTitel:=titel;
        PlugIns[High(PlugIns)].PlugInFile:=FileName;
        PlugIns[High(PlugIns)].PlugInName:=TempPlugIn;
        PlugIns[High(PlugIns)].PlugInHandle:=TempHandle;

        //PlugIns[High(PlugIns)].PlugInVersion:=GetVersion(FileName);
        PlugIns[High(PlugIns)].PlugInName.InitPlugIn;
        PlugIns[High(PlugIns)].PlugInName.TransmitHandle(self.Handle);

        // Wird das PlugIn zum ersten mal geladen?
        AddToWrapper:=True;
        for i:=0 to High(PlugInWrapper) do
        begin
          if (PlugInWrapper[i].PlugInTitel = titel) then
          begin
            addToWrapper:=false;
            Exit
          end;
        end;

        if (addToWrapper) then
        begin
          Item:=TreeView1.Items.AddChild(TreeView1.Items.GetFirstNode, titel);
          SetLength(PlugInWrapper, Succ(Length(PlugInWrapper)));
          PlugInWrapper[High(PlugInWrapper)].PlugInTitel:=titel;
          PlugInWrapper[High(PlugInWrapper)].PlugInFile:=FileName;
        end;

      UnloadPlugIns;
      FreeLibrary(TempHandle);

      end else
      begin
        MessageDLG('Das Plugin ('+filename+') ist nicht mit der Programmversion kompatibel.', mtError, [mbOK], 0);
      end;

    end else
    begin
      MessageDLG('Die Datei '+Filename+' ist kein gültiges PlugIn', mtError, [mbOK], 0);
    end;

  end else
  begin
    MessageDLG('Die Datei '+Filename+' ist kein gültiges PlugIn', mtError, [mbOK], 0);
  end;
  TempPlugIn:=nil;
end;
Hier wird das PlugIn geladen und INNERHALB der MainApp auf Panel1 angezeigt:

Delphi-Quellcode:
procedure TForm1.RunPlugIn(Sender: TObject);
var
  i,j: Integer;
  s: String;
  hndl: Integer;
  sl:TStringList;
begin
  UnloadPlugins;
  s:=TTreeNode(Sender).Text;
  
  for i:=0 to high(PlugInWrapper) do
  begin
    if (s = PlugInWrapper[i].PlugInTitel) then
    begin
      LoadPlugIn(PlugInWrapper[i].PlugInFile);
      hndl:=PlugIns[High(PlugIns)].PlugInName.SendFormHandle;
      PlugInActive:=hndl;
      Windows.SetParent(hndl, Panel1.Handle);
      SetWindowPos(hndl, hwnd_top, -5, -25, 0, 0, SWP_NOSIZE);
      PlugIns[High(PlugIns)].PlugInName.Execute;
    end;
  end;
end;
Das ist mein Login in der MainApp:

Delphi-Quellcode:
 if (Key = #13) then
  begin
    if not (Form1.ZConnection1.Connected) then
      Form1.ZConnection1.Connect;


    if (Form1.ZConnection1.Connected) then
    begin
      Form1.ZQuery1.SQL.Text:='SELECT * FROM benutzer WHERE username = '''+Edit1.Text+''' AND passwort = '''+MD5Print(MD5String(MaskEdit1.Text))+''';';
      Form1.ZQuery1.Open;
      if (Form1.ZQuery1.RecordCount > 0) then
      begin
        username:=Form1.ZQuery1.FieldByName('username').AsString;
        uid:=Form1.ZQuery1.FieldByName('uid').AsInteger;
        loggedin:=True;

        Label2.Caption:='Angemeldet als '+username;

        Label3.Hide;
        Label4.Hide;
        Edit1.Hide;
        MaskEdit1.Hide;

        Windows.SetParent(Form2.Handle, Panel1.Handle);
        SetWindowPos(Form2.Handle, hwnd_top, 0, 0, 0, 0, SWP_NOSIZE);

        Form2.Label5.Caption:='Guten Tag '+username+',';
        Form2.Show;

      end else
      begin
        MessageDLG('Die Benutzerdaten sind nicht korrekt', mtInformation, [mbOK], 0);
      end;
    end;

  end;
  Form1.ZQuery1.Close;
end;
Und das ist die Prozedur, die ausgeführt wird, wenn das Plugin vom User geöffnet wird. Das wird nicht beim Starten ausgeführt, wenn die MainApp die PlugIns einliest:

Delphi-Quellcode:
procedure TForm1.StartUp;
var
  Tab: TTabSheet;
begin
  if not (Connection1.Connected) then
  begin
    Connection1.Connect; //Wenn MainApp Connected!
  end;

  Form1.Query1.SQL.Text:='SELECT realname FROM benutzer WHERE rang = 2 ORDER BY uid ASC;';
  Form1.Query1.Open;
  while not (Form1.Query1.Eof) do
  begin
    Tab:=TTabSheet.Create(PageControl1);
    Tab.Caption:='Hallo';
    Form1.Query1.Next;
  end;
  Form1.Query1.Close;
  Connection1.Disconnect;

end;
So, das ist so ziemlich alles an Code, was es bisher gibt.

Nochmal kurze Erklärung:

Einloggen in MainApp -> PlugIn öffnen -> Programm beendet ohne Fehler
kein Einloggen in MainApp -> PlugIn öffnen -> zu viele aufeinanderfolgende Exceptions (siehe FastMM)

Dabei hat der Login keinerlei Bezug zum Plugin und umgekehrt. Daher muss es was Speichertechnisches sein...

Danke
  Mit Zitat antworten Zitat