The MASM Forum

General => The Workshop => Topic started by: aw27 on October 04, 2019, 09:58:44 PM

Title: Comments on Simple inter application communication
Post by: aw27 on October 04, 2019, 09:58:44 PM
The example is nice, but since the HWND_BROADCAST message is sent to all top level windows in the system, lots of things can stale SendMessage and make the applications freeze for a long time after the first message.
SendMessageTimeout improves a little, but is not the solution.

Sure, some people may not experience any of these.
Title: Re: Re: Simple inter application communication
Post by: hutch-- on October 05, 2019, 12:37:40 AM
Funny I have never seen the effect, I regularly run video processing software the run on 6 core, 12 threads and it does not effect software that I have written it into for years. I imagine this is what RegisterWindowMessage() is for, to add a private message into the system queue passing messages to all apps running on the system. I imagine it is possible to load a machine up so badly that you could slow down the messaging mechanism in the OS but the whole system would be in trouble, not just an app sending a private message.
Title: Re: Re: Simple inter application communication
Post by: aw27 on October 05, 2019, 12:42:02 AM
Google search:
HWND_BROADCAST hangs



Title: Re: Re: Simple inter application communication
Post by: hutch-- on October 05, 2019, 01:18:31 AM
In the case of any app that does not respond for whatever reason, SendMessage is synchronous so you can expect that result, if you know that can happen between two apps that communicate in that manner, use PostMessage which just dumps the message in the system message queue and does not wait. The example posted above is between two apps that don't hang and that pass messages between each other, how HWND_BROADCAST was designed to be used.
Title: Re: Re: Simple inter application communication
Post by: aw27 on October 05, 2019, 01:45:00 AM
 :biggrin:

You may recognize 2 things (or possibly not):

1) This method is not in the list of usual Interprocess Communications methods.
https://docs.microsoft.com/en-us/windows/win32/ipc/interprocess-communications

2) Still you can send messages to windows (not always), in addition to WM_COPYDATA, but is not savvy to broadcast a message to hundreds of windows when the target is just one.
What I believe is more savvy is find the HWND of the window we want then send our Registered_Window_Message message only to it.

Title: Re: Re: Simple inter application communication
Post by: hutch-- on October 05, 2019, 02:29:33 AM
An interesting enough article but it does not even mention using Send/PostMessage. In this context, it is a signalling method as any message sent can only pass 2 values. A vast amount of the data in that article does not apply to using HWND_BROADCAST as the posted example is not trying to message apps on other machines, across the network or any other external method.

ALA Win32.hlp SendMessage

Remarks
Applications that need to communicate using HWND_BROADCAST should use the RegisterWindowMessage function to obtain a unique message for inter-application communication.
If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, Windows switches to that thread and calls the appropriate window procedure. Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message.


Use something in accordance with the documentation and it works correctly. Anyone can do it the wrong way and fail but write 2 or more apps that use the documented technique and it all works as it should.
Title: Re: Re: Simple inter application communication
Post by: aw27 on October 05, 2019, 02:35:28 AM
I have modified your files caller.asm and slave.asm, and using FindWindow to find the top Window in each application now all work fine.
Title: Re: Re: Simple inter application communication
Post by: hutch-- on October 05, 2019, 03:29:07 AM
 :biggrin:

You can do it that way but the originals worked fine. I had a look at the mod and it works fine but what happens if you want to send a common message to multiple apps or instances, HWND_BROADCAST does this fine, your technique does not. I use this technique on things like QE that has multiple instances so I can shut them all down or change setting in all instances at once.
Title: Re: Re: Simple inter application communication
Post by: aw27 on October 05, 2019, 04:16:57 AM
For signalling I use events on a separate thread.
As we have seen SendMessage may not work well with HWND_BROADCAST. There are a few other alternatives to SendMessage  which may work better, but never tested because for signaling I use events.  :biggrin:
Title: Re: Re: Simple inter application communication
Post by: jj2007 on October 05, 2019, 07:00:55 AM
Quote from: hutch-- on October 05, 2019, 03:29:07 AMwhat happens if you want to send a common message to multiple apps or instances, HWND_BROADCAST does this fine, your technique does not.

You can use FindWindow plus WM_COPYDATA in a loop. For WinByTitle (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1097), I use EnumWindows, but that's a matter of taste. In any case, HWND_BROADCAST is kind of anti-social. I hate to agree with José but he's right :badgrin:
Title: Re: Re: Simple inter application communication
Post by: hutch-- on October 05, 2019, 10:53:01 AM
 :biggrin:

> As we have seen SendMessage may not work well with HWND_BROADCAST.

What do you mean WE paleface ? The criticism being made here is of either API that can use HWND_BROADCAST, SendMessage() and PostMessage() and the solution to any problems in use is called "Programming[tm]". Simply recognising the difference between synchronous and asynchronous actions by the two APIs means the "programmer" has to understand the target for where they are pointing their message.

Now look at the solution that Jose came up with using FindWindow(), you need either a class name or the content of the title bar of the app that you want the handle from and there is no garrantee that you have either. When you need to broadcast a single message to a number of instances, Jose's method only works on the first one so you then have to do it again and again and again.

The enumerate technique that JJ mentioned will work OK as long as you have a method of storing all of the handles that meet the criterion in use but it is big, slow and clunky along side a single Send/PostMessage that does it all in one API call.

Now for any that have doubts about the efficiency of such a single API call, set up a SPY tool for a simple app and don't filter out any of the messages and watch it stream some massive count of messages fed to the application's default handler.

I see little value in scouring the internet to listen to people squarking about their stuff ups, just read the standard Microsoft reference material on SendMessage(), understand how it works and it is a fast and reliable technique designed to operate within the operating system. In my case I have been using the technique since 16 bit Win 3.0 and it never fails if you do it properly.
Title: Re: Re: Simple inter application communication
Post by: jj2007 on October 05, 2019, 12:00:18 PM
See Raymond Chen: Remember what happens when you broadcast a message (https://devblogs.microsoft.com/oldnewthing/20060612-00/?p=30903). Broadcasting may work, of course, but it remains an anti-social way of communicating.
Title: Re: Re: Simple inter application communication
Post by: aw27 on October 05, 2019, 02:17:45 PM
Quote
What do you mean WE paleface ?
:biggrin:

When we make programs for other people we need to pay attention when they say it does not work properly for them. Even if only 1% mentions that it is already important.
Since I don't have a weird system and other palefaces from the internet have the same problem this means that the solution is not good.
In addition, Microsoft is not recommending that solution. That solution is as good for interprocess communication as using the Registry to pass values or writing to a temp file and expecting the other process to read them. None of these is a sound solution.
Title: Re: Re: Simple inter application communication
Post by: hutch-- on October 05, 2019, 02:18:46 PM
This is nothing exciting but it does show a lack of understanding on what is happening.
Quote
Suppose you broadcast the message
SendMessage(HWND_BROADCAST, WM_COMMAND, 100, 0);
What happens?
Now if you actually READ the Microsoft documentation for SendMessage() as posted above you will see that with the HWND_BROADCAST message you use the RegisterWindowMessage() API for a private message. Now differing from Raymond Chen's post, if you use the technique properly, it works as documented. As he said, you can send WM_COMMAND but why would you do so ? By making a private message, you dramatically narrow the range of apps that respond to the message.

You may now understand why I don't listen to this waffle and go to the source, Microsoft documentation. Anyone can stuff up normal code but the general idea is to fix it. Would you stop using CreateWindowEx() because someone somewhere made a mess of it ?
Title: Re: Re: Simple inter application communication
Post by: hutch-- on October 05, 2019, 02:22:31 PM
 :biggrin:

> In addition, Microsoft is not recommending that solution.
Quote
Remarks
Applications that need to communicate using HWND_BROADCAST should use the RegisterWindowMessage function to obtain a unique message for inter-application communication.
If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, Windows switches to that thread and calls the appropriate window procedure. Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message.
Microsoft document the usage, usage is determined by the programmer.
Title: Re: Comments on Simple inter application communication
Post by: sinsi on October 05, 2019, 03:58:34 PM
QuoteThe sending thread is blocked until the receiving thread processes the message.
That's the problem,

Quote from: hutchMicrosoft document the usage, usage is determined by the programmer.
In this case, by other programmers. According to spy++ there are around 300 top level windows going.
Title: Re: Comments on Simple inter application communication
Post by: aw27 on October 05, 2019, 04:02:48 PM
Quote
Microsoft document the usage, usage is determined by the programmer

:biggrin:

In your caller.asm you have used PostMessage for buttons 2 to 8 either because you have seen something wrong with SendMessage or because you like to try multiple alternatives.
In the last case, why have you not tested SendNotifyMessage, SendMessageTimeout or SendMessageCallback as well?
Title: Re: Comments on Simple inter application communication
Post by: hutch-- on October 05, 2019, 05:53:35 PM
Nah, it was because the first 2 buttons were originally used to show or hide the slave window. It does not matter much in this context as both work.