C++.Windows图形

news2025/5/13 20:14:05

Windows图形

  • 1. 基础知识
    • 1.1 Windows图形编程基础
    • 1.2 GDI与GDI+
    • 1.3 窗口消息处理
    • 2.1 注册窗口类
    • 2.2 创建窗口
    • 2.3 显示窗口
    • 3.1 创建按钮
    • 3.2 按钮消息处理
    • 4.1 设置窗口透明度
    • 4.2 透明窗口示例
    • 5.1 使用区域创建异形窗口
    • 5.2 异形窗口示例
    • 6.1 GDI+抗锯齿设置
    • 6.2 抗锯齿绘图示例
    • 7.1 DirectX基础
    • 7.2 Direct2D硬件加速
      • Direct2D 的优势
      • Direct2D 的基本使用
    • 8.1 Direct2D矢量图形基础
      • Direct2D 矢量图形的优势
      • Direct2D 矢量图形的基本概念
      • Direct2D 矢量图形的绘制流程
    • 8.2 矢量图形绘制示例
    • 9.1 窗口布局管理
      • 静态布局
      • 动态布局
      • 使用布局管理器
        • 水平布局
        • 垂直布局
        • 网格布局
    • 9.2 控件排序与定位
      • 设置控件的 Z 顺序
      • 控件的定位
      • 动态调整控件位置
      • 使用布局管理器简化定位
    • 9.3 布局管理器的高级应用
      • 自适应布局
      • 弹性布局
      • 响应式布局
    • 9.4 布局管理的注意事项

1. 基础知识

1.1 Windows图形编程基础

Windows图形编程主要基于Windows API,它提供了丰富的函数来创建和管理图形界面。以下是几个关键概念:

  • 窗口(Window):是用户界面的基本元素,可以包含菜单、按钮、文本框等控件。每个窗口都有一个唯一的句柄(HWND)。
  • 设备上下文(DC):是与设备相关的数据结构,用于存储绘图属性,如画笔、画刷等。通过设备上下文可以对窗口进行绘图操作。
  • 消息(Message):是Windows操作系统与应用程序之间通信的方式,包括鼠标点击、键盘输入等事件。应用程序需要通过消息循环来处理这些消息。
  • 坐标系统:Windows使用像素作为单位,坐标原点在窗口的左上角,水平向右为x轴正方向,垂直向下为y轴正方向。

1.2 GDI与GDI+

GDI(Graphics Device Interface)是Windows提供的图形设备接口,用于基本的绘图操作,如绘制线条、矩形、文本等。GDI+是GDI的升级版本,提供了更强大的功能,如抗锯齿、透明度、矢量图形等。

  • GDI:使用设备上下文(HDC)进行绘图,例如:
    HDC hdc = GetDC(hwnd);
    HPEN hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
    SelectObject(hdc, hPen);
    MoveToEx(hdc, 10, 10, NULL);
    LineTo(hdc, 100, 100);
    DeleteObject(hPen);
    ReleaseDC(hwnd, hdc);
    
  • GDI+:使用GDI+对象进行绘图,例如:
    Gdiplus::Graphics graphics(hdc);
    Gdiplus::Pen pen(Gdiplus::Color(255, 255, 0, 0), 2);
    graphics.DrawLine(&pen, 10, 10, 100, 100);
    

1.3 窗口消息处理

窗口消息处理是Windows图形编程的核心,应用程序通过消息循环来接收和处理消息。以下是基本的消息循环代码:

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

在窗口过程函数中,可以处理各种消息,例如:

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
   
    switch (uMsg) {
   
        case WM_PAINT:
            // 绘图操作
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

窗口消息处理是实现图形界面交互的基础,通过处理不同的消息,可以实现按钮点击、窗口移动等功能。# 2. 创建简单窗口

2.1 注册窗口类

在Windows编程中,注册窗口类是创建窗口的第一步。窗口类定义了窗口的外观和行为,包括窗口的标题、样式、图标、背景色等。以下是注册窗口类的代码示例:

WNDCLASS wc = {
   0};
wc.lpfnWndProc = WindowProc; // 指定窗口过程函数
wc.hInstance = hInstance;    // 当前实例句柄
wc.lpszClassName = L"MyWindowClass"; // 窗口类名
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // 背景色
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 鼠标光标样式
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 窗口图标
if (!RegisterClass(&wc)) {
   
    MessageBox(NULL, L"Failed to register window class", L"Error", MB_OK | MB_ICONERROR);
    return 0;
}

在上述代码中,WNDCLASS结构体用于描述窗口类的属性。lpfnWndProc字段指定了窗口过程函数,用于处理窗口消息;hInstance是当前程序实例的句柄;lpszClassName是窗口类的名称,用于后续创建窗口时引用;hbrBackground定义了窗口的背景颜色;hCursorhIcon分别指定了鼠标光标样式和窗口图标。

2.2 创建窗口

注册窗口类后,可以使用CreateWindow函数创建窗口。该函数需要指定窗口类名、窗口标题、窗口样式、窗口位置和大小等参数。以下是创建窗口的代码示例:

HWND hwnd = CreateWindow(
    L"MyWindowClass", // 窗口类名
    L"My Simple Window", // 窗口标题
    WS_OVERLAPPEDWINDOW, // 窗口样式
    CW_USEDEFAULT, CW_USEDEFAULT, // 窗口位置
    640, 480, // 窗口大小
    NULL, // 父窗口句柄
    NULL, // 菜单句柄
    hInstance, // 当前实例句柄
    NULL // 创建参数
);
if (!hwnd) {
   
    MessageBox(NULL, L"Failed to create window", L"Error", MB_OK | MB_ICONERROR);
    return 0;
}

在上述代码中,CreateWindow函数的第一个参数是窗口类名,必须与注册窗口类时指定的类名一致;第二个参数是窗口标题,显示在窗口的标题栏上;第三个参数是窗口样式,WS_OVERLAPPEDWINDOW表示创建一个具有标题栏、边框和最大化/最小化按钮的窗口;接下来的四个参数分别指定窗口的左上角坐标和宽度、高度;NULL表示该窗口没有父窗口;NULL表示该窗口没有菜单;hInstance是当前程序实例的句柄;最后一个参数通常用于传递额外的创建参数。

2.3 显示窗口

创建窗口后,需要使用ShowWindow函数来显示窗口。此外,通常还会调用UpdateWindow函数来刷新窗口内容。以下是显示窗口的代码示例:

ShowWindow(hwnd, nCmdShow); // 显示窗口
UpdateWindow(hwnd); // 刷新窗口内容

在上述代码中,ShowWindow函数的第一个参数是窗口句柄,nCmdShow是命令行参数,通常在程序入口处由WinMain函数传递。nCmdShow的值可以是SW_SHOWNORMALSW_SHOWMAXIMIZED等,用于指定窗口的显示状态。UpdateWindow函数会发送WM_PAINT消息给窗口,触发窗口的绘制操作。

通过以上三个步骤,就可以创建并显示一个简单的窗口。这是Windows图形编程的基础,后续可以在此基础上添加更多的控件和功能。# 3. 按钮控件

3.1 创建按钮

在Windows编程中,按钮是一种常见的控件,用于接收用户的点击操作。按钮可以通过CreateWindow函数创建,指定按钮的类型、位置、大小等属性。以下是创建按钮的代码示例:

// 创建一个普通按钮
HWND hwndButton = CreateWindow(
    L"BUTTON", // 按钮控件类名
    L"Click Me", // 按钮显示的文本
    WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, // 按钮样式
    100, 100, // 按钮左上角坐标
    100, 30, // 按钮宽度和高度
    hwnd, // 父窗口句柄
    (HMENU)1, // 按钮的ID,用于消息处理
    hInstance, // 当前实例句柄
    NULL // 创建参数
);
if (!hwndButton) {
   
    MessageBox(hwnd, L"Failed to create button", L"Error", MB_OK | MB_ICONERROR);
}

在上述代码中,CreateWindow函数的第一个参数是按钮控件的类名,固定为L"BUTTON";第二个参数是按钮上显示的文本;第三个参数是按钮的样式,WS_CHILD表示按钮是子窗口,WS_VISIBLE表示按钮可见,BS_PUSHBUTTON表示创建一个普通按钮;接下来的四个参数分别指定按钮的左上角坐标和宽度、高度;hwnd是父窗口句柄;(HMENU)1是按钮的ID,用于在消息处理中区分不同的按钮;hInstance是当前程序实例的句柄;最后一个参数通常为NULL

除了普通按钮,还可以创建其他类型的按钮,例如单选按钮和复选按钮。单选按钮和复选按钮的创建方式与普通按钮类似,只是需要指定不同的样式。以下是创建单选按钮和复选按钮的代码示例:

// 创建一个单选按钮
HWND hwndRadioButton1 = CreateWindow(
    L"BUTTON", // 单选按钮控件类名
    L"Option 1", // 单选按钮显示的文本
    WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON, // 单选按钮样式
    100, 150, // 单选按钮左上角坐标
    100, 30, // 单选按钮宽度和高度
    hwnd, // 父窗口句柄
    (HMENU)2, // 单选按钮的ID
    hInstance, // 当前实例句柄
    NULL // 创建参数
);
if (!hwndRadioButton1) {
   
    MessageBox(hwnd, L"Failed to create radio button 1", L"Error", MB_OK | MB_ICONERROR);
}

// 创建另一个单选按钮
HWND hwndRadioButton2 = CreateWindow(
    L"BUTTON", // 单选按钮控件类名
    L"Option 2", // 单选按钮显示的文本
    WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON, // 单选按钮样式
    100, 200, // 单选按钮左上角坐标
    100, 30, // 单选按钮宽度和高度
    hwnd, // 父窗口句柄
    (HMENU)3, // 单选按钮的ID
    hInstance, // 当前实例句柄
    NULL // 创建参数
);
if (!hwndRadioButton2) {
   
    MessageBox(hwnd, L"Failed to create radio button 2", L"Error", MB_OK | MB_ICONERROR);
}

// 创建一个复选按钮
HWND hwndCheckBox = CreateWindow(
    L"BUTTON", // 复选按钮控件类名
    L"Check Me", // 复选按钮显示的文本
    WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, // 复选按钮样式
    100, 250, // 复选按钮左上角坐标
    100, 30, // 复选按钮宽度和高度
    hwnd, // 父窗口句柄
    (HMENU)4, // 复选按钮的ID
    hInstance, // 当前实例句柄
    NULL // 创建参数
);
if (!hwndCheckBox) {
   
    MessageBox(hwnd, L"Failed to create check box", L"Error", MB_OK | MB_ICONERROR);
}

在上述代码中,BS_AUTORADIOBUTTON是单选按钮的样式,BS_AUTOCHECKBOX是复选按钮的样式。单选按钮通常用于一组互斥的选项,用户只能选择其中一个;复选按钮则允许用户选择多个选项。

3.2 按钮消息处理

按钮的主要功能是接收用户的点击操作,并触发相应的事件。在Windows编程中,按钮的点击事件通过WM_COMMAND消息来处理。当用户点击按钮时,系统会向父窗口发送WM_COMMAND消息,父窗口可以通过检查消息的参数来确定是哪个按钮被点击,并执行相应的操作。以下是处理按钮点击事件的代码示例:

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
   
    switch (uMsg) {
   
        case WM_COMMAND:
            // 检查是哪个按钮被点击
            switch (LOWORD(wParam)) {
   
                case 1: // 普通按钮被点击
                    MessageBox(hwnd, L"Button clicked", L"Message", MB_OK);
                    break;
                case 2: // 单选按钮1被选中
                    if (IsDlgButtonChecked(hwnd, 2) == BST_CHECKED) {
   
                        MessageBox(hwnd, L"Radio button 1 selected", L"Message", MB_OK);
                    }
                    break;
                case 3: // 单选按钮2被选中
                    if (IsDlgButtonChecked(hwnd, 3) == BST_CHECKED) {
   
                        MessageBox(hwnd, L"Radio button 2 selected", L"Message", MB_OK);
                    }
                    break;
                case 4: // 复选按钮被点击
                    if (IsDlgButtonChecked(hwnd, 4) == BST_CHECKED) {
   
                        MessageBox(hwnd, L"Check box checked", L"Message", MB_OK);
                    } else {
   
                        MessageBox(hwnd, L"Check box unchecked", L"Message", MB_OK);
                    }
                    break;
            }
            break;
        case WM_PAINT:
            // 绘图操作
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

在上述代码中,WM_COMMAND消息的wParam参数包含了按钮的ID和通知代码。通过检查LOWORD(wParam)的值,可以确定是哪个按钮被点击。对于普通按钮,当按钮被点击时,会触发BN_CLICKED通知代码,父窗口可以直接执行相应的操作。对于单选按钮和复选按钮,需要使用IsDlgButtonChecked函数来检查按钮的状态。如果按钮被选中,IsDlgButtonChecked函数返回BST_CHECKED;否则返回BST_UNCHECKED

通过上述代码,可以实现按钮的基本功能,如接收点击事件并触发相应的操作。按钮是Windows图形界面中非常重要的控件之一,通过合理使用按钮,可以为用户提供

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

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

相关文章

vue实现与后台springboot传递数据【传值/取值 Axios 】

vue实现与后台springboot传递数据【传值/取值】 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是node.js和vue的使用。前后每一小节的内容是存在的有:学习and理解的关联性。【帮帮志系列文章】:每…

【英语笔记(三)】介绍谓语动词的分类,初步讲解四种基本状态:一般、进行、完成、完成进行

1. 五大类谓语动词 2. 谓语动词分类 3. 动词时间 过去--------------------------现在-----------------------未来 3. 动词状态 3.1 进行状态 3.2 完成状态 3.3 完成进行状态 3.4 一般状态 4. 时间 状态 名称说明例句现在现在现在现在进行时态现在某物正在做什么事情一只…

【Python】让Selenium 像Beautifulsoup一样,用解析HTML 结构的方式提取元素!

我在使用selenium的find_element的方式去获取网页元素,一般通过xpath、css_selector、class_name的方式去获取元素的绝对位置。 但是有时候如果网页多了一些弹窗或者啥之类的,绝对位置会发生变化,使用xpath等方法,需要经常变动。…

2025 后端自学UNIAPP【项目实战:旅游项目】3、API接口请求封装,封装后的简单测试以及实际使用

一、创建请求封装目录 选中自己的项目,右键鼠标---->新建---->目录---->名字自定义【我的是api】 二、创建两个js封装文件 选中封装的目录,右键鼠标---->新建---->js文件---->名字自定义【我的两个js文件分别是my_http和my_api】 三…

Ascend的aclgraph(二)_npu_backend中还有些什么秘密?

1 _npu_backend 文章还是从代码开始 import torch_npu, torchair config torchair.CompilerConfig() # 设置图下沉执行模式 config.mode "reduce-overhead" npu_backend torchair.get_npu_backend(compiler_configconfig) opt_model torch.compile(model, back…

ventoy安全启动怎么选_ventoy安全启动支持是开还是关

ventoy安全启动怎么选?Ventoy新一代多系统启动U盘解决方案。国产开源U盘启动制作工具,支持Legacy BIOS和UEFI模式,理论上几乎支持任何ISO镜像文件,支持加载多个不同类型的ISO文件启动,无需反复地格式化U盘,…

CC53.【C++ Cont】二分查找的普通模版

目录 1.知识回顾 2.关键点 特点 三个模版 普通的模版(有局限) 以LeetCode上的一道题为例:704. 二分查找 分析 引入二段性:分两段,舍一段,操作另一段(这个是二分查找的本质!) 代码 提交结果 当然也可以使用随机数来分两段 普通模版总结 1.知识回顾 之前在C语言专栏…

【优选算法 | 链表】链表操作技巧:常见算法

算法相关知识点可以通过点击以下链接进行学习一起加油!双指针滑动窗口二分查找前缀和位运算模拟 链表是一种灵活的数据结构,广泛用于需要频繁插入和删除的场景。掌握链表的常见操作技巧,如插入、删除、翻转和合并等,能帮助开发者更…

w~大模型~合集30

我自己的原文哦~ https://blog.51cto.com/whaosoft/13284996 #VideoMamba 视频理解因大量时空冗余和复杂时空依赖,同时克服两个问题难度巨大,CNN 和 Transformer 及 Uniformer 都难以胜任,Mamba 是个好思路,让我们看看本文是…

PBR材质-Unity/Blender/UE

目录 前言: 一、Unity: 二、Blender: 三、UE: 四、全家福: 五、后记: 前言: PBR流程作为表达物理效果的经典方式,很值得一学。纹理贴图使用的是上一期的Textures | cgbookcas…

websocketpp 安装及使用

介绍 WebSocket 是从 HTML5 开始支持的一种网页端和服务端保持长连接的消息推送机制。 传统的 web 程序都是属于 "一问一答" 的形式,即客户端给服务器发送了一个 HTTP 请求,服务器给客户端返回一个 HTTP 响应。这种情况下服务器是属于被动…

第8章-2 查询执行的基础

上一篇:《第8章-1 查询性能优化-优化数据访问》,接着来了解查询执行的过程,这个对sql执行有个更直观的了解。 查询执行的基础 当希望MySQL能够以更高的性能运行查询时,最好的办法就是弄清楚MySQL是如何优化和执行查询的。一旦理解…

java面试OOM汇总

在正式 Minor GC 前,JVM 会先检查新生代中对象,是比老年代中剩余空间大还是小。假如 Minor GC之后 Survivor 区放不下剩余对象,这些对象就要进入老年代 老年代剩余空间大于新生代中的对象大小,那就直接 Minor GC, GC 完…

react-diff-viewer 如何实现语法高亮

前言 react-diff-viewer 是一个很好的 diff 展示库,但是也有一些坑点和不完善的地方,本文旨在描述如何在这个库中实现自定义语法高亮。 Syntax highlighting is a bit tricky when combined with diff. Here, React Diff Viewer provides a simple rend…

自定义prometheus exporter实现监控阿里云RDS

# 自定义 Prometheus Exporter 实现多 RDS 数据采集## 背景1. Prometheus 官网提供的 MySQL Exporter 对于 MySQL 实例只能一个进程监控一个实例,数据库实例很多的情况下,不方便管理。 2. 内部有定制化监控需求,RDS 默认无法实现,…

【计算机网络】--tcp三次握手

文章目录 示意图:抓包结果:第一次握手(Client → Server)第二次握手(Server → Client)第三次握手(Client → Server)为什么是三次握手 不是两次或者四次 示意图: 抓包结…

UI-TARS: 基于视觉语言模型的多模式代理

GitHub:https://github.com/bytedance/UI-TARS 更多AI开源软件:发现分享好用的AI工具、AI开源软件、AI模型、AI变现 - 小众AI 基于视觉语言模型(Vision-Language Model)的 GUI 代理应用,允许用户通过自然语言控制电脑操…

Spark SQL 运行架构详解(专业解释+番茄炒蛋例子解读)

1. 整体架构概览 Spark SQL的运行过程可以想象成一个"SQL查询的加工流水线",从原始SQL语句开始,经过多个阶段的处理和优化,最终变成分布式计算任务执行。主要流程如下: SQL Query → 解析 → 逻辑计划 → 优化 → 物理…

【计算机网络】网络IP层

📚 博主的专栏 🐧 Linux | 🖥️ C | 📊 数据结构 | 💡C 算法 | 🅒 C 语言 | 🌐 计算机网络 上篇文章:传输层协议TCP 下篇文章:数据链路层 文章摘要&#xff1…

一天学会Maven

一、Maven简介和快速入门 1.1 Maven介绍 Maven 是一款为 Java 项目构建管理、依赖管理的工具(软件),使用 Maven 可以自动化构建、测试、打包和发布项目,大大提高了开发效率和质量。 总结:Maven就是一个软件&#xf…