Aplikacja MDI - jak poinformować, o które okienko lub komponent nam chodzi

Piotrekdp

W tym artykule dotyczącym aplikacji MDI (wielookienkowych) odpowiem na Pytanie
JAK POWIADOMIĆ PROGRAM O KTÓRE OKIENKO NAM CHODZI
Przede wszystkim muszę wspomnieć ,że każde olienko ma swój unikalny
uchwyt (handle) który może się nam przydać ale o tym za chwilę...

narazie przedstawię kroki tworzenia prostej aplikacji MDI

  1. wybieramy formę główną aplikacji
    na zakładce properties ustawiamy form style na fsMDIForm

2.tworzymy formę dziecko File>New>Form
na zakładce properties tej formy ustawiamy form style na fsMDIChild

3.Wybieramy menu Project>Options i wybieramy z menu Auto-Create forms
formę - dziecko przenosimy ją na Available forms
(forma ta dzięki temu nie zostanie stworzona od razu i posłuży nam jako szablon dla innych form)

  1. wybieramy forme główną i dajemy File>Use Unit
    wybieramy formę - dziecko klikamy OK

{teraz przystąpimy do oprogramowania form}

UWAGA PRZYJMUJĘ TUTAJ ,ŻE
FORMA GŁÓWNA NAZYWA SIĘ MAINFM (WŁAŚCIWOŚĆ NAME = MAINFM)
FORMA -DZIECKO NAZYWA SIĘ CHILDFM (WŁAŚCIWOŚĆ NAME = CHILDFM )

**Tworzymy okienko (dynamicznie)
Wrzucamy przycisk na formę główną i w procedurze OnClick Piszemy np.:

procedure Tmainfm.BNewFormClick(Sender: TObject);
begin
Tchildfm.Create(Self);//<<forma dziecko zostaje stworzona
{można zapisać tak }
With Tchildfm.Create(self) do 
     begin
//<< blok instrukcji odnoszących się do tworzonej formy 
Color:=Rgb(Random(255),Random(255),Random(255)) ; //np losowy kolor
     end;
end;
 

Jeżeli wrzucimy teraz jakieś komponenty na formę-dziecko to zostaną one
stworzone automatycznie gdy tylko stworzymy formę
Uwaga czasami chcielibyśmy zrobić formę na której rysowana bitmapa która będzie edytowana(np program grficzny ) ale powstaje problem

**jak skojarzyć bitmapę z danym dynamicznym okienkiem

odpowiedz jest prosta
tworzymy tablicę dynamiczną bitmapek wraz z informacją o uchwycie okienka {tablice rekordu}
{pozatym pasowałoby mieć licznik dotychczas tworzonych form Łącznie z zamkniętymi formami ,Po co to zaraz wyjaśnię }

 
type
rec=record
Bitmapka:TBitmap;
Uchwyt:THandle;
end;
var
Tablica:array of rec; 
L:integer;// << licznik form dzieci

więc procedura tworzenia nowego okienaka wyglądała by tak:

procedure Tmainfm.BNewFormClick(Sender: TObject);
begin
inc(L); //powiększamy licznik o 1
setLength(Tablica,L);
// powiększamy tablicę z bitmapami o 1
With Tchildfm.Create(self) do 
   begin
   Tablica[L-1].uchwyt:=Handle;
{przypisanie uchwytu okna do zmiennej w rekordzie potem w pętli będziemy szukać rekordu z bitmapką do aktualnego okna(porównywanie Handle okna i zmiennej uchwyt w rekordach)}
   Bitmapka:=TBitmap.create;
   Bitmapka.width:=500;
   Bitmapka.height:=200;
   Canvas.draw(0,0,bitmapka);
 
   end;
end;
 

**jak znaleźć rekord skojarzony z oknem
wystarczy w OnActivate formy dziecka wpisać

{Find to nazwa zmiennej typu integer}
 
for Find:=0 to length (Tablica)-1 do 
if Tablica[Find].uchwyt = handle then break;
{jeżeli znajdzie rekord w którym zmienna uchwyt jest identyczna z handle okna to przerwie szukanie i zmienna Find będzie miała numer  tego rekordu tym samym znaleźliśmy rekord a jak znależliśmy rekord to i wszystkie zmienne w tym rekordzie }

teraz wystarczy tylko napisać coś np.

 
Tablica[Find].Bitmapa.LoadFromFile('C:\xxxbmp');

Jak już potarafimy skojarzyć rekord z oknem to jeszcze pasowało by wiedzieć o tym ,
**jak poinformować program o tym o które okienko lub komponent nam chodzi
Odpowiedz jest prosta -Potrzebujemy wskaźnika najlepiej globalnego:

var 
Wsk:Pointer;

W onActivate formy -dziecka piszemy:

Wsk:=self;

A potem w dowolnej procedurze piszemy:

Chldfm:=wsk; // poprostu piszemy forma o którą nam chodzi to forma wskazana przez wskażnik np.
 
procedure Tmainfm.Wklej1Click(Sender: TObject);
begin
Childfm:=wsk;//<< po napisaniu tej linijki w procedurze piszemy tak jakby  była to zwykła aplikacja z pojedyńczym komponentem 
childfm.memo.PasteFromClipboard;
end; 

lub jeżeli to odnosi się do aktywnego okienka możemy napisać:

with mainfm.ActiveMDIChild do 
begin {z aktywnym dzieckiem zrób}
// i tu blok instrukcji
end;

Trzeba jednak pamiętać, że ta druga opcja działa na aktywne okienka, a wskażnik możemy przypisać do nie - aktywnego okna (np. instrukcja repaint musi działać na nieaktywne).

3 komentarzy

No dobra mam powiedzmy 3 okna dzieci i kazde ma rozne nazwy z wlasciwosci CAPTION
no i teraz jedno jest aktywne np okno 2 a 1 i 3 sa nieaktywne. To jak teraz za pomoca buttona
wstawic text do okienka nr 1 ? np do MEMO1 ktore tam wstawie na probe ?

Bardzo śmieszne hehehe :) :) ;)

WŁĄŚCIWOŚĆ - WTF? :> Moze: WŁAŚCIWOŚĆ ? :D