Win32 API – Creating a window
Thing aren’t exactly going fast forward with this project or learning about the Win32 API, due to my lack of motivation of reading stuff. I’ve managed to take my time to finish the application window for today at least. This is the complete code.
Create an application window
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Simple Window");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass)) {
MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName,
TEXT("Simple Application Window"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message) {
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
DrawText(hdc, TEXT("Hello world!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
It’s a lot of code to explain, so i’ll try to cover the most relevant parts of the code in this post.
The window class
All kinds of windows and “controls” like buttons and check boxes are based on a certain window class. In my program above, this class is instantiated to use for the window. The window procedure that processes messages to the window is identified by the window class.
In my program, you can see that WNDCLASS wndclass; is definied in the WinMain function. This class/structure has to be registered using a call to RegisterClass after all fields of the structure are initialized.
Window class definition
WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName;
wndclass.style definies how the window should be created. The flags I specified in this example makes sure the program repaints every time the window is resized either horizontal or vertical. (CS_HREDRAW | CS_VREDRAW)
wndclass.lpfnWndProc This field sets the window procedure for this class (WndProc). The window procedure is the functon that handles all the messages. This window procedure will now process messages to all windows based on this class.
wndclass.cbClsExtra = 0, wndclass.cbWndExtra = 0
These fields are used internally to maintain some space, I have no idea what. All I know is that this program doesn’t use this extra space.
wndclass.hInstance = hInstance this line sets the instance of the program. It’s the same as the parameter.
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION)
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW)
These lines sets the icon and cursor type. Since I call these functions with the first parameter as NULL, a predetermined icon will be choosed.
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
The background of the application will become white.
wndclass.lpszMenuName = NULL
I don’t use a menu in this program so I set this value to NULL. I’ll most likely become familiar with this later though, let’s save it for that time.
wndclass.lpszClassName
Last but not least, the application name. In this case, the name is of the type TCHAR.
This instance has to be registered as well.
Register the window class
if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("Show some error message"), szAppName, MB_ICONERROR); return 0; }
After we’ve registered the window class, the actual window creation code comes into play. HWND hwnd definied at the top of the “main” function is a handle to the window. The created window will be saved into this variable.
Create the actual window
hwnd = CreateWindow(szAppName, TEXT("Simple Application Window"), WS_OVERLAPPEDWINDOW, 200, 250, 640, 480, NULL, NULL, hInstance, NULL);
The above example will simply create a window with a size of 640×480 pixels at the start position (200,250).
Right now, the window has only been created internally in Windows. In order to make the window appear on the video display, it’s necessary to make a call to ShowWindow and UpdateWindow.
Display window
ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd);
Like usual, it’s nothing really that’s necessary to memorize. It’s good to know though, that hwnd is the window handler we just created using CreateWindow and iCmdShow is used to keep track of the current state of the window (maximized, minimized, etc). ShowWindow shows the window on the screen, it sends the WM_PAINT message to the window procedure.
The last part of the application that makes it complete, is the event handling. Before going on to the window procedure, a while loop that retrieves all the messages from the message queue is necessary.
Retrieve all messages
while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
Where msg is a part of the MSG structure and the NULL parameters indicate that we want to retrieve ALL messages for this program. The DispatchMessage() function call sends the message to the window procedure. It’s the windows procedure that takes care of the actual event checking.
The window procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect; switch (message) { case WM_PAINT: hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rect); DrawText(hdc, TEXT("Hello world!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }
This is where we take care of the input and what actions that we take depending on which message we get. There isn’t much to explain about this code without going into too much background. The last return statement that returns the DefWindowProc(…) call, is the default processing of all messages that the window procedure doesn’t process. It’s important to remember.
The WM_PAINT code block is executed whenever the window is updated. In other words, it’s the code that displays the text on the screen. I won’t go into detail how it draws the text right now, because I honestly have no idea right now and I want this post to end.
Preparing the Win32 API
I’ve started to learn a little Windows coding using its API today. I’m preparing it for my chat application i’m going to make in C++. Here’s how a typical hello world program looks like when coding in win32. It displays a message box on the screen which says “Hello world”.
Hello world in Win32
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
MessageBox(NULL, TEXT(“Hello world!”), TEXT(“Message”), 0);
return 0;
}
WinMain is the same as the main() function in C and C++ (the entry point of the application).
The hInstance parameter is a handler to the current window. It seems that the second parameter hPrevInstance isn’t used anymore. It was used to keep track of other instances of the same application. Last time it was used was in 16-bit Windows. The parameter is always NULL.
The third parameter szCmdLine takes care of the commands the application is started with.
The last parameter iCmdShow indicates how the program should be displayed, for example if it’s going to be maximized, minimized or hidden.
Chat application
My next project I have in mind, is going to be a chat application in C++. This is project is originally something we’re doing in school and I chose to make an internet chat with a server and a client. I haven’t thought out all the details about the project yet, but I started on it a couple of weeks ago. In the beginning, I had decided to use SDL because it’s easy to use when making graphical applications and it also has SDLnet for networking. My plans has changed however.
In order to implement a GUI, I decided to use the Win32 API together with C++. I know from experience that Win32 coding is quite nasty and extremely hard, so I hope i’ll pull it off somehow.
Tetris game in Python
We’ve had a project in school this year and this is the thing I came up with. It’s a Tetris clone coded in Python using the library PyGame. Unfortunately, I won’t release the source code for this game, I have my reasons : )
I took some things into consideration when I made this game (game play wise). I’ve tried many different versions of Tetris before and become very frustruated because the rotation and block types are different than they use to be. That’s why I tried to make this Tetris clone as much alike the standard version as possible.
How to play
The block is controlled by the arrow keys and you can rotate the block with the UP-key and move the block fast with the DOWN-key.
I’ve added a web highscore system so players can upload their scores.
http://www.pbe.se/blockbreaker/index.php?page=highscore
Download game
Windows Executable (blockbreaker.rar)
Project in school – Tetris clone
We’ve had a school project the last two terms where you have to choose a subject and write a report about it. You can also create something and write log books trough the whole process which is what I did. I saw this as an opportunity to either make something really cool, or just make it easy for myself. Guess what? I chose the latter.
The Project, Tetris
I decided to make a Tetris clone in Python and PyGame. I’ve made Tetris twice before so I thought it would be a piece of cake. First of all, I had never tried Python before when I started this project, but that part was quite easy. The game was quite a pain to make though and Python honestly drove me crazy sometimes. In the end I finished it though, this was about 1 week ago. I started on this project in October 2007 if I remember correctly and worked with it according to a schedule.
I tried to keep the game as simple as possible. You get points for each row you clear. It’s my first game in Python so the code is most likely terrible, i’ll live with that. I will show the game after i’ve packaged it. I added a highscore list to my website as well.
web browser controller module in Python
I’m currently making a school project in Python and came to the point where I wanted to open my webbrowser trough my application. To my surprise, I found a module named webbrowser which is just as easy to use as lifting your arm. It only requires two lines of code.
Open specified URL in standard browser
import webbrowser
webbrowser.open(“http://pbeblog.wordpress.com/”)
More information:
http://docs.python.org/lib/module-webbrowser.html
creating a login script using PHP and MySQL
This article will go trough the process of creating a fairly simple login script using PHP. The script is database driven so there are some things we need to take into consideration, for example the possibility of doing SQL-injections. I also assume you at least have access to a webserver with PHP and MySQL.
We start by creating the file that holds the form, the login page. Nothing fancy here, just a regular form which points to the php file that’s going to handle the login process. Here is how I did it.
<form action=”login.php” method=”POST”>
Username:<br>
<input type=”text” name=”username”><br>
Password:<br>
<input type=”password” name=”password”><br>
<input type=”submit” name=”submit” value=”Login”>
</form>
Before going on to the php code, we need a place to store the users. In this case i’ll create a table named ‘users’. I mostly use PhpMyAdmin when i’m administrating my databases, but it’s easier to explain the table structure using SQL.
CREATE TABLE `users` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` TEXT NOT NULL ,
`password` TEXT NOT NULL)
That should be fairly straightforward, it simply creates a table with two text fields. That’s all we need, now i’ll go trough the php code. Create a file named login.php. We need to open a connection to the database server and locate the database first of all.
Open connection to the database
mysql_connect(“localhost”, “username”, “password”) or die(“Cannot open connection: ” . mysql_error());
mysql_select_db(“database”) or die(“Database not found”);
After we’ve connected to the database, we need to check if the posted username and password is equal to the stored username/password in the ‘users’ table
Get user data and compare it with the stored users
$username = $_POST['username'];
$password = $_POST['password'];
$query = mysql_query(“SELECT * FROM users WHERE username=’$username’ AND password=’$password’”);
The problem with the above script, is that it’s completely vulnerable to SQL-injections. The user can input anything he/she wants in the form and post it. Imagine if the user then types ‘ OR ” = ‘ as the password which is one of the most common SQL injections in this kind of script. Then the SQL-query would look like this.
$query = mysql_query(“SELECT * FROM users WHERE username=’$username’ AND password=” OR ” = ” “);
And the user would be able to log in without typing a password.
Protect against SQL injections
The good news is that SQL injections like these are pretty easy to protect against. There are many ways to protect against them actually, but the most recommended way is to use the database’s own escape function. MySQL for example has the function named mysql_real_escape_string. A good way to describe this function is that it makes the data safe to use in the SQL query. It adds backslashes to characters that may pose a security risk, for example single quotes and regular quotes.
If we apply that to the code before, we will get the following.
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
$query = mysql_query(“SELECT * FROM users WHERE username=’$username’ AND password=’$password’”);
Next, we will check if the SQL query returns any results. If it does, the username and password is correct and we will get logged in with the specified username. If not, we will just be redirected to the login page again. Here is how I did it.
if (mysql_num_rows($query) == 0) {
header(“location: index.php”);
exit;
}$_SESSION['user'] = $username;
header(“location: index.php”);
This is about how simple it can get, we store the username into a session variable. This session variable is what we use to check if the client is logged in everywhere on the website. Don’t forget to put session_start() at the top of the login file, else it won’t work.
The code is safe against SQL injections right now but we can still improve the login script by adding encryption to the password and a salt. This is quite important, it’s not very smart to store the passwords in clear text. I’ve used sha1 and a very simple salt function. This assumes that all the passwords are stored with the same salt function so the comparison will be correct. Here is the complete code.
login.php
<?php
session_start();function salt($pw) {
$salt = “This comment should suffice as salt.”;
return sha1($salt.$pw);
}if (isset($_POST['submit'])) {
mysql_connect(“localhost”, “root”, “”) or die(“Cannot open connection: ” . mysql_error());
mysql_select_db(“experiment”) or die(“Database not found”);$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
$password = salt($password);$query = mysql_query(“SELECT * FROM users WHERE username=’$username’ AND password=’$password’”);
if (mysql_num_rows($query) == 0) {
header(“location: index.php”);
exit;
}$_SESSION['user'] = $username;
header(“location: index.php”);
}
?>
index.php
<?php
session_start();if (isset($_GET['logout'])) {
session_unset();
session_destroy();
header(“location: index.php”);
exit;
}
?>
<html>
<head>
<meta http-equiv=”content-type” content=”text/html; charset=iso-8859-1″>
<title>Login Script</title>
<style type=”text/css”>
body { font-size: 12px; }
input { font-size: 12px; }
</style>
</head><body>
<?php
if (isset($_SESSION['user'])) {
echo “You are logged in!”;
echo “<br><a href=’?logout’>Log out</a>”;
} else {
?><h2>Member Login</h2>
<form action=”login.php” method=”POST”>
Username:<br>
<input type=”text” name=”username”><br>
Password:<br>
<input type=”password” name=”password”><br>
<input type=”submit” name=”submit” value=”Login”>
</form><?php
}
?></body>
</html>
Login script in PHP/MySQL
A simple login script using PHP and MySQL. It’s safe against SQL injections and uses sha1 encryption for the passwords.
login.php
<?php
session_start();function salt($pw) {
$salt = “This comment should suffice as salt.”;
return sha1($salt.$pw);
}if (isset($_POST['submit'])) {
mysql_connect(“localhost”, “root”, “”) or die(“Cannot open connection: ” . mysql_error());
mysql_select_db(“experiment”) or die(“Database not found”);$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
$password = salt($password);$query = mysql_query(“SELECT * FROM loginscript WHERE username=’$username’ AND password=’$password’”);
if (mysql_num_rows($query) == 0) {
header(“location: index.php”);
exit;
}$_SESSION['user'] = $username;
header(“location: index.php”);
}
?>
index.php
<?php
session_start();if (isset($_GET['logout'])) {
session_unset();
session_destroy();
header(“location: index.php”);
exit;
}
?>
<html>
<head>
<meta http-equiv=”content-type” content=”text/html; charset=iso-8859-1″>
<title>Login Script</title>
<style type=”text/css”>
body { font-size: 12px; }
input { font-size: 12px; }
</style>
</head><body>
<?php
if (isset($_SESSION['user'])) {
echo “You are logged in!”;
echo “<br><a href=’?logout’>Log out</a>”;
} else {
?><h2>Member Login</h2>
<form action=”login.php” method=”POST”>
Username:<br>
<input type=”text” name=”username”><br>
Password:<br>
<input type=”password” name=”password”><br>
<input type=”submit” name=”submit” value=”Login”>
</form><?php
}
?></body>
</html>