API入门系列之五 -一个正儿八经的SDK程序

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

原创文章,转载请注明作者及出处。

首发

http://blog.csdn.net/beyondcode

http://www.cnblogs.com/beyond-code/

http://hi.baidu.com/beyondcode

 

SDK编程群号:81543028 欢迎加入

上一篇,讲了一个简单的SDK程序的多种版本的编写,弹出了一个窗口,显示了我们计算1到10的结果,计算的程序不是重点,重点在于,一:让大家认识到Unicode版本的程序和ASCII版本的程序在编程方面的区别,以及怎么样编写出通用代码的程序。二:怎么样运用API或者c++库函数格式化非字符数据到一个字符串中显示出来。

不过,那个相当简单的程序,还算不上是一个正儿八经的SDK程序,也就是说还不是一个纯爷们儿,因为我们并亲自完成一个SDK程序的经典步骤。而是调用了一个MessageBox API函数,这个函数虽然使用简单,但是在它的内部,那可是相当复杂啊~~~。怎么个复杂法,具体的我不知道,但是我知道的是一个SDK程序的经典步骤它是都用到了的,什么是编写SDK程序的经典步骤呢?新手朋友们听好了哦,现在我就告诉你。

第一步:注册窗口类

第二步:创建窗口

第三步:消息循环

第四步:编写窗口消息处理函数

上面我所说的,听起来都比较专业,下面我就解释一下,什么是注册窗口类呢?注册窗口类就是使用一个 窗口类结构体(WNDCLASSEX) 来描述一类窗口,这类窗口具有相同的属性,也就是你在结构体WNDCLASSEX中指定的那些值。只要是用这个窗口类创建的窗口都具有这些特性。至于WNDCLASS能描述哪些特性,下面会具体讲,这里你只要了解是用一个名叫WNDCLASSEX的结构体来描述一个窗口的类别。

创建窗口应该比较好理解吧,就是创建一个具体的窗口,好像是一句废话嘛。也就是说这个窗口是根据一个窗口类而创建的,不是凭空而造的。意思是你要创建一个窗口,那么必须要有一个已经注册的窗口类。

对于前两步,我打一个比方,就好比你要造一辆车,那们第一步首先是干什么? 当然是设计图纸啦,图纸上就有说明这种车有哪些特性。然后第二步才是根据这个图纸来创建一个具体的看得见的车。所以我上面说的注册窗口类就好比设计窗口的图纸,然后就是根据这个窗口的图纸来创建一个具体的窗口。都说成这样了,应该明了了吧~~

至于消息循环,就是创建的窗口随时都有可能发生很多事情,那么发生的这些事情怎么通知你呢?比如窗口最小化了,窗口大小改变了,怎么通知你呢?  其实就就是通过消息循环不断的取得窗口所发生的事情,然后以消息的形式发送给我们后面要介绍的窗口消息处理函数。

消息处理函数呢就是我们程序员负责编写代码对具体的消息进行具体的处理,当然你也可以不处理,交给系统的默认处理函数来处理。

对于这两步,我也打一个比方。消息循环就好比汽车的一个总传感器,它源源不断的将汽车内部所发生的事情以消息的形式通过仪表板传达给开车的人,开车的人根据具体的事情而采取具体的操作,当然你也可以不操作,无动于衷,对于windows消息来说,不操作倒没有什么,而对于开车的人来说,不操作的后果就不好说了。 在这里,这个总传感器就相当于SDK程序的消息循环,不断的发送消息,而开车的人就相当于窗口消息处理函数,负责处理各种消息。明白了吧,还不明白的话就看看下面的具体的程序吧,也需还有最后一丝希望可以让你恍然大悟。

讲了正儿八经的SDK程序的经典步骤后,我们进入正式的代码阶段,通过代码结合上面所讲理论进一步巩固知识。我讲逐步讲解并逐步编写一个自己注册窗口类,创建窗口,带消息循环,并自己编写消息处理过程的程序。

首先给出程序框架

/* BY beyondcode */

#include <windows.h>

#include <tchar.h>

LRESULT CALLBACK WinMessageProcHWND hwndUINT msgWPARAM wParamLPARAM lParam );

int WINAPI _tWinMainHINSTANCE hInstanceHINSTANCE hPrevInstanceLPTSTR lpCmdLineint nShowCmd )

{

return 0;

}

第一个函数声明,返回类型为LRESULT,本质经查看是long,然后函数调用约定CALLBACK和WINAPI是一样的,都是__stdcall,说明函数调用相关的约定,不必深究。至于为什么用CALLBACK是为了意思显而易见,表示是回调函数,什么是回调函数?也就是系统负责调用的,不必你亲自调用的函数,所以你在你的程序里是看不到调用WinMessageProc这个函数的代码的,你只负责编写它的代码,至于调用,系统会在有消息的时候自动调用它。WinMessageProc的参数类型和个数是规定好了的,不然系统怎么知道怎么掉用,所以不能更改。

再解释一下这四个参数吧,第一个参数是一个窗口的句柄,也就是告诉你,是哪个窗口的消息,第二个参数是消息的类型,告诉你是什么消息,第三个和第四个参数是这个消息所带的一些额外的但是必须的数据。你在窗口消息处理函数中只使用他们就可以了,他们的值都是系统传递进来的。你只是根据他们来判断是哪个窗口的什么消息,并且获取该消息的额外参数信息。

有了程序框架,我们来第一步,注册一个窗口类

   //注册一个名叫MyWindowClass的窗口类

WNDCLASSEX wc;

wc.cbSize sizeofwc );

wc.style CS_VREDRAW | CS_HREDRAW;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);

wc.hCursor LoadCursorNULLIDC_ARROW );

wc.hIcon LoadIconNULLIDI_APPLICATION );

wc.hIconSm LoadIconNULLIDI_APPLICATION );

wc.hInstance hInstance;

wc.lpfnWndProc WinMessageProc;

wc.lpszMenuName NULL;

wc.lpszClassName _T("MyWindowClass");

if( !RegisterClassEx( &wc ) )

{

MessageBoxNULL_T("注册窗口类出错"), _T("出错"), MB_OK );

return 0;

}

上面的WNDCLASS的各个成员值我就不一一介绍是什么含义,MSDN上面讲的非常清楚,我只讲一两个比较重点的,第一个lpszClassName这个成员,我们给它指定的是_T("MyWindowClass")这个值,这是指定这个窗口类的名字是什么,因为下面的创建窗口会用到这个名字。

lpfnWndProc这个成员是WinMessageProc这个函数,这是指定这个窗口类所创建的窗口的消息处理函数是哪一个,我们这里指定的是WinMessageProc。其他的参数我就不啰嗦了,各位不懂的MSDN一下或者在群里来交流一下。

指定了这个窗口类有哪些特性后就完了?当然没有,没有注册怎么使用啊,所以还需要注册,注册调用RegisterClassEx这个API函数,将刚才的WNDCLASS变量的地址传给它就可以进行注册了,如果注册失败,返回值为零,成功的话返回值为非零。

注册了窗口类,我们来第二步,创建一个窗口。代码如下:

// 根据上面注册的一个名叫MyWindowClass 的窗口类创建窗口

HWND newWind = CreateWindowEx( 0L, _T("MyWindowClass"), _T("beyondcode"), WS_OVERLAPPEDWINDOW, 0, 0, 200, 200, NULLNULLhInstanceNULL );

ifNULL==newWind )

{

MessageBoxNULL_T("创建窗口出错"), _T("出错"), MB_OK );

return 0;

}

ShowWindownewWindnShowCmd );

UpdateWindownewWind );

可见,创建窗口用CreateWindowEx这个API函数,它的第一个参数是扩展样式,我们这里不设置扩展样式,所以传递0L,第二个参数就是窗口类的名字,我们这里指定我们上面已经注册了的那个名叫MyWindowClass的窗口类,第三个参数是窗口的标题,随便设置,第四个参数是窗口的样式,我们这里设置的是WS_OVERLAPPEDWINDOW,一般主窗口都用这个样式,就是有最大化,最小化框,有标题栏,有系统菜单。。具体的可以参见MSDN,第五个,六个,七个,八个参数分别指定窗口的初始坐标和长宽,第九个参数指定父窗口是哪个,这里没有父窗口,所以传递NULL,第十个参数指定菜单的句柄,我们这里不设置菜单,所以传递NULL,第十一个是应用程序句柄,用WinMain传递进来的那个hInstance参数,第十二个参数表示额外数据,不设置,所以为NULL。

这个API函数有点复杂,不过用熟悉了也就不觉得了。这样我们就创建了一个窗口,返回值是一个窗口的句柄,如果是NULL的话,说明创建窗口失败了,如果不是NULL的话,说明成功了。

光创建成功了还不行,如果你不显示和更新它,你还是看不到它,所以需要调用2个API函数,ShowWindow和UpdateWindow,参数就是刚才创建成功的那个窗口的句柄,至于ShowWindow的第二个参数是指显示的类型,是最大化显示呢还是最小化显示呢,不过在程序中第一次调用ShowWindow必须使用WinMain所传递进来的参数的第四个参数的值。这是MSDN上说的~

窗口创建成功了,下面一步是消息循环了,消息循环说起来复杂,其实代码挺简单的,而且基本格式固定,如下:

//消息循环

MSG msg;

whileGetMessage( &msgNULL, 0, 0 ) )

{

TranslateMessage( &msg );

DispatchMessage( &msg );

}

看到了吗? 一直在一个循环里面,一直调用GetMessage,只要GetMessage所取得的消息不是WM_QUIT的话,那么GetMessage的返回值就不是0,那么循环就一直进行。在循环内部,将GetMessage取得的消息传递给TranslateMessage和DispatchMessage两个API函数进行处理.其中DispatchMessage就是将消息发送给了对应的窗口的窗口消息处理函数进行处理。至于TranslateMessage呢,则进行一些消息的转换,可以先不深究。

最后就是编写窗口消息处理函数的代码了,你需要处理那些消息,那么你就编写处理那些消息的代码,对于你不处理的消息,则统统交给一个叫DefWindowProc的API函数进行默认的处理。

LRESULT CALLBACK WinMessageProcHWND hwndUINT msgWPARAM wParamLPARAM lParam )

{

switch ( msg )

{

case WM_DESTROY:

{

PostQuitMessage( 0 );

break;

}

default:

return DefWindowProchwndmsgwParamlParam );

}

return 0;

}

这里我们只处理了WM_DESTROY这个消息,这个消息是在窗口被销毁的时候发送给窗口消息处理函数的,在窗口处理函数中,我们判断这个消息是不是WM_DESTROY,如果是,就调用PostQuitMessage这个API函数,如果是其他消息,我们就不管,将参数全部传递给DefWindowProc这个函数进行处理。

而PostQuitMessage这个API函数的功能就是发送一个WM_QUIT的消息。而我们前面说到过, 在消息循环中GetMessage一旦取得WM_QUIT这个消息,就返回值为0,那么消息循环也就结束了,进而整个程序也就结束了,如果在这里我们处理WM_DESTORY函数,但是不调用PostQuitMessage,那么结果会怎样呢,读者朋友们思考一下~~

好了,到这里,这个什么功能也没有的SDK程序也就完了,它只显示一个带有标题栏的可最大化,最小化的窗口,除了能够关闭它,你几乎不能进行其他任何操作,因为我们除了处理窗口销毁这个消息,其他任何消息我们都没处理。

这篇文章中的源代码在VS2008,windows 7平台下编写并完成编译运行,我会将源代码上传到群空间或其他地方,以方便新手朋友们对比学习~ 

 

C++边缘AI智能体框架Agents-SDK:本地优先的高性能开发指南 在嵌入式与物联网领域,边缘计算正成为降低延迟、保障数据隐私的关键技术。其核心原理在于将计算任务从云端迁移至网络边缘的设备端执行,从而减少网络传输开销,实现实时响应。这一技术价值在工业自动化、智能终端等对时延和可靠性要求极高的场景中尤为突出。随着大语言模型(LLM)能力的普及,如何在资源受限的边缘设备上高效部署和运行AI智能体,成为工程实践的新挑战。本文聚焦的Agents-SDK,正是一个采用现代C++20标准构建的原生框架,它通过模块化设计、多模型供应商支持及Bazel构建系统,为开发者提供了在边缘侧开发高 阅读详情

相关推荐

Android设备完整性检测:Play Integrity API原理与实战应用

设备完整性验证是移动应用安全领域的核心技术,它通过评估设备硬件、软件及运行环境的可信状态,为应用提供安全准入依据。其核心原理在于构建多层次信任链,从系统底层到应用层进行动态检测,确保设备未被恶意篡改。这项技术的价值在于有效对抗Root、Bootloader解锁、应用重打包等安全威胁,保障金融支付、版权保护、游戏反作弊等高敏感场景的业务安全。在实际应用中,开发者常借助Play Integrity API等标准化方案进行设备状态评估,并结合自定义检测逻辑形成分层防御策略。本文聚焦Android平台的设备完整性检

weixin_33895695的博客 401

Windows 60个常用API

Windows 60个常用API附录A 常用的Windows API 调用本附录列出了PowerBuilder 常用Windows API 系统调用同时给出了这些函数的功能说明方式以及应用示例下表首先给出常用API 调用的名称和扼要功能读者需要详细了解某个函数的声明格式和示例时可通过序号在本附录中找到相应说明表A 常用的Windows API 系统序号 函数 功能1 Arc() 在窗口上画一条弧线2 Beep() 让计算机按指定的频率和周期发声3 BringWindowToTop() 将窗口放置在最前面4

haiou327’blog 2187

Windows API函数大全(Windows编程参考手册)

文档声明: 以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。感谢各位的参考查看。 笔记资料仅供学习交流使用,转载请标明出处,谢谢配合。 如果存在相关知识点的遗漏,可以在评论区留言,看到后将在第一时间更新。 作者:Aliven888 ...

eli的博客 2万+

Windows API函数大全(精心总结)_winapi函数大全

RemoveDirectory删除指定目录SearchPath查找指定文件SetCurrentDirectory设置当前目录SetEndOfFile针对一个打开的文件,将当前文件位置设为文件末尾SetFileAttributes设置文件属性SetFilePointer在一个文件中设置当前的读写位置SetFileTime设置文件的创建、访问及上次修改时间SetHandleCount这个函数不必在win32下使用;即使使用,也不会有任何效果。

2401_84447233的博客 3783

Windows API 入门(什么是 Windows API?、 实例程序Windows API函数有几个?)

Windows API又叫做 API 函数, 是 Windows 的核心,从技术上讲,我们技术人员在 Windows 操作系统里做技术开发,Windows 对我们技术人员来说,里面有大量的 API 函数。 API 叫做 “应用程序编程接口”(Application Programming Interface) ,我们在使用各种各样的编程语言在 Windows 开发时,都可以使用 API函数。

x_y_q_的博客 4万+

Windows API入门系列 -一个正儿八经SDK程序

上一篇,讲了一个简单的SDK程序的多种版本的编写,弹出了一个窗口,显示了我们计算1到10的结果,计算的程序不是重点,重点在于,一:让大家认识到Unicode版本的程序和ASCII版本的程序在编程方面的区别,以及怎么样编写出通用代码的程序。二:怎么样运用API或者c++库函数格式化非字符数据到一个字符串中显示出来。 不过,那个相当简单的程序,还算不上是一个正儿八经SDK程序,也就是说还不是一

Qsir的专栏 3239

(转)API入门系列 -一个正儿八经SDK程序

API入门系列 -一个正儿八经SDK程序 2009年03月26日 23:51:00 阅读数:5090 出处(https://blog.csdn.net/beyondcode/article/details/4028236)。 首发 http://blog.csdn.net/beyondcode http://www.cnblogs.com/beyond-code/ htt...

moshumu1的博客 255

Windows API入门:5:正式SDK程序

编写一个带有注册窗口类和消息循环的SDK程序

Soda Wang的博客 245

嵌入式入门学习方向

电子烟(不多说,这行业技术门槛低,前途堪忧)、充电宝(要求会PD协议,上限太低)、简单消费品(如体重秤等)、简单消费品带无线通信(如蓝牙、4G、WIFI、LORA等)、简单医疗产品(指的是做医疗产品的小公司,其实没什么实力,之所以打医疗的名头出来无非在复杂的消费品上做不过人家,就以产品准确为噱头,真不一定测出来准)、大型医疗公司(后面排名我觉得不分前后,看个人爱好)、大型工控公司、大型高级消费产品公司(如无人机、运动相机、仿apple watch手表之类的产品)、大型电源公司、大型车企。

qq_58662768的博客 2044

免 JAR 依赖、纯 API 调用阿里云短信接口

不用依赖庞大的 jar 就可以发短信

zhangxin09的专栏 1164

ZLMediaKit Windows编译快速入门

一、下载源码 前提条件:安装git #国内用户推荐从同步镜像网站gitee下载 git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit #下载cmake编译的包(完整更新文件) cd ZLMediaKit git submodule update --init 二、下载编译器 windows使用cmake来构建项目,需要下载cmake客户端进行创建VS的sln文件 下载地址:cmake-gui 下载完成后解压文件,打开bin目录下

GAQ9527的博客 7793

博观人脸算法工作记录

博观人脸算法的使用

qq_58601798的博客 418

(一)JAVA基于OPENXML的word文档插入、合并、替换操作系列之基础篇

JAVA基于OPENXML的word文档插入、合并、替换操作系列之基础篇(一)前言新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 前言 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用

南老頭 5018

Uniapp uni-app学习与快速上手

uni,读you ni,是统一的意思。Dcloud即数字天堂(北京)网络技术有限公司是W3C成员及HTML5中国产业联盟发起单位,致力于推进HTML5发展构建,HTML5生态。2012年,DCloud开始研发小程序技术,优化webview的功能和性能,推出了HBuilder可视化开发工具。2015年,DCloud正式商用了自己的小程序,产品名为“流应用”,它是能接近原生功能、性能的App,并且即点即用,第一次使用时可以做到边下载边使用。

Beatingworldline的博客 3359

OpenRouter 免费模型 Ox Alpha 上手:1M 上下文保姆级教程与性能答疑

不花一分钱、不占本地内存,直接白嫖云端刚上线的新模型:Ox Alpha。 这个模型最近在 OpenRouter 上悄悄上线,一露面就带着三个抓眼球的标签:匿名隐身模型、1M 超长上下文、完全免费。

邵奈一的博客 1万+
上一篇: API入门系列之四 -相当简单的SDK程序
下一篇: API入门系列之六 -自己实现MessageBox
BeYoNDCoDE
博客等级 码龄18年 159粉丝 13原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值