Patrick’s development blog

Win32 API – Creating a window

Posted in Uncategorized by Patrick on March 29, 2008

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.

Advertisements
Tagged with: , , , , , ,

Preparing the Win32 API

Posted in Uncategorized by Patrick on March 25, 2008

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

Posted in Uncategorized by Patrick on March 24, 2008

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

Posted in Uncategorized by Patrick on March 20, 2008

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

Posted in Uncategorized by Patrick on March 16, 2008

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.

Tagged with: , , , , ,

web browser controller module in Python

Posted in Python by Patrick on March 5, 2008

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(“https://pbeblog.wordpress.com/&#8221;)

More information:
http://docs.python.org/lib/module-webbrowser.html

Creating a horizontal CSS navigation using lists

Posted in Webdesign by Patrick on March 3, 2008

Here follows an example of creating a horizontal navigation bar using CSS. I’ve marked the mandatory lines, the rest are just for the looks that I added.

<html>
<head>
<title>Horizontal navigation bar</title>
<style type=”text/css”>
body {
font-family: arial;
font-size: 12px;
}

#nav {
width: 900px;
height: 100px;
background: #dddddd;
border: 1px solid #000000;
padding: 7px;
}

#nav ul {
padding: 0px;
margin: 0px;
list-style-type: none;
}

#nav li {
float: left;
}

#nav a {
background: #555557;
border: 1px solid #333333;
color: #ffffff;
padding: 5px 35px 5px 35px;
display: block;
margin: 1px;
}

#nav a:hover {
background: #777777;
}
</style>
</head>

<body>

<div id=”nav”>
<ul>
<li><a href=”#”>Link 1</a></li>
<li><a href=”#”>Link 1</a></li>
<li><a href=”#”>Link 1</a></li>
<li><a href=”#”>Link 1</a></li>
<li><a href=”#”>Link 1</a></li>
</ul>
</div>

</body>
</html>

Tagged with: , , , ,