WinMain
All Windows programs begin execution with a call to WinMain(). Winmain is the Windows equivalent of the C function main() and marks the initial entry point for any Win32-based application. WinMain contains the code to initialise and register the Windows application, display its main window, and enter a message retrieval-and-dispatch loop.
The prototype of this function is as follows
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow);
The four parameters are:
hInstance – handle to the current instance of the application. The operating system uses this value to identify the executable (EXE) when loaded in memory.
hPrevInstance – used in 16-bit applications to provide a handle to the previous application instance. For a Win32-based application, this parameter is always NULL and has no meaning.
pCmdLine – is a pointer to a null-terminated string used to pass command line parameters to Windows programs.
nCmdShow – is a flag that says whether the main application window will be minimised, maximised, or shown normally.
The function returns an int value. Although the operating system does not utilise this value, it can convey a status code to another program.
Defining and Registering the Windows Class
The Windows class structure WNDCLASSEX contains information relating to the behaviour and looks of a window. The syntax of the WNDCLASSEX structure is as follows
typedef struct _WNDCLASSEX
{
UINT cbSize; // size of this structure
UINT style; // style flags (see below)
WNDPROC lpfnWndProc; // function pointer to the windows callback procedure
int cbClsExtra; // extra window-class info (usually 0)
int cbWndExtra; // extra window info (usually 0)
HANDLE hInstance; // the instance of the application
HICON hIcon; // the main icon that will represent the application
HCURSOR hCursor; // the cursor for the window
HBRUSH hbrBackground; // the background brush to paint the window
LPCTSTR lpszMenuName; // the name of the menu to attach if any
LPCTSTR lpszClassName; // the name of the registered class itself
HICON hIconSm; // the handle of the small icon
} WNDCLASSEX;
style – Specifies the class style(s). Styles can be combined by using the bitwise OR (|) operator. The style can be any combination of the following: CS_BYTEALIGNCLIENT, CS_BYTEALIGNWINDOW, CS_CLASSDC, CS_DBLCLKS, CS_GLOBALCLASS, CS_HREDRAW, CS_NOCLOSE, CS_OWNDC, CS_PARENTDC, CS_SAVEBITS, CS_VREDRAW.
RegisterClassEx – Before a window can be displayed on the screen it must be registered. RegisterClassEx() accepts a single parameter with the address of the WNDCLASS struct. The registered class name is later called in the CreatWindowsEx function.
In addition to the WNDCLASSEX structure, a window can be registered with the depreciated WNDCLASS structure and the associated RegisterClass function. The main difference between the two is the inclusion of a size parameter and a parameter to specify the handle to a small icon for the window.
For a more detailed explanation of these styles and options use the following resource.
https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-wndclassexw
Windows also offers a standard selection of predefined child window classes which can be used to implement the functionality of common controls.
CreateWindow
A Window is created by a call to the CreateWindowEx() or CreateWindow() function. CreateWindowEx differs from CreateWindow in that it offers an extended window style. The prototype for this function is
HWND CreateWindowEx( DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hwndParent, HMENU hmenu, HANDLE hinst, LPVOID lpvParam )
The parameter description is as follows –
DWORD dwExStyle – defines extended window style. For an in-depth description of extended styles –https://docs.microsoft.com/en-gb/windows/win32/winmsg/extended-window-styles
LPCTSTR lpClassName –pointer to a null-terminated string containing the predefined control-class names. The class name can be created with RegisterClass or one of the predefined classes used to create child controls.
LPCTSTR lpWindowName – pointer to a null-terminated string that specifies the window name.
DWORD dwStyle – indicates the style of windows that will be created. The style is made up of values that are combined together with the | operator. For a full list of styles – https://docs.microsoft.com/en-gb/windows/win32/winmsg/window-styles
int x – horizontal position of the window.
int y – vertical position of the window.
int nWidth – window width.
int nHeight – window height.
HWND hwndparent – handle to parent or owner window. A NULL value is used if there is no parent window.
HMENU hmenu – menu handle or child identifier.
HINSTANCE hInst- handle to the application instance.
LPVOID lpvParam – window creation data.
The function returns a handle to the new window or NULL if it fails.
Message Loop
A Windows program is event-driven. This means that program flow will be determined by an almost non-stop stream of notifications from various events generated by the system or users such as a keypress, mouse click, or an application change. Each of these events will be converted into a message. Windows creates a message queue for every running application. The application, in turn, includes a small message loop to retrieve these queued messages and then dispatches them back to the window. Windows by way of a message handler then identifies and calls the correct Windows procedure Wndproc() with the message as one of the parameters. Each time the application is ready to read a message, it must call the API function GetMessage(). The prototype for the GetMessage function is
BOOL GetMessage(
LPMSG lpMsg, // point to MSG structure containing message information
HWND hWnd, // specifies for which window messages will be obtained. To receive all messages directed at the application this value must be null.
UINT wMsgFilterMin, // first message
UINT wMsgFilterMax // last message
);
Inside the message loop, there are two functions
Translate message() – This Windows API call translates virtual key codes into messages.
Dispatch message() – Dispatches message back to windows.
What is a Message?
All messages are 16-bit integers of structure type MSG and have the following format –
typedef struct tagMSG{
HWND hwnd;//Identifies the window whose window procedure receives the message.
UINT message;//Specifies the message number.
WPARAM wParam;//Specifies additional information about the message.
LPARAM lParam;//Specifies additional information about the message.
DWORD time; //Specifies the time at which the message was posted.
POINT pt; //Specifies screen coordinates of cursor, when the message was posted.
} MSG;
SendMessage Function
The SendMessage() API function used throughout the examples on this site, allows specified messages to be sent to a window by calling the windows procedure for the specified window. The prototype for the SendMessage function is –
LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
where
hWnd – is a handle to the window whose window procedure will receive the message. If this parameter is type HWND_BROADCAST, the message will be sent to all top-level windows in the system, including any windows that have been disabled or are invisible.
Msg – The message to be sent. For a full list and description of system-provided messages –
https://docs.microsoft.com/en-gb/windows/win32/winmsg/about-messages-and-message-queues .
WParam – holds additional message-specific information.
LParam – holds additional message-specific information.
The return value specifies the result of the message processing and will depend on the message sent.
Windows Procedure
The Windows procedure or WndProc(), is used by a Windows application to process messages until the application is terminated. Each application window must have a WndProc declared as returning type LRESULT CALLBACK. In Windows, a callback function is used to describe any function that is called by the operating system. Although the system produces hundreds of different messages, an application will typically need to filter out and process only a small fraction of these messages. In our simple window, WndProc returns type DefWindowProc to ensure default processing for messages that the application does not act on.
The prototype of WndProc is.
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg,WPARAM wParam, LPARAM lParam );
The four Parameters are-
hwnd – is a handle to the window to which the message was sent.
uMsg – specifies the message.
wParam – specifies additional message information.
lParam -specifies additional message information.