SendMessage i TApplicationEvents

0

Cześć, mam w aplikacji jakiś unit. Mam też formę tworzoną dynamicznie. Na formie leży sobie TApplicationEvents, który odbiera komunikaty. Z użyciem PostMessage wszystko ładnie działa:

PostMessage(Application.Handle, MY_MSG, 0, 0);

Natomiast potrzebuję poczekać na obsłużenie komunikatu, więc chcę wysłać SendMessage w ten sam sposób. Jednak TApplicationEvents tego nie przechwytuje. Czy przy SendMessage MUSZĘ podać handla konkretnego okna, zamiast handla aplikacji? Nie da się tego jakoś obejść?

1

Note: OnMessage only receives messages that are posted to the message queue, not those sent directly with the Windows API SendMessage function.

A dlaczego musisz wysłać komunikat do Application? Nie możesz odebrać go np. w głównym oknie programu?

0

Nie mogę, bo po np. po odebraniu pewnego komunikatu muszę odświeżyć jakiś Dataset, który znajduje się na jakiejś formie dynamicznej (ona może istnieć, ale nie musi). Takich form może być kilka i teraz sprawdzając to w MainForm robi się burdel i jest to dość niewygodne. Więc każde okno, które musi zareagować na ten komunikat otrzymuje go.

1

A czemu nie możesz przeiterować Components dla Application:

var I:Integer;
var Com:TComponent;
begin
  for I:=0 to Application.ComponentCount-1 do
  begin
    Com:=Application.Components[I];
    if Com is TDataModule1 then
    begin
      TDataModule1(Com).UpdateMyData;
    end;
  end;
end;
1

Albo subclasing

  private
    { Private declarations }
    pNewAppWndProc: Pointer;
    pOldAppWndProc: Pointer;
    procedure AppWndProc(var Message: TMessage);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.AppWndProc(var Message: TMessage);
begin
  Message.Result:= CallWindowProc(pOldAppWndProc, Application.Handle,
      Message.Msg, Message.WParam, Message.LParam);
  //nie wiem czy to chcesz przed domyslną obsluga komunikatow czy po. T
  //To twoja dzialka jak to ustawic i czy obslugiwać default dla wszyskich komunikatow
  if Message.Msg = MY_MSG then
  begin
    ShowMessage('Działa :)'); //tu robisz co chcesz :)
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  SendMessage(Application.Handle, MY_MSG, 0, 0);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  pNewAppWndProc:= Classes.MakeObjectInstance(AppWndProc);
  pOldAppWndProc:= Pointer(SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(pNewAppWndProc)));
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(pOldAppWndProc));
  if pNewAppWndProc <> nil then
    Classes.FreeObjectInstance(pNewAppWndProc);
end;
0

OK, dzięki za odpowiedzi

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