Solved

broadcast messages to all open forms/controls?

Posted on 1998-10-17
17
1,107 Views
Last Modified: 2010-04-06
I need to notify all my open windows of changes in some global settings.
How do I do that? My program does not store references to all of them...
The Delphi documentation is pretty useless :-(
They tell me how to define and handle custom messages (which I knew), but not how to create and send them!!

What I have is this:
CONST WM_ViewChange=WM_APP+501;
TYPE  TWMViewChange = record
        Msg : Cardinal;
        lParam:word;
        wParam:Longint;
        Result:Longint;
    END;

TMyForm = class(TForm)
.....

  protected
    procedure WMViewChange(VAR Msg: TWMViewChange); message WM_ViewChange;
END;

I tried  PostMessage(Application.Handle, WM_VIEWCHANGE, 0,0); but it didn't work (message didn't "arrive" in my second form (modal))

Again: This message should be sent to all open windows because they might have to adjust their layout...

I hope this will be easy for most "experts" :-)))

Thanks for your help!
0
Comment
Question by:Ronald112197
  • 7
  • 5
  • 4
  • +1
17 Comments
 
LVL 5

Expert Comment

by:inter
ID: 1343199
Try declaring your message with

  WM_USER+501

regards, igor
0
 
LVL 2

Author Comment

by:Ronald112197
ID: 1343200
Nope, that's not the problem... I used WM_APP because the Delphi documentation told me to! (that might have been for component writers, but so what - I use it for a derived class).

I tried changing it to WM_USER+501, but that didn't help. Must be something with the dispatch mechanism --- if I post the message to one specific component, it works ok, but I need to post it to ALL components...

Any other ideas? (sorry, but I have to reopen the question, because most people don't look at the locked questions and if I wait for two days, it'll be way down the list...- also, I urgently need that answer :-( )
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343201
How about using SendMessage() instead of PostMessage() or doing this....
var
  Forms : Integer;
begin
  for Forms := 0 to Application.ComponentCount - 1 do
    if Application.Components[i] is TForm then
      SendMessage(TForm(Application.Components[i]).Handle, WM_VIEWCHANGE, 0, 0);
end;

I hope this gives you an idea or something and hope this method works :-)

Regards,
Viktor Ivanov
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343202
OOppps.... I use the variable "i" frequently so I've mistaken it with Forms...here is how the code is suppose to look.....

var
  Forms : Integer;
begin
  for Forms := 0 to Application.ComponentCount - 1 do
    if Application.Components[Forms] is TForm then
      SendMessage(TForm(Application.Components[Forms]).Handle,WM_VIEWCHANGE,0,0);
end;

Regards,
Viktor Ivanov
0
 
LVL 2

Author Comment

by:Ronald112197
ID: 1343203
sorry, but
a) SendMessage does not behave differently from PostMessage - the only difference is that SendMessage "locks", i.e. it returns after the message is handled while PostMessage returns immediately (which is what I would prefer)

b) This code doesn't work. Give it a try - if you set a breakpoint in the handler, you'll see that Application.ComponentCount is "low" - in my application, it is 2. First one's ClassName is THintWindow, second one is TForm1. It does NOT contain all the open windows - supposedly because I create my window with TMyWindow.Create(Self); //self=Form1, so it's owned by Form1. Of course I could use FOR Ct:=1 TO Self.ComponentCount and then also override each form's event dispatching mechanism, but that's not the "nice" solution. Delphi help says that I should never have to override the event dispatching mechanism.

There must be a way to post a message in such a way that it is passed to the open forms and controls!! (i.e. all the controls on the form)
0
 
LVL 12

Accepted Solution

by:
rwilson032697 earned 50 total points
ID: 1343204
Ronald,

I'm a little confused here - do you want to inform all forms of the change, or all forms AND all components that each form contains?

Anyway, some observations:

1. You should use TMessage in the declaration of your message handler and cast the TMessage to your own message structure.

2. You can use the Broadcast method of TWinControl to broadcast a message to all windowed controls contained within it (so, you could use this to spread a message around all windowed controls of a form, but not non-windowed controls (like TLabel))

3. You could send a message to every form in your app like this:

for I := 0 to Screen.Forms.Count - 1 do
  SendMessage(Screen.Forms[i].handle, WM_VIEWCHANGE, 0, 0);

4. Send the address of your message record in the fourth parameter (the LParam). Like this:

var
  MsgInfo : TMyMesgInfo;
.
// File in Msg Info
.
// Send the message
  SendMessage(Screen.Forms[i].handle, WM_VIEWCHANGE, 0, &MsgInfo);
.

I hope these help.

Cheers,
Raymond.
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343205
Ronald,

I used SendMessage() because I like it better.

About the THintWindow and TForm1 it's just what should happen...... that's why I use if Application.Components[Forms] is TForm //I check if it is...if not then just continue on hunting....

I didn't also say that that's a solution.... I didn't even tried the code with Delphi so I wasn't sure if it will work anyway....

Raymond's example might work.. I have a simple suggestion for Raymond's code. He used the & operator which is the in C/C++ but you need to use the @ operator which is in Delphi(Pascal)... Someone who reads this might wonder what this symbol is so I decided to comment that....

Regards,
Viktor Ivanov
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343206
Raymond:

Actually this code doesn't work in D4....

for I := 0 to Screen.Forms.Count - 1 do
     SendMessage(Screen.Forms[i].handle, WM_VIEWCHANGE, 0, 0);

Don't know why . o O

Regards,
Viktor Ivanov
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 10

Expert Comment

by:viktornet
ID: 1343207
Here is a fix for it...

for i := 0 to Screen.FormCount - 1 do
  SendMessage(Screen.Forms[i].handle, WM_VIEWCHANGE, 0, 0);
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1343208
Doh!

Serves me right for typing in code without compiling it first. Of course its screen.formcount (doesn't it annoy you when they don't do some things consistently)!

Using the & instead of @ is caused by working with C++ and Delphi at the same time, sigh :-)

Cheers,
Raymond.
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343209
Ya,
I didn't say there was something wrong w/ typing text and not compiling it,... I just wanted to clear things out so everyone can use your examples efficiently... That's all... It might take someone some time to figure things out that it was just misstyping....

Regards,
Viktor Ivanov
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1343210
Viktor,

Thanks for the correction. I guess I should have added a smiley after the not compiling sentence :-)

Cheers,
Raymond.
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343211
:-)
0
 
LVL 2

Author Comment

by:Ronald112197
ID: 1343212
sorry for being slow, but I didn't have time to test that solution... mainly because I had already found a solution myself.
The Delphi FAQ pages (stupid me for not reading all of those first!) suggest
for f := 0 to Screen.FormCount - 1 do
     Screen.Forms[f].Perform(UM_MyGlobalMessage, 42, 42);
which is very close to your suggestion. Thanks.

Some comments about your "observations":
#1) nope. That's not true. "New" Windows API uses named parameters
#2, #3) ok :-)
#4) I would only do that if the information about my message is longer than 2 times 4 bytes, right?

viktornet: Thanks for your comments, but I didn't like "ComponentCount": That's a loop through 140 components every time - only 2 of them are forms...
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1343213
Ronald,

re: #4 - Yes, you're right. If it fits into a couple of longints then you can pass them in WParam and LParam (though I am not sure how you get them out at the end...).

Cheers,

Raymond.
0
 
LVL 2

Author Comment

by:Ronald112197
ID: 1343214
well... I could pass 64 boolean parameters in 2 longints *bg* - I only need 6 ;-))

How I get them out?
procedure WMViewChange(VAR Msg: TWMViewChange); message WM_ViewChange;
  BEGIN
    IF Msg.MyFirstParameterName AND 8 >0 THEN ....
    ....
  END;

re-Cheers :-)
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1343215
Um.. No. What I meant was how you get the WParam and LParam values into that structure of yours automagically...

Raymond.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).
Both in life and business – not all partnerships are created equal. As the demand for cloud services increases, so do the number of self-proclaimed cloud partners. Asking the right questions up front in the partnership, will enable both parties …

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now