Board index » cppbuilder » IPC, using Application->OnMessage

IPC, using Application->OnMessage


2007-10-28 11:58:09 PM
cppbuilder64
Hi all
After another sleepless night here another question:
I try to implement IPC between my two processes.
For a test I implemented a simple form with one button that sends a message
PostMessage(HWND_BROADCAST, msgTEST, 0, 0);
and a OnMessage handle that receives this message.
if (Msg.message == msgTEST)
{
OutputDebugString("Message received");
Handled=true;
}
I use HWND_BROADCAST because in future the sender and receiver will be in
two separate processes.
msgTEST is registered using
msgTEST = RegisterWindowMessage("msgTest");
If I run the application like this and press the button, I receive one
OutputDebugString. This is what I expected.
But when I create a second form, and place a TTimer component on it, I
receive the OutputDebugString twice. If I place two TTimer component on it,
I receive the OutputDebugString three times. The second form is not event
referenced in my first form.
Curious enough this does not happen with a TButton component, so it depends
on the component I place on this second form.
Does this make sense ?
Is not the "Handled=true" statement supposed to prevent the message from
being sent to another Window ?
Rds
Marc
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
UINT msgTest;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::AppMessage(tagMSG &Msg, bool &Handled)
{
if (Msg.message == msgTest)
{
OutputDebugString("Message received");
Handled=true;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
msgTest = RegisterWindowMessage("msgTest");
Application->OnMessage = AppMessage;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
PostMessage(HWND_BROADCAST, msgTest, 0, 0);
}
//---------------------------------------------------------------------------
 
 

Re:IPC, using Application->OnMessage

Marc wrote:
Quote
I try to implement IPC between my two processes.
I use HWND_BROADCAST because in future the sender and receiver will be in
two separate processes.
If in the future they will be on different computers, this won't work.
Quote
If I run the application like this and press the button, I receive one
OutputDebugString. This is what I expected.

But when I create a second form, and place a TTimer component on it, I
receive the OutputDebugString twice.
Every top-level window (form) gets the message.
Quote
Is not the "Handled=true" statement supposed to prevent the message from
being sent to another Window ?
No.
It is a BROADCAST just like radio or TV.
Your watching it doesn't stop others from viewing it too.
Every running (windowed) application on your machine will get your spam.
 

Re:IPC, using Application->OnMessage

Hi Bob
Thank you for your reply.
Quote
If in the future they will be on different computers, this won't work.
This is OK as the two processes will run on the same computer.
If not what alternative would you recommend? Using IP messaging ?
Quote
It is a BROADCAST just like radio or TV.
Your watching it doesn't stop others from viewing it too.
Every running (windowed) application on your machine will get your spam.
I see.
I helped myself right now in looking if the Msg.message + Msg.time is
different before continuing... not very nice, but it helps.
Rds
Marc
"Bob Gonder" < XXXX@XXXXX.COM >schrieb im Newsbeitrag
Quote
Marc wrote:

>I try to implement IPC between my two processes.

>I use HWND_BROADCAST because in future the sender and receiver will be in
>two separate processes.

If in the future they will be on different computers, this won't work.

>If I run the application like this and press the button, I receive one
>OutputDebugString. This is what I expected.
>
>But when I create a second form, and place a TTimer component on it, I
>receive the OutputDebugString twice.

Every top-level window (form) gets the message.

>Is not the "Handled=true" statement supposed to prevent the message from
>being sent to another Window ?

No.
It is a BROADCAST just like radio or TV.
Your watching it doesn't stop others from viewing it too.
Every running (windowed) application on your machine will get your spam.


 

{smallsort}

Re:IPC, using Application->OnMessage

Marc wrote:
Quote
This is OK as the two processes will run on the same computer.
If not what alternative would you recommend? Using IP messaging ?
Named Pipes are good if you need to send data.
Otherwise Named Mutex or Event for simple signaling.
See:
CreateNamedPipe
CreateEvent
OpenEvent
CreateMutex
OpenMutex
CreateSemaphore
OpenSemaphore
Quote
I helped myself right now in looking if the Msg.message + Msg.time is
different before continuing... not very nice, but it helps.
You might have 2 different messages, one for each process.
Each process looks only for the other process' message, not it's own.
 

Re:IPC, using Application->OnMessage

Bob
Considering your last post about processes on different computers I started
implementing a socket based IPC, using ICS.
Thanks again for your valuable help :-)
Rds
Marc
"Bob Gonder" < XXXX@XXXXX.COM >schrieb im Newsbeitrag
Quote
Marc wrote:

>This is OK as the two processes will run on the same computer.
>If not what alternative would you recommend? Using IP messaging ?

Named Pipes are good if you need to send data.
Otherwise Named Mutex or Event for simple signaling.
See:
CreateNamedPipe

CreateEvent
OpenEvent

CreateMutex
OpenMutex

CreateSemaphore
OpenSemaphore

>I helped myself right now in looking if the Msg.message + Msg.time is
>different before continuing... not very nice, but it helps.

You might have 2 different messages, one for each process.
Each process looks only for the other process' message, not it's own.


 

Re:IPC, using Application->OnMessage

"Marc" < XXXX@XXXXX.COM >wrote in message
Quote
I use HWND_BROADCAST because in future the
sender and receiver will be in two separate processes.
That does not necessarily mean that HWND_BROADCAST is the best choice. It
would be better if the sender knew ahead of time the HWND that the receiver
is actually using to receive messages with.
Quote
But when I create a second form, and place a TTimer component on it,
I receive the OutputDebugString twice. If I place two TTimer component
on it, I receive the OutputDebugString three times.
What is your TTimer actually doing?
Quote
The second form is not event referenced in my first form.
It doesn't have to be.
Quote
Curious enough this does not happen with a TButton component,
so it depends on the component I place on this second form.
What component are you putting on the second form to reproduce the problem?
Gambit
 

Re:IPC, using Application->OnMessage

Hi Gambit
As per my last post I now use ICS and implemented some TCP messages instead.
This works OK.
I finally got the API messages to work by filtering them according to the
Windows they were sent (msg.hwnd), to make sure that I only read a message
once.
The TTimer didn't do anything, it was just a test installation I used to try
to understand the API messaging.
Rds
Marc
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >schrieb im Newsbeitrag
Quote

"Marc" < XXXX@XXXXX.COM >wrote in message
news:4724b19d$ XXXX@XXXXX.COM ...

>I use HWND_BROADCAST because in future the
>sender and receiver will be in two separate processes.

That does not necessarily mean that HWND_BROADCAST is the best choice. It
would be better if the sender knew ahead of time the HWND that the
receiver is actually using to receive messages with.

>But when I create a second form, and place a TTimer component on it,
>I receive the OutputDebugString twice. If I place two TTimer component
>on it, I receive the OutputDebugString three times.

What is your TTimer actually doing?

>The second form is not event referenced in my first form.

It doesn't have to be.

>Curious enough this does not happen with a TButton component,
>so it depends on the component I place on this second form.

What component are you putting on the second form to reproduce the
problem?


Gambit