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 ?
Zbyt wiele informacji nie dales aby Ci pomoc, moze to
Wtyczki (Plugin) w oparciu o interfejsy
lepiej kopiowac link :)
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 :/
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)
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 :/
Nie widze, gdzie tworzysz wtyczke
CoCreateInstance
, i czy TMainForm to wtyczka (dlaczego tam jest TabControl, powinno to byc w aplikacji wtyczkowej
- bardziej uniwersalne ??).
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 :/
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.
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 :/
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
Ok postaram sie go dzisiaj dostarczyc
OK czekam reichel()rudy.mif.pg.gda.pl