Professional Documents
Culture Documents
o
o +6
The Windows API (also known as the Win32 API, Windows Desktop API, and Windows
Classic API) is a C-language-based framework for creating Windows applications. It has
been in existence since the 1980s and has been used to create Windows applications for
decades. More advanced and easier-to-program frameworks have been built on top of
the Windows API. For example, MFC, ATL, the .NET frameworks. Even the most modern
Windows Runtime code for UWP and Store apps written in C++/WinRT uses the
Windows API underneath. For more information about the Windows API, see Windows
API Index. There are many ways to create Windows applications, but the process above
was the first.
Important
For the sake of brevity, some code statements are omitted in the text. The Build the
code section at the end of this document shows the complete code.
Prerequisites
A computer that runs Microsoft Windows 7 or later versions. We recommend
Windows 10 for the best development experience.
A copy of Visual Studio. For information on how to download and install Visual
Studio, see Install Visual Studio. When you run the installer, make sure that
the Desktop development with C++ workload is checked. Don't worry if you
didn't install this workload when you installed Visual Studio. You can run the
installer again and install it now.
An understanding of the basics of using the Visual Studio IDE. If you've used
Windows desktop apps before, you can probably keep up. For an introduction,
see Visual Studio IDE feature tour.
An understanding of enough of the fundamentals of the C++ language to follow
along. Don't worry, we don't do anything too complicated.
Your project is now created and your source file is opened in the editor. To continue,
skip ahead to Create the code.
1. Just as every C application and C++ application must have a main function as its
starting point, every Windows desktop application must have
a WinMain function. WinMain has the following syntax.
C++Copy
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
);
For information about the parameters and return value of this function,
see WinMain entry point.
Note
What are all those extra words, such as CALLBACK, or HINSTANCE, or _In_? The
traditional Windows API uses typedefs and preprocessor macros extensively to
abstract away some of the details of types and platform-specific code, such as
calling conventions, __declspec declarations, and compiler pragmas. In Visual
Studio, you can use the IntelliSense Quick Info feature to see what these typedefs
and macros define. Hover your mouse over the word of interest, or select it and
press Ctrl+K, Ctrl+I for a small pop-up window that contains the definition. For
more information, see Using IntelliSense. Parameters and return types often
use SAL Annotations to help you catch programming errors. For more information,
see Using SAL Annotations to Reduce C/C++ Code Defects.
C++Copy
#include <windows.h>
#include <tchar.h>
C++Copy
LRESULT CALLBACK WndProc(
_In_ HWND hWnd,
_In_ UINT message,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
C++Copy
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
C++Copy
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL,
_T("Call to RegisterClassEx failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
C++Copy
static TCHAR szWindowClass[] = _T("DesktopApp");
static TCHAR szTitle[] = _T("Windows Desktop Guided Tour Application");
return 1;
}
4. At this point, the window has been created, but we still need to tell Windows to
make it visible. That's what this code does:
C++Copy
// The parameters to ShowWindow explained:
// hWnd: the value returned from CreateWindow
// nCmdShow: the fourth parameter from WinMain
ShowWindow(hWnd,
nCmdShow);
UpdateWindow(hWnd);
The displayed window doesn't have much content because you haven't yet
implemented the WndProc function. In other words, the application isn't yet
handling the messages that Windows is now sending to it.
5. To handle the messages, we first add a message loop to listen for the messages
that Windows sends. When the application receives a message, this loop
dispatches it to your WndProc function to be handled. The message loop resembles
the following code.
C++Copy
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
For more information about the structures and functions in the message loop,
see MSG, GetMessage, TranslateMessage, and DispatchMessage.
C++Copy
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL,
_T("Call to RegisterClassEx failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
if (!hWnd)
{
MessageBox(NULL,
_T("Call to CreateWindow failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
To handle a WM_PAINT message, first call BeginPaint, then handle all the logic to lay
out the text, buttons, and other controls in the window, and then call EndPaint. For
the application, the logic between the beginning call and the ending call displays
the string "Hello, Windows desktop!" in the window. In the following code,
the TextOut function is used to display the string.
C++Copy
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("Hello, Windows desktop!");
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
}
HDC in
the code is a handle to a device context, which is used to draw in the
window's client area. Use the BeginPaint and EndPaint functions to prepare for and
complete the drawing in the client area. BeginPaint returns a handle to the display
device context used for drawing in the client area; EndPaint ends the paint request
and releases the device context.
C++Copy
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("Hello, Windows desktop!");
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
// Global variables
HINSTANCE hInst;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL,
_T("Call to RegisterClassEx failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
if (!hWnd)
{
MessageBox(NULL,
_T("Call to CreateWindow failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}