Forma w dll, interfejsy

0

Nie wiem czemu, ale niestety w momencie kiedy stworze dana forme z dll w PageControl, to po ukryciu calej formy (visible) i ponownym pokazaniu formy z dll-ki juz nie ma. Na dodatek nie da się tego w żaden spób odświerzyć. Jakieś pomysły ?

0

Zbyt wiele informacji nie dales aby Ci pomoc, moze to

Wtyczki (Plugin) w oparciu o interfejsy

lepiej kopiowac link :)

0

No własnie na podstawie tego napisałem system pluginów z formami. W momencie kiedy PageControl jest umieszczone na głównej formie, która nigdy nie "znika" to jest ok, ale gdy próbuje zastowować tą metode na PageControl umieszczonym na niewidocznej formie tworzy się tylko dodatkowa karta, ale niestety jest pusta :/

0

Stworzylem w tym przykladzie nowa forme z trzem guzikami i ta startuje jako pierwsza

procedure TForm3.Button1Click(Sender: TObject);
begin
Form1.Show;
end;

procedure TForm3.Button3Click(Sender: TObject);
begin
Form1.Hide;
end;

procedure TForm3.Button2Click(Sender: TObject);
var
 LI:TListItem;
 PR:PPlugs;
 PlugGUID:TGUID;
 HR:HResult;

begin

        LI := Form1.ListView1.Items[0];
        PR := PPlugs(LI.Data);
        PlugGUID := StringToGuid(PR^.CLSID);

        HR := CoCreateInstance(PlugGUID,nil,CLSCTX_INPROC_SERVER,IID_IPlug,PR^.Int);
        if SUCCEEDED(HR) then
        begin

          PR^.Tab := TTabSheet.Create(Form1.PageControl1);
          PR^.Tab.PageControl := Form1.PageControl1;
          PR^.Tab.Caption := PR^.Name;
          If SUCCEEDED(PR^.Int.Init(Form1 as IPlugsApplication, PR^.Tab.Handle)) then
            PR^.Loaded := true
          else
            PR^.Tab.Free;
        end;


end;

Teraz pokazuje za pomoca show - robie listuj wtyczki (aby cos bylo do LI := Form1.ListView1.Items[0];)

Potem Hide i wciskam guzik tworzacy wtyczke, potem show i wszytsko jest OK.

Podaj wiecej szczegolow (minimalny przyklad z bledem)

0

W ten sposób przydzielam uchwyty do wtyczek:

function TMainForm.GetHandle(out hwnd:HWND; plug_type:integer; plug_clsd:PChar):HResult;
var
  p:integer;
  no:integer;
begin
  for p:=0 to High(Plugins) do
    if Plugins[p].CLSID=plug_clsd then
      no:=p;

  Plugins[no].plug_type:=plug_type;

  if plug_type = pAcc then
  begin
    Plugins[no].Tab:=TTabSheet.Create(PageControl1);
    Plugins[no].Tab.PageControl:=PageControl1;
    Plugins[no].Tab.Caption:=Plugins[no].name;

    hwnd:=Plugins[no].Tab.Handle;

  end;

  if plug_type = pApp then
  begin
    Plugins[no].Tab:=TTabSheet.Create(options.PageControl1);
    Plugins[no].Tab.PageControl:=options.PageControl1;
    Plugins[no].Tab.Caption:=Plugins[no].name;

    hwnd:=Plugins[no].Tab.Handle;
  end;

  result := S_OK;
end;

A tutaj jest caluśki kod tego okna, które się tworzy ukryte.

unit settings;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, FileCtrl, interfaces;

type
  TOptions = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    GroupBox1: TGroupBox;
    Edit1: TEdit;
    Label1: TLabel;
    Edit2: TEdit;
    Label2: TLabel;
    Label3: TLabel;
    Edit3: TEdit;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    GroupBox2: TGroupBox;
    Edit4: TEdit;
    Label4: TLabel;
    Edit5: TEdit;
    Label5: TLabel;
    Edit6: TEdit;
    Label6: TLabel;
    Edit7: TEdit;
    Label7: TLabel;
    GroupBox3: TGroupBox;
    Label8: TLabel;
    Edit8: TEdit;
    Button4: TButton;
    Button5: TButton;
    procedure Button3Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Options: TOptions;

implementation

uses main;

{$R *.dfm}

procedure TOptions.FormShow(Sender: TObject);
var
  p:integer;
begin
  Edit1.Text:=MainForm.general.def_user_path;
  Edit2.Text:=MainForm.general.def_plug_path;
  Edit3.Text:=MainForm.general.service_path;
  Edit5.Text:=IntToStr(MainForm.general.service_port);
  Edit6.Text:=MainForm.general.service_username;
  Edit7.Text:=MainForm.general.service_password;
  Edit8.Text:=MainForm.general.domain_name;
end;

procedure TOptions.Button1Click(Sender: TObject);
var
  Dir:string;
begin
  if SelectDirectory('Wybierz folder...','',Dir) then
    Edit1.Text:=Dir+'\';
end;

procedure TOptions.Button2Click(Sender: TObject);
var
  Dir:string;
begin
  if SelectDirectory('Wybierz folder...','',Dir) then
    Edit2.Text:=Dir+'\';
end;

procedure TOptions.Button3Click(Sender: TObject);
var
  Dir:string;
begin
  if SelectDirectory('Wybierz folder...','',Dir) then
    Edit3.Text:=Dir+'\';
end;

end.

Próbowałem na różne sposoby, ale żaden nie działa :/

0

Nie widze, gdzie tworzysz wtyczke

CoCreateInstance

, i czy TMainForm to wtyczka (dlaczego tam jest TabControl, powinno to byc w aplikacji wtyczkowej - bardziej uniwersalne ??).

0

Wtyczki są tworzone w innej procedurze, procedure pobierająca uchwyt wywołuje sama wtyczka
TMain Form, jest to forma pierwszego zawsze widocznego okna

Tworzenie wtyczki:

procedure TMainForm.LoadPlugins;
var
  HR:HResult;
  p:integer;
begin
  for p:=0 to High(Plugins) do
  begin
    HR := CoCreateInstance(StringToGuid(Plugins[p].CLSID),nil,CLSCTX_INPROC_SERVER,StringToGuid(IID_IPLU),Plugins[p].Inter);
    if SUCCEEDED(HR) then
    begin
      Plugins[p].Inter.Init(MainForm as IApp,aVis);
      Plugins[p].Loaded:=true;
    end;
  end;
end;

Główny kod wtyczki:

unit pop3_c_main;

interface

uses
 Windows, ActiveX, ComObj, ShlObj, Messages, interfaces,Dialogs,main,pop3_c_srv;

type

TPlugin = class(TComObject, ICMD, IPlug)
  private
    Vis:TSettings;
  public
    //IPlug
    function Init(App:IApp;AppType:integer):HResult;stdcall;
    function FillInfo(AId: integer):HResult;stdcall; //Implement only in account plugins
    function CMD(cmd:PChar;var Buf;BufLength:integer):HResult;stdcall;
    function FreePlug():HResult;stdcall;
  public
    procedure Initialize; override;
    destructor Destroy; override;
  end;

const
  CLSID_Plug : TGUID = '{E8140BBB-2824-405C-B99C-9DB75AB1FC89}';

implementation

uses ComServ, ShellAPI, SysUtils, Registry;

procedure TPlugin.Initialize;
begin
//Tutaj inicjujemy elementy potrzebne do dzialania naszego pluginu
  inherited;
end;

destructor TPlugin.Destroy;
begin
  //if Fwind <> nil then FWind.Close;
  inherited;
end;

function TPlugin.Init(App:IApp;AppType:integer):HResult;
var
  handle:HWND;
begin
  if App = nil then   //zakładamy, że aplikacja musi miec interfejs aplikacji
  begin
    result := E_FAIL;
    Exit;
  end;

  if AppType = aVis then
  begin
    App.GetHandle(handle,pAcc,PChar(GuidToString(CLSID_Plug)));

    Vis:=TSettings.CreateP(handle);
    Vis.Color:=RGB(252,252,254);
    Vis.Show;
    Vis.App:=App;
  end;

  if AppType = aService then
  begin
    Srv:=TPOP3CSRV.Create;
    Srv.App:=App;
    Srv.Init;
  end;

  App.PLog('P3C >> Zainicjalizowałem system conectorów POP3.');

  result := S_OK;
end;

function TPlugin.FillInfo(AId:Integer):HResult;
begin
  Vis.App.AccountInfo(Vis.AccInfo,AId);
  Vis.ShowSettings;
  result:=S_OK;
end;

function TPlugin.CMD(cmd:PChar;var Buf;BufLength:integer):HResult;
begin
  result:=E_NOTIMPL;
end;

function TPlugin.FreePlug:HResult;
begin
  Vis.Free;
  Srv.Free;
  result:=S_OK;
end;

//Plugin Factory

type
  TPFSPlugFactory = class(TComObjectFactory)
  public
    procedure UpdateRegistry(Register: Boolean); override;
  end;

procedure TPFSPlugFactory.UpdateRegistry(Register: Boolean);
var
  ClassID: string;
begin
  if Register then begin
    inherited UpdateRegistry(Register);


      ClassID := GUIDToString(CLSID_Plug);
      with TRegistry.Create do
        try
          RootKey := HKEY_CURRENT_USER;
          OpenKey(szPlugin+'\'+ClassID,True);
          CloseKey;
        finally
           Free;
        end;
  end
  else begin
       with TRegistry.Create do
        try
          RootKey := HKEY_CURRENT_USER;
              ClassID := GUIDToString(CLSID_Plug);
          DeleteKey(szPlugin+'\'+ClassID);
        finally
           Free;
        end;
    inherited UpdateRegistry(Register);
  end;
end;

initialization
CoInitialize(nil);
  TPFSPlugFactory.Create(ComServer, TPlugin, CLSID_Plug, '',
      'Konektor POP3', ciMultiInstance, tmApartment);
finalization
CoUnInitialize;

end.

Funkcje towrzące okno wtyczki:

constructor TSettings.CreateP(Parent:THandle);
begin
  FParent := Parent;
  inherited Create(nil);
end;

procedure TSettings.CreateParams(var Params:TCreateParams);
begin
 inherited CreateParams(Params);
 Params.WndParent := FParent;
 //chcemy aby nasza wtyczka byla dzieckiem okna podanego
 //jako parametr (tu zakladka TTabSheet)
 Params.Style := WS_CHILD or WS_CLIPSIBLINGS;
end;

to akurat jest na zywo spisane z artykulu o interfejsach, ja nie widze tutaj nigdzie bledu, ale niestety nie dziala tak jak powinno :/

0

Na razie ja tez nie widze nic co moglo by byc zle, ale diabel tkwi w szczegolach.

Czy tej wtyczki w ogóle nia ma? (tj jakiekolwieko odwaloanie do funkcji np cmd daje blad ?!)

Moze wygeneruj mini przyklad (pusta forma guzik hide/show i wtyczka) i podeslij - bo za bardzo nie mam czasu sklejac tego sam z tego kodu.

0

Zdazylem zauwazyc, ze w momencie kiedy page control jest ustawione na glownej formie, to mozna robic z nia praktycznie wszystko, pokazywac ukrywac a zawartosc z TabSheet nie znika. Problem dopiero sie pojawia, gdy PageControl znajduje sie na jakiejś pobobcznej formie :/

0

No tak ale ja juz na poczatku rozwazalem przypadek kiedy PageControl nie bylo na glownej formie.

Bys moze lista z interfejsami w innej klasie niz ta z forma..... ale nie trzyma sie kupy.

Ciekawe ... jesli moglbys zrobic mini przyklad nie dzialajacy (forma + guzik pokaz ukryj oraz forma poboczna+tabcontrol)

pozdrawiam

0

Ok postaram sie go dzisiaj dostarczyc

0

OK czekam reichel()rudy.mif.pg.gda.pl

1 użytkowników online, w tym zalogowanych: 0, gości: 1