SDK入门

news2025/7/17 9:37:17

目录

控制台程序 与 Windows程序

Windows程序与Console程序入口的区别

代码编写区别

SDK 基本概念

VS2019 SDK

VS2019创建桌面应用程序

ANSI 与 Unicode

TCHAR char wchat_t

解决编码的影响

MessageBox()

第一个SDK程序

MessageBox函数


控制台程序 与 Windows程序

控制台机制:主要使用顺序的,过程驱动的程序设计方法顺序的,过程驱动的程序有一个明显的开始,明显的过程及一个明显的结束,因此程序能直接控制程序事件或过程的顺序。虽然在顺序的过程驱动的程序中也有很多处理异常的方法,但这样的异常处理也仍然是顺序的,过程驱动的结构。

Windows程序:消息驱动,不由事件的顺序来控制,而是由事件的发生来控制所有的事件都是无序的,所为一个程序员,在你编写程序时,你并不知道用户先按哪个按纽,也不知道程序先触发哪个消息。你的任务就是对正在开发的应用程序要发出或要接收的消息进行排序和管理。事件驱动程序设计是密切围绕消息的产生与处理而展开的,一条消息是关于发生的事件的消息。

Windows程序与Console程序入口的区别

代码编写区别

Windows应用程序的编程就围绕这两个部份进行的。其中WinMain函数为应用程序的入口点,它的名字一定要是WinMain。

在Windows中,应用程序通过要求Windows完成指定操作,而承担这项通信任务的API函数就是Windows的相应窗口函数WindowProc。

在dos里,程序能直接控制事件的发生顺序,结果等。而在Windows里,应用程序不直接调用任何窗口函数,而是等待Windows调用窗口函数,请求完成任务或返回信息。为保证Windows调用这个窗口函数,这个函数必须先向Windows登记,然后在Windows实施相应操作时回调,所以窗口过程函数又称为回调函数。WindowProc是一个主回调函数,Windows至少有一个回调函数。

SDK 基本概念

SDK —— software development kit 软件开发包(套件)

SDK(软件开发工具包)是一组用于开发软件的工具、库和文档的集合。它提供了一系列的接口、功能和示例代码,以帮助开发人员更快速、更高效地构建应用程序。这里我们主要学习使用SDK开发GUI界面

通常情况下,SDK会包含以下内容:

  1. 库文件:SDK提供一组现成的库文件,包含了各种功能模块和工具,例如网络通信、图形处理、数据存储等。开发人员可以直接调用这些库文件,加快开发速度,并且可以避免从头开始编写复杂的功能模块。

  2. API文档:SDK通常会提供详细的API文档,其中包含了所有可用的函数、类和方法的说明。开发人员可以通过查阅API文档了解每个接口的用法、参数说明以及返回值,从而正确地使用SDK提供的功能。

  3. 示例代码:SDK通常提供一些示例代码,展示如何使用SDK进行开发。这些示例代码可以作为开发人员学习和参考的范例,帮助他们快速上手并理解各种功能的实现方式。

  4. 工具软件:一些SDK还会提供一些辅助性的工具软件,用于调试、测试、模拟等目的。这些工具可以简化开发过程中的一些任务,提高开发效率。

SDK可以用于各种不同的应用领域,如移动应用开发、Web开发、物联网开发等。通过使用SDK,开发人员可以快速构建出功能完善、稳定可靠的软件,并且降低了开发过程中的复杂性和风险。

VS2019 SDK

SDK被集成在VS中,以VS2019为例:

安装位置:C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC

查看方式:项目属性 -- VC++目录 -- 库目录

VS2019创建桌面应用程序

开发参考文档:使用 Win32 API 生成桌面 Windows 应用 - Win32 apps | Microsoft Learn

创建Windows桌面应用程序,即可使用SDK开发

项目依赖的库

ANSI 与 Unicode

ANSI(American National Standards Institute)编码是指使用ASCII码表的字符编码方式,ANSI编码的字符范围是0-127,共计128个字符。其中包括了大写和小写字母、数字、标点符号以及一些控制字符。ANSI编码是单字节编码,每个字符只占用一个字节的存储空间。这意味着ANSI编码只能表示有限的字符集,并且不支持多国语言的字符。

Unicode编码是一种用于表示文字字符的标准编码系统。它旨在统一世界上所有的字符,包括各种语言的字母、符号、标点符号和特殊字符等。Unicode编码使用了固定的位数来表示每个字符,常见的有UTF-8、UTF-16和UTF-32等不同的编码方案。

  • UTF-8使用变长字节表示字符,通常使用1至4个字节来表示不同的字符。UTF-8编码保留了ASCII码表中的字符,只需一个字节表示,这使得UTF-8与ASCII兼容。
  • UTF-16采用固定的16位(2字节)来表示大部分常用的字符,对于非常用字符采用双字节或四字节的方式表示。UTF-16编码可以兼容ASCII编码,但与UTF-8相比,存储空间可能更大。
  • UTF-32则使用固定的32位(4字节)来表示每个字符,不论字符是否为常用字符。UTF-32编码能够提供与其他Unicode编码方案之间的更好的互操作性,但也会占用更多的存储空间。

ASNI对比Unicode:

  1. ASNI仅适用于英语,占空间比Unicode更小
  2. Unicode兼容所有国家语言,但是占空间大

VS2019配置项目编码:两者的区别就是编译器会自动加上宏定义

TCHAR char wchat_t

THAR:就是当你的字符设置为什么就是什么

  • 程序编译为 ANSI, TCHAR 就是相当于 CHAR
  • 当程序编译为 UNICODE, TCHAR 就相当于 WCHAR

如果在程序中既包括ANSI又包括Unicode编码,需要包括头文件tchar.h。TCHAR是定义在该头文件中的宏,它视你是否定义了_UNICODE宏而定义成: 

  • 定义了_UNICODE:    typedef wchar_t TCHAR ; 
  • 没有定义_UNICODE: typedef char TCHAR ;
#ifdef UNICODE 
typedef char TCHAR; 
#else 
typede wchar_t TCHAR; 
#endif

_T( )也是定义在该头文件中的宏,视是否定义了_UNICODE宏而定义成: 

  • 定义了_UNICODE:    #define _T(x) L##x 
  • 没有定义_UNICODE: #define _T(x) x 

注意:如果在程序中使用了TCHAR,那么就不应该使用ANSI的strXXX函数或者Unicode的wcsXXX函数了,而必须使用tchar.h中定义的_tcsXXX函数

char :单字节变量类型,最多表示256个字符,

wchar_t :宽字节变量类型,用于表示Unicode字符,它实际定义在<string.h>里:typedef unsigned short wchar_t。

为了让编译器识别Unicode字符串,必须以在前面加一个“L”

wchar_t a[] = L"Hello!" ;

宽字节类型每个变量占用2个字节,故上述数组a的sizeof(a) = 14

 在字符串前加一个L作用: 
 如  L"我的字符串"    表示将ANSI字符串转换成unicode的字符串,就是每个字符占用两个字节。 

  strlen("asd")   =   3;   
  strlen(L"asd")   =   6; 

_T宏可以把一个引号引起来的字符串,根据你的环境设置,使得编译器会根据编译目标环境选择合适的(Unicode还是ANSI)字符处理方式 

  • 如果你定义了UNICODE,那么_T宏会把字符串前面加一个L。这时 _T("ABCD") 相当于 L"ABCD" ,这是宽字符串。 
  • 如果没有定义,那么_T宏不会在字符串前面加那个L,_T("ABCD") 就等价于 "ABCD" 

TEXT,_TEXT 和_T 一样的 ,如下面三语句:   

  TCHAR   szStr1[]   =   TEXT("str1");   
  char   szStr2[]   =   "str2";   
  WCHAR   szStr3[]   =   L("str3");   

那么第一句话在定义了UNICODE时会解释为第三句话,没有定义时就等于第二句话。但二句话无论是否定义了UNICODE都是生成一个ANSI字符串,而第三句话总是生成UNICODE字符串。 

解决编码的影响

背景:一家公司A,有一款应用,要推广到其他国家,为了兼容语言,需要把原先ASNI编码替换为Unicode。

在SDK中,很多函数都有两种形态,比如:MessageBox,这个本质是一个宏,有两个函数,分别是:MessageBoxA,MessageBoxW分别适合于不同的字符集,实际上在操作系统底层A的使用还是要先转化为W

在上述背景,如何解决字符集使用带来的问题?

方式一:直接全部使用A;或者全部使用W,字符串前需加L

MessageBoxA(NULL,"ANSI","51asm",MB_YESNO)
MessageBoxW(NULL,L"Unicode",L"51asm",MB_YESNO)

方式二:使用宏,MessageBox本质是一个宏

#ifdef UNICODE
#define MessageBox  MessageBoxW
#else
#define MessageBox  MessageBoxA
#endif // !UNICODE

若有定义# define UNICODE,则为W,否则为A

//#define UNICODE

#include <Windows.h>

int WINAPI WinMain(HINSTANCE hInstace, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	MessageBox(NULL, "Hello World", "51asm", MB_YESNO);
	return 0;
}


#define UNICODE

#include <Windows.h>

int WINAPI WinMain(HINSTANCE hInstace, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	MessageBox(NULL, L"Hello World", L"51asm", MB_YESNO);
	return 0;
}

项目依然很难维护

方式三:使用TCHAR,需包含<tchar.h>,也类似于上面,是一个宏定义

ASNI版本

#include <Windows.h>
#include <tchar.h>

int WINAPI WinMain(HINSTANCE hInstace, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	MessageBox(NULL, _T("Hello World"), _T("51asm"), MB_YESNO);
	return 0;
}


Unicode版本
#define _UNICODE
#define UNICODE

#include <Windows.h>
#include <tchar.h>

int WINAPI WinMain(HINSTANCE hInstace, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	MessageBox(NULL, _T("Hello World"), _T("51asm"), MB_YESNO);
	return 0;
}

这样也有缺点,很多函数无法使用,例如:strcpy对应ASNI,wtrcpy对应Unicode,需要用_mbscpy

方式四:使用系统库提供,并默认使用Unicode,建议使用


#include <Windows.h>

int WINAPI WinMain(HINSTANCE hInstace, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	TCHAR szBuf[] = { TEXT("HELLO 你好") };
	MessageBox(NULL,szBuf , L"51asm", MB_OK);
	return 0;
}

现在,普通公司都是直接Unicode

wchar_t szBuf[] = {L"Hello 你好"};
MessageBoxW(NULL,szBuf,L"51asm",MB_OK);

MessageBox()

int MessageBox(
  [in, optional] HWND    hWnd,
  [in, optional] LPCTSTR lpText,
  [in, optional] LPCTSTR lpCaption,
  [in]           UINT    uType
);

第一个SDK程序


#include <Windows.h>
#include <tchar.h>

int WINAPI WinMain(HINSTANCE hInstace, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	TCHAR szBuf[] = { TEXT("请点击") };
	TCHAR szTitle[] = { TEXT("51 asm") };
	int nType = MB_YESNO;
	int nRet = MessageBox((HWND)1, szBuf, szTitle, nType);
	DWORD dwError = GetLastError();
	if (dwError != ERROR_SUCCESS) {
		MessageBox(NULL, TEXT("MessageBox调用错误" ), szTitle, nType);
		return 0;
	}
	if (nRet == IDYES) {
		MessageBox(NULL, TEXT("确定"), szTitle, MB_OK);
	}
	else if (nRet == IDNO) {
		MessageBox(NULL, TEXT("取消"), szTitle, MB_OK);
	}

	return 0;
}

结果如下:

MessageBox函数

ASNI版本

WINUSERAPI
int WINAPI MessageBoxA(
    _In_opt_ HWND hWnd,
    _In_opt_ LPCSTR lpText,
    _In_opt_ LPCSTR lpCaption,
    _In_ UINT uType);

Unicode版本

WINUSERAPI int WINAPI
MessageBoxW(
    _In_opt_ HWND hWnd,
    _In_opt_ LPCWSTR lpText,
    _In_opt_ LPCWSTR lpCaption,
    _In_ UINT uType);
  • _In_opt_ 是一个预处理宏,表示该参数是可选的,可以传入 NULL 或默认值。在函数调用时,可以选择是否提供该参数的值。如果不提供该参数或将其设置为 NULL,函数将使用默认行为或忽略该参数。
  • HWND 是 Windows 平台上的一个数据类型,它代表了一个窗口句柄(Handle to Window)。窗口句柄是用来标识和操作窗口的唯一标识符。在 Windows 操作系统中,每个窗口都有一个对应的窗口句柄。通过使用窗口句柄,程序可以与指定的窗口进行交互,如改变窗口的属性、发送消息给窗口、获取窗口的信息等等。窗口句柄通常是由系统分配和管理的,开发者不能直接创建或销毁窗口句柄。可以通过调用系统提供的函数来获取窗口句柄,如 CreateWindowFindWindow 等。
  • typedef const CHAR *LPCSTR;,LPCWSTR 类型的变量实际上是一个指向 Unicode 字符串常量的指针,而且指向的内容不可修改。如果需要修改字符串内容,则需要使用另一个类型 LPWSTR,其中 W 表示宽字符。
  • typedef unsigned int        UINT;

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

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

相关文章

PPC-R22.1N-T-Q2-G2-NN-FW 使用反馈来解决误差和系统干扰

PPC-R22.1N-T-Q2-G2-NN-FW 使用反馈来解决误差和系统干扰 伺服机构是自动控制系统&#xff0c;用于从数控机床&#xff0c;机器人技术&#xff0c;仓库自动化还有更多。与开环系统相比&#xff0c;带伺服驱动器的闭环系统在运动应用中具有更高的可靠性和精度。怎么会&#xff…

Spring系列综合

目录 1 Spring介绍2 Spring核心技术3 Spring入门案例3.1 Spring jar包下载(了解)3.2 通过mven方式导入jar包3.3 编辑application.xml文件3.4 编辑测试类 4 Spring核心技术IOC4.1 什么是IOC4.2 IOC实现原理 5 Spring创建对象方式5.1 静态工厂模式5.1.1 编辑静态工厂类5.1.2 编辑…

请求分页管理方式(页表机制,缺页中断,地址变换)

请求分页存储管理与基本分页存储管理的主要区别: 在程序执行过程中&#xff0c;当所访问的信息不在内存时&#xff0c;由操作系统负责将所需信息从外存调入内存&#xff0c;然后继续执行程序。&#xff08;操作系统要提供请求调页功能&#xff0c;将缺失页面从外存调入内存)若…

MapReduce任务个数如何影响执行效率?性能优化从这里做起

在正文开始之前&#xff0c;请先来回答一下这个问题&#xff1a; 题目&#xff1a;输入为3个文件&#xff0c;a.txt 300MB,b.txt 100MB,c.txt 58.MB&#xff0c;使用MapReduce的example程序&#xff0c;计算Wordcount&#xff0c;请问&#xff0c;应该有多少个MapTask&#xf…

分享一种非隔离控制三象限双向可控硅的产品级电路

上图是一款在美国卖得很火的挂烫机的电源电路和双向可控硅控制电路&#xff0c;可以看到电源部分采用的是阻容降压&#xff0c;阻容降压电路适用于低成本小电流的应用场合&#xff0c;根据电容容抗的计算公式Xc1/(2πfC) 可算出容抗大小&#xff0c;&#xff08;f为市电的频率5…

编译和链接(小白初理解)

目录 1. 翻译环境和运⾏环境 1.2翻译环境 2. 翻译环境&#xff1a;预编译编译汇编链接 2.1预处理&#xff08;预编译&#xff09;阶段 2.2编译 2.2.1词法分析 2.2.2语法分析 2.2.3语义分析 2.3 汇编 2.4 链接 3. 运⾏环境 1. 翻译环境和运⾏环境 翻译环境指的是&a…

设计模式截图记录

设计模式截图记录

GeoServer改造Springboot启动五(解决接口返回xml而不是json)

请求接口返回的是xml&#xff0c;而不是我们常用的json&#xff0c;问题呈现如下图 40 图 40请求接口返回XML 在RequestMapping注解上增加produces {MediaType.APPLICATION_JSON_UTF8_VALUE} 图 41增加produces

AP8100 DC-DC 升压恒压电源管理芯片

说明 AP8100 是一款外围电路简单的 BOOST 升压恒压控 制驱动芯片&#xff0c;适用于 2.8-40V 输入电压范围的升压恒 压电源应用领域&#xff0c;启动电压可以低至 2.5V。 芯片会根据负载的大小自动切换 PWM &#xff0c; PFM 和 BURST 模式以提高各个负载端的电源系统效率。 本…

跨境电商系统源码分享,助力企业快速搭建电商平台

在如今的全球化时代&#xff0c;跨境电商成为了许多企业拓展国际市场的重要途径。然而&#xff0c;搭建一个完善的跨境电商系统并不是一件容易的事情。幸运的是&#xff0c;有许多跨境电商系统的现成源码可供使用&#xff0c;以解决企业在电商过程中遇到的各种难题。 一、现成源…

[架构之路-239]:目标系统 - 纵向分层 - 中间件middleware

目录 前言&#xff1a; 一、中间件概述 1.1 中间件在软件层次中的位置 1.2 什么是中间件 1.3 为什么需要中间件 1.4 中间件应用场合&#xff08;应用程序不用的底层需求&#xff1a;计算、存储、通信&#xff09; 1.5 中间件分类 - 按内容分 二、嵌入式系统的中间件 2…

基于SpringBoot的漫画动漫网站

基于SpringBootVue的漫画动漫网站的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 动漫详情 排行榜 通知公告 管理员界面 摘要 基于SpringBoot的漫画动漫网…

confluence8.5.1版本升级到8.5.2

由于confluence的漏洞CVE-2023-22515的出现&#xff0c;现在需要升级版本 查看漏洞已修复版本&#xff1a; 需要升级到8.5.2 下载软件包&#xff1a; https://product-downloads.atlassian.com/software/confluence/downloads/atlassian-confluence-8.5.2-x64.bin 完成后上传…

浅谈新能源电动汽车充电设施的建设及运营平台分析

安科瑞 崔丽洁 摘要&#xff1a;在社会经济发展的新时期&#xff0c;我国城市化的水平也在随之不断的提高&#xff0c;使我国制造业迅速崛起&#xff0c;并加剧了该行业的竞争力&#xff0c;要想使企业在竞争中占据有力的位置&#xff0c;企业就要顺应时代发展的潮流&#xff0…

Linux之iostat溯源diskstats

iostat 默认输出解析详细输出解析关键指标 diskstats字段解析await的计算来源计算方法 svctm计算来源计算方法 util的计算来源计算方法 系统级别的IO工具 默认输出解析 iostat%usr CPU在用户模式下的时间百分比%nice CPU处在带NICE值的用户模式下的时间百分比%system CPU在系统…

11+肠道微生物群+孟德尔随机化

今天给同学们分享一篇孟德尔随机化的生信文章“Causal relationship between gut microbiota and cancers: a two-sample Mendelian randomisation study ”&#xff0c;这篇文章于2023年2月21日发表在 BMC Med 期刊上&#xff0c;影响因子为11.15。 观察性研究和临床试验的…

《动手学深度学习 Pytorch版》 8.7 通过时间反向传播

8.7.1 循环神经网络的梯度分析 本节主要探讨梯度相关问题&#xff0c;因此对模型及其表达式进行了简化&#xff0c;进行如下表示&#xff1a; h t f ( x t , h t − 1 , w h ) o t g ( h t , w o ) \begin{align} h_t&f(x_t,h_{t-1},w_h)\\ o_t&g(h_t,w_o) \end{ali…

实验2.1.3 交换机的远程配置

实验2.1.3 交换机的远程配置 一、任务描述二、任务分析三、实验拓扑四、具体要求五、任务实施&#xff08;一&#xff09; password认证1. 进入系统视图重命名交换机的名称为SWA2. 关闭干扰信息3. 设置vty为0-44. 设置认证方式为password5. 设置登录密码为&#xff1a;huawei6.…

芯片测试一般包含哪些方面,ATECLOUD如何部署进行测试?

芯片测试主要包括以下方面&#xff1a; 功能测试&#xff1a;检查芯片是否按照预期进行功能操作。这涉及到对芯片内部的各种功能模块进行测试&#xff0c;以确保它们能够正常工作。 性能测试&#xff1a;检查芯片在特定工作负载或条件下的性能。这包括测试芯片在不同频率、电…