
visual studio2019自动生成的代码:
// WindowsProject1.cpp : 定义应用程序的入口点。
//
#include "framework.h"
#include "WindowsProject1.h"
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
WCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
WCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此处放置代码。
// 初始化全局字符串
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_WINDOWSPROJECT1, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT1));
MSG msg;
// 主消息循环:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// 函数: MyRegisterClass()
//
// 目标: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW 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, MAKEINTRESOURCE(IDI_WINDOWSPROJECT1));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT1);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// 函数: InitInstance(HINSTANCE, int)
//
// 目标: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 将实例句柄存储在全局变量中
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目标: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 在此处添加使用 hdc 的任何绘图代码...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
文章参考:chatgpt和Windows应用程序基础(详细,简单易懂)_windows编程基础-CSDN博客
加注释后代码:
// WindowsProject1.cpp : 定义应用程序的入口点。
//
#include "framework.h"
#include "WindowsProject1.h"
#define MAX_LOADSTRING 100 /*定义一个宏,表示字符串缓冲区的最大长度为100*/
// 全局变量:
HINSTANCE hInst; // 当前实例
WCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本 /*存储窗口标题的字符串
WCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名 /*存储窗口类名,windows系统通过窗口类名识别窗口
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance); /*用于注册窗口类,使Windows知道如何创建窗口*/
BOOL InitInstance(HINSTANCE, int); /*初始化应用程序实例,创建窗口*/
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); /*窗口过程函数,用于处理窗口的各种消息*/
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); /*关于对话框的消息处理函数*/
/*主函数wWinMain,是程序的入口点*/
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, /*操作系统使用此值来标识 EXE (加载到) 可执行文件。 某些函数需要实例句柄Windows例如,加载图标或位*/
_In_opt_ HINSTANCE hPrevInstance, /*没有意义。 它用于 16 位Windows,但现在始终为零。*/
_In_ LPWSTR lpCmdLine, /*用于指定程序的命令行,是指向字符串的指针类型。*/
_In_ int nCmdShow) /*是一个标志,指示主应用程序窗口是最小化、最大化还是正常显示。*/
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此处放置代码。
// 初始化全局字符串
/*LoadStringW: 加载资源文件中的字符串,将应用程序标题和窗口类名存入全局变量*/
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_WINDOWSPROJECT1, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance); /*注册窗口类*/
// 执行应用程序初始化:
/*InitInstance: 初始化实例并创建主窗口*/
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT1));
MSG msg;
// 主消息循环:
/*GetMessage: 主消息循环,等待并处理系统消息(如鼠标点击、键盘输入等)*/
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
/*TranslateMessage 和 DispatchMessage: 将消息翻译并分发给窗口过程函数 WndProc*/
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// 函数: MyRegisterClass()
//
// 目标: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc; /*WndProc: 指定窗口的消息处理函数*/
wcex.cbClsExtra = 0; /*指定分配给窗口类结构之后的额外字节数*/
wcex.cbWndExtra = 0; /*指定分配给窗口实例之后的额外字节数*/
wcex.hInstance = hInstance; /*指定窗口过程所对应的实例句柄*/
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT1)); /*指定窗口的图标*/
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); /*指定窗口的鼠标指针(光标)*/
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); /*窗口背景颜色*/
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT1); /*窗口的菜单资源名称*/
wcex.lpszClassName = szWindowClass; /*窗口类名*/
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
/*虽然我们定义了一个窗口,但是系统并不知道这个窗口的存在,
所以接下来我们通过RegisterClass()函数来注册窗口类。*/
return RegisterClassExW(&wcex); /*RegisterClassExW: 注册窗口类*/
}
//
// 函数: InitInstance(HINSTANCE, int)
//
// 目标: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 将实例句柄存储在全局变量中
/*CreateWindowW: 创建主窗口*/
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
/*ShowWindow: 显示窗口;UpdateWindow: 更新窗口内容*/
/*参数 hWnd 指定要显示的窗口的句柄,nCmdShow 表示窗口的显示方式,
可以指定为从函数 WinMain()的nCmdshow 所传递而来的值。*/
ShowWindow(hWnd, nCmdShow);
/*由于函数 Show Window()的执行优先级不高,所以当系统正忙着执行其他任务时,不会立即显示窗口,
此时,调用函数 Update Window()立即显示窗口*/
UpdateWindow(hWnd);
/*同时,函数UpdateWindow()还会给窗口过程发出 WM_ PAINT 消息使窗口客户区重绘。*/
return TRUE;
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目标: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
/*WM_COMMAND: 菜单和控件的消息*/
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
/*WM_PAINT: 绘制窗口内容*/
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 在此处添加使用 hdc 的任何绘图代码...
EndPaint(hWnd, &ps);
}
break;
/*WM_DESTROY: 销毁窗口时发送退出消息*/
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
创建窗口类:
在注册窗口后,并没有生成一个窗口实体,我们可以用函数CreateWindows()来创建窗口,其代码为:
HWND WINAPI CreateWindow( //返回值是窗口句柄
LPCTSTR lpClassName, //窗口类名,要与注册时指定的名称相同
LPCTSTR lpWindowName, //窗口标题
DWORD dwStyle, //窗口样式
int X, //窗口最初的x位置
int y, //窗口最初的y位置
int nWidth, //窗口最初的x大小
int nHeight, //窗口最初的y大小
HWND hWndParent, //父窗口句柄
HMENU hMenu, //窗口菜单句柄
HINSTANCE hInstance, //应用程序实例句柄
LPVOID lpParam //指向一个传递给窗口的参数值的指针,以便后续在程序中加以引用
);
其具体创建实例的代码为:
hwnd=CreateWindow ( "HelloWin",
"我的窗口",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
480,
320,
NULL,
NULL,
hInstance,
NULL
);
创建窗口时,我们只需要按照参数的位置给其逐一赋值即可,如果想知道详细内容可以点击下方链接了解。链接:详细内容
实践代码:
更改标题:
HWND hWnd = CreateWindowW(szWindowClass, L"我的新标题", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 480, CW_USEDEFAULT, 320, nullptr, nullptr, hInstance, nullptr);
添加"L"的原因:
ANSI 字符串与 Unicode 字符串:
- 普通的字符串,比如
"Hello",是 ANSI 字符串,它使用char类型,一个字符通常占用1个字节。- 使用
L"Hello",则是 Unicode 字符串,使用wchar_t类型,一个字符占用2个字节(在Windows上),它可以支持更多的字符集(如中文、日文、韩文等)。Windows API 函数:
CreateWindowW和SetWindowTextW等函数要求传入 宽字符 类型的字符串,也就是L"..."。- 如果不加
L,而使用普通字符串,例如"Hello",会导致类型不匹配,因为普通字符串是char*,而这些函数需要wchar_t*类型。示例:
"Hello"是const char*类型,适用于CreateWindowA等使用ANSI字符串的函数。L"Hello"是const wchar_t*类型,适用于CreateWindowW等使用Unicode字符串的函数。
添加文字代码:
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
RECT rect;
// TODO: 在此处添加使用 hdc 的任何绘图代码...
GetClientRect(hWnd, &rect);
DrawText(hdc, TEXT("加油!相信你自己!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps);
}
break;
其中,获取窗口的客户区 GetClientRect:
RECT rect;
GetClientRect(hWnd, &rect);
RECT rect:定义一个矩形结构体,它将保存窗口客户区(显示区域)的大小和位置。GetClientRect:获取窗口客户区的大小,并将结果存储到rect结构体中。客户区是窗口标题栏以下可以绘制的区域。
绘制文本 DrawText:
DrawText(hdc, TEXT("加油!相信你自己!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
DrawText函数用于在指定的矩形区域内绘制文本。hdc: 用于绘图的设备上下文。TEXT("加油!相信你自己!"): 要绘制的文本。TEXT宏用于确保字符串的字符集与项目设置一致(ANSI 或 Unicode)。-1: 表示文本长度,由函数自动计算(以 null 结尾)。&rect: 指定绘制文本的矩形区域,这里是窗口的整个客户区。DT_SINGLELINE | DT_CENTER | DT_VCENTER:这几个标志指定了文本的绘制方式:DT_SINGLELINE: 绘制单行文本。DT_CENTER: 将文本水平居中。DT_VCENTER: 将文本垂直居中。
效果:

直接修改按钮



6877

被折叠的 条评论
为什么被折叠?



