control '....' has no parent window problem + dll

0

Ogólnie mówiąć mam mały problem a że przekopałem już połowe internetu i dobrego rozwiązania nie znalazłem to pisze tu.

Potrzebuje zrobić pluginy do aplikacji. -> TFrame lub TPanel.

DLL 1:

  • tworzy okno TForm.Create(nil)..
  • ładuje na tym oknie pluginy z innych DLL

DLL 2:

  • kopiuje application, screen z okna w DLL1
  • tworzy TPanel i wyświetla go na oknie w DLL1
  • tworzy TFrame i wyświetla je na TPanel.

Problem ejst ciekawe gdyż jak wrzucam komponenty na TFrame to wszystko gra, problemy zaczynają się dopiero jak gdy na TFrame rzuce np PageControl a na niego do zakładek co innego.

Dostaje wtedy taki error:

Error reading RichEdit1.Color: Control 'Frame2' has no parent window

Pojawia się bo dziwnym trafem jakoś niemoże odczytać właściwości Color z dfm, przynajmniej tak mi się wydaje. W momencie tworzenia TFrame(Frame2) nie jest on przypisany jeszcze do TPanel i w tym tkwi problem.

Może ktoś zna sposób jak opóżnić ładowanie elementów formy aż do momentu przypisania parentu ?

0

Jak ktoś nie ma parenta to trza mu go dać. To chyba proste, nie?

0
Juhas napisał(a)

Jak ktoś nie ma parenta to trza mu go dać. To chyba proste, nie?

Sorry zapomniałem dodac że ustawiam parenta, jak i parentwindow i owner.
Problem polega tylko na tym że niemoge ustawić parenta dla TFrame przed tym jak tworzy on kontrolki zdefiniowane w dfm. Bo to właśnie wypiepsza się na kontrolkach które jako parent dostają z automatu kontrolki zdefiniowane w dfm.

Inaczej.

TFrame->Panel <- działa
TFrame->Panel->Label <- wypiepsza się

0

Zaraz.
Najpierw tworzysz frame'a:

frame:=TFrame.Create(owner);
frame.parent:=owner; //przeważnie, ale nie zawsze się tak uda

//potem tworzysz inne komponenty
panel:=TPanel.Create(frame);
panel.parent:=frame;

//i na koniec label:
myLabel:=TLabel.Create(panel);
myLabel.Parent:=panel;

kontrolki mają taki konstruktor jak CreateParented, co pewnie powoduje zastąpienie dwóch linii kodu jedną, ale osobiście nigdy tego nie używałem, więc nie wiem.
Jak będziesz miał tak napisany kod, jak wyżej przedstawiłem, to nie ma bata, musi działać.

0
Juhas napisał(a)

Zaraz.
Najpierw tworzysz frame'a:

frame:=TFrame.Create(owner);
frame.parent:=owner; //przeważnie, ale nie zawsze się tak uda

//potem tworzysz inne komponenty
panel:=TPanel.Create(frame);
panel.parent:=frame;

//i na koniec label:
myLabel:=TLabel.Create(panel);
myLabel.Parent:=panel;

kontrolki mają taki konstruktor jak CreateParented, co pewnie powoduje zastąpienie dwóch linii kodu jedną, ale osobiście nigdy tego nie używałem, więc nie wiem.
Jak będziesz miał tak napisany kod, jak wyżej przedstawiłem, to nie ma bata, musi działać.

Wiesz gdy tworze komponenty dynamicznie to wszystko jest ok, problemem jest TFrame i komponenty zdefiniowane w w dfm.

 
 shell:=sh;
 Application:=shell.GetApplication;
 Screen:=shell.GetScreen;
 panel:=TPanel.Create(shell.GetParent);
 panel.ParentWindow:= shell.GetParent.Handle;
 panel.Parent:=shell.GetParent;
 panel.Align:=alClient;
 panel.BevelOuter:=bvNone;
 Frame:=TFrame2.CreateParented(panel.Handle);
 Frame.Parent:=panel;
 panel.Caption:='';
 panel.Visible:=false;

Jeśli np tworze obiekt t frame tak to się wywala (kod w dll) shell.GetParent to TPanel.
"control has no parent window"

Ale gdy tworze komponent tak:

shell:=sh;
 Application:=shell.GetApplication;
 Screen:=shell.GetScreen;
 panel:=TPanel.Create(shell.GetParent);
 panel.ParentWindow:= shell.GetParent.Handle;
 panel.Parent:=shell.GetParent;
 panel.Align:=alClient;
 panel.BevelOuter:=bvNone;
 panel.DockSite:=true;
 Form1:=TForm1.Create(nil);
 form1.Frame21.ParentWindow:=panel.Handle;
 form1.Frame21.Parent:=panel;
 Frame:=form1.Frame21;
 panel.Caption:='';
 panel.Visible:=false;

To działa, musze po prostu tworzyc obiekt na oknie i go potem z niego przenosić.

Ciekawostą jest też to że np w pierwszym przypadku bez względu czy użyje CreateParented czy Create efekt jest ten sam. Kolejną zabwaną rzeczą jest to że gdy na tym TFrame znajduje się np tylko Memo to działa, ale jak już to memo wrzuce na panel to się wywala.

Miał ktoś taki przypadek ? a może jakoś inaczej da się to zrobić. (Niechce sie bawić w dokowanie okien)

0

Zaraz, co Ty chcesz uzyskać?
Panel na panelu, a na tym frame?

0
Juhas napisał(a)

Zaraz, co Ty chcesz uzyskać?
Panel na panelu, a na tym frame?

Proste. Chce tworzyć komponent na formie z poziomu dll - pluginy.
Ten dodatkowy panel w środku jest pownieważ dzieki temu na wstepie nie wypiepsza Od razu errora tego co w temacie.
Równie dobrze może go tam niebyć.

Problemem jest to że niemoge stwożyć komponentu który projektuje sobie wizualnie (dfm) np TFrame na głownym oknie aplikacji z poziomu dll bo wywala error.

0

Ale wiesz, że jako argumenty do dllki powinieneś przekazywać wskaźnik, a nie obiekt?

0
Juhas napisał(a)

Ale wiesz, że jako argumenty do dllki powinieneś przekazywać wskaźnik, a nie obiekt?

Argumenty do dll lecą poprawnie bo przez metode w klasie wirtualnej :d Tzn tworze obiekt typu TPlugin i zwracam wskaźnik do tego obiektu poprzez jedną funkcje w dll. Potem głownej aplikacji sobie z tego korzystam..

0

Pokaż dokładnie cały kod metody z argumentami, w której tworzysz obiekt i go zwracasz.
Oczywiście pomiń w kodzie nieważne linijki :)

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