何问起C++教程 - Windows编程 - Win32编程
Win32编程之Hello Hovertree示例
每个Windows程序都包含一个名为 WinMain 或 wWinMain 的入口点函数。 下面是 wWinMain 的签名。
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow);
这四个参数为:

hInstance 称为“实例句柄”或“模块句柄”。操作系统使用此值在内存中加载可执行文件时标识可执行文件 (EXE) 。 某些Windows函数需要实例句柄,例如加载图标或位图。
hPrevInstance 没有意义。 它在 16 位Windows中使用,但现在始终为零。
pCmdLine 包含命令行参数作为 Unicode 字符串。
nCmdShow 是一个标志,指示主应用程序窗口是最小化、最大化还是正常显示。

该函数返回 int 值。 操作系统不使用返回值,但可以使用返回值将状态代码传达给你编写的其他程序。

WINAPI 是调用约定。 调用约定定义函数如何从调用方接收参数。 例如,它定义参数在堆栈上显示的顺序。 只需确保声明 wWinMain 函数,如下所示。

WinMain 函数与 wWinMain 相同,但命令行参数作为 ANSI 字符串传递。 首选 Unicode 版本。 即使将程序编译为 Unicode,也可以使用 ANSI WinMain 函数。 若要获取命令行参数的 Unicode 副本,请调用 GetCommandLine 函数。 此函数返回单个字符串中的所有参数。 如果要将参数作为 argv 样式数组,请将此字符串传递给 CommandLineToArgvW。

编译器如何知道调用 wWinMain 而不是标准 主 函数? 实际上,Microsoft C 运行时库 (CRT) 提供了调用 WinMain 或 wWinMain的主要实现。

备注:
CRT 在 main 中执行一些额外的工作。 例如,在 wWinMain 之前调用任何静态初始值设定项。 虽然你可以告诉链接器使用不同的入口点函数,但如果链接到 CRT,请使用默认值。 否则,将跳过 CRT 初始化代码,结果不可预知。 (例如,全局对象不会正确初始化。)

下面是一个空 的 WinMain 函数。
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR lpCmdLine, INT nCmdShow)
{
return 0;
}
接下来使用Visual Studio 2022来创建Windows桌面应用。新建项目时选择的类型为:Windows桌面向导。如下图:

到后面,应用程序类型 选择桌面应用程序.exe
其他选项勾选“空项目”:

然后右键点击项目,在弹出菜单选择“添加”-“新建项”,在弹出对话框中选择C++文件(.cpp)
文件名称可修改为hovertree.cpp,如下图:

新建完成后,复制以下代码并粘贴,保存和运行。

以下是一个C++的Win32桌面应用程序的代码:
#ifndef UNICODE
#define UNICODE
#endif

#include <windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";

WNDCLASS wc = { };

wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;

RegisterClass(&wc);

// Create the window.

HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows By Hovertree", // Window text
WS_OVERLAPPEDWINDOW, // Window style

// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);

if (hwnd == NULL)
{
return 0;
}

ShowWindow(hwnd, nCmdShow);

// Run the message loop.

MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;

case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);

// All painting occurs here, between BeginPaint and EndPaint.

FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));

EndPaint(hwnd, &ps);
}
return 0;

}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
以上示例代码运行结果如下图:
收藏 列表

评论: