Message handling in a console app
-
Monday, April 06, 2009 1:48 PMI am trying to access window messages from a console app. Using http://bobobobo.wordpress.com/2008/02/03/getting-the-hwnd-and-hinstance-of-the-console-window/ as a reference i created something that looks like this
// these are defined in another part of the code
HWND gConsoleHWND;
HDC gConsoleHDC;
HINSTANCE gConsoleHInstance;
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
// note: frame movement must be passed on to the last return
// note2: any functions that have issues because of the return 0 in this function, have the subfunction call
// DefWindowProc with the appropriate arguments
switch(message)
{
...
}
return DefWindowProc( hwnd, message, wparam, lparam );
}
ATOM RegisterInstance(HINSTANCE hInstance)
{
WNDCLASSEX wc = {
sizeof(WNDCLASSEX),
(CS_HREDRAW | CS_VREDRAW),
(WNDPROC) WndProc, // function that will receive messages
0,
0,
hInstance,
NULL,
LoadCursor(NULL, IDC_ARROW),
(HBRUSH)GetStockObject(BLACK_BRUSH),
NULL,
title,
NULL
};
return RegisterClassEx(&wc);
}
int main()
{
setupConsole(); // setup the hdc, hwnd, and hinstance
// Register the console window -> HINSTANCE, HDC, and HWND
if(!RegisterInstance(gConsoleHInstance))
MessageBox(GetDesktopWindow(),L"could not register instance",L"!",MB_OK);
// pump messages
MSG msg;
while( GetMessage( &msg, gConsoleHWND, 0, 0 ) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
system("pause");
return 0;
}
the code runs fine but it will never enter WndProc, any suggestions? Or will the console not let me define a process for it using RegisterClassEx?
All Replies
-
Monday, April 06, 2009 2:42 PMConsole windows don't receieve window messages like normal windows. They have a different behavior.
-
Monday, April 06, 2009 2:47 PMModeratorWhy do you need it to be a console app? If you can't change that, then have you tried creating a hidden window? That might be an easier approach.
http://blog.voidnish.com -
Monday, April 06, 2009 2:50 PMI was trying to do it from a console app to see if it were possible to draw directly onto the console (say text or even a bitmap).
I might try the hidden window approach, though im not sure if it will get WM_PAINT if it is hidden. -
Monday, April 06, 2009 3:02 PMWhat do you mean by saying "draw directly onto the console (say text or even a bitmap)"? You cannot "draw" anything within a console. Maybe you could be more specific on what you want to achieve using a console window? By the way, the WM_PAINT message is sent to a window when it is about to be fully or partially redrawn on screen.
-
Monday, April 06, 2009 3:05 PMI was working on the principal that in windows console is in a window, including having a drawing context. So since you can get the drawing context from the console window, i was attempting to draw directly to it. It was just a theory, i didn't plan on it working :)
-
Monday, April 06, 2009 3:07 PMModerator
I was trying to do it from a console app to see if it were possible to draw directly onto the console (say text or even a bitmap).
I might try the hidden window approach, though im not sure if it will get WM_PAINT if it is hidden.
The console is text-only so you won't be able to draw on it at the pixel level. You could get colors though and by using the upper-ASCII set (128-255) you might be able to do text-based graphics.
In olden DOS days you could go to graphics mode, but I doubt if it's supported these days (definitely not in Vista I'd guess).
http://blog.voidnish.com -
Monday, April 06, 2009 3:07 PM
If you want to intercept the console application window messages do the following :
- Get the handle of the console window with hWnd = GetConsoleWindow().
- Sub-class the console window with a new procedure, say, ConsoleWndProc() as follows :
glpfnConsoleWindow = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC, (LONG)ConsoleWndProc);
where glpfnConsoleWindow is the address of the Windows procedure, used to process the console window app. - Use ConsoleWndProc() to pre-process the messages for the console window.
Just don't forget to
return CallWindowProc(glpfnConsoleWindow, hWnd, message, wParam, lParam);
for the messages that you don't want to process in ConsoleWndProc().
You would also have to use a Win32 project, not a Win32 console app, to run the above code.
- Marked As Answer by Nancy ShaoModerator Friday, April 10, 2009 10:09 AM
- Unmarked As Answer by Nancy ShaoModerator Friday, April 10, 2009 10:12 AM
-
Monday, April 06, 2009 3:08 PMYeah i was trying to avoid text based graphics, but it looks like i may have to. But il try the method above... seems like it might work well. Thanks everyone
-
Monday, April 06, 2009 5:27 PMI don't know for sure, for I never tried it. But I can't see why one would not be able to draw on the console window, using the Windows API, since this a window like any other window.
-
Tuesday, April 07, 2009 2:22 AMModerator
You've registered a window class, but you are not actually creating a window. That's the rub, the console window already has its own window class and its own WndProc(). Just fuggedaboutit, it isn't worth the hassle.
Hans Passant.- Marked As Answer by Nancy ShaoModerator Friday, April 10, 2009 10:13 AM
-
Tuesday, April 07, 2009 7:23 AM
Just fuggedaboutit, it isn't worth the hassle.
That's the best answer. Microsoft does not intend for console windows to be used in that manner and I would assume there are barriers. Even if one barrier is overcome, there is likely another one.
Sam Hobbs; see my SimpleSamples.Info -
Tuesday, April 07, 2009 1:30 PM
You've registered a window class, but you are not actually creating a window. That's the rub, the console window already has its own window class and its own WndProc(). Just fuggedaboutit, it isn't worth the hassle.
Hans Passant.
I just don't understand what is the problem here !
It is perfectly normal to subclass a window control, like a button, a combo box, etc... They also have their own window classes and their internal window procedures. It is the same thing with the console window.
I'm not saying that to draw on the console window is practical, but only that it is possible, and as far as I know, there shouldn't be any hassle doing this. -
Tuesday, April 07, 2009 7:59 PM
I'm not saying that to draw on the console window is practical, but only that it is possible, and as far as I know, there shouldn't be any hassle doing this.
Then provide a sample of doing it; either a link to a sample elsewhere or a simple sample posted here.
Sam Hobbs; see my SimpleSamples.Info -
Friday, January 18, 2013 7:21 PM
You can get the console window's handle with GetConsoleWindow(), you can get it's drawing context using the handle you just got using GetDC(handle), you can then plot pixels using SetPixel(consoleDrawingContext, x, y, RGB(255, 0, 0)), for a red pixel for instance. I actually just got through doing this so I'm positive it works. You of course have to make sure you update things when you modify the console output. I'll insert a screen snip below.
- Edited by C S Taylor Jr Friday, January 18, 2013 7:25 PM Added a related screen snip for my example.

