首页 > 系统相关 >在CodeBolcks+Windows API下的C++面向对象的编程教程——给你的项目中添加图标

在CodeBolcks+Windows API下的C++面向对象的编程教程——给你的项目中添加图标

时间:2024-12-17 15:13:05浏览次数:3  
标签:CodeBolcks LoadIcon Windows 代码 oTetris C++ 添加 aTetris 图标

0.前言

我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程。我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识。

了解我编写教程的思路,请参阅体现我最初想法的那篇文章中的“1.编程计划”:

学习编程从游戏开始 - lexyao - 博客园

这是一篇专题文章,这篇文章是用来讲解下面这篇文章用到的知识的,我在这篇文章中讲解程序使用的例子就是在下面这篇文章中创建的oTetris项目:

在CodeBolcks+Windows API下的C++面向对象的编程教程——用面向对象的方法改写用向导创建一个Windows GUI项目(oTetris) - lexyao - 博客园

在这篇文章里,我主要讲述以下几个方面的内容:

  1. 给项目添加资源文件文件
  2. aTetris项目中添加图标的代码分析
  3. oTetris项目中添加图标的方法
  4. oTetris和aTetris项目添加图标的代码对比
  5. 创建窗口后给项目添加图标
  6. 结束语

 

1.给项目添加资源文件文件

在Win32 GUI项目中,要给应用程序添加图标,需要做以下几个方面的工作:

  1. 先创建一个资源文件,在资源文件中添加菜单资源
  2. 在cpp文件中修改代码,将图标添加到应用程序中

以上工作在aTetris项目中已经做过了,在oTetris项目中直接使用aTetris的资源文件就行了。创建资源文件的过程请看下面的文章:

在CodeBolcks+Windows API下的C++编程教程——给你的项目中添加资源文件和图标 - lexyao - 博客园

在这里直接使用aTetris的文件,不用修改。具体操作包括以下步骤:

  1. 将资源文件添加到oTetris项目
  2. 在cpp文件中添加使用图标资源的代码

首先是添加资源文件,操作如下:
在CodeBlocks的项目列表中鼠标右击oTetris项目->在菜单中选择“Add files...”->选择aTetris项目的aTetris.rc添加到oTetris项目中。

剩下的就是添加使用菜单的代码了。

2.aTetris项目中添加图标的代码分析

aTetris项目使用菜单的代码是在入口函数WinMain中定义主窗口类数据的时候添加的。aTetrisMain.cpp中的代码如下:

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    ......
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
    ....../* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (hThisInstance, _T("aaaa"));//wincl.hIcon = LoadIcon (NULL, );
    wincl.hIconSm = LoadIcon (hThisInstance, _T("aaaa"));//wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    ....../* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;
    ......
}

在程序入口函数WinMain中使用下面语句将资源文件中图标资源的名称“aaaa”赋值给窗口结构的wincl的hIcon和hIconSm。

    wincl.hIcon = LoadIcon (hThisInstance, _T("aaaa"));
    wincl.hIconSm = LoadIcon (hThisInstance, _T("aaaa"));

没有添加资源图标的时候这个语句的赋值是IDI_APPLICATION,使用的是操作系统资源中的图标:

    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);

3.oTetris项目中添加图标的方法

在oTetris项目中要实现同样的方法只需要添加下面代码中的红色语句:

void MainWindow::WindowClassEx(PWNDCLASSEX wc)
{
    wc->hIcon = LoadIcon (wc->hInstance, _T("aaaa"));
    wc->hIconSm = LoadIcon (wc->hInstance, _T("aaaa"));
    ......
}

其中的WindowClassEx是我们在基类BaseWindow中添加了纯虚函数后在MainWindow中添加的实现。

以下是使用WindowClassEx的代码:

template <class DERIVED_TYPE>
BOOL BaseWindow<DERIVED_TYPE>::Create(
    PCWSTR lpWindowName,
    DWORD dwStyle,
    DWORD dwExStyle,
    int x ,
    int y,
    int nWidth ,
    int nHeight,
    HWND hWndParent,
    HMENU hMenu
)
{
    WNDCLASSEX wc = {0};
    ......
    WindowClassEx(&wc);
    if (!RegisterClassEx(&wc))
        return 0;
    ......
}

从代码看,aTetris和oTetris项目中设置菜单的代码执行的位置是一样的,只是代码的表现形式不一样罢了。

4.oTetris和aTetris项目添加菜单的代码对比

在前面的内容中已经对aTetris和oTetris项目中设置菜单的代码进行了对比,采用的方法、使用的位置是一样的。
不同点在于:

  • aTetris在程序的入口函数中直接加入,代码简单、明了,比较容易看懂
  • oTetris在子类中重载基类的纯虚函数的代码中,看起来不那么直观,但了解了程序执行的流程后就明白了

从这个简单的代码来看,看不出面向对象的优势,甚至还会觉得面向对象的编程方法把简单的事情搞得复杂了。真的是这样吗?
或许使用的多了才会感觉到:面向对象的的编程方法把简单的事情搞得复杂了,把复杂的事情搞得简单了。

 5.创建窗口后给项目添加图标

前面说的添加图标的方法是在创建程序的主窗口之前定义项目主窗口类的结构数据的时候添加的。还有一种方法是在创建主窗口后的任何时候头可以使用的添加方法。

首先我来了解一下用到的知识。

添加图标的方法是使用SendMessage向主窗口的手柄发送WM_SETICON消息实现的。以下是Microsoft资料库中对SendMessage函数和WM_SETICON消息的说明:

WM_SETICON消息 (Winuser.h) - Win32 apps | Microsoft Learn

sendMessage 函数 (winuser.h) - Win32 apps | Microsoft Learn

函数及参数的格式如下:

LRESULT SendMessage(
  [in] HWND   hWnd,
  [in] UINT   Msg,
  [in] WPARAM wParam,
  [in] LPARAM lParam
);

发送消息时,

wParam要设置的图标的类型。 此参数的取值可为下列值之一,下面的常数是在winuser.h中定义的:

#define ICON_SMALL 0
#define ICON_BIG 1
#define ICON_SMALL2 2

lParam新的大图标或小图标的句柄。 如果此参数为 NULL,则删除 wParam 指示的图标。

图标的句柄由LoadIcon函数获得。从资源获得图标句柄有两种情况:

  • 资源文件中图标的ID是数字6666时:HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(666));
  • 资源文件中图标的ID是字符串aaaa时:HICON hIcon = LoadIcon(hInstance, _T("aaaa"));

LoadIcon函数的定义:

HICON WINAPI LoadIcon ( HINSTANCE hInstance, LPCTSTR lpIconName );

hInstance:图标资源所在模块的实例句柄。如果是标准图标,此参数必须为NULL。

lpIconName:如果 hInstance 为非 NULL, 则 lpIconName 按名称或序号指定图标资源。 必须使用 MAKEINTRESOURCE 宏打包此序号。

在面向对象的方法中,通常是吧底层的东西封装起来。我们添加两个函数,这样使用的时候就不用直接去写Windows API的代码了:

在MainWindow添加函数定义:

LRESULT SetIcon(HINSTANCE hInstance,WPARAM wParam, LPCTSTR lpIconName);

添加函数实现:

LRESULT MainWindow::SetIcon(HINSTANCE hInstance,WPARAM wParam, LPCTSTR lpIconName)
{
    HICON hIcon = LoadIcon(g_hInstance, lpIconName);
    return SendMessage(hwndDlg, WM_SETICON, wParam, (LPARAM)hIcon); 
}

使用时调用SetIcon就可以设置窗口图标了。

6.结束语

从添加菜单的代码来看,没有看出面向对象的编程有什么优势,甚至比面向过程的方法更复杂。或许真的是这样。不过,面向对象的编程技术是用来解决复杂问题的,目的是代码的重复利用。使用的越多的代码在面向对象的方法中表现的越有优势。
面向过程将数据和代码都摆在同一个层面上,都是看得见的。
面向对象的方法将数据和代码打包封装在类里,你只需要知道类的接口就可以使用,而不需要类的内部做了什么。
在将来当你的程序越来越大的时候,你会体验到面向对象编程的魅力。

 

标签:CodeBolcks,LoadIcon,Windows,代码,oTetris,C++,添加,aTetris,图标
From: https://www.cnblogs.com/lexyao/p/18612314

相关文章

  • C++实时性和时延优化
    C++实时性和时延优化主要体现在如何通过代码、算法和系统设计上的调整,确保程序能够在预定时间内完成任务,特别是在对响应时间要求极高的系统中。实时性和时延优化对于嵌入式系统、硬实时应用、通信系统、游戏引擎等领域尤为重要。具体的优化策略包括以下几个方面:1. 减少内存分配......
  • [OS] 基于 Windows 宿主机安装 VMWare Workstation 17 【转】
    Step1下载安装包VMWare官网百度网盘VMware-workstation-full-17.0.0-20800274.exe链接:https://pan.baidu.com/s/1y3jSI9p_qMhTqNVYa2OqfQ?pwd=vm17提取码:vm17Step2安装step2.1双击安装包,选择:【是】step2.2电脑重启之后,找到VMwareWorkstation17下载位......
  • C++ 智能指针
    目录内存泄漏内存泄漏分类(了解)如何检测内存泄漏(了解)如何避免内存泄漏智能指针的使用及原理RAIIstd::auto_ptr(转移管理权,不建议使用)std::unique_ptr(防止拷贝)std::shared_ptr(引用计数)make_shared()模拟实现shared_ptrstd::shared_ptr的循环引用(导致内存泄......
  • python往windows系统的txt文件读取内容和写入内容
    继上一节windows系统打开命令行窗口,这一节开始讲述windows系统下读取txt文件内容和写入txt文件内容一、读取文件里面的内容:1、在python安装路径下创建一个文件pyfileio.txt文件,如下图所示,记录好pyfileio.txt文件的绝对路径C:\Users\Administrator\AppData\Local\Program......
  • 打卡信奥刷题(435)用C++信奥B4006[普及组/提高] [GESP202406 四级] 宝箱
    [GESP202406四级]宝箱题目描述小杨发现了nnn个宝箱,其中第iii......
  • 在CodeBolcks+Windows API下的C++面向对象的编程教程——给你的项目中添加头文件和菜
    0.前言我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程。我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识。了解我编写教程的思路,请参阅体现我最初想法的那篇文章中的“1.编程计划”:学习编程......
  • Electron-builder 是如何打包 Windows 应用的?
    本文首发同名微信公众号:前端徐徐大家好,我是徐徐。今天我们聊聊electron-builder中windows是如何打包的。前言electron-builder中windows的打包其实也是很复杂的,因为光是使用这个工具去打包就会遇到很多问题,更别说去探究里面的源码了解其原理了。但是之前已经写......
  • C++快速失败策略
    函数一种推荐的策略是,遇到错误时尽快退出。一般来说这个叫快速失败策略。比较懒的人很难一直遵循这个规则,所以不如直接写个宏吧。#include<iostream>//尽早退出#defineRET_IF(_CONDITION_,RET_VALUE,...)\do{\if(......
  • 电脑开机或打开程序提示缺少Microsoft.Windows.Storage.Core.dll文件问题
    在大部分情况下出现我们运行或安装软件,游戏出现提示丢失某些DLL文件或OCX文件的原因可能是原始安装包文件不完整造成,原因可能是某些系统防护软件将重要的DLL文件识别为可疑,阻止并放入了隔离单里,还有一些常见的DLL文件缺少是因为系统没有安装齐全的微软运行库,还有部分情况是因为......
  • SSM高校社团学生会管理系统--47676(免费领源码)可做计算机毕业设计JAVA、PHP、爬虫、APP
    摘  要本论文基于SSM框架,设计和实现了一个高校社团学生会管理系统。该系统旨在提供一个全面、高效、智能的高校社团学生会管理平台,以便管理者可以迅速且便捷地进行各项管理工作,并及时向社团成员提供准确的社团信息。  该系统通过角色划分为社团成员、社团社长和管理员......