Przekazywanie danych między zakładkami (TTabSheet) różnych form

0

Chciałbym zasięgnąć opinii czy moja idea przekazywania danych między różnymi formami, zakładkami itp jest właściwa. Czy jest jakiś lepszy sposób?

Forma1: Zawiera spis np. klientów.

procedure TForm1.buttonClick(Sender: TObject);
var
  pMess: TMessage;
begin
  pMess.Msg := WM_SelectContractors;             //WM_USER+1001
  pMess.WParam := 7;                                    //Liczba oznacz np index klienta w bazie który został wybrany z np tabeli;
  pMess.LParam := ect_button_delivery.Tag;      //Handle okna które wywołało szukanie klienta
  Form2.PageDostawy.Broadcast(pMess); //Wyślij wiadomość do wszystkich zakładek  
end;

Forma2 - Zawiera edit i przycisk który wywołuje aby użytkownik wybrał kontrahenta

procedure TForm2.SelectContractors(var Msg: TMessage);
begin
  if Msg.LParam = Handle then 
    TForm2(FindControl(Msg.LParam)).Edit1.Text := IntToStr(Msg.WParam);  //Zwraca Index wybranego kontrahenta
end;

procedure TForm2.ButtonSelectClick(Sender: TObject);
begin
  Form1.button.Tag := Handle; //Zapamiętuje handle okna z którego wywołane jest zapytanie wyboru klienta
  PokazForm1; //Procedura która pokazuje / przeskakuje do Form1
end;

UWAGI

TForm2 jest tworzone dynamicznie i przypisywane do zakładek PageControl / TabSheet. Dlatego na jednej formie może być PageControl z wieloma zakładkami na których jest umieszczony TForm2; Np Tak jak byśmy klika razy wywołali poniższą procedurę:

procedure TForm3.button_modifyClick(Sender: TObject);
var
  TabSheet: TsTabSheet;
  aComponent: TComponent;
  fC: TForm2;
begin
  TabSheet := TsTabSheet.Create(Form3.PageControl);
  TabSheet.PageControl := Form3.PageControl;
  fC := TForm2.Create(TabSheet);
  fC.Align := alClient;
  fC.Parent := TabSheet;
  Form3.PageControl.ActivePage := TabSheet;
end;

Nie chciałbym zakładać kolejnego wątku ale czy to normalne że polecenie

PageControl1.Broadcast(pMess); 

Nie rozsyła komunikatów po zakładkach ?

1
Rafał D napisał(a):

Nie chciałbym zakładać kolejnego wątku ale czy to normalne że polecenie

PageControl1.Broadcast(pMess); 

Nie rozsyła komunikatów po zakładkach ?

Nie jest normalne trzeba tylko prawidłowo taki komunikat odebrać:

const
  WM_SelectContractors = WM_USER + 1000;

type
  TTabSheet = class(ComCtrls.TTabSheet)
  protected
    procedure WMSelectContractors(var Msg: TMessage); message WM_SelectContractors;
  end;
//....
procedure TTabSheet.WMSelectContractors(var Msg: TMessage);
begin
  ShowMessage('!'); //tu coś robisz w przykładzie tyle razy zobaczysz komunikat ile masz załadaek
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  Msg: TMessage;
begin
  Msg.Msg:= WM_SelectContractors; //komunikat
  Msg.WParam:= 0; //jakaś dane
  Msg.LParam:= 0; //jakaś dane
  Msg.Result:= 0; //co domyślnie zwraca
  PageControl1.Broadcast(Msg);
end;
0

Ale dokładnie tak mam jak teraz napisałeś z tym wyjątkiem że procedura odbioru komunikatu nie jest w zakładce TabSheet tylko w innym komponencie na tej zakładce. I teraz wykonanie poniższej procedury nie wysyła komunikatu.

Form2.PageDostawy.Broadcast(pMess); 

Ale wykonanie procedury poniżej działa i komunikat jest przechwytywany.

  for x := 0 to Form2.PageDostawy.PageCount-1 do
    Form2.PageDostawy.Pages[x].Broadcast(pMess); //Wyślij wiadomość do wszystkich zakładek
0

@Rafał D w helpie wyraźnie piszą że komunikat jest wysyłany do potomków ale bezpośrednich jak chcesz do kontrolek na zakładce to można go forwardować:

procedure TTabSheet.WMSelectContractors(var Msg: TMessage);
begin
  Self.Broadcast(Msg); //forward
end;

procedure TEdit.WMSelectContractors(var Msg: TMessage);
begin
  ShowMessage('Kominikat dostal też edit')
end;
0

Mamy tutaj przykład jak przekazywać konkretny komunikat a czy można jakoś przekazać każdy jeden komunikat do kontrolek? tak aby nie pisać dla każdego z osobna tzn aby nie robić tego:

type
  TTabSheet = class(ComCtrls.TTabSheet)
  protected
    procedure WMSelectContractors(var Msg: TMessage); message WM_SelectContractors;
    procedure komunikat1(var Msg: TMessage); message WM_SelectContractors_1;
    procedure komunikat2(var Msg: TMessage); message WM_SelectContractors_2;
  end;

dodanie znacznika <code class="delphi"> - @furious programming

0

Wszystkich za jednym zamachem obsłużyć się nie da ponieważ dużo komunikatów i tak jest przekazywanych do kontrolek więc gdybyś taki komunikat dodatkowo chciał przesłać do kontrolki która go już otrzymała miałbyś niezły burdel czyli piękny StackOverflow... No chyba że chodzi o komunikaty użytkownika a nie systemowe to pewien zakres spokojnie można by coś kombinować z nadpisaniem WndProc i inherited dla systemowych a forward dla swoich.

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