首页 > 系统相关 >Windows桌面应用程序源文件.cpp注释

Windows桌面应用程序源文件.cpp注释

时间:2023-10-06 21:24:45浏览次数:51  
标签:窗口 函数 Windows 句柄 应用程序 源文件 窗体 消息 cpp

 

这个是visual studio 2022上利用 Windows桌面应用程序模板创建的源文件注释

一个Windows图形界面(GUI)应用程序通常由主窗体,对话框,控件组成。

当应用程序创建一个窗体,需要调用CreateWindowEx函数,必须提供的参数
1.窗体类
窗体类是一个结构体。是一系列属性的集合,用来描述窗体的行为及外观,应用程序
通过它的描述来注册和创建窗体类,在创建窗体前向操作系统注册窗体类。
窗体在创建之前需要先注册窗体类。
控件?
控件是系统窗体类,由操作系统“注册”
常见控件:
Button,ComboBox,Edit,ListBox,MDIClient,ScrollBar,Static等
创建控件的时机?
应用程序框架,主窗体分为非客户区域,客户区域,要在客户区域创建控件,需要等客户区域
创建完成之后才能创建。怎样才能知道客户区域创建完成了呢?操作系统会给我们发送一条消
息WM_CREATE。即当收到WM_CREAT消息时,代表主窗体的客户区域创建完成,此时可以
创建控件。
窗体类的分类
1.系统窗体类
2.应用程序本地窗体类
3.应用程序全局窗体类
在一个动态库里调用RegisterClassEx,WNDCLASS的style成员设置成
CS_CLOBALCLASS;最后把DLL的名字写到注册表里。其他应用程序可以使用这个窗体类。

这么多窗体类,操作系统怎么定位它们?
当应用程序调用CreateWindow or CreateWindowWx, 操作系统使用下面的步骤定位窗体类:
第一步,从”应用程序本地窗口类“表中查找:用CreateWindow的参数hInstance和
szWindowClass匹配出”窗口类结构体“,用这个窗体类创建窗体。
模块句柄hInstance1 窗体类名称1 窗体类结构体1
模块句柄hInstance2 窗体类名称2 窗体类结构体2
第二步,如果第一步么有找到,从”应用程序全局窗体类“表中查找。
第三步,如果第二步没有找到,从”系统窗体类“表中查找。

// Project1.cpp : 定义应用程序的入口点。
//
#include "framework.h"
#include "Project1.h"
#include<windowsx.h>//GET_Y_LPARAM
#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);
//----------------------------------------------------------------------------------------------------------------
/*
这段代码是一个Windows应用程序的入口函数,即程序启动后执行的第一个函数。
它接受一些参数,
包括实例句柄(hInstance)、
上一个实例句柄(hPrevInstance)、
命令行参数(lpCmdLine)
显示命令(nCmdShow)。
*/
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{ //代码中的UNREFERENCED_PARAMETER宏用于解决编译器产生的未使用参数的警告。
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// 初始化全局字符串
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);//函数加载应用程序的标题和窗口类名。
LoadStringW(hInstance, IDC_PROJECT1, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);////函数注册自定义的窗口类。
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))//通过调用InitInstance函数初始化应用程序实例。
{
return FALSE;
}
//通过调用LoadAccelerators函数加载加速器表,用于处理加速器键盘消息。
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PROJECT1));
//之后使用一个消息结构体MSG来接收消息。
MSG msg;
// 主消息循环:
/*
在主消息循环内部,通过调用GetMessage函数获取消息,
并进行TranslateAccelerator、TranslateMessage和DispatchMessage操作来处理消息。
TranslateAccelerator函数用于处理加速器键盘消息,TranslateMessage函数用于将虚
拟键消息转换为字符消息,DispatchMessage函数用于将消息派发给窗口过程函数进行处理。
*/
while (GetMessage(&msg, nullptr, 0, 0))//通过调用GetMessage函数获取消息
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))//TranslateAccelerator函数用于处理加速器键盘消息
{
TranslateMessage(&msg);//TranslateMessage函数用于将虚拟键消息转换为字符消息
DispatchMessage(&msg);//DispatchMessage函数用于将消息派发给窗口过程函数进行处理。
}
}
//当主消息循环结束后,返回msg.wParam作为应用程序的返回值。
return (int) msg.wParam;
}
 
//-------------------------------------------------------------------------------------------------------------
// 函数: MyRegisterClass()
//
// 目标: 注册窗口类。
//这段代码用于注册自定义窗口类。在Windows应用程序中,窗口类是用来定义窗口的外观和行为的结构体。
//函数MyRegisterClass接受一个实例句柄(hInstance)作为参数。
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;//在函数内部,创建一个WNDCLASSEXW结构体变量wcex来描述窗口类。
wcex.cbSize = sizeof(WNDCLASSEX);//在结构体的成员赋值部分,将cbSize成员设置为sizeof(WNDCLASSEX),即结构体的大小。
//style成员用于指定窗口样式,包括如何绘制和响应窗口的行为,这里使用了CS_HREDRAW(水平重绘)和CS_VREDRAW(垂直重绘)样式。
wcex.style = CS_HREDRAW | CS_VREDRAW;
//lpfnWndProc成员是指向窗口过程函数的指针,用于处理窗口消息,这里指定为WndProc函数。
wcex.lpfnWndProc = WndProc;
//cbClsExtra和cbWndExtra是额外的窗口类和窗口实例的附加字节数,这里都设置为0。
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
//hInstance成员是应用程序的实例句柄。
wcex.hInstance = hInstance;
//hIcon成员是窗口的图标,通过调用LoadIcon函数加载一个图标资源。
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PROJECT1));
//hCursor成员是窗口的光标,通过调用LoadCursor函数加载一个光标资源。
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
//hbrBackground成员是窗口的背景刷子,这里使用了COLOR_WINDOW+1来指定颜色
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
//lpszMenuName成员是窗口的菜单资源,通过调用MAKEINTRESOURCEW将资源ID转换为字符串,并指定为窗口类的菜单。
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_PROJECT1);
//lpszClassName成员是窗口类的名称,这里指定为之前加载的窗口类名。
wcex.lpszClassName = szWindowClass;
//hIconSm成员是窗口的小图标,通过调用LoadIcon函数加载一个小图标资源。
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
//最后,调用RegisterClassExW函数来注册窗口类,并将注册的ATOM值作为函数的返回值。
return RegisterClassExW(&wcex);
//通过这段代码,我们可以看到窗口类的各种属性是如何设置的,
// 包括样式、窗口过程函数、图标、光标、背景等,这些属性将影响窗口的外观和行为。
}
//-------------------------------------------------------------------------------------------------
// 函数: InitInstance(HINSTANCE, int)
//
// 目标: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//这段代码是用于初始化应用程序实例的函数InitInstance。它接受一个实例句柄(hInstance)和一个显示命令(nCmdShow)作为参数。
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
//在函数内部,将传入的实例句柄存储在全局变量hInst中,以便其他函数可以访问它。
hInst = hInstance; // 将实例句柄存储在全局变量中
//然后,通过调用CreateWindowW函数创建一个窗口,并将窗口类名(szWindowClass)、窗口标题(szTitle)
// 和窗口样式(WS_OVERLAPPEDWINDOW)作为参数传递给它。
// 窗口的初始位置和大小使用CW_USEDEFAULT指定。
// 这个函数返回一个窗口句柄(hWnd)。
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
//接下来,使用条件判断语句检查窗口句柄是否创建成功。如果窗口句柄为NULL,表示创建窗口失败,则函数返回FALSE。
if (!hWnd)
{
return FALSE;
}
//如果窗口创建成功,将通过调用ShowWindow函数显示窗口,
// 并使用传入的显示命令(nCmdShow)来指定窗口的显示状态,
// 例如最大化、最小化或正常状态。
ShowWindow(hWnd, nCmdShow);
//然后,通过调用UpdateWindow函数更新窗口客户区的显示。
UpdateWindow(hWnd);
//最后,函数返回TRUE表示初始化成功。
return TRUE;
//通过这段代码,可以看到函数InitInstance实际上是将传入的实例句柄存储在全局变量中,
// 并创建并显示一个窗口。它负责初始化应用程序实例的一些基本操作。
}
//------------------------------------------------------------------------------------------------
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目标: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//这段代码是一个窗口过程函数(WndProc),用于处理窗口的消息。
//窗口过程函数接受四个参数:窗口句柄(hWnd)、消息代码(message)、消息的附加信息(wParam和lParam)。
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//在函数内部,通过使用switch语句根据不同的消息代码进行处理。
switch (message)
{
//当收到WM_COMMAND消息时,表示接收到菜单命令。
case WM_COMMAND:
{
//从wParam中获取菜单的ID(wmId),然后使用switch语句进一步处理选择的菜单ID。
int wmId = LOWORD(wParam);
// 分析菜单选择:
//然后使用switch语句进一步处理选择的菜单ID。
switch (wmId)
{
//当菜单ID为IDM_ABOUT时,调用DialogBox函数创建一个模态对话框,显示关于对话框。
// hInst表示应用程序的实例句柄,
// MAKEINTRESOURCE将资源ID转换为字符串,
// hWnd表示所属的窗口句柄,
// About是关于对话框的回调函数。
case IDM_ABOUT: //关于
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
//当菜单ID为IDM_EXIT时,调用DestroyWindow函数销毁窗口,结束应用程序的运行。
case IDM_EXIT: //退出
DestroyWindow(hWnd);
break;
//默认情况下,使用DefWindowProc函数进行默认的窗口消息处理。
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
//当收到WM_PAINT消息时,表示窗口客户区需要重绘。
// 在处理此消息时,首先通过调用BeginPaint函数创建一个绘图设备环境(HDC)
// 和一个PAINTSTRUCT结构体(ps),然后执行绘图操作。
// 绘图操作可以在注释处添加,然后通过调用EndPaint函数结束绘图,
// 并释放绘图设备上下文。
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 在此处添加使用 hdc 的任何绘图代码...
TCHAR szInfo[] = _T("Hello, world!");
TextOut(hdc, 200, 20, szInfo,_tcslen(szInfo));
EndPaint(hWnd, &ps);
}
break;
//当收到WM_DESTROY消息时,表示窗口正在被销毁。
// 在处理此消息时,调用PostQuitMessage函数向消息队列发送一个退出消息,通知主消息循环退出。
case WM_DESTROY:
PostQuitMessage(0);
break;
//第一步
//当鼠标点击应用程序窗口的“客户区域”,操作系统将鼠标左键单机消息:WM_LBUTTONDOWN
//放到消息队列里。消息队列由操作系统维护。
//第二步
//由于应用程序的消息循环一直在运行,它的GetMessage函数从消息队列中获取消息,保存到MSG结构体中
/*
typedef struct tagMSG {
HWND hwnd; //消息所关联的窗口句柄
UINT message; //消息代码
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
#ifdef _MAC
DWORD lPrivate;
#endif
} MSG
*/
//第三步
//应用程序调用TranslateMessage,将虚拟建消息转换为字符消息。
//它处理键盘消息,不必关心这个函数的细节
//第四步
//应用程序调用DispatchMessage,DispatchMessage函数通知操作系统,
//操作系统根据DispatchMessage提供的窗口句柄,查找它的窗口句柄,
//查找它的窗口句柄表(操作系统维护了一个窗口句柄表)类似
/*
Hwnd1 窗口过程函数1
Hwnd2 窗口过程函数2
*/
//找到窗口句柄对应的窗口过程函数
//操作系统执行这个窗口过程函数
//第五步
//窗口过程函数对消息做出响应,执行完毕返回到DispatchMessage,回到消息循环
case WM_LBUTTONDOWN://鼠标左击的消息
{
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
WCHAR szOutput[128] = { 0 };
wsprintf(szOutput, _T("x:%d,y:%d\n"), pt.x, pt.y);
OutputDebugString(szOutput);
}
break;
//默认情况下,使用DefWindowProc函数进行默认的窗口消息处理。
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
//最后,窗口过程函数返回一个LRESULT类型的值,通常是0。这个返回值的具体含义取决于消息的类型和处理方式。
return 0;
//通过这段代码,我们可以看到窗口过程函数根据不同的消息类型执行相应的操作,从而实现了对窗口消息的处理。
}
 
//-------------------------------------------------------------------------------------------------------
// “关于”框的消息处理程序。
//这段代码是一个关于对话框的回调函数(About),用于处理关于对话框的消息。
//回调函数接受四个参数:
// 对话框句柄(hDlg)、
// 消息代码(message)、
// 消息的附加信息(wParam和lParam)。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
//在函数内部,通过使用switch语句根据不同的消息代码进行处理。
switch (message)
{
//当收到WM_INITDIALOG消息时,表示对话框即将初始化。
// 在处理此消息时,将返回(INT_PTR)TRUE,表示对话框初始化成功。
case WM_INITDIALOG:
return (INT_PTR)TRUE;
//当收到WM_COMMAND消息时,表示接收到控件的命令消息。
// 在处理此消息时,首先检查wParam中的控件ID(LOWORD(wParam))。
// 如果是IDOK或者IDCANCEL,表示点击了“确定”或“取消”按钮。
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
//当点击了“确定”或“取消”按钮时,
// 调用EndDialog函数结束对话框,
// 并将按钮的ID作为参数传递给EndDialog函数。
// 然后返回(INT_PTR)TRUE,表示对话框处理成功。
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
//默认情况下,返回(INT_PTR)FALSE,表示对话框处理失败。
return (INT_PTR)FALSE;
//通过这段代码,我们可以看到关于对话框的回调函数根据不
// 同的消息类型执行相应的操作,例如初始化对话框、处理按钮点击等。
// 在处理完消息后,根据返回值决定对话框的继续运行或结束。
}

标签:窗口,函数,Windows,句柄,应用程序,源文件,窗体,消息,cpp
From: https://www.cnblogs.com/bigbabyone/p/17745044.html

相关文章

  • PanguHA,一款Windows双机热备工具
    1.简介         PanguHA是Windows平台的双机热备集群系统,是提供系统高可用性的解决方案,一般由两个节点构成,分为活动节点及备用节点(两者之间可以相互切换),软件界面如下PanguHA下载地址 2.功能说明2.1IP漂移:对外提供一个集群IP,并且该IP始终只会设置在活动主机......
  • Windows10 22H2更新失败怎么办?Windows10 22H2安装失败的解决方法
    如果之前更新系统的缓存未清除的话,也是会导致Win1022H2更新失败的,针对此类情况,我们可以选择手动清除更新缓存来修复问题1、按【Win】输入cmd,并以管理员身份打开命令提示符;2、在命令提示符窗口中输入【netstopwuauserv】,并按【Enter】键,停止Windows更新服务;3、打开文件资源......
  • Windows2012上搭建帝国CMS网站步骤(一)
    1.点击左下角开始按钮,选择“服务器管理器”; 2.默认仪表盘选项,选择“添加角色和功能”; 3.直接下一步; 4.选择“基于角色或基于功能的安装”; 5.选择“从服务器池中选择服务器”,选定好服务器,下一步; 6.选择“Web服务器(IIS)”, 7.在弹出的弹窗中选择“添加工具”,然后下......
  • libuv windows编译和学习资料
    官方下载github代码使用cmake编译windows仅仅支持cmake然后编译出lib放入vs工程vs加入头文件和lib文件路径 ,lib名加入工程依赖如图 需要加入lib很多libuv.libuv.libWs2_32.libadvapi32.libiphlpapi.libpsapi.libshell32.libuserenv.libuser32.libdbghe......
  • Windows 10 VS2015旧项目缺少MFC42D.DLL, MFCD42D.DLL, mfco42d.dll, MSVCP60D.DLL和M
    文章目录问题解决参考问题在Windows10中的VS2015找开旧项目,由于缺少MFC42D.DLL,MFCD42D.DLL,mfco42d.dll,MSVCP60D.DLL和MSVCRTD.DLL,无法调试并运行程序,进行了解决。解决下载MFC42D.DLL,MFCD42D.DLL,mfco42d.dll,MSVCP60D.DLL和MSVCRTD.DLL这些DLL文件,旧系统中是可以放在......
  • 多IP应用云主机切换出口IP地址[Windows系统教程]
    如果要指定出口,设置方法:1.查看ip设置情况netshinterfaceipv4showipaddresseslevel=verbose 2.手工删除不需要设置出口的ip3.netshintipv4addaddress"以太网5"1.2.3.4/24skipassource=true 然后用此命令将删除的ip重新添加上去(如果ip较多,可以参考后半段脚本......
  • 【分享】Windows XP N合1转自XP终极珍藏系列2014,个人做了一些xp软件包的添加
    添加的软件包见下图  WindowsXPSP3多合一"终极珍藏"第一版微软于2014/04/08公告停止XP服务支持。意思也就是从此你使用XP将不再收到XP系统漏洞补丁推送当然,如果你不在乎系统漏洞补丁这方面,你的日常应用又必须XP兼容支持,你依然可以安装上安全防卫软件继续长期使用。......
  • MaSuRCA 软件安装 swig/perl5/swig_wrap.cpp:342:20: fatal error: string.h: No such
     001、问题MaSuRCA软件安装swig/perl5/swig_wrap.cpp:342:20:fatalerror:string.h:Nosuchfileordirectory  002、原因,当前环境处于conda的base环境,可能是函数库调用混乱。  003、解决方法,推出conda基础环境安装(base)[b20223040323@admin1MaSuRCA-4......
  • windows上的C++编译环境
    Windows上的C++编程环境比Linux上的繁杂很多,有许多工具已经很老了,但是很多教材也还在用,很多学校的教学也还在用。另一方面,有更现代的选择,但是需要一些必要的配置和对工具链组成的理解,本文将必要的环境都介绍一遍,让新手能有一个相对完整的理解,然后迅速抛弃老旧的工具链,使用更现代......
  • C和CPP程序是如何运行起来的?
    C和CPP程序是如何运行起来的?个人见解,谨慎阅读。如有错误,欢迎指正!代码均在Linux下编译运行。1.C语言程序从源码到可执行文件的过程C语言程序从源码到可执行文件的过程主要分为以下几个步骤:预处理、编译、汇编、链接。flowchartLRA1[代码]--"预处理"-->B1[预处理文......