Dynamiczne okienka jak te z GG

Misiek__

Od jakiegoś czasu robię swój komunikator używając do tego komponentu THGG. Nie mogłem sobie poradzić z tworzeniem dynamicznych okienek, ale w taki sposób, aby okienko, które już zostało utworzone wcześniej nie było tworzone kolejny raz. :) Jestem początkującym w delphi, ale poświęcam na to dużo swojego wolnego czasu. Wiem, że tematy odnośnie tworzenia okienek dynamicznie są na forum, ale albo są niedokończone, albo kody tam zamieszczone są czasami niezrozumiałe dla początkujących. Mnie się jakoś udało to wszystko poskładać do kupy, więc podam kod, który ułatwi życie początkującym (mam taką nadzieję :) )

...
implementation

uses ...

var  // <--- WSTAWIĆ
 F: array of TForm2; // <--- WSTAWIĆ
 NrOkna: Integer; // <--- WSTAWIĆ


{$R *.dfm}
...

Teraz w zdarzeniu OnDblClick komponentu ListView (ten komponent użyłem do wyświetlania listy kontaktów) wpisujemy poniższy kod:

procedure TForm1.ListView1DblClick(Sender: TObject);
var
Nr: integer;
begin
if ListView1.Selected=nil then Exit;

if HGG1.Connected=false then Exit;

if HGG1.Logged=false then Exit;

SetLength(F,20);

// Sprawdzenie czy istnieje juz to okno
for Nr := 0 to Screen.FormCount -1 do
begin
if F[Nr].Caption='Rozmowa z ' + HGG1.Users.User[ListView1.ItemIndex].Name then
begin
if F[Nr].Showing=true then begin
//Okno istnieje wiec nie tworz nowego tylko pokaz! :)
F[Nr].BringToFront;
exit;
end else begin
//Okno istnieje, ale go nie widac, więc je pokaż (niestety obciąża procesor :)
F[Nr].Show;
F[Nr].BringToFront;
exit;
end;
end;
end;

//Okno nie istnieje wiec utworz je!!!
NrOkna:=NrOkna+1;
F[NrOkna] := TForm2.Create(Self);
F[NrOkna].Caption:='Rozmowa z ' +  HGG1.Users.User[ListView1.ItemIndex].Name; 
F[NrOkna].Edit1.Text:=IntToStr(HGG1.Users.User[ListView1.ItemIndex].GGNumber);
F[NrOkna].Show;


end;

Wiem, że osoby, które na delphi znają się bardzo dobrze pewnie inaczej by to napisali, ale jak dla mnie i dla wielu podobnych to rozwiązanie jest najprostsze.

Mile widziane inne rozwiązania, jeżeli ktoś oczywiście posiada ;)

14 komentarzy

A cha... bo ty je chcesz dynamicznie tworzyć

Lol, robisz tablice Form?

wszytko fajnie , ale jest problem jak wstawiać odebraną wiadomość do danego okna....?

O rany, FindWindow chyba nie bolało??

Fajne ale z bugami :-/

proponuje zapisywanie wskaznikow do foremek, a nie szukanie ich po tytulach o_O

A jak zrobic zeby na tej formie wyswietlane były jeszcze 2 komponenty Memo ??

"który ułatwi życie początkującym"
a do jakich poczatkujacych sie zwracasz? bo np imho niektorzy poczatkujacy nie bedza rozumieli czemu kompilator wywala blad przy linijce:
[delphi]uses Unit2, Unit3, Unit4, Unit5, Unit6, Unit7;[/delphi]
tak samo nie kazy musi miec TForm2 (moga zmienic nazwe no nie? )
jesli bys to uogolnil to spoko ale w danej chwili to nawet 'glosuj' sie nie chce kliknac :P
// to mialbyc komentarz motywacyjny :F

"(mam taką nadzieję :) )" :P

if ListView1.Selected = nil then Exit;
if HGG1.Connected=false then Exit;
if HGG1.Logged=false then Exit;

To jest dziwne nie lepiej:

if (ListView1.Selected <> nil) and (HGG1.Connected=true) and (HGG1.Logged=true) then
  begin
  ...
  end;

To sie chyba zbuguje jak np. jest user A, otwierasz okno, zamykasz, usuwasz A,zmieniasz nazwe usera B na A, otwierasz okno A.

necrokris miales racje, cos bylo nie tak wczesniej, bo po zamknieciu okna i próbie ponownego jego otwarcia były problemu, ale jakoś sobie z tym poradziłem ;) Może mało profesjinalnie, ale działa :D

IMO uważam że metoda z tablicą nie jest zbyt dobra.
Też pracuje nad IMem i rozwiązałem do tak:

procedure TfrmMain.CreateChatWindow(User: Integer; Caption: String);
var
  frmMsg1: TfrmMsg; // TfrmMsg jest okienkiem rozmowy
  i: Integer;
begin
  for i := 0 to Screen.FormCount - 1 do begin // pętla przechodzi przez wszystkie okienka w aplikacji
    if Screen.Forms[i].Tag = User then begin // sprawdzamy czy okienko z określonym numerem już istnieje
      Screen.Forms[i].Caption := Caption; // nadajemy tytuł okna
      Screen.Forms[i].SetFocus; // dajemy focus na to okienko
      Exit;  // nie wykonuj reszty funkcji
    end;
  end;
  frmMsg1 := TfrmMsg.Create(Application); // tworzymy nowe okno
  frmMsg1.Tag := User; // właściwośc Tag przechowywuje numer użytkownika z którym rozmawiamy
  frmMsg1.Caption := Caption;
  frmMsg1.Show; // pokazujemy nowo utworzoną formę
end;

// zdarzenie występujące w przypadku podwójnego kliknięcia na użyszkodnika ;) 
procedure TfrmMain.lstUsersDblClick(Sender: TObject);
var
  ListItem: TListItem;
begin
  if lstUsers.Selected = nil then Exit;
  CreateChatWindow(gg.Users.User[gg.Users.Find(lstUsers.Selected.Caption)].GGNumber, gg.Users.User[gg.Users.Find(lstUsers.Selected.Caption)].Name);
end;