Although it is correct that console applications initially do not have a message queue... the first time a
win32k.sys/GDI syscall greater or equal to 0x1000 is invoked... the Windows kernel invokes
KiConvertToGuiThread
and increases the thread stack-size which will convert the console thread into a GUI thread with a message queue.
How do you 'invoke a system call above 0x1000'?
WIN32K.SYS System Call Table[
^]
As you can see in that table... the first GDI system call
NtGdiAbortDoc
is at index
0x1000
. Because we know that the
GetMessage function[
^] results in a call to
NtUserGetMessage
and the
DispatchMessage function[
^] results in a call to
NtUserDispatchMessage
. We can infer that by simply creating a message loop... we will have in-fact promoted the thread into a GUI thread.
In other words... by simply attempting to pump the message queue... the thread is given one.
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
So what do you have now? Now you have a console process with a thread containing a message queue that has no window HANDLE so cannot receive window messages. Is this the end of the road?
No, window messages are not the only type of messages. You can still use the
PostThreadMessage function[
^] to post thread messages to the console.
Step 1: Create two console applications... Sender and Receiver.
Step 2: In the receiver, begin an infinite message pump (console thread will be promoted to GUI thread by the subsystem)
Step 3: In the sender, call
CreateProcess
with the
CREATE_NEW_CONSOLE
flag that creates the receiver process. (otherwise, messages will appear in senders console!)
Step 4: Using the
PROCESS_INFORMATION.dwThreadId
, begin posting messages with
PostThreadMessage
to receiver from sender.
A complete working sample on my blog:
http://www.scatternetwork.com/console_messages.zip.
This tip does not address issues such as unique
application-defined messages[
^]
Best wishes,
-David Delaune