PostMessage() Reception

I need to retrieve a message that's being sent by PostMessage() in another application. I think I know how to code the substance of it, but I'm not sure where to put this in my main message loop. I was told that I need to watch for it in my main message loop, but I'm not sure where. Here is my main message loop --

1
2
3
4
5
6
7
8
	while(GetMessage(&msg, NULL, 0, 0))
	{
		if(!TranslateAccelerator(hWinMainWnd, hAccel, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}


Does anybody know where I shoud put it, and also, do I use GetMessage() or PeekMessage() to do it?
You shouldn't need any special coding to receive a message via PostMessage(). Just code whatever you need to code in the window procedure and that should be the end of it.
Okay, thanks. I'll give it a try. If it doesn't work, I'll come back here to haunt you! -:)
@ webJose: I think the "...being sent by PostMessage() in another application." part is where he is running into trouble. You most certenly WOULD need special code to do that.

@ OP: What application? What version of Windows? You're locked out of some of them for security reasons.

Anyway you would need to grab the HANDLE to the target process, use "OpenProcess(...)" for that: http://msdn.microsoft.com/en-us/library/ms684320(VS.85).aspx

Pass the HANDLE that is returned from there to "CreateRemoteThread(...)": http://msdn.microsoft.com/en-us/library/ms682437(VS.85).aspx the fourth argument will be a pointer to a function simular to the one you have listed above.

There is a bit more to this but I'm leaving soon, and would need to hear more about your intentions before handing over code like that.
Last edited on
Computergeek01: I'm going to try out what I think might work, and if I can't get it done, I'll come back and ask. If I can get it done, I'll also post it here.
Hello Computergeek01. Why do you think the user needs to somehow inject code in the foreign process? I would agree that doing such a thing requires code to be written especially for that. But I think that "...being sent by PostMessage() in another application" means that another application already does this or will do this, and his responsibility just encompasses to process such a message.

I also agree that your question to the OP about the version of Windows is relevant because of the locked messages. But I think that unless a Windows service is involved, or we talk about LUA he/she should be fine, right?
Last edited on
FWIW, I'm only handling the message for XP and later. I know XP has a different id than Vista and Win 7.
@ webJose: That's another possibility, in which case your post was correct. Even in the two recent posts the OP hasn't specified which one he is trying to do. I guess we'll have to wait and see.

LUA? As in the scripting language? I've recently read a tutorial on it but I've never used it for anything practical nor do I know what it is capable of so I'm not sure what you mean here.
Nope, LUA as in Least User Access. Example: Internet Explorer in Protected Mode.
WOW!!! I haven't heard that term since I was studying CompTIA! I know what you're talking about now.

Some processes in the user memory space don't like to be spied on as well, they crash and sometimes take Explorer (But not the whole system) down with it. I'm not sure why, I only have theories nothing I would post with my name on it. I discovered that while I was goofing around with thread injection myself.

Otherwise we could go over how to make and start a Windows service, it complicates the hell out of this but I that's up to the OP.
Just use a global hook to intercept windows message from another application.
Use SetWindowsHookEx() to install the hook . Note that you must use a DLL with a shared read-write data segment for this to work (most probably this requires visual studio compiler, i do not know an gcc equivalent for
#pragma data_seg(".GEORGE") //Shared data among all instances.
// your shared global variables here ...
#pragma data_seg()
Last edited on
@ modoran: So then how would you inject that DLL into the target process? You suggestion isn't wrong, but it seems a little round about and a little sloppy if I can be honest.
I was told by the programmer of the external program that I only need to intercept the message in my main message loop. With this program, I can already send information to the external from my program.

For example -- and this is probably the premier Bible program on the planet, called BibleWorks -- I can double-click on a listbox in my program which contains a verse referemce and have the BibleWorks program go to that verse within BibleWorks. And all I have to do is use SHSetValue() and PostMessage().

Within the BibleWorks program itself, I have to make sure that menu item called "Receive (Paratext)" is checked.

I was told that I basically have to do the reverse to RECEIVE messages from BibleWorks.

IOW, I have now to check the menu item in BibleWorks which says "Send (Paratext)" i.e., the opposite of above.

When this menu item is checked in BibleWoriks, every verse change within BibleWorks is broadcasts outside to any other program that wants to receive it.

So I'm told that all I have to do is watch for it in my main message loop and then handle it however I want.

I haven't had time to work on it yet, but I suspect it's not anywhere near as complicated as has been declared.

At least I hope not. The BibleWorks programmer is light-years ahead of anyone I know, and since it's his program, I presume he knows what he's talking about.

My main question right now is I'm not sure how "look" for the broadcast in my main message loop.
Last edited on
Okay, I think the programmer already showed me how to look for the message, but I overlooked it. I'm gonig to try it, and when I get it worked out I'll post here what I did.
FYI, you don't have to change your message pump to receive the message. All you need to "listen" to a broadcasted message is a top-level window. Just add a case to the switch inside that window procedure's switch statement.
Hadn't thought of that. I've got two ways I'm going to try it. Hopefully Ill get to it today.
I've got it working perfectly, and it was MUCH easier than I thought --

1
2
3
4
5
6
7
8
9
10
11
	while(GetMessage(&msg, NULL, 0, 0))
	{
		if(msg.message == uDataStr)
			VerselatorCheckVerse(hWinMainWnd, 0);

		if(!TranslateAccelerator(hWinMainWnd, hAccel, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}


uDataStr was declared in the global namespace as

UINT uDataStr=RegisterWindowMessage("uDataStr")

Works perfectly.

Of c ourse, "uDataStr" is not merely a random UNIT, rather, it is the code word in the sending program, so you have to use that exact string. Actually, uDatatr is not the real code word, but I haven't been given permission to give that away, so uDataStr is just a substitute for this conversations.
Last edited on
In a top-level window's window procedure, I would have done:

1
2
3
4
5
6
7
switch (uMsg)
{
    case uDataStr:
        //Process here.
        break;
    ...
}


That is all it should take.
I don't see how it makes any difference. I guess that would work, but the sending program is not always sending, nor is my program always receiving.

IOW, the user in BOTH programs much check a box or menu item in order to send/receive.

I guess your code would still work, but I also have five tabbed main windows in this program, so it is much simpler to just put the one statement in the message loop, rather than five times in a main tabbed window.
Upon further reflection, your code won't work anyway. uDataStr is a UINT and thus it won't even compile your switch() statement.
Topic archived. No new replies allowed.