MFC - 类封装 - 取工程内部的程序版本信息

文章目录

    • MFC - 类封装 - 取工程内部的程序版本信息
    • 概述
    • class用法
    • class实现 - CInternalVersionInfo.h
    • class实现 - CInternalVersionInfo.cpp
    • 设置程序标题
    • END

MFC - 类封装 - 取工程内部的程序版本信息

概述

在整理程序内部显示版本信息相关的实现.
程序在开发中的时候, 随便硬编码.
现在准备和程序rc资源中的版本信息对应起来, 这样的话, 程序升级后, 只需要改rc中的信息, 不用担心程序中用到的版本信息的硬编码问题.
以前也见过这种类实现, 没存货. 用了2个小时, 自己封装了一个类. 好用.

class用法

类变量定义

CInternalVersionInfo* m_pFileVersionInfo;

主程序初始化时(和UI无关, 可以尽早初始化), 初始化类变量.

CMainDlg::CMainDlg(CWnd* pParent /*=nullptr*/)
{
m_pFileVersionInfo = new CInternalVersionInfo(NULL); // 参数1是BlockHeader的name, 默认是中文rc => _T("080404b0")  
// 在类构造函数中, 就取到了工程版本信息
// 等要用工程版本信息时, 就拿这个类指针取值来用
}

如果是其他语言rc, 可以看工程实际rc的Block Header的实际值.
在这里插入图片描述
程序销毁前, 删除new出来的类实例

void CMoneyCostParserDlg::OnDestroy()
{__super::OnDestroy();// ...if (NULL != m_pFileVersionInfo){delete m_pFileVersionInfo;m_pFileVersionInfo = NULL;}
}

class实现 - CInternalVersionInfo.h

// @file CInternalVersionInfo.h
// @brief 取工程内部资源中的文件版本的所有信息, 取的信息等同于右键文件属性看到的文件版本信息#ifndef __CINTERNALVERSIONINFO_H__
#define __CINTERNALVERSIONINFO_H__/

 Version

//
//VS_VERSION_INFO VERSIONINFO
// FILEVERSION 1,0,0,1
// PRODUCTVERSION 1,0,0,1
// FILEFLAGSMASK 0x3fL
//#ifdef _DEBUG
// FILEFLAGS 0x1L
//#else
// FILEFLAGS 0x0L
//#endif
// FILEOS 0x40004L
// FILETYPE 0x1L
// FILESUBTYPE 0x0L
//BEGIN
//    BLOCK "StringFileInfo"
//    BEGIN
//        BLOCK "080404b0"
//        BEGIN
//            VALUE "CompanyName", "xx公司"
//            VALUE "FileDescription", "xxProg"
//            VALUE "FileVersion", "1.0.0.1"
//            VALUE "InternalName", "xx.exe"
//            VALUE "LegalCopyright", "(C) xx公司 20xx-2023"
//            VALUE "OriginalFilename", "xx.exe"
//            VALUE "ProductName", "progName"
//            VALUE "ProductVersion", "1.0.0.1"
//        END
//    END
//    BLOCK "VarFileInfo"
//    BEGIN
//        VALUE "Translation", 0x804, 1200
//    END
//ENDclass CInternalVersionInfo
{
public:CInternalVersionInfo(const TCHAR* pszBlockHeder);virtual ~CInternalVersionInfo();// 公开的接口// 程序顶部显示给用户看的程序标题(效果 => xx程序 Vx.x.x.x)CString getAppTitle() { return (m_csProductName + _T(" V") + m_csProductVersion); }// 共有成员CString m_csCompanyName; // VALUE "CompanyName", "xx公司" => "xx公司"CString m_csFileDescription; // VALUE "FileDescription", "xxProg" => "xxProg"CString m_csFileVersion; // VALUE "FileVersion", "1.0.0.1" => "1.0.0.1"CString m_csInternalName; // VALUE "InternalName", "xx.exe" => "xx.exe"CString m_csLegalCopyright; // VALUE "LegalCopyright", "(C) xx公司 20xx-2023" => "(C) xx公司 20xx-2023"CString m_csOriginalFilename; // VALUE "OriginalFilename", "xx.exe" => "xx.exe"CString m_csProductName; // VALUE "ProductName", "progName" => "progName"CString m_csProductVersion; // VALUE "ProductVersion", "1.0.0.1" => "1.0.0.1"private:const TCHAR* getBlockHeader() { return (LPCWSTR)m_csBlockHeader; }CString m_csBlockHeader; // BLOCK "080404b0" => "080404b0"CString get_FileInfoValue(BYTE* byData, const TCHAR* pszValueName);
};#endif // #ifndef __CINTERNALVERSIONINFO_H__

class实现 - CInternalVersionInfo.cpp

// @file CInternalVersionInfo.cpp#include "pch.h" // 其他缺的头文件放在预编译头文件中 e.g. framework.h#include <winver.h>
#pragma comment(lib, "Version.lib")#include "CInternalVersionInfo.h"CInternalVersionInfo::CInternalVersionInfo(const TCHAR* pszBlockHeder): m_csBlockHeader(_T("080404b0"))
{TCHAR szAppName[MAX_PATH];DWORD dwSize = 0;DWORD dwHandle = 0;BYTE* byData = NULL;TCHAR* lpVers = NULL;unsigned   int   uLen = 0;CString csQuery;CString csTmp;if (NULL != pszBlockHeder){m_csBlockHeader = pszBlockHeder;}_stprintf(szAppName, _T("%s.exe"), AfxGetApp()->m_pszExeName);dwSize = GetFileVersionInfoSize(szAppName, &dwHandle);byData = new BYTE[dwSize + 0x10];if (NULL != byData){memset(byData, 0, dwSize + 0x10);GetFileVersionInfo(szAppName, NULL, dwSize, byData);//        VALUE "CompanyName", "xx公司"m_csCompanyName = get_FileInfoValue(byData, _T("CompanyName"));//        VALUE "FileDescription", "xxProg"m_csFileDescription = get_FileInfoValue(byData, _T("FileDescription"));//        VALUE "FileVersion", "1.0.0.1"m_csFileVersion = get_FileInfoValue(byData, _T("FileVersion"));//        VALUE "InternalName", "MoneyCostParser.exe"m_csInternalName = get_FileInfoValue(byData, _T("InternalName"));//        VALUE "LegalCopyright", "(C) xx公司 2019-2023"m_csLegalCopyright = get_FileInfoValue(byData, _T("LegalCopyright"));//        VALUE "OriginalFilename", "xx.exe"m_csOriginalFilename = get_FileInfoValue(byData, _T("OriginalFilename"));//        VALUE "ProductName", "电商账单分析处理"m_csProductName = get_FileInfoValue(byData, _T("ProductName"));//        VALUE "ProductVersion", "1.0.0.1"m_csProductVersion = get_FileInfoValue(byData, _T("ProductVersion"));delete[]byData;}
}CInternalVersionInfo::~CInternalVersionInfo()
{}CString CInternalVersionInfo::get_FileInfoValue(BYTE* byData, const TCHAR* pszValueName)
{CString csQuery;CString csRc;TCHAR* lpVers = NULL;unsigned int uLen = 0;_ASSERT(NULL != pszValueName);csQuery.Format(_T("\\StringFileInfo\\%s\\%s"), getBlockHeader(), pszValueName);_ASSERT(NULL != byData);VerQueryValue(byData, (LPCWSTR)csQuery, (void**)&lpVers, &uLen);if ((uLen > 0) && (NULL != lpVers)){csRc = lpVers;}return csRc;
}

设置程序标题

要在程序标题上显示一个和实际程序名称版本一致的信息. 在类中封了一个常用函数getAppTitle(), 当然用到时再拼字符串也行, 不过麻烦.

BOOL CMoneyCostParserDlg::OnInitDialog()
{// ...// TODO: 在此添加额外的初始化代码if (NULL != m_pFileVersionInfo){this->SetWindowText(m_pFileVersionInfo->getAppTitle());}

END

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

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

相关文章

【jdk与tomcat配置文件夹共享防火墙设置(入站出站规则)】

目录 一、jdk与tomcat配置 1.1 jdk配置 1.2 tomcat配置 二、文件夹共享 2.1 为什么需要配置文件夹共享功能 2.2 操作步骤 2.2.1 高级共享 2.2.2 普通共享 2.3 区别 三、防火墙设置&#xff08;入站规则&出站规则&#xff09; 3.1 入站规则跟出站规则 3.2 案例…

Flask笔记

一&#xff1a;模板渲染 一般的话都序列化成字符串 二&#xff1a;项目拆分 2.1 项目拆分 app.py init.py views.py models.py 模型数据 2.2 蓝图 三&#xff1a;路由参数 3.1 String 重点 3.2 int 3.3 path 3.4 UUID 3.5 any 四&#xff1a;请求方式 五&#xff1a;Requ…

oracle-sga-shared_pool

shared pool 缓冲sql语句和执行计划 shared pool由三部分组成 free libray&#xff1a;缓存sql执行计划 row cathe &#xff1a;缓存数据字典 硬解析&#xff1a;1判断语法2判断对象是否存在3有没有权限4 从n个执行方案中选出最优解&#xff0c;生成执行计划&#xff0c;这一…

C#的checked关键字判断是否溢出

目录 一、定义 二、示例&#xff1a; 三、生成&#xff1a; 一、定义 使用checked关键字处理溢出。 在进行数学运算时&#xff0c;由于变量类型不同&#xff0c;数值的值域也有所不同。如果变量中的数值超出了变量的值域&#xff0c;则会出现溢出情况&#xff0c;出现溢出…

【Echarts】使用echarts和echarts-wordcloud生成词云图

一、下载echarts和echarts-wordcloud 地址&#xff1a;https://download.csdn.net/download/qq_25285531/88663006 可直接下载放在项目中使用 二、词云数据 词云数据是对象的格式&#xff0c;可以从后端获取&#xff0c;这里以下面数据为例 $list3 array(array(name >…

Python学习 - 爬虫系统架构设计

主要业务流程 初始请求请求过滤器请求队列响应下载器数据解析器数据清洗器存储器 设计图 master slave&#xff1a;master控制队列&#xff0c;过滤&#xff0c;传递任务&#xff1b;slave负责执行 缺点&#xff1a;master和slave端交互数据频繁&#xff0c;slave的数据进出…

如何理解Go语言的数组

什么是数组 首先下一个定义&#xff0c;数组是对线性的内存区域的抽象。高维数组和一维数组有着同样的内存布局。&#xff08;大学生考试的时候别借鉴哈&#xff0c;这是自己下的定义&#xff0c;相当于是一篇议论文的论点。&#xff09; 线性的内存区域说白了就是连续的内存…

【Kubernetes】什么是 kubectl ?

什么是 kubectl &#xff1f; 1.什么是 kubectl &#xff1f;2.Kubernetes 内部结构3.Kubernetes API 的作用 1.什么是 kubectl &#xff1f; 在学习如何更有效地使用 kubectl 之前&#xff0c;您应该对它是什么以及它如何工作有一个基本的了解。从用户的角度来看&#xff0c;…

贪心算法—会议安排

与其明天开始&#xff0c;不如现在行动&#xff01; 文章目录 1 安排会议1 题目描述2 解决思路3 代码实现 &#x1f48e;总结 1 安排会议 1 题目描述 一些项目要占用一个会议室宣讲&#xff0c;会议室不能同时容纳两个项目的宣讲。 给你每一个项目开始的时间和结束的时间 你来…

leetcode贪心算法题总结(三)

本章目录 1.合并区间2.无重叠区间3.用最少数量的箭引爆气球4.整数替换5.俄罗斯套娃信封问题6.可被三整除的最大和7.距离相等的条形码8.重构字符串 1.合并区间 合并区间 class Solution { public:vector<vector<int>> merge(vector<vector<int>>&…

【并发】AtomicInteger很安全

AtomicInteger 简介与常规用法 AtomicInteger 是 Java 中 java.util.concurrent.atomic 包下的一个类。用于实现原子操作的整数。它是一个基于CAS&#xff08;Compare-And-Swap&#xff09;实现的原子整数类。它提供了一系列的原子操作&#xff0c;确保对整数的操作是原子性的&…

C#高级 08Json操作

1.概念 Json是存储和交换文本信息的语法。类似于XML。Json比XML更小、更快、更易解析。Json与XML一样是一种数据格式。Json是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。Json采取完全独立于语言的文本格式&#xff0c; 但是也使用了类似于C语言的习惯。这些特性使…