API category list
The simple windows program below creates a very basic window with a system menu icon, a minimise, maximise and close box. It can be compiled in either C or C++.
- #include <windows.h>
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
- {
- WNDCLASSEX wc;
- MSG msg;
- //Registering the Window Class
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.style = 0;
- 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)(COLOR_WINDOW+1);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = TEXT("myWindowClass");
- wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
- RegisterClassEx(&wc);
- //Creating the Window
- CreateWindowEx(WS_EX_CLIENTEDGE,TEXT("myWindowClass"),TEXT("Simple Window"), WS_VISIBLE | WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);
- //The Message Loop
- while(GetMessage(&msg, NULL, 0, 0) > 0)
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- }
- //WndProc procedure. Application acts on messages
- 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;
- default:
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
- return 0;
- }
Line 1 – All Windows programs must include the header file <windows.h>. This contains declarations for all of the functions in the Windows API, all the common macros used by Windows programmers, and all the data types used by the various functions and subsystems.
Line 2 – Function declaration for CALLBACK function WndProc.
Line 3 – WinMain function. Marks the program entry point.
Line 5 – Declares the wc structure variable that defines the Window’s class.
Line 6 – Declares the msg structure variable for holding Windows messages.
Lines 8 to 19 – Defines the Window’s class
Line 20 – Registers Windows class using the function RegisterClassEx.
Line 22 – Once a Window has been defined and registered it is created using the API function CreateWindowEx.
Lines 24 to 30 – The final part of WinMain is the message loop. The purpose of the message loop is to receive and process messages sent from windows. Once the message loop terminates the value of msg.wParam is returned to Windows.
Line 32 to 46 – The WndProc procedure is used by Windows to pass messages to an application. In this instance, only the WM_DESTROY & WM_CLOSE message is explicitly processed.
- Details
- Category: API category list
- Hits: 752
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, // message information HWND hWnd, // handle to window 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.
- Details
- Category: API category list
- Hits: 303
Data Types in Win32 API
Windows does not widely use standard C/C++ data types but instead uses a collection of type-defined data types found with the windows.h header file. A selection of these is listed below
BOOL | This type of data has two values – 0 or 1. |
BYTE | The same as unsigned char. Declared as typedef unsigned char BYTE, |
DWORD | 32-bit unsigned integer. |
INT | 32-bit integer. It is declared as typedef int INT. |
LONG | A 32-bit signed integer. |
UINT | 32-bit unsigned integer. It is declared as typedef unsigned int UINT. |
HANDLE | 32-bit integer used to identify a resource. |
HBITMAP | Handle to a bitmap. |
HBRUSH | Handle to a brush. |
HCURSOR | Handle to a cursor. |
HDC | A device context handle. |
HFONT | Handle to a font. |
HINSTANCE | Handle to the application instance. |
HMENU | Handle to a menu. |
HPEN | Handle to a pen. |
HWND | Handle to a window. |
LPCSTR | 32-bit pointer to a constant null-terminated 8-bit Windows (ANSI) character string. |
LPCWSTR | 32-bit pointer to a constant 16-bit Unicode character string, which may be null-terminated |
LPCTSTR | An LPCWSTR if UNICODE is defined, an LPCSTR otherwise. |
LPSTR | 32-bit pointer to a string of 8-bit characters, which MAY be null-terminated. |
LPWSTR | 32-bit pointer to a string of 16-bit Unicode characters, which MAY be null-terminated. |
LPTSTR | An LPWSTR if UNICODE is defined, an LPSTR otherwise |
TCHAR | A WCHAR if UNICODE is specified, a CHAR otherwise. |
LPARAM | A message parameter. |
LRESULT | Value, returned by the window procedure of type long. |
WPARAM | A message parameter. |
For a full list of Windows data types
https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
Identifier Constants
Every Windows program will feature a large number of identifiers. These are constants used to represent numerical values. These will typically be in uppercase and consist of a two or three-letter prefix donating the general category, followed by an underscore and the constant name. A selection of type prefixes and associated messages is listed below
Prefix | Description | Example |
CS | Class style | CS_HREDRAW | CS_VREDRAW |
CW | Create window | CW_USEDEFAULT CW_USEDEFAULT |
DT | Draw text | DT_CENTER DT_LEFT DT_RIGHT |
IDI | Icon identifier | IDI_ASTERISK IDI_ERROR IDI_HAND |
IDC | Cursor identifier | IDC_ARROW IDC_HAND |
MB | Message box options | MB_HELP MB_OK MB_OKCANCEL |
SND | Sound option | SND_ASYNC SND_NODEFAULT |
WM | Window message | WM_NULL WM_CREATE WM_DESTROY |
WS | Window style | WS_OVERLAPPED WS_SYSMENU WS_BORDER |
Naming conventions
Microsoft follows a set naming convention known as Hungarian notation. Hungarian notation uses short, lowercase prefixes to indicate the data type followed by the variable name, which begins with a capital letter. Function names should start with a capital letter and no type prefix. For further reading on MS coding style conventions
https://docs.microsoft.com/en-us/windows/win32/stg/coding-style-conventions
Character sets
Text and numbers are encoded in a computer as patterns of binary digits known as character codes. For computers to communicate there must be an agreed standard that defines which character code is used for which character. A complete collection of characters is a character set. Two common character sets are ASCII and Unicode.
ASCII
ASCII is a character encoding system that can represent 128 characters. It uses 7 bits to represent each character since the first bit of the byte is always 0. The code set allows 95 printable characters and 33 non-printable Control characters.
Extended ASCII
Although the 128 characters supported by standard ASCII are enough to represent all the standard English characters, they cannot represent all the special characters in other languages. Extended ASCII uses eight bits to represent a character as opposed to seven. Despite extended ASCII doubling the number of characters available, it does not include nearly enough characters to support all languages therefore other forms of character encoding such as Unicode are now commonly used.
UNICODE
The Unicode Standard is a universal character-encoding standard that can represent data in any combination of languages by assigning a unique code, known as a code point, to every character and symbol in that language. A Unicode transformation format (UTF) is an algorithmic mapping of every Unicode code point to a unique byte sequence. The two most common Unicode implementations for encoding the Unicode standard are UTF-8 and UTF-16.
UTF-8 is a variable-width encoding standard. A character in UTF8 can be from 1 to 4 bytes long. The first 128 Unicode codes are the same as ASCII making it backward compatible. This backward compatibility is useful for older API functions. UTF-8 is the preferred encoding for e-mail and web pages.
UTF-16 is a variable-width encoding standard using either 2 or 4 bytes to represent a character. UTF-16 is not backward compatible with ASCII. In Windows, strings are either ANSI or UTF-16LE.
Unicode in the Windows API
Unicode has been standard in Windows since Windows NT. Windows API functions that use or return a string are generally implemented in one of three formats: a version that is based on ANSI (called “A”), a wide version (called “W“) to deal with Unicode, and a generic function prototype. The generic prototype gets resolved into one of the other two function prototypes at compile time by adding a single character suffix to the generic root function name. For instance, the generic root function CreateWindowEx can be suffixed with an ‘A’ (indicating ANSI) or ‘W’ (indicating Unicode) depending on the compilation environment.
Working with Strings
C++ has four built-in character types: char, wchar_t, char16_t, and char32_t. In 2011, C and C++ introduced fixed-size character types char16_t and char32_t to deal with the UTF-16 and UTF-32 formats. Since the width of wchar_t is compiler-specific, any program that needs to be compiler-portable should avoid using wchar_t for storing Unicode text.
Any string literal should also use the prefix L,u, or U to indicate a wchar_t, char16_t, and char32_t character string.
char *ascii_example = "This is an ASCII string."; wchar_t *Unicode_example = L"This is a wide char string."; char16_t * char16_example = u"This is a char16_t Unicode string."; har32_t * char32_example = U"This is a char32_t Unicode string.";
TCHAR and the TEXT Macro
To make applications portable between Unicode and non-Unicode systems, Microsoft introduced the macro TCHAR. When a developer needs to support Unicode and earlier non-Unicode compliant operating systems, TCHAR enables the compilation of the same code in either environment by automatically mapping strings to Unicode or ANSI. To complement TCHAR, the TEXT() or _T() macro can automatically define a string as Unicode or ANSI. For example
TCHAR *autostring = TEXT("This message can be either ASCII or UNICODE!");
For further detailed reading on dealing with character encoding –
https://docs.microsoft.com/en-us/windows/win32/learnwin32/working-with-strings
- Details
- Category: API category list
- Hits: 166
A device context is a Windows data structure containing information about the drawing attributes of an output device. When an application needs to send data to a screen or printer it must first obtain a handle to a device context or DC of that device. Windows then fills the device context structure with the attribute values of the device being written to. The relevant API function can then use the information in the device context to display output as required. The process of writing to the screen is known as ‘painting’.
A window might need to be ‘painted’ or ‘repainted’ when the window is first created, when it is uncovered from behind another window, or as the result of some action by the user. Usually, an application will only be responsible for painting the client area. The client area is the rectangular part of a window inside the window’s border that doesn’t include the window frame, caption, menu, system menu, or scrollbars. The operating system automatically paints the surrounding frame, including the title bar.
System Generated Repaint Requests
Windows does not keep a record of the application window content. If any part of the client area is overwritten, Windows will notify the application by sending a WM_PAINT message to the application window indicating that the client area needs to be ‘repainted’. The region of the application client that needs updating is known as an ‘invalid area’. Windows maintains the size and coordinates of this region for each window.
BeginPaint()
The WM_PAINT message is used with the BeginPaint() function to obtain a device context. It prepares the specified window for painting and fills a PAINTSTRUCT structure with information about the invalidated area which will exclude the area outside the update region. The application can then use these values to redraw the window starting with the window’s background which is repainted with the current brush selected in the device context.
Windows continues sending WM_PAINT messages to the message queue if there is an invalidated area. The EndPaint() function must be called after BeginPaint to validate the client area before leaving the WM_PAINT handler block. Failure to validate the client area results in an endless WM_PAINT loop. The EndPaint marks the end of the screen validation and releases the display device context.
The prototype of the BeginPaint function is as follows-
HDC BeginPaint(HWND hwnd,LPPAINTSTRUCT lpPaint);
hwnd is the handle of the window for which the device context is being obtained
lpPaint is a pointer to a PAINTSTRUCT structure.
If the function is successful, its return value is the device context. If it fails, the return value is NULL.
The prototype of PAINTSTRUCT is as follows –
typedef struct tagPAINTSTRUCT {HDC hdc;BOOL fErase;RECT rcPaint;BOOL fRestore; BOOL fIncUpdate;BYTE rgbReserved[16];} PAINTSTRUCT;
Only 3 parameters are available to the user application, the rest are filled in by Windows when the user application calls BeginPaint. The hdc field is the handle to the device context returned from BeginPaint, fErase specifies whether the background needs to be redrawn and rcPaint specifies the upper left and lower right corners of the rectangle in which the 'painting' is requested.
The EndPaint() function is required for each call to the BeginPaint function to validate the client after the screen 'painting' is complete. It has the following syntax
BOOL EndPaint(HWND hwnd, const PAINTSTRUCT *lpPaint);
Where hwnd is the Handle to the window that has been 'repainted' and lpPaint is a Pointer to a PAINTSTRUCT structure. The return value is always nonzero.
Other Device Context-Related API Functions
GetDC()
The GetDC() function retrieves a handle to a display device context for the client area of a specified window or the entire screen. GetDC is usually called when an application needs to 'repaint' the screen instantly and occurs in response to an action by the user that does not generate a WM_Paint message. The GetDC method 'paints' the Windows client area and not merely the invalid region. The prototype for this function is
HDC GetDC(HWND hWnd);
Where hWnd is a handle to the required Windows device context. If this value is NULL, GetDC retrieves the device context for the entire screen. If the function succeeds, the return value is a handle to the DC for the required window’s client area. If the function fails, the return value is NULL.
GetWindowDC()
Similar to the GetDC function the GetWindowDC() function retrieves the device context (DC) for the entire application window, including non-client areas such as the title and scroll bars. Since the origin of the device context will be the upper-left corner of the window instead of the client area the application will be able to paint anywhere in the application window. The prototype for this function is
HDC GetWindowDC(HWND hWnd);
Where hWnd is a handle to the required Windows device context. If this value is NULL, GetWindowDC retrieves the device context for the entire screen. If the function succeeds, the return value is a handle to the DC for the required window’s client area. If the function fails, the return value is NULL.
ReleaseDC()
Releases a device context (DC), freeing it for use by other applications after a call to GetDC or GetWindowsDC. The prototype is
int ReleaseDC(HWND hWnd,HDC hdc);
Where hWnd is a handle to the window whose DC is to be released and hdc is the device context to be released. The return value indicates whether the DC was released with a value of 1 indicating success and a value of zero indicating failure.
ValidateRect()
Allows an application to validate a Windows region manually. The prototype for this function is
BOOL ValidateRect(HWND hWnd,const RECT *lpRect);
Where
hWnd is a handle to the window.
lpRect is a pointer to a RECT structure that contains the client coordinates of the rectangle to be removed from the update region. If the hWnd parameter is NULL the system invalidates and 'redraws' the entire window. If the RECT structure is NULL the entire client area is removed from the update rectangle. If the function is successful, the return value is nonzero.
If the function fails, the return value is zero.
InvalidateRect()
Allows an application to invalidate a Windows region manually and tells Windows to 'repaint' that region.
The prototype for this function is
BOOL InvalidateRect(HWND hWnd,const RECT *lpRect,BOOL bErase);
where
hWnd – is a handle to the window that needs to be updated. If this parameter is NULL, the system invalidates and redraws all windows, not just the windows for this application.
lpRect – is a pointer to a RECT structure containing the client coordinates of the update region. If the parameter is NULL, the entire client area is set for update.
bErase – specifies whether the background within the update region is to be erased when the update region is processed. If this parameter is TRUE, the background is erased when the BeginPaint function is called. If this parameter is FALSE, the background remains unchanged.
If the function is successful then the return value is nonzero. If the function fails, the return value is zero.
SaveDC and RestoreDC.
Each time an application requests a device context its attributes are reset to the system default and the default pen and brush will be used. To avoid this reinitialisaton, the current device context state can be saved with the API function SaveDC() and restored with the API function RestoreDC().
Example
he following program demonstrates the WM_PAINT message by keeping a running total of client area repaints. Dragging another window over the application window or clicking the minimise and maximise icons can generate a repaint request.
- Details
- Category: API category list
- Hits: 213
In Windows, the graphics device interface (GDI) displays graphics and formatted text on both the screen and the printer. One of the primary goals of the GDI is to support a device-independent development environment. The GDI provides several hundred functions for drawing points, lines, rectangles, polygons, ellipses, bitmaps, and text-special objects such as pens and brushes to manipulate the appearance of graphical output. Pens define the style, thickness, and colour of the pixels drawn, while a brush determines the fill colour of a shape.
A device context always contains one pen, brush, font, and a series of values to control how the device context behaves. If the application requires a change to the device context such as a new pen, then this new pen must be created and selected into the device context. Selecting a new graphics object does not change pre-existing display elements but any new graphic output. Each time a new GDI object is opened, it consumes Windows resources. It therefore becomes important to release GDI objects after use.
Creating Pens
Pens are created and referred to by using a handle type definition HPEN. In addition to a limited number of pre-supplied stock pens, the programmer can define user-defined pens using the API function CreatePen(). The prototype of this function is
HPEN CreatePen(int iStyle,int cWidth,COLORREF color);
where –
iStyle – The pen style. It can be any one of the following values.
PS_SOLID – The pen is solid.
PS_DASH – The pen is dashed. This style is valid only when the pen width is one or less in device units.
PS_DOT – The pen is dotted. This style is valid only when the pen width is one or less in device units.
PS_DASHDOT – The pen has alternating dashes and dots. This style is valid only when the pen width is one or less in device units.
PS_DASHDOTDOT – The pen has alternating dashes and double dots. This style is valid only when the pen width is one or less in device units.
PS_NULL – The pen is invisible.
PS_INSIDEFRAME – The pen is solid. When this pen is used in any GDI drawing function that takes a bounding rectangle, the figure dimensions are shrunk so that it fits entirely in the bounding rectangle, taking into account the width of the pen. This applies only to geometric pens
cWidth – The width of the pen, in logical units. If nWidth is zero, the pen is a single pixel wide, regardless of the current transformation.
color – is a COLORREF that determines the pen colour.
If the function succeeds, the return value identifies a logical pen. If the function fails, the return value is NULL.
Creating a Brush
Brushes are used to fill in any closed objects. They have colour, style and can be bitmaps. Brushes are created and referred to by using a handle type definition HBRUSH. In addition to the pre-created stock brushes, programmers can define custom brushes using the API function CreateSolidBrush(). The prototype for this function is
HBRUSH CreateSolidBrush( COLORREF color);
Where color is a COLORREF value. If the function succeeds, the return value identifies a logical brush. If the function fails, the return value is NULL.
In addition to solid brushes, a programmer can create a pattern brush that fills the brush area with a bitmapped image and a hatchbrush that creates a specified hatch pattern and colour. The prototype for these two API functions are
HBRUSH CreatePatternBrush(NBITMAP hbmap);
Where hbmap is a handle to the bitmap used to create the logical brush. If the function succeeds, the return value identifies a logical brush. If the function fails, the return value is NULL.
HBRUSH CreateHatchBrush(int style,COLORREF color);
Where
style – is the hatch style of the brush and can be one of the following
HS_BDIAGONAL – 45-degree upward left-to-right hatch
HS_CROSS – Horizontal and vertical crosshatch
HS_DIAGCROSS – 45-degree crosshatch
HS_FDIAGONAL – 45-degree downward left-to-right hatch
HS_HORIZONTAL – Horizontal hatch
HS_VERTICAL – Vertical hatch
Color – is a COLORREF value.
If the function succeeds, the return value identifies a logical brush. If the function fails, the return value is NULL.
Selecting Objects
Before any graphics object can be used it is ‘selected’ into the current device context (DC). The new object will then replace the previous graphic object of the same type. The SelectionObject() API prototype function is
HGDIOBJ SelectObject(HDC hdc,HGDIOBJ h);
where hdc refers to the device context and h is a handle to the object to be selected. SelectObject will return a handle to the previous font which may be useful should the application need to use the previous selection.
The following shortcode segment creates a new brush and then selects it into the current device context
HBRUSH greenbrush; Greenbrush=CreateSolidBrush(RGB(0,255,0)); SelectObject(hdc, Greenbush)
For further reading
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-selectobject
DeleteObject
The DeleteObject() function deletes a logical pen, brush, font, bitmap, region, or palette, freeing all system resources associated with the object and rendering the specified handle invalid. This is necessary as the system only has a finite amount of resources and failure to release the memory allocated reduces the remaining memory available. The syntax for this function is
BOOL DeleteObject(HGDIOBJ hobject);
Where hobject is a handle to a logical pen, brush, font, bitmap, region, or palette. If the function succeeds, the return value is nonzero. If the specified handle is invalid the return value is zero.
Using Stock Objects
When a window creates its first display device context, it comes with a limited number of pre-created graphics objects known as stock objects. These stock objects consist of pens, brushes, fonts, and palettes. The API function GetStockObjects() retrieves a handle to one of these stock objects. The prototype of this function is
HGDIOBJ GetStockObject(int i);
Where the parameter i can be one of the following values: BLACK_BRUSH, DKGRAY_BRUSH ,DC_BRUSH ,GRAY_BRUSH ,HOLLOW_BRUSH ,LTGRAY_BRUSH ,NULL_BRUSH ,WHITE_BRUSH ,BLACK_PEN ,DC_PEN ,NULL_PEN ,WHITE_PEN, ANSI_FIXED_FONT ,ANSI_VAR_FONT ,DEVICE_DEFAULT_FONT ,DEFAULT_GUI_FONT ,OEM_FIXED_FONT ,SYSTEM_FONT ,SYSTEM_FIXED_FONT , DEFAULT_PALETTE
If the function succeeds, the return value is a handle to the requested logical object. If the function fails, the return value is NULL
Since stock objects are pre-created system resources there is no need to delete the object handle once they are no longer required.
Dealing with Colour Values
The Windows graphics system uses RGB additive colour mixing to display colours. A computer screen combines individual pixels to form an image and each pixel consists of varying degrees of the primary colours red, green and blue. The term additive colour mixing comes from the fact that every RGB colour is made by combining varying amounts of these three basic colours. Since the Windows graphics system uses the 8-bit(0 to 255) RGB colour model this translates to 16,777,216 possible colours. The Windows API uses the COLORREF type to represent an RGB value as a 32-bit value. The GDI contains several macros to combine RGB values into a 32-bit value and to turn a COLORREF data value into its RGB components –
//converts rgb to colourref value COLORREF RGB(BYTE byRed, BYTE byGreen, BYTE byBlue); //converts colourref value to RGB equivalent int iRed= GetRValue(COLORREF rgb); int iGreen =GetGValue(COLORREF rgb); int iBlue =GetBValue(COLORREF rgb);
- Details
- Category: API category list
- Hits: 156