Hey,
I'm just bored and i want to write small (maybe) tutorial.
In this lesson i will tell how to create window.
So, lets start!
Open your VC++ and click "Create new project". Choose "Win32 Application".
Call it as you want. I'll call it "MyTest".
If you'll open MyTest.cpp file, you'll see this code:
Now, you need to remove all useless code. Such as 'About' method.
Keep only WinProc and WinMain . You don't need another methods.
Or just use this clean code. I have included "windows.h" and "windowsx.h" to get less code and another stuff.
It is just empty project. Nothing special. Lets create real window!
CreateWindow method creates just empty window without buttons and another stuff. Just empty window with title.
Lets create it.
Okay now, lets see, which functions we do need.
This code prepares window and sets owner.
Finally, it is there! CreateWindow method. It creates blank window.
This part of code is requried too. It handles every window messages and shows it.
It's just WinMain return value; Requried too.
This code you must have:
But if you'll click F5, it will show. But if you close it, it will just minimize window.
IMPORTANT NOTE: "WIN_MAIN" string MUST be same for CreateWindow and WNDCLASSEX. Else window won't show. ( It's LPCWSTR type ).
You can change window sizes, window names, background colors. Lets create some variables for it!
X and Y are position data of window.
Window size data contains in "CreateWindow" method.
Lets create variables for it.
Press F5, and you will see 1024x768 sized window. Lets fix exit now.
We will need only WindowProc method. This method is unique handler of all window's messages. ( use google to see them all ).
I will use WM_DESTROY msg.
To exit application i will use PostQuitMessage call.
Use UINT message to catch WM_DESTROY.
You must get that:
Now program will quit normaly.
Last important step is - looping. ( realtime ).
As you can see in this code ( in WinMain )
It works only when message caught. We need to make it working for real-time. ( always ).
Just add second loop.
But, it's not done. We need to add loopquitting there. Or program will not close ( again ).
I will use WM_QUIT message. Note: you can't use WM_DESTROY there. It's a loop.
Example:
This looping will need for our game.
Note: Bug can happen because of GetMessage method. Use PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) if happened.
Code:
You will see this:
End of tutorial. In next tutorial i'll tell about directx, and making something in window!
This tutorial was written by me.
Thanks for reading!
I'm just bored and i want to write small (maybe) tutorial.
In this lesson i will tell how to create window.
You need the following things:
C++ knowledge
DirectX SDK 2010 ( You can find it on Microsoft site )
Some math ( not now )
Visual C++ 2010 or 2012 ( I will use Express 2010 )
Some time
DirectX SDK 2010 ( You can find it on Microsoft site )
Some math ( not now )
Visual C++ 2010 or 2012 ( I will use Express 2010 )
Some time
So, lets start!
Making new project and creating window
Open your VC++ and click "Create new project". Choose "Win32 Application".
Call it as you want. I'll call it "MyTest".
If you'll open MyTest.cpp file, you'll see this code:
Code:
// as.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "as.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_AS, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_AS));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_AS));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_AS);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
Now, you need to remove all useless code. Such as 'About' method.
Keep only WinProc and WinMain . You don't need another methods.
Or just use this clean code. I have included "windows.h" and "windowsx.h" to get less code and another stuff.
Code:
#include <windows.h>
#include <windowsx.h>
// required
#include "stdafx.h"
LRESULT CALLBACK WindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int ShowCmd)
{
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//return 0;
return DefWindowProc (hWnd, message, wParam, lParam);
}
It is just empty project. Nothing special. Lets create real window!
CreateWindow method creates just empty window without buttons and another stuff. Just empty window with title.
Lets create it.
Okay now, lets see, which functions we do need.
Code:
MSG msg;
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC,
WindowProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1),
NULL, L"Window name", NULL};
RegisterClassEx(&wc);
Code:
// create new window
HWND hMainWnd = CreateWindow(L"Empty Window",
L"Window title there",
WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
NULL, NULL, hInstance, NULL);
Finally, it is there! CreateWindow method. It creates blank window.
Code:
// show it
ShowWindow(hMainWnd, ShowCmd);
UpdateWindow(hMainWnd);
// handle all window messages there
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
This part of code is requried too. It handles every window messages and shows it.
Code:
return 0;
It's just WinMain return value; Requried too.
This code you must have:
Code:
#include <windows.h>
#include <windowsx.h>
// required
#include "stdafx.h"
// class
LPCWSTR WIN_MAIN = L"MAIN_WINDOW";
LRESULT CALLBACK WindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int ShowCmd)
{
MSG msg;
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC,
WindowProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1),
NULL, WIN_MAIN, NULL};
RegisterClassEx(&wc);
// create new window
HWND hMainWnd = CreateWindow(WIN_MAIN,
L"Window title there",
WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
NULL, NULL, hInstance, NULL);
// show it
ShowWindow(hMainWnd, ShowCmd);
UpdateWindow(hMainWnd);
// handle all window messages there
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(0);
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc (hWnd, message, wParam, lParam);
}
But if you'll click F5, it will show. But if you close it, it will just minimize window.
IMPORTANT NOTE: "WIN_MAIN" string MUST be same for CreateWindow and WNDCLASSEX. Else window won't show. ( It's LPCWSTR type ).
Changing window size, title, etc
You can change window sizes, window names, background colors. Lets create some variables for it!
X and Y are position data of window.
Window size data contains in "CreateWindow" method.
Code:
HWND hMainWnd = CreateWindow(WIN_MAIN,
TITLE(LPCWSTR type),
WS_OVERLAPPEDWINDOW, X(int), Y(int), WIDTH(int), HEIGHT(int),
NULL, NULL, hInstance, NULL);
Lets create variables for it.
Code:
#include <windows.h>
#include <windowsx.h>
// required
#include "stdafx.h"
// class
LPCWSTR WIN_MAIN = L"MAIN_WINDOW";
// size
int SCREEN_WIDTH;
int SCREEN_HEIGHT;
// position
int SCREEN_POS_X;
int SCREEN_POS_Y;
LPCWSTR WIN_TITLE;
LRESULT CALLBACK WindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int ShowCmd)
{
// variables sets there ( c++ basics )
// size of window
SCREEN_WIDTH = 1024;
SCREEN_HEIGHT = 768;
// position of window
SCREEN_POS_X = 0;
SCREEN_POS_Y = 0;
// title of the window
WIN_TITLE = L"Windowed program ^_^"; // L prefix is required ( C++ basics )
// Window creation
MSG msg;
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC,
WindowProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1),
NULL, WIN_MAIN, NULL};
RegisterClassEx(&wc);
// create new window
HWND hMainWnd = CreateWindow(WIN_MAIN,
WIN_TITLE,
WS_OVERLAPPEDWINDOW, SCREEN_POS_X, SCREEN_POS_Y, SCREEN_WIDTH, SCREEN_HEIGHT,
NULL, NULL, hInstance, NULL);
// show it
ShowWindow(hMainWnd, ShowCmd);
UpdateWindow(hMainWnd);
// handle all window messages there
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(0);
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc (hWnd, message, wParam, lParam);
}
Press F5, and you will see 1024x768 sized window. Lets fix exit now.
We will need only WindowProc method. This method is unique handler of all window's messages. ( use google to see them all ).
I will use WM_DESTROY msg.
To exit application i will use PostQuitMessage call.
Use UINT message to catch WM_DESTROY.
You must get that:
Code:
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
//catch program quitting
case WM_DESTROY:
// quit
PostQuitMessage(0);
return(0);
}
return DefWindowProc (hWnd, message, wParam, lParam);
}
Now program will quit normaly.
Last important step is - looping. ( realtime ).
As you can see in this code ( in WinMain )
Code:
// handle all window messages there
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
It works only when message caught. We need to make it working for real-time. ( always ).
Just add second loop.
Code:
while(TRUE)
{
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
But, it's not done. We need to add loopquitting there. Or program will not close ( again ).
I will use WM_QUIT message. Note: you can't use WM_DESTROY there. It's a loop.
Example:
Code:
// real time looping
while(TRUE)
{
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// use only after translate/dispatching msg.
if(msg.message == WM_QUIT)
break;
}
Note: Bug can happen because of GetMessage method. Use PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) if happened.
Code:
Code:
#include <windows.h>
#include <windowsx.h>
// required
#include "stdafx.h"
// class
LPCWSTR WIN_MAIN = L"MAIN_WINDOW";
int SCREEN_WIDTH;
int SCREEN_HEIGHT;
int SCREEN_POS_X;
int SCREEN_POS_Y;
LPCWSTR WIN_TITLE;
LRESULT CALLBACK WindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int ShowCmd)
{
// size of window
SCREEN_WIDTH = 1024;
SCREEN_HEIGHT = 768;
// position of window
SCREEN_POS_X = 0;
SCREEN_POS_Y = 0;
// title of the window
WIN_TITLE = L"Windowed program ^_^"; // L prefix is required ( C++ basics )
// Window creation
MSG msg;
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC,
WindowProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1),
NULL, WIN_MAIN, NULL};
RegisterClassEx(&wc);
// create new window
HWND hMainWnd = CreateWindow(WIN_MAIN,
WIN_TITLE,
WS_OVERLAPPEDWINDOW, SCREEN_POS_X, SCREEN_POS_Y, SCREEN_WIDTH, SCREEN_HEIGHT,
NULL, NULL, hInstance, NULL);
// show it
ShowWindow(hMainWnd, ShowCmd);
UpdateWindow(hMainWnd);
// real time loop
while(TRUE)
{
while(GetMessage(&msg, NULL, 0, 0)) //PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// game loop can be there
if(msg.message == WM_QUIT)
break;
// game loop can be there // recommended there
}
return(0);
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
PostQuitMessage(0);
return(0);
}
return DefWindowProc (hWnd, message, wParam, lParam);
}
You will see this:
End of tutorial. In next tutorial i'll tell about directx, and making something in window!
This tutorial was written by me.
Thanks for reading!