[C/C++]WIN32 Basic Tutorial
#1

This is a basic tutorial for WN32 that shows how to make a WIN32 dialog window with some basic controlls and how to use them. This tutorial was posted first time by me in the HTS forum.

 

All windows API are in C, except for MFC, CLR, ATL, some say they are classes but if you look at the description they are structs.

 

Introduction

The main function in windows is a little different from the traditional int main()(from the console programming), the function will look something like this(2).

int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

Win main it is not really necessary you could just simply use int main() if you want.

 

Creating a Window

Many types (like dialogs, controls, and other visual objects) are actual windows and sub-windows. The windows are created by the API function 2, to create any kind of window, be it the main window, or a control.

#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInt, HINSTANCE hpInt, LPSTR lpLine, int nShow){
//Creating a window
CreateWindowEx(
WS_EX_CLIENTEDGE, // Window Type
WC_DIALOG, //Class Name
"MyWindow", // Window Title
WS_OVERLAPPEDWINDOW | WS_VISIBLE, // Window Proprieties
0, // x Position on the Screen
0, // y Position on the Screen
width, // window Width
height, //window Height
NULL, // Parent window
NULL,
NULL, //Hint, handle to the previous window
NULL
);
//add await time or the window will close really fast
return 0;
}

 

Or it could be added in the WM_CREATE(will talk later into the window Procedure)

 

Creating Controllers

The window handle is an HWND(usually we call it hWnd), the function CreateWindowEx returns the window handle which it creates. Without the handle we can not send messages to the child windows(controls).

HWND myDialogWindow = CreateWindowEx( arguments);

 

The code will look like(2):

#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInt, HINSTANCE hpInt, LPSTR lpLine, int nShow){
//Creating a window
HWND hMainWindow = CreateWindowEx(
WS_EX_CLIENTEDGE, // Window Type
WC_DIALOG, //Class Name
"MyWindow", // Window Title
WS_OVERLAPPEDWINDOW | WS_VISIBLE, // Window Proprieties
0, // x Position on the Screen
0, // y Position on the Screen
width, // window Width
height, //window Height
NULL, // Parent window
NULL,
NULL, //Hint, handle to the previous window
NULL
);
//Creating a button
HWND hButton1 = CreateWindowEx(
0,
"BUTTON",// the class name, there are many classes "LABLE", EDIT", etc
"Buton",
BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD,
50,50,100,25,
hMainWindow ,// handle to the main parent window
NULL,NULL,NULL
);

//add await time or the window will close really fast
return 0;
}

 

The Window Procedure

2 receives every event that happens on the main window(for example it could be user events, pressing a button, etc). The window procedure is called by the system when an event on the window happens, and the window is informed with a message.

LRESULT WINAPI proc_name(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)

 

For a procedure to be attached to a window it needs to instantiate a class of type 2 and registered with 2. The function 2 informs the main loop to break, any window procedure must not always return 0.

#include <windows.h>
//the window procedure
LRESULT WINAPI wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
//if the message is WM_CLOSE
if(message == WM_CLOSE) {
// when pressing the X on the window it will send WM_CLOSE to the window procedure
// with PostQuitMessage will exit the while loop
PostQuitMessage(0);
}

return 0;
}

//the entry point of the window
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int){
WNDCLASSEX wc; //the window class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = wndProc; //the window procedure
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hint;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = "WindowClass"; //the class name
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

// registering the class
if(!RegisterClassEx(&wc)){
//error it can not register the class
}

// creating a window
HWND hwnd = CreateWindowEx( 0, "WindowClass","A dialog window",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
400,100,200,200,
NULL,NULL,NULL,NULL
);

//making the window visible, showing the window
ShowWindow(hwnd, true);

//updating the window(this will call WM_PAINT)
UpdateWindow(hwnd);

//the window message loop
MSG msg;
while(GetMessage(&msg,NULL,0,0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}

 

Controllers types and how to use them

A good thing to know about controllers is that they are windows. As any other normal window they have a window procedure, window class, etc. which they are registered from the system. Anything you can do with a normal window you can do with a controller.

 

Messages:

Windows communicate using messages, when an event happens or when you want an control to do something, it will send a notification message. For standard controls the message will be WM_COMMAND and for common controls its WM_NOTIFY.

 

Messages can be send to a window using the API 2 with the use of 2 to access the data from that control, or you can use 2 to do what SendMessage and GetDlgItem does.

 

The Edit Boxes

One of the most used controls are the windows environments is the edit control, that permits the user to insert, modify, copy,etc text.

 

We said earlier about the CreateWindowEx to create controls.

#define IDC_EDIT 101 //used to identify a control, or you could use an enum

HWND hEdit = CreateWindowEx(
0,
"EDIT",// class name
"Text Box",
WS_VISIBLE | WS_CHILD,
50,50,100,25,
hwnd,
(HMENU)IDC_EDIT, //the control identifier
NULL,NULL
);

 

Accessing the information on the in the edit box it is made using the functions 2,si 2, 2, 2:

 

//hEdit is the control handle, and it can be accessed from anywhere
HWND hEdit = GetDlgItem( hwnd, IDC_EDIT);
GetWindowText(hEdit,buffer,255);
SetWindowText(hEdit,"New Message");

//or
GetDlgItemText(hwnd, IDC_EDIT, buffer, 255)
SetDlgItemText(hwnd, IDC_TEXT, "This is a string");

 

Notification Messages

When someone presses a button, the button sends the notification codes in type of WM_COMMAND to the parent window. for example a button control sends a notification code under the IDC_BUTTON every time the user presses the button.

 

#define IDC_BUTON 102 //used for identifying a button
//...
CreateWindowEx(
0,
"BUTTON",// button class
"Button",
BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD,
50,50,100,25,
hwnd,
(HMENU)IDC_BUTON,
NULL,NULL
);

And in the Window procedure:

LRESULT WINAPI wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
//you can change the if into a switch
if(message == WM_COMMAND){
switch(wParam){
case IDC_BUTON:
MessageBox(hwnd,"Button Pressed","BTN WND",0);
break;
}
return 0;
}
}

 

Other Notifications:

WM_CREATE runs only once when the main window is created, in this notification you can create controls(Wrote above). WM_DESTROY same as WM_CREATE it runs once, when the window is destroyed, WM_PAINT it is called every time the function DispatchMessage is called.

 

WM_KEYDOWN and WM_KEYUP is called every time you press or release a keyboard key;

Code is from my Disertation Project

switch(message) {
case WM_KEYDOWN: // If we get a key down message, do stuff
switch(wParam){
case VK_ESCAPE: // If they push ESC, close the app
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;

case 'W':
case VK_UP: // If they push up, move forward (Camera's +Z)
gCamera->move(Camera::eForward, MoveSpeed);
break;

case 'S':
case VK_DOWN: // If they push down, move backward (Camera's -Z)
gCamera->move(Camera::eBack, MoveSpeed);
break;

case 'D':
case VK_RIGHT: // If they push right, move right (Camera's +X)
gCamera->move(Camera::eRight, MoveSpeed);
break;

case 'A':
case VK_LEFT: // If they push left, move left (Camera's -X)
gCamera->move(Camera::eLeft, MoveSpeed);
break;

case 'R':
gCamera->reset(); // Recenter the camera
break;
}
break;
}

 

2 notifications are mouse events notifications or you could use WM_INPUT

case WM_MOUSEMOVE:
{
int xPos = GET_X_PARAM(lParam); //X absolute position
int yPos = GET_Y_PARAM(lParam); //Y absolute position
// ...
break;
}



Messages In This Thread
[No subject] - by someone - 09-03-2012, 02:09 PM
[No subject] - by Slipknotrus555 - 12-16-2013, 09:44 PM
[No subject] - by soryjero - 12-16-2013, 10:23 PM
[No subject] - by Slipknotrus555 - 12-16-2013, 10:47 PM
[No subject] - by soryjero - 12-17-2013, 06:19 AM
[No subject] - by Paramount - 12-17-2013, 07:19 AM
[No subject] - by soryjero - 12-17-2013, 01:47 PM

Forum Jump:


Users browsing this thread: 1 Guest(s)