Solved

WM_USER message does not arrive

Posted on 1997-09-16
25
1,230 Views
Last Modified: 2010-04-04
OK. I give up.

My app does not receive my own messages (WM_USER + n) sent from
another instance of the same app.

Sample app:

------------------------------ code ----------------------------
type
  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    Label1: TLabel;
    Edit1: TEdit;
    procedure BitBtn1Click(Sender: TObject);
  protected
    procedure WMUser(var M: TMessage); message WM_User;
  end;

procedure TForm1.WMUser(var M: TMessage);
begin
  label1.caption:= 'received '+IntToStr(M.lParam);
  inherited;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  PostMessage(HWND_BROADCAST, WM_USER, 0, StrToInt(Edit1.Text));
end;
--------------------------- end code ---------------------------

Then:
start two instances of this app (one for send, one for receive)
in one instance:
  enter a number in the editbox (ex: 23),
  press the button,

the other instance does not write 'received 23'.

Why? And what to do? Thanks in advance.
0
Comment
Question by:krisz
  • 9
  • 7
  • 5
  • +3
25 Comments
 
LVL 1

Expert Comment

by:jackb022197
ID: 1345179
You can not send a msg from one instance to another instance this way. You need to look at IPC to exchange info between different processes. Check the Win32 API help file for this.
0
 

Author Comment

by:krisz
ID: 1345180
Why not? Delphi or windows prevents it? Please be more verbose,
this answer is not acceptable.

Using DDE or pipes requires sending messages, and I see
no reason to prevent it between two instances of an app.
0
 
LVL 1

Expert Comment

by:ygolan
ID: 1345181
Notice that you should not broadcast a WM_USER. WM_USER-based messages are defined only within a window class - different applications respond differently to WM_USER. For all you know, there might be a running application that considers WM_USER to be a command to shut down, delete a file or format the hard disk :-)

I suggest that (if you wish to avoid IPC, which BTW is very easy to use) you create a hidden window with a special name, use FindWindow to find it from the other instance, and use its handle to PostMessage directly to it.
0
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:krisz
ID: 1345182
Thanks for this comment. But I think it's not really the point.
Or registered messages will arrive? If so, the problem is no
more. If won't, bad. I'll try it.

Also I have to disagree about IPC.
Actually I'm trying to set up an IPC communication. I want to
train myself in the usage of unnamed pipes, the problem is I
have to tell to the other app the handles of the pipe. Messages
look the easiest way for this. Yes, I can use shared memory, but
if I do why do I need the pipe?

I can't believe that there is no way to send messages between
two instances of an app.
0
 
LVL 5

Expert Comment

by:julio011597
ID: 1345183
Hello, just a guess:

procedure WMUser(var M: TMessage); message WM_User;
----------------------------------------------^^^^

should be WM_USER (all uppercase).

Does this makes any difference?

-julio
0
 

Author Comment

by:krisz
ID: 1345184
Ok. I reject jackb's answer, and increase points to 150.

Note to julio: letter case is not the solution.
0
 

Author Comment

by:krisz
ID: 1345185
Adjusted points to 150
0
 
LVL 1

Expert Comment

by:ygolan
ID: 1345186
> Yes, I can use shared memory, but  if I do why do I need the > pipe?

You don't :-) that's the whole point.

I've got source code that makes  IPC easy. Email me for it - ygolan@hyperact.com
0
 

Author Comment

by:krisz
ID: 1345187
Look!

It's NOT about IPC! I talk about _messages_.
I've used shared memory earlier. I've used pipes too.
IPC is cool, but I want messages, messages, MESSAGES!!!!!

Meanwhile I found a workaround. I still don't know what is
the problem with my code above, but the new code works, so
the 'what to do?' part of the question is no more.

I'm still waiting for somebody who can tell me what's the
problem.

(Note: this 150 points are the final offer)
0
 
LVL 12

Expert Comment

by:andrewjb
ID: 1345188
Try using WM_USER + n, where n is about 100. Delphi itself uses some of the user messages in its own components. Who knows what! So the message might be being trapped by something else.
0
 
LVL 12

Expert Comment

by:andrewjb
ID: 1345189
Try using WM_USER + n, where n is about 100. Delphi itself uses some of the user messages in its own components. Who knows what! So the message might be being trapped by something else.
0
 

Author Comment

by:krisz
ID: 1345190
Bad.

I tried it with registered messages. Still doesn't work.
0
 
LVL 12

Accepted Solution

by:
andrewjb earned 150 total points
ID: 1345191
Got it!

The BROADCAST message sends to all the APPLICATIONS, not the forms. So you have to trap application messages :

TForm1.FormCreate...
begin
  ......
  Application.OnMessage := TrapAppMessages;
  ....
end;

TForm1.TrapAppMessages( var Msg: TMsg; var Handled: Boolean);
begin
  if ( Msg.Message = WM_MYMSG ) then
  begin
    .... { Do your stuff }
    Handled := True;
  end;
end;

Still use WM_USER + n ( n = about 150 or so )

0
 

Author Comment

by:krisz
ID: 1345192
This was a clue!

-- Win32.hlp, PostMessage ----------------------------
HWND_BROADCAST:

The message is posted to all top-level windows
in the system, including disabled or invisible
unowned windows, overlapped windows, and pop-up
windows. The message is not posted to child windows.
-- end -----------------------------------------------

But all windows including the main form are child windows
in delphi. The top-level window is hidden, and you can
get it's handle with Application.Handle.

It's not in the help, but you can see it in Forms.pas.
See TApplication.Create and TApplication.CreateHandle.

It's an inconsistency in Delphi. I think the MainWndProc
should forward all messages sent to the top-level window
to the main window.

Solutions:
- Application.OnMessage
- Application.HookMainWindow

(And still don't broadcast WM_USER+n messages, use
registered messages instead!)

Because you gave only a clue, and not a detailed description,
I offer you an 'acceptable' grading. Comment if you want more.
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1345193
Hi krisz.
I have a question for you.
I try too broadcast messages (WM_USER+n) and when I set OnMessage for Application i can't get this message, Can You boadcast WM_USER now ? If You can than How ?
0
 
LVL 12

Expert Comment

by:andrewjb
ID: 1345194
For mirek :

( Form with a button on it )


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure AppMsg (var Msg: TMsg; var Handled: Boolean);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

const
  WM_MYMSG = WM_USER + 150;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
  PostMessage( HWND_BROADCAST , WM_MYMSG , 0 , 0 );
end;

procedure tForm1.AppMsg (var Msg: TMsg; var Handled: Boolean);
begin
  if ( Msg.Message = WM_MYMSG ) then
  begin
      { This just prints something on the screen }
    AllocConsole;
    writeln('Hello there!');
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := AppMsg;
end;

end.
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1345195
Yes i write this in the same way but this don't working. Delphi3.
Why ?
When You try this i think so this is working. Mayby this depend of Delphi version ?
0
 
LVL 12

Expert Comment

by:andrewjb
ID: 1345196
Works OK for me in Delphi 3.

0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1345197
It's seems as impossible, but I know so This working for You. Do you have any idea why this not working for me ?
0
 
LVL 12

Expert Comment

by:andrewjb
ID: 1345198
The FormCreate and Button1Click methods are event handlers. You are attaching them to the form / button correctly, I assume ...

AJB

0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1345199
Yes.

In MS-SDK i found :


When SendMessage() is used to send a broadcast message (hwnd = 0xFFFF or
hwnd = -1), the message is sent to all top-level windows. A message
broadcast by PostMessage() is only sent to top-level windows that are
visible, enabled, and have no owner.

You might observe the effect of the difference when, for example, the top-
level window of your application calls DialogBox() to present a modal
dialog box. While the modal dialog box exists, its owner (your top-level
window) will be disabled. Messages broadcast using PostMessage() will not
reach the top-level window because the window is disabled, and will not
reach the dialog box because the dialog box has an owner. Messages
broadcast using SendMessage() will reach both the top-level window and the
dialog.

In Windows 3.1, PostMessage() will broadcast to invisible and disabled
windows just like SendMessage() already does.


But Send Message don't working too !!!.
0
 

Author Comment

by:krisz
ID: 1345200
No differences between SendMessage and PostMessage.

----- win32.hlp -----------------------
SendMessage:
If this parameter is HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows.

PostMessage
The message is posted to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows. The message is not posted to child windows.
----- end ------------------------------

Application.OnMessage should work. If not, the problem is
something else.

andrewjb, if you agree, I won't grade your answer until this
conversation is going on, because the grading prevents
adding more comments. Tell me if you disagree.
0
 
LVL 12

Expert Comment

by:andrewjb
ID: 1345201
Indeedy, I don't know why mirek is having problems. Perhaps you should post the code you're trying to execute, mirek ??


0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1345202
Sorry. You can grade the answer if this work for you. This is Your question not My.
0
 

Author Comment

by:krisz
ID: 1345203
Mirek! Ask your question as a separate one. This thread is
going to close.
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Comparing dates in Delphi. Greater than/ Less than 3 211
Base1 Encode/Decode 3 81
I want to use librsync in my Delphi backup application. 3 58
MS Access from Delphi 31 59
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

807 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