Page 1 of 1

Win32 Programming Introduction Rate Topic: ***** 1 Votes

#1 Cha0sBG  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 5
  • View blog
  • Posts: 167
  • Joined: 09-April 09

Posted 21 May 2009 - 12:11 PM

Hello dear Dream In Code members, i will explain the basics of Win32 programming.
We will start from the basics and continue to more complex stuff

Now taking your suggestions. Please post a comment with what u want me to add to this tutorial.

Tutorial Index:

1: The WinMain function. (Done)

2: Creating your very first WIN32 GUI. (Done)

3: Creating Button controls. (Done)

4: Responding to Button clicks. (Done)

5: Message Boxes (Done)

* Message Box types (Done)
* Type Of buttons to add on a message box. (Done)
* Handling Message box events (Done)
* Message Box icons (Done)

6: Working with a dll (Done)

* Attach a DLL (Done)
* Detach a DLL (Done)
* Do something when attached (Done)
* Do something when detached (Done)



Part 1 - The WinMain Function:

The WinMain function is the entry point of the Win32 programs just like the main() function is for the C++ console application. In this function will be stored all the information about the program events and GUI controls, but i'll explain this later and will get more in depth.

Here is a simple example of the WinMain Function:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nShowCmd)
 {
   return 0;
}

This is what the WinMain function looks like. But please take a good look at it and renember all the parameters as i explain them becouse they can't be overloaded.

HINSTANCE hInstance - Its called “instance handle”

HINSTANCE hPrevInstance - Was used in earlier version of Windows. When you run the same program more than ones you created multiple instances

LPSTR szCmdLine - What it really is is a “long pointer to a zero terminated string” L for long, P for pointer and STR for string

int nShowCmd - The way that your program will be loaded ex: Minimized, Maximized, Hidden, Shown normally etc.

Lets just make a small add-in code to demonstrate the procedure of the WinMain function.

#include <Windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nShowCmd)
{
MessageBox(NULL, "My First Win32 Program", "Caption", MB_OK);
return 0;
}

About the MessageBox syntax - I will explain everything when we get to the part about message boxes.

This was a very simple example that will do the following things:
1: Load the program.
2: Go to the WinMain function (Entry Point).
3: Show a MessageBox.
4: See there are no loops or anything that requires the program to run.
5: Exit the program.

Part 2 - Creating your first GUI:

First i will give the code for a simple GUI window then i'll go in depth to explain every single detail.

Here is the code:
#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nShowCmd)
{
	static char name[] = "My Window Class";
	WNDCLASSEX wc;
	HWND hwnd;
	MSG Msg;
	
	
	//Step 1: Registering the Window Class
	wc.cbSize		 = sizeof(WNDCLASSEX);
	wc.style		 = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc	 = WndProc;
	wc.cbClsExtra	 = 0;
	wc.cbWndExtra	 = 0;
	wc.hInstance	 = hInstance;
	wc.hIcon		 = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH) CreateSolidBrush(RGB(255, 0, 0));
	wc.lpszMenuName  = NULL;
	wc.lpszClassName = name;
	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION);

	if(!RegisterClassEx(&wc))
	{
		MessageBox(NULL, "Window Registration Failed!",
"Registration Failure",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	// Step 2: Creating the Window
	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, name, "Win32LSS1", WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, 400, 400, NULL, NULL, hInstance, NULL);

	ShowWindow(hwnd, nShowCmd);
	UpdateWindow(hwnd);

	// Step 3: The Message Loop
	while(GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	return (int)Msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);
}



Ok so now lets start to explain what does everything do. And please note that i made the tutorial 1 time then by accident pressed backspace so now i need to rewrite 1-2 hours of work.....

First we need to declare the Windows Procedure function ( WndProc ) that function will handle all the events in our program.
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

Now we'll go in our WinMain function and look at the first 3 variables that we have declared:
static char name[] = "Window Class Name";
	WNDCLASSEX wc;
	HWND hwnd;
	MSG Msg;

In the first line we declare our Window Class Name.
In the second line we declare a windows class structure.
In the third line we declare our Main Window Handle.
In The fourth line we declare a Message Structure.

Now lets look at how we register our windows class:
wc.cbSize		 = sizeof(WNDCLASSEX);
	wc.style		 = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc	 = WndProc;
	wc.cbClsExtra	 = 0;
	wc.cbWndExtra	 = 0;
	wc.hInstance	 = hInstance;
	wc.hIcon		 = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH) CreateSolidBrush(RGB(255, 0, 0));
	wc.lpszMenuName  = NULL;
	wc.lpszClassName = name;
	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION);

wc.cbSize - is the size of the windows class aways set it to sizeof(WNDCLASSEX);
wc.style - is the window style. Spesifies how the window will look.
wc.lpfnWndProc - requires a pointer to the WndProc function.
wc.cbClsExtrxtra - here u give how many extra bytes to allocate. Set it to 0. Do the same for wc.cbWndExtra.
wc.hInstance - This is the Instance handle passed to WinMain
wc.hIcon - a handle to the icon of the program.
wc.hCursor - a handle to the Cursor that our program will use
wc.hbrBackground - the background color of the window. For this tutorial i've set it to a solid red color. If u want a normal window color use:
(HBRUSH) (COOR_WINLDOW+1);

wc.lpszMenuName - a handle to a menu. Since we're not gonna use a menu or resource script set this to 0
wc.lpszClassName - the class name that we declared.
wc.hIconSm - a handle to small icon that will be displayed in the upper left corner.

Now we need to register the class:
if(!RegisterClassEx(&wc))
	{
		MessageBox(NULL, "Window Registration Failed!",
"Registration Failure",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

If the registration failed it will display a message box and will terminate the program.

If the registration was successful lets move to the window creation:
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, name, "Win32LSS1", WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, 400, 400, NULL, NULL, hInstance, NULL);
This function will return the handle of the main window.
The first parameter is the extended windows style. You can combine more that one using " | " this symbol to seperate the styles.

The second parameter is the class name.

The third parameter is the caption of our window.

The fourth parameter is the Windows Style of how our window will look.

The fifth and sixth parameters are the X and Y position of our window. The place it will be drawn. Set them to CW_USEDEFAULT so windows will decide where to put it.

The seventh parameter is the how wide our window will be.

The eight parameter is how tall our window will be.

The ninght parameter is the handle to the parent window. But since this will be the parent window set that ot NULL. It wont be null if we are creating some Control like a button or textbox or something.

The tenth parameter is the handle to a menu. But since we are not gonna use one set it to NULL.

The eleventh parameter is a instance handle to the window.

The twelfth parameter is a pointer to be passed to the Windows procedure WM_Create. We wont use that set it to NULL.


Ok now that that is done we need to display our window:
ShowWindow(hwnd, nShowCmd);

Now we need to update the window and take messages so if we press the minimize or close buttons it will work
UpdateWindow(hwnd);

The message Loop - Handling all the messages send by Windows to our program , but first it translates them.

while(GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	return (int)Msg.wParam;

Now we're in the final strech of this part - The almighty WndProc function:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
  case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);

The first parameter that the window procedure takes is a handle to the window that called it. The second parameter is the message that Windows has sent to the program. The last two parameters that store more information about the message.
Inside the Windows Procedure we use a switch statement to check what message Windows has sent to the program.

Part 3 - Creating Button Controls:

Ok so we've reached part 3 of our Win32 Programming tutorial. Now i'm gonna teach u how to create a simple button.

Get the source from Part2 ( The complete one ). Now Add a header file to your project and give it the following Name -> "hWndDec". At the top of your main C++ file right under the "#Include <window.h>" include the header file like so:
#include "hWndDec.h"
In this header file we will store the Global variables needed for the button control etc.

Open hWndDec.h and fill the following code:
HWND hCloseBTN;
#define BUTTON_CLOSE 40000

Here we defined The button handle.

Now replace your origninal WndProc Funtion with this one:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
	case WM_CREATE:
		hCloseBTN = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Close",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 20, 50, 80, 30, hwnd, NULL,
		GetModuleHandle(NULL), NULL);
		break;
	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}
That will create the button but lets explain what we've done now shall we ?
Lets look at the following lines of code
case WM_CREATE:
Case WM_CREATE: The event to create the controls when the window is painted on the screen.

Now lets look at the actual code that we've used to create the button:
hCloseBTN = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Close",
		 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 20, 50, 80, 30, hwnd, NULL,
		 GetModuleHandle(NULL), NULL);
Do u know this function ? Oh yeah ... that's the function that we've used to create our window, but we will modify it a little so we will create our button now. You know the first parameter is the style.

Second is the button class "BUTTON"

Third is the button caption.

And now the styles: WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON

* WS_CHILD makes it a child window for our main one. If this wasn't here the button would of been painted someone on the screen and not on the main window.
* WS_VISIBLE - this is self explaining.
* BS_PUSHBUTTON - makes it a button and being able to push it ?

The next 4 parameters are as they follow: X, Y, Wight , Height .

Next parameter we give the parent handle ( the handle of our MainWindow)

Next parameter is the menu... NULL
GetModuleHanlde(NULL) gets the instance handle which is passed to
main (HINSTANCE hInstance)

Part 4 - Responding When u click the button:

Ok we've added the button to our form now it's time to give it some functionality. Add the following lines to your WndProc function:
case WM_COMMAND:
		
	switch(LOWORD(wParam))
	{
	case BN_CLICKED:

		if(hCloseBTN == (HWND)lParam)
		{
		
		}
		
	}

	break;
And now lets explain what we've done. When u click the button it sends a WM_COMMAND to the parent window. This is one way of handling the button clicks. The lParam is the handle to the control that send the message. So now lets carefully see what we did after the switch message:

If a button is clicked
 case BN_CLICKED:


We check if the right button is clicked :
if(hCloseBTN == (HWND)lParam)
		{
		
		}


and in the curly brackets we give the functionality to our button like so:

if(hCloseBTN == (HWND)lParam)
		{
		MessageBox(hwnd, "The Button WORKED", "Info", MB_OK);
		}
So now your WndProc Function should look like this:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
	case WM_CREATE:
		hCloseBTN = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Close",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 20, 50, 80, 30, hwnd, NULL,
		GetModuleHandle(NULL), NULL);
		break;
	case WM_COMMAND:
		
	switch(LOWORD(wParam))
	{
	case BN_CLICKED:

		if(hCloseBTN == (HWND)lParam)
		{
		MessageBox(NULL, "The Button WORKED", "Info", MB_OK);
		}
		
	}
	break;

	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}

Part 5: Message Boxes ( All u need to know ):

Lets view a simple message box syntax:
MessageBox(NULL, "Text Here", "Caption Here", MB_OK);
First parameter is the parent window handle. It can be NULL. But if u want the user to be unable to click anyware else in the program while the message box is open give it the parent window handle ( The Main Window Handle ). In our prevourse project it can be done like this when the button is clicked to open a message box and the user to be unable to click anyware else till he closes the messagebox:

 case WM_COMMAND:
		
	switch(LOWORD(wParam))
	{
	case BN_CLICKED:

		if(hCloseBTN == (HWND)lParam)
		{
		MessageBox(hwnd, "Text u want goes here", "Caption", MB_OK);
		}
		
	}
	break
Not that thats covered lets look at the other parameters aswell.

The second parameter is the text to be displayed on the message box.

The third parameter is the message box caption.

The fourth is the message box BUTTONS and ICONS.

The difirent buttons:

* MB_OK -> Displays a OK button
* MB_OKCANCEL -> Displays a OK and Cancel buttons
* MB_YESNO -> Displays a Yes and No buttons.
* MB_RETRYCANCEL -> Displays a Retry and Cancel buttons
* MB_YESNOCANCEL -> Displays a Yes, No, And Cancel buttons.

The difirent icons:

* MB_ICONEXCLAMATION -> Displays a "!" icon
* MB_ICONWARNING -> Displays a warning icon
* MB_ICONINFORMATION
* MB_ICONASTERISK
* MB_ICONQUESTION
* MB_IConstop
* MB_IConerror

Try them out. The syntax for a combination - button(s) + Icon is the following:
 MessageBox(NULL, "Want to continue?", "Question", MB_YESNO | MB_ICONQUESTION);
Now lets see how we can respond when the user click the yes button on a messagebox with a YES And No Buttons. When the user presses the "X" button on the Form a message box will pop up and ask the user is he sure he wants to exit the program.

Go to the WndProc function and find "case WM_CLOSE:"
replace the code with the following one:

case WM_CLOSE:
		int iResult;
		iResult = MessageBox(hwnd, "Are u sure u want to exit?", "Confirmation", MB_YESNO | MB_ICONQUESTION);
		if(iResult == IDYES)
		{
		DestroyWindow(hwnd);
		
		}
		else if(iResult == IDNO)
		{
			return false;
		}
break;
Now lets see what we've done:
Declared iResult as integer.
Set iResult = to the messagebox code.
Then passed a If statement: if the user presses Yes button (IDYES) then distroy the window. else to return false and do nothing.

The ID's For all the buttons gotten from WinUser.h:
#define IDOK				1
#define IDCANCEL			2
#define IDABORT			 3
#define IDRETRY			 4
#define IDIGNORE			5
#define IDYES			   6
#define IDNO				7
#define IDCLOSE		 8
#define IDHELP		  9
#define IDTRYAGAIN	  10
#define IDCONTINUE	  11
Part 6 - Working with a DLL:

Now it's time to teach u a little something about the DLL's.

How to import a dll that's in the same directory as our exe file:
LoadLibrary("DllName.dll");
How can we do something when the dll was loaded ? Create a new Win32 Project -> Empty project & DLL

Then Add the following code:
#include <windows.h>


BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
	if(dwReason = DLL_PROCESS_ATTACH)
	{
		MessageBox(NULL, "Dll Attached successfully", "Success", MB_OK | MB_ICONINFORMATION);
	}
	return TRUE;
}
When u Load the dll with LoadLibrary a message box will pop-up and say that the dll is attached successfully.

The following code will show u how to attach and detach a dll:
HANDLE hWnd;
hWnd = LoadLibrary("DllName.dll");
// And now the detach:
CloseHandle(hWnd);

How do we do something when the dll is detached? Here is how u just have to change the DLL_PROCESS_ATTACH to DLL_PROCESS_DETACH
#include <windows.h>


BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
	if(dwReason = DLL_PROCESS_DETACH)
	{
		MessageBox(NULL, "Dll Detached successfully", "Success", MB_OK | MB_ICONINFORMATION);
	}
	return TRUE;
}


Is This A Good Question/Topic? 1
  • +

Replies To: Win32 Programming Introduction

#2 programmer_temae  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 26
  • Joined: 01-May 09

Posted 03 June 2009 - 04:06 PM

Hi, i'm a complete newbie with win32, i have a question, considering the next code:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nShowCmd)
 {
   return 0;
}


in the fist line (the header of the function), what is WINAPI? if the first word (int) is the data type returned and the next is the name of the function (WinMain), what is WINAPI??

Thanks.
Was This Post Helpful? 0
  • +
  • -

#3 Cha0sBG  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 5
  • View blog
  • Posts: 167
  • Joined: 09-April 09

Posted 11 June 2009 - 11:12 AM

Here is what Wikipedia has to say about it. Figured this would be the best answer :)

http://en.wikipedia.org/wiki/WinAPI

WINAPI = Windows Application Programming Interface

This post has been edited by Cha0sBG: 11 June 2009 - 11:14 AM

Was This Post Helpful? 0
  • +
  • -

#4 aquafatz  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 19
  • Joined: 23-September 12

Posted 24 May 2013 - 10:49 AM

Very helpful tutorials!! Thanks!! :)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1