Windows图形界面(GUI)-SDK-C/C++ - 应用程序结构

  • 公开视频 -> 链接点击跳转公开课程
  • 博客首页 -> 链接点击跳转博客主页

目录

入口函数

窗口注册

窗口创建

窗口显示

窗口更新

消息循环

窗口过程

窗口销毁

调试信息

示例代码


入口函数

  • 在Windows应用程序中,WinMain是主函数,作为应用程序的入口点。这与许多其他平台上的main函数类似。
  • 函数原型
  • int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
    
  • 参数解析
    • HINSTANCE hInstance:当前实例的句柄(IMAGEBASE)。
    • HINSTANCE hPrevInstance:在32位Windows应用程序中,这个参数总是为NULL。在早期版本的Windows中,用于标识程序的前一个实例。
    • LPSTR lpCmdLine:指向一个以null终止的字符串,该字符串包含命令行参数。请注意,它不包含程序的名称。
    • int nCmdShow:指定窗口如何显示。

窗口注册

  • 在Windows应用程序中,每个窗口都需要一个窗口类,这个类包含了窗口的属性和一个事件处理函数(窗口过程)。要创建窗口,必须先注册一个窗口类。
  • 函数原型
  • ATOM RegisterClassEx(const WNDCLASSEX *lpwcx);
    
  • 参数解析
    • lpwcx:指向WNDCLASSEX结构的指针,该结构包含了窗口类的信息。
    • WNDCLASSEX结构定义了窗口的特征,包括背景颜色、光标、图标、菜单名和窗口过程等。
      • cbSize: 指定了结构体的大小,必须设置为 sizeof(WNDCLASSEX)
      • style: 类型的风格。可以是任何窗口类风格的组合,比如 CS_HREDRAWCS_VREDRAW
      • lpfnWndProc: 指向窗口过程的指针。这是一个函数指针,指向一个由系统调用以处理窗口消息的函数。
      • cbClsExtra: 指定分配给窗口类结构后面的额外字节数。通常这个值设为0。
      • cbWndExtra: 指定分配给每个窗口实例的额外字节数。例如,可以使用额外的空间存储一个指向窗口数据的指针。
      • hInstance: 一个句柄,标识了包含窗口过程的应用程序实例。
      • hIcon: 一个图标的句柄,这是与窗口类关联的图标。
      • hCursor: 一个光标的句柄,这是与窗口类关联的光标。
      • hbrBackground: 设置窗口背景色的画刷句柄。可以是一个颜色值的句柄,前面加上COLOR_的前缀。
      • lpszMenuName: 指向一个以 null 结束的字符串,该字符串指定类菜单,为资源名称。如果使用类菜单,所有由该类创建的窗口都将使用这个菜单。
      • lpszClassName: 指向一个以 null 结束的字符串或是一个原子,如果此参数是一个原子,则它必须是一个全局原子。
      • hIconSm: 与窗口类关联的小图标的句柄。如果这个成员是 NULL,系统会从 hIcon 成员指定的大图标中提取一个小图标。

窗口创建

  • 注册了窗口类之后,可以用CreateWindowEx函数创建窗口。
  • 函数原型
  • HWND CreateWindowEx(DWORD dwExStyle,LPCSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam
    );
    
  • 函数参数
    • dwExStyle: 扩展窗口样式。这些样式控制各种扩展的窗口特征,例如带有边界阴影的窗口或者无边框的窗口等。
    • lpClassName: 注册的窗口类名。这可以是一个指向以 null 结尾的字符串的指针,或一个由 RegisterClassEx 函数返回的原子。
    • lpWindowName: 窗口的标题文字。如果窗口是一个控件,这个参数是一个指向以 null 结尾的字符串的指针,表示控件的文本。
    • dwStyle: 窗口的风格。这些风格控制着窗口的一般外观和行为。
    • X: 窗口创建时水平位置的坐标。如果参数是 CW_USEDEFAULT,系统会选择窗口的默认位置。
    • Y: 窗口创建时垂直位置的坐标。如果参数是 CW_USEDEFAULT,系统会选择窗口的默认位置。
    • nWidth: 窗口的宽度。如果设置为 CW_USEDEFAULT,系统会选择窗口的默认宽度。
    • nHeight: 窗口的高度。如果设置为 CW_USEDEFAULT,系统会选择窗口的默认高度。
    • hWndParent: 父窗口句柄。如果没有父窗口,此参数应为 NULL。弹出窗口和消息框将使用此参数指定的窗口作为它们的所有者。
    • hMenu: 窗口菜单句柄或子窗口标识符。如果是一个子窗口,此参数是一个菜单的句柄;如果是顶层窗口,此参数指定窗口的菜单;如果是子窗口,此参数是子窗口的标识符。
    • hInstance: 拥有窗口过程的应用程序的实例句柄。
    • lpParam: 指向一个值的指针,该值将被传递给窗口通过 WM_CREATE 消息。如果不需要传递值,此参数可以为 NULL

窗口显示

  • ShowWindow函数设置窗口的显示状态。在一个窗口被创建后,它不会自动显示;必须调用此函数来控制窗口的显示。
  • 函数原型
  • BOOL ShowWindow(HWND hWnd,int  nCmdShow
    );
    
  • 函数参数
    • hWnd:窗口句柄,标识要设置显示状态的窗口。
    • nCmdShow:指定窗口如何被显示。常用参数包括:
      • SW_SHOW:显示窗口。
      • SW_HIDE:隐藏窗口,活动状态给另一个窗口。
      • SW_MINIMIZE:最小化窗口,活动状态给另一个窗口。
      • SW_RESTORE:激活并显示窗口。如果窗口最小化或最大化,系统会将其恢复到原始尺寸和位置。
      • SW_SHOWMAXIMIZED:激活窗口并将其最大化。
      • SW_SHOWMINIMIZED:激活窗口并将其最小化。
      • SW_SHOWMINNOACTIVE:窗口最小化,类似SW_SHOWMINIMIZED,但窗口不被激活。

窗口更新

  • UpdateWindow函数用于更新客户区的无效区域,即发送一个WM_PAINT消息给窗口过程,如果客户区没有无效区域,则不发送消息。
  • 函数原型
  • BOOL UpdateWindow(HWND hWnd
    );
    
  • 函数参数
    • hWnd:窗口句柄,标识要更新的窗口。
    • 该函数通常在ShowWindow后调用,以便立即更新窗口的客户区而无需等待WM_PAINT消息的正常排队。

消息循环

  • Windows应用程序是事件驱动的。在WinMain中,程序必须不断检查和处理消息。这就是所谓的消息循环或消息处理机制。每个GUI应用程序都有一个消息队列,Windows操作系统使用它来存储对该应用程序的所有输入(如鼠标点击、键盘输入等)。
  • 示例代码
  • while (GetMessage(&msg, NULL, 0, 0))
    {TranslateMessage(&msg);DispatchMessage(&msg);
    }
    
  • 函数解析
    • GetMessage从消息队列检索消息。如果没有消息,它会等待,直到有消息为止。如果返回0,意味着接收到WM_QUIT消息,循环会结束。
    • TranslateMessage将虚拟键消息转换为字符消息。
    • DispatchMessage将消息发送到窗口程序。

窗口过程

  • 窗口过程是一个函数,它处理发送到窗口的消息。每个窗口都有一个与之关联的窗口过程。当事件发生(比如用户点击按钮),Windows会将相应的消息发送到窗口过程。窗口过程根据消息的类型执行相应的操作,并返回结果。
  • LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    • HWND hwnd: 窗口的句柄。
    • UINT uMsg: 消息的标识。
    • WPARAM wParam: 消息特定的附加信息。
    • LPARAM lParam: 消息特定的附加信息。
    • // 实现窗口过程函数
      LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
      {return DefWindowProc(hwnd, uMsg, wParam, lParam);
      }

窗口销毁

  • 窗口的销毁 通常通过调用DestroyWindow函数来完成。当窗口被销毁后,Windows会发送WM_DESTROY消息给窗口过程,窗口过程可以在接收到此消息时执行清理操作。

调试信息

  • OutputDebugStringA 函数是 Windows API 中的一个函数,它用于将一个字符串输出到调试器。
#include <windows.h>
#include <stdio.h>int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{char buffer[256];int value1 = 42;int value2 = 100;// 使用 sprintf 格式化字符串sprintf_s(buffer, sizeof(buffer), "Value 1: %d, Value 2: %d\n", value1, value2);// 输出格式化后的字符串到调试器OutputDebugStringA(buffer);return 0;
}

示例代码

#include <Windows.h>LRESULT CALLBACK MainWindowProc (HWND, UINT, WPARAM, LPARAM);INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{// 注册窗口WNDCLASSEX wndclass = { 0 };wndclass.cbSize = sizeof(WNDCLASSEX);wndclass.style = NULL;wndclass.lpfnWndProc = MainWindowProc;wndclass.cbClsExtra = NULL;wndclass.cbWndExtra = NULL;wndclass.hInstance = hInstance;wndclass.hIcon = NULL;wndclass.hCursor = NULL;wndclass.hbrBackground = (HBRUSH)COLOR_WINDOW;wndclass.lpszMenuName = NULL;wndclass.lpszClassName = TEXT("0xCC");wndclass.hIconSm = NULL;if (!RegisterClassEx(&wndclass)){MessageBox(NULL, TEXT("RegisterClassEx Failed"), TEXT("Error"), MB_OK);return 1;}// 创建窗口HWND hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,TEXT("0xCC"),TEXT("CreateWindowEx"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,960,540,NULL,NULL,hInstance,NULL);if (hwnd == NULL){MessageBox(NULL, TEXT("CreateWindowEx Failed"), TEXT("Error"), MB_OK);return 1;}// 显示窗口ShowWindow(hwnd, SW_SHOWDEFAULT);// 更新窗口UpdateWindow(hwnd);// 消息处理MSG msg = { 0 };while (GetMessage(&msg, 0, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}return 0;
}// 窗口过程
LRESULT CALLBACK MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{switch (uMsg){case WM_CREATE:{MoveWindow(hwnd, 0, 0, 500, 500, FALSE);CREATESTRUCT* Cs = (CREATESTRUCT*)lParam;break;}case WM_DESTROY:{PostQuitMessage(0);break;}case WM_SIZE:{TCHAR szBuffer[0xFF] = { 0 };wsprintf(szBuffer, TEXT("WM_SIZE -> %d %d\r\n"), HIWORD(lParam), LOWORD(lParam));OutputDebugString(szBuffer);break;}case WM_MOVE:{TCHAR szBuffer[0xFF] = { 0 };wsprintf(szBuffer, TEXT("WM_MOVE -> %d %d\r\n"), HIWORD(lParam), LOWORD(lParam));OutputDebugString(szBuffer);break;}case WM_LBUTTONDOWN:{TCHAR szBuffer[0xFF] = { 0 };wsprintf(szBuffer, TEXT("WM_LBUTTONDOWN -> %d %d\r\n"), HIWORD(lParam), LOWORD(lParam));OutputDebugString(szBuffer);break;}case WM_KEYDOWN:{TCHAR szBuffer[0xFF] = { 0 };wsprintf(szBuffer, TEXT("WM_KEYDOWN -> %d\r\n"), wParam);OutputDebugString(szBuffer);break;}default:return DefWindowProc(hwnd, uMsg, wParam, lParam);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/42576.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网格化监控:Eureka与分布式服务网格的协同监控

网格化监控&#xff1a;Eureka与分布式服务网格的协同监控 引言 在微服务架构中&#xff0c;服务网格技术提供了一种有效的方式来管理和监控服务间的通信。Eureka作为Netflix开源的服务发现框架&#xff0c;虽然本身不直接提供服务网格的监控功能&#xff0c;但可以与服务网格…

设计模式探索:适配器模式

1. 适配器模式介绍 1.1 适配器模式介绍 适配器模式&#xff08;adapter pattern&#xff09;的原始定义是&#xff1a;将一个类的接口转换为客户期望的另一个接口&#xff0c;适配器可以让不兼容的两个类一起协同工作。 适配器模式的主要作用是把原本不兼容的接口&#xff0c…

【Python_GUI】thinker布局管理——place方法

place方法可以设置组件的大小以及组件在容器中的精确位置&#xff0c;其参数及含义如下&#xff1a; 参数含义X设置组件距离窗口左侧的水平距离y设置组件距离窗口顶部的垂直距离width设置组件的宽度height设置组件的高度relx设置组件距离窗口左侧的相对距离&#xff0c;范围为…

c++初阶学习----入门(上)

大家好啊。最近学习了一点关于c的知识。这不就迫不及待的来与大家分享了嘛。但我这也是现学现卖所以咧。有很多遗落甚至不对的地方希望大家可以在评论区里面指出来。这样也可以增加大家对知识的巩固。 c语言与c的联系 不知道大家看到c会不会不由自主的联想到C语言啊。毕竟都是…

手机自带录屏在哪?6个软件教你快速进行手机录屏

手机自带录屏在哪&#xff1f;6个软件教你快速进行手机录屏 手机自带的录屏功能可以让你轻松录制屏幕上的内容&#xff0c;记录游戏过程、制作教程或捕捉其他重要时刻。不同品牌的手机可能在不同位置提供录屏功能。以下是一些常见的手机品牌及其录屏功能位置&#xff0c;以及一…

【康复学习--LeetCode每日一题】724. 寻找数组的中心下标

题目&#xff1a; 给你一个整数数组 nums &#xff0c;请计算数组的 中心下标 。 数组 中心下标 是数组的一个下标&#xff0c;其左侧所有元素相加的和等于右侧所有元素相加的和。 如果中心下标位于数组最左端&#xff0c;那么左侧数之和视为 0 &#xff0c;因为在下标的左侧不…

运动爱好者的新选择:哈氪聆光气传导耳机,轻巧又安全

平时不管是漫步街头、骑行穿梭&#xff0c;还是乘坐公共交通时&#xff0c;我总是喜欢佩戴耳机&#xff0c;借此隔绝外部的喧嚣&#xff0c;享受音乐的乐趣。在户外使用耳机&#xff0c;我更倾向于选择气传导耳机&#xff0c;它们更符合我的需求&#xff0c;因为这种耳机能让我…

优雅下线的艺术:Eureka服务管理深度解析

优雅下线的艺术&#xff1a;Eureka服务管理深度解析 引言 在微服务架构中&#xff0c;服务的动态注册与发现是保证系统高可用性的关键。Eureka作为Netflix开源的服务发现框架&#xff0c;提供了服务注册与发现的基本功能。然而&#xff0c;服务在下线时如何做到"优雅&qu…

每日一编程,早点拿offer

计算字符串最后一个单词的长度&#xff0c;单词以空格隔开 输入描述&#xff1a; 输入一行&#xff0c;代表要计算的字符串&#xff0c;非空 输出描述&#xff1a; 输出一个整数&#xff0c;表示输入字符串最后一个单词的长度。 输入&#xff1a;hello world输出&#xff1a…

kubernetes集群证书过期问题解决

kubernetes集群证书过期问题解决 问题描述检查证书是否过期更新证书master节点操作node节点操作 问题描述 K8S 各个组件需要与 api-server 进行通信&#xff0c;通信使用的证书都存放在 /etc/kubernetes/pki 路径下&#xff0c;kubeadm 生成的证书大部分默认有效期为 1 年&…

SECS/GEM快速完成半导体设备通讯

金南瓜帮助国内大量从事半导体前道设备开发研制、生产的设备厂商&#xff0c;通过快速提供稳定可靠的SECS/GEM、GEM300产品&#xff0c;为客户在激光退火、湿法设备&#xff08;清洗、镀膜等&#xff09;、离子注入、MOCVD、PVD等客户专注于核心工艺提升&#xff0c;提升企业的…

`CyclicBarrier` 是 Java 中的一个同步辅助工具类,它允许一组线程相互等待,直到所有线程都达到了某个公共屏障点(barrier point)

CyclicBarrier 是 Java 中的一个同步辅助工具类&#xff0c;它允许一组线程相互等待&#xff0c;直到所有线程都达到了某个公共屏障点&#xff08;barrier point&#xff09;。当所有线程都到达屏障点时&#xff0c;它们可以继续执行后续操作。CyclicBarrier 的特点是可以重复使…

中介子方程五十

XXFXXaXnXaXXαXLXyXXWXuXeXKXXiXyXΣXXΣXXVXuXhXXWXηXXiXhXXpXXhXiXXηXWXXhXuXVXXΣXXΣXyXiXXKXeXuXWXXyXLXαXXaXnXaXXFXXaXnXaXXαXLXyXXWXuXeXKXXiXyXΣXXΣXXVXuXhXXWXηXXiXhXXpXXhXiXXηXWXXhXuXVXXΣXXΣXyXiXXKXeXuXWXXyXLXαXXaXnXaXXFXXuXXWXXuXXdXXrXXαXXuXpX…

Gen4Gen:多概念个性化图像生成的数据驱动革新

个性化文本到图像生成模型在用户控制生成过程方面取得了重要进展。这些模型能够通过少量训练样本学习并合成包含新颖个性化概念的图像&#xff0c;例如用户的宠物或特定物品。然而&#xff0c;现有技术在处理多概念个性化时存在局限性&#xff0c;尤其是在生成包含多个相似概念…

连接与隔离:Facebook在全球化背景下的影响力

在当今全球化的背景下&#xff0c;Facebook作为全球最大的社交网络平台&#xff0c;不仅连接了世界各地的人们&#xff0c;还在全球社会、经济和文化中发挥着深远的影响。本文将深入探讨Facebook在全球化进程中的作用&#xff0c;以及其对个体和社会之间连接与隔离的双重影响。…

【续集】Java之父的退休之旅:从软件殿堂到多彩人生的探索

Java之父的退休之旅&#xff1a;从软件殿堂到多彩人生的探索-CSDN博客 四、科技领袖退休后的行业影响 4.1 传承与启迪 Gosling等科技领袖的退休&#xff0c;为行业内部年轻一代提供了更多的发展机会和成长空间。他们的退休不仅意味着权力和责任的交接&#xff0c;更是一种精…

等保测评新趋势:应对数字化转型中的安全挑战

随着信息技术的飞速发展&#xff0c;数字化转型已成为企业提升竞争力、优化运营效率的重要手段。然而&#xff0c;这一转型过程中&#xff0c;企业也面临着前所未有的安全挑战。等保测评&#xff08;信息安全等级保护测评&#xff09;作为保障信息系统安全的重要手段&#xff0…

html5路由如何在nginx上部署(vite+vue3)

我们知道前端常用的有Hash 模式和html5模式的路由&#xff0c;hash模式在nginx上部署不需要额外的操作&#xff0c;而html5模式则需要额外设置&#xff0c;这里介绍下如何在nginx根地址&#xff08;location / {}&#xff09;下部署和在非根地址上&#xff08;location /admin{…

【MATLAB源码-第232期】基于matlab的 (204,188) RS编码解码仿真,采用QPSK调制输出误码率曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 Reed-Solomon码&#xff08;RS码&#xff09;是一类广泛应用于数字通信和存储系统中的纠错码&#xff0c;尤其在光盘、卫星通信和QR码等领域有着重要作用。RS码是一种非二进制的纠删码&#xff0c;由Irving S. Reed和Gustave…

当CNN遇上Mamba,高性能与高效率通通拿下!

传统视觉模型在处理大规模或高分辨率图像时存在一定限制&#xff0c;为解决这个问题&#xff0c;研究者们就最近依旧火热的Mamba&#xff0c;提出了Mamba结合CNN的策略。 这种结合可以让Mamba在处理长序列数据时既能够捕捉到序列中的时间依赖关系&#xff0c;又能够利用CNN的局…