Tutorial: window in console main(), events

Before anything, I wanna say that it took me a while to piece it all together. I am very grateful for everyone who's posted bits here and there, and now it's my turn to give people like me an additional possibility.
Also I want to mention a post that has helped me reach my goal. I will credit it in a separate comment.

First, a short description:
-this is a complete explanation of how you can handle events using just the console and no winapi entry point (such as WinMain)
-you can also create a window while inside main() with ease
-documentation can be found at Microsoft's site (msdn.microsoft.com), and I will post links in a reply comment
-it is pure windows.h, no external libraries

Step 1:
You might have in mind, "also I want no command prompt to be displayed," and I will grant that wish. To do that, use the "FreeConsole()" function.
[bold]WARNING![/bold] If you do this (eliminate the console), then it's just like saying "delete consoleHandle", so don't use its handle anymore!
1
2
3
4
5
#include<windows.h>
int main()
{
  FreeConsole();
}


Step 2:
Make a window procedure, because that's how the window manages its messages. Even though I sometimes don't use it, it's still useful to have it. And it is simply done by declaring it before main() and then defining it after main() OR just defining the function before main() (not preferred).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
int main()
{
...
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
  switch (message)
  {
    case WM_CHAR: //this is just for a program exit besides window's borders/taskbar
      if (wparam==VK_ESCAPE)
      {
          DestroyWindow(hwnd);
      }
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    default:
      return DefWindowProc(hwnd, message, wparam, lparam);
  }
}


Step 3:
Window Class. It is just like in a winapi program. Except this one does not need all of its variables filled in, and these are the only essential ones:
1
2
3
4
5
6
7
8
9
10
11
  WNDCLASS windowClass={0};
  windowClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
  windowClass.hCursor=LoadCursor(NULL, IDC_ARROW);
  windowClass.hInstance=NULL;
  windowClass.lpfnWndProc=WndProc;
  windowClass.lpszClassName="Window in Console"; //needs to be the same name
  //when creating the window as well
  windowClass.style=CS_HREDRAW | CS_VREDRAW;
  //also register the class
  if (!RegisterClass(&windowClass))
    MessageBox(NULL, "Could not register class", "Error", MB_OK);

It is worth mentioning: you don't need any hinstance, this can do just fine on its own. If you try and point to one, I am not sure what would happen.

Step 4:
Now to create the window itself. As I've mentioned, it needs to be independent of console and such, or else malfunctioning might occur.
1
2
3
4
5
6
7
8
9
10
11
12
13
  HWND windowHandle=CreateWindow("Window in Console",
                                 NULL,
                                 WS_POPUP, //borderless
                                 0, //x coordinate of window start point
                                 0, //y start point
                                 GetSystemMetrics(SM_CXSCREEN), //width of window; this function
                                 //retrieves the screen resolution.
                                 GetSystemMetrics(SM_CYSCREEN), //height of the window
                                 NULL, //handles and such, not needed
                                 NULL,
                                 NULL,
                                 NULL);
  ShowWindow(windowHandle, SW_RESTORE);


Step 5:
Now for the message queue: it is the same as in a winapi program.
1
2
3
4
5
6
7
8
  MSG messages;
  while(GetMessage(&messages, NULL, 0, 0)>0)
  {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
  }
  DeleteObject(windowHandle); //doing it just in case
  return messages.wParam;


And now, putting it together looks like this (final code):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<windows.h>
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
int main()
{
  FreeConsole();
  WNDCLASS windowClass={0};
  windowClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
  windowClass.hCursor=LoadCursor(NULL, IDC_ARROW);
  windowClass.hInstance=NULL;
  windowClass.lpfnWndProc=WndProc;
  windowClass.lpszClassName="Window in Console";
  windowClass.style=CS_HREDRAW | CS_VREDRAW;
  if (!RegisterClass(&windowClass))
    MessageBox(NULL, "Could not register class", "Error", MB_OK);
  HWND windowHandle=CreateWindow("Window in Console",
                                 NULL,
                                 WS_POPUP,
                                 0,
                                 0,
                                 GetSystemMetrics(SM_CXSCREEN),
                                 GetSystemMetrics(SM_CYSCREEN),
                                 NULL,
                                 NULL,
                                 NULL,
                                 NULL);
  ShowWindow(windowHandle, SW_RESTORE);
  MSG messages;
  while(GetMessage(&messages, NULL, 0, 0)>0)
  {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
  }
  DeleteObject(windowHandle); //doing it just in case
  return messages.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
  switch (message)
  {
    case WM_CHAR: //this is just for a program exit besides window's borders/task bar
      if (wparam==VK_ESCAPE)
      {
          DestroyWindow(hwnd);
      }
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    default:
      return DefWindowProc(hwnd, message, wparam, lparam);
  }
  return 0;
}
Last edited on
post that has helped me reach my goal

About hinstance of console window (obsolete in this case, but it's helped me understand a lot, thank you very much author):
https://bobobobo.wordpress.com/2008/02/03/getting-the-hwnd-and-hinstance-of-the-console-window/

Eliminate the Console:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms683150(v=vs.85).aspx

About the window class WNDCLASS:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633576(v=vs.85).aspx

About MessageBox():
https://msdn.microsoft.com/en-us/library/windows/desktop/ms645505(v=vs.85).aspx

About CreateWindow():
https://msdn.microsoft.com/en-us/library/windows/desktop/ms632679(v=vs.85).aspx

About ShowWindow():
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx

About GetMessage():
https://msdn.microsoft.com/en-us/library/windows/desktop/ms644936(v=vs.85).aspx
Last edited on
I think you should post this in the articles section:
http://www.cplusplus.com/articles/
I will do just that, since now it came to me that it would be a good idea. And should I delete this thread?
Topic archived. No new replies allowed.