学习api的使用方式

2023-05-16

网上有很多API教程,但是都是针对单个API的使用来讲解,但是如果遇到网上没有教程的API呢?
这篇教程的目的就是这样:当遇到一个不会的API的时候,懂得如何利用资料学会使用这个API
这是我个人的心得总结,其实这个方法也不是我原创的,但是貌似没见到有人写文章介绍,所以我就来写一篇了
水平不算高,如果有错请指出!
By Defanive

本文读者需具备的知识:
1、VB的基本语法
2、API、结构体、常数
3、VB的数据类型,C语言的简单数据类型
4、API Viewer 2004(或其他同类软件)的基本使用
5、一定的英文阅读能力

那么要调用一个陌生的API,基本上遵循以下步骤
1、找到相关API、结构体、常数的声明
2、到MSDN阅读这个API的网页指南
3、按照MSDN写代码

好吧看起来很简单,不过这样说了也是白说,实战一下吧

这次实战的目标是:GetOpenFileName

首先介绍一下这个API吧,这个API会显示一个打开对话框,给用户选择一个文件打开
这个跟CommonDialog里面的打开对话框是一样的(那干嘛不直接用那个控件?教程用来做演示嘛,而且用API也有他的好处)

第一步:找到声明

找声明主要有两种方法
第一种是通过软件找,例如API Viewer 2004,这类软件内置有绝大部分常用的声明,直接复制即可,方便快捷
第二种是去MSDN找到API的页面,然后复制声明。MSDN是微软的网站,声明肯定是准确的,但是对于VB开发者的劣势是,绝大部分声明都是按照C语言的格式的(至今没见过一个API的页面有VB声明),所以如果不懂C语言的话要转换成VB的声明难度就大了
还有其他方法,例如dump dll文件之类的
本文主要讨论第一种方法,使用的软件是API Viewer 2004,其他同类软件操作大同小异

打开API Viewer 2004,打开Win32api.apv文件,然后选择Declarations一栏,然后选择Subs and Functions,在文本框输入GetOpenFileName,然后就找到这个API的声明了,复制下来,扔进VB的代码里面

好了,现在来仔细看一下这个声明:
Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" (ByRef pOpenfilename As OPENFILENAME) As Long
可以看到这里有一个陌生的参数类型OPENFILENAME,这明显不是VB的基本数据类型,所以我们需要这个OPENFILENAME的声明

于是回到API Viewer 2004,选择Types一栏,在文本框输入OPENFILENAME,找到声明了,复制下来,扔到VB代码里面
Private Type OPENFILENAME
lStructSize As Long
hwndOwner As Long
hInstance As Long
lpstrFilter As String
lpstrCustomFilter As String
nMaxCustFilter As Long
nFilterIndex As Long
lpstrFile As String
nMaxFile As Long
lpstrFileTitle As String
nMaxFileTitle As Long
lpstrInitialDir As String
lpstrTitle As String
flags As Long
nFileOffset As Integer
nFileExtension As Integer
lpstrDefExt As String
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type
继续仔细看这个结构体的声明,可以发现成员都是VB的基本数据类型,说明不需要在找其他声明了
好吧找声明这里就搞定了

第二步:阅读MSDN对于这个API的解释 & 第三步:按照MSDN写代码

这里说的MSDN不是按F1出来那个MSDN,而是MSDN网站msdn.microsoft.com。这个是微软的官方开发者网站,里面资料齐全绝对是开发者的天堂
网站有中文版本和英文版本,不过强烈建议大家看英文版本,中文版的翻译质量不好(这就是为什么要求有一定的英文阅读能力)

好吧进入了这个官网之后,在最上面的Bing搜索里面打GetOpenFileName,然后搜索
出来的结果,一般选择xxxx function这种页面,这里选的就是第一个结果GetOpenFileName function
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646927(v=vs.85).aspx

页面打开了,可以看到这个页面分成几大节:
开头:对API的简单介绍
Syntax:语法,也就是API的声明
Parameters:API的参数
Return Value:返回值
Remarks:一些附加的说明
Examples:示例代码,一般都是用C语言写的
Requirements:API对系统的要求等等
See Also:与此相关的API等
Community Additions:其他人对此文章的评论
网页左栏:是整个站点的分类目录

好吧,英文不好的同学要加油了,混国外网站英文是必须要会的
不要觉得一个API能有这么多内容,很多信息都是很有用很关键的,耐心从上往下一节一节读完

开头:
这个嘛,自己看就是了,对API的介绍和描述,不是很重要的部分(不过有时会有很重要的批注,例如此API不再被微软支持建议用xxx代替之类的)

Syntax:
这个就是API的语法,也就是声明啦,C语言的,所以对我们没什么用,可以跳掉不看
如果要根据这个C语言的声明自己写出VB的声明,还是需要一定的C语言数据类型的知识

PS:这里为什么返回值是BOOL,但是我们的声明是Long呢?是不是应该把我们的VB声明改成Boolean?不需要的。BOOL在C里面的定义就是long型(unsigned long?具体忘了,差不多这类东西),占用4字节,所以应该对应VB的Long型。当然,你闲着蛋疼也可以把返回值声明成Single型,同样也是4字节,不过没什么意义

Parameters:
API的参数部分啦,整个网页最重要的部分之一
按照这里的解释,填写参数就可以调用API了

好吧这里只有一个参数,网页写的是
lpofn [in, out]
Type: LPOPENFILENAME

这个[in, out]是什么意思呢?in表示这个是个输入参数,这个参数的值会作为输入对API的结果进行影响。out表示这个同时也是个输出参数,API会把部分数据返回到这个参数里面。(除了in和out,有些还会出现optional,表示这是个可选参数)

LPOPENFILENAME说的就是参数的类型,等等,我们的声明不是写的类型是OPENFILENAME吗,怎么这里多了个LP?这个是C语言里指针的意思(long pointer?),意思是当调用API的时候,不是把这个整个OPENFILENAME结构体的数据传过去,而是只把这个结构体的指针传过去。同样的写法还有xxx*,例如OPENFILENAME*

接下来看他对这个参数的描述,大致是这个参数装载着启动这个API的参数,当API返回的时候会把结果放到这个结构体里面
说的基本都是废话,这个结构体有这么多成员,我们还是不知道怎么填,那么就点进去这个OPENFILENAME的链接

点进去之后,发现这个OPENFILENAME文章结构也差不多

Syntax可以跳过,我们已经从API Viewer 2004里面找到声明了(PS:后面这个#if和#endif中间的是什么东西呢?这个是C的预编译指令,具体可以自己去看,在这里没什么用)

Members,终于在讲解这些成员的意思了,好吧可以开始写代码了,首先在VB里面写
Dim ofn As OPENFILENAME
With ofn
End With

那么接下来就一个一个看成员,看他的解释,是什么意思,应该怎么填
需要注意的一些东西是,不像API的参数,并没有告诉你每个成员是作为输入还是输出的作用,需要自己认真读解释

lStructSize,Type: DWORD
结构体的字节大小,用sizeof(OPENFILENAME)获得
sizeof其实就是C语言里面获得结构体大小的函数,那VB里面我们就用LenB吧(Len也行,不过按照MSDN的说法还是用LenB吧)
(PS:DWORD对应VB的Long)
代码:.lStructSize = LenB(ofn)

hwndOwner,Type: HWND
这个对话框的父窗体的句柄,可以设置成NULL
那我们就做成父窗体是我们的Form1吧
(PS:HWND也是对于VB的Long,NULL则是0)
代码:.hwndOwner = Me.hWnd

hInstance,Type: HINSTANCE
如果要指定对话框的模板,那么这个需要填上模板所在的程序句柄
我们没兴趣用什么模板,windows自带的那个已经够好看了,不理他填个NULL
代码:.hInstance = 0

lpstrFilter,Type: LPCTSTR
文件类型过滤器,格式为 描述文字 \0 *.xxx \0 描述文字 \0 *.xxx \0 ....... \0\0
所谓文件类型过滤器,其实就是那个下拉框,例如选择文本文件*.txt就只显示txt文件
C语言中\是转义字符,\0其实就是VB中的chr(0)
那么我们这里做一个简单的吧,用户可以选择文本文件或者是任意文件
(PS:LPCTSTR对应VB的String,详细一点应该这样解读,LP C T STR,LP表示这个是字符串的指针,C表示是常量字符串,就是API执行前后不会被修改,T表示是根据程序设置选择是ANSI还是Unicode编码,STR表示是个字符串)
代码:.lpstrFilter = "文本文件" & Chr(0) & "*.TXT" & Chr(0) & "所有文件" & Chr(0) & "*.*" & Chr(0) & Chr(0)

lpstrCustomFilter,Type: LPTSTR
大概就是如果选的是文本文档txt的过滤器,但是用户强制输了个不是txt后缀,API就会分析这个后缀然后返回到这里
这里有一点必须要读到的是,这个是个缓冲区,API会把数据返回到这里。其实从数据类型也可以看到,这个并不像lpstrFilter一样,这个是LPTSTR而不是LPCTSTR,少了个C意味着这个不是一个常量,可能会被API改变,说明是充当一个缓冲区的作用
我们貌似也对用户选怎么后缀没兴趣,所以按照他的要求,填NULL
但是这个是个String类型,NULL表示一个0指针,VB中String类型的0指针就要填vbNullString
代码:.lpstrCustomFilter = vbNullString

nMaxCustFilter,Type: DWORD
lpstrCustomFilter的缓冲区大小
反正我们对这个没兴趣,按照要求填个0就可以了(实际上,只要lpstrCustomFilter填了NULL,这个填什么都没关系)
代码:.nMaxCustFilter = 0

nFilterIndex,Type: DWORD
Filter的序号,作为输入时是默认过滤器的序号,作为输出时是用户选择了哪个序号
我们就让默认是文本文档的过滤器好了,所以序号是0
代码:.nFilterIndex = 0

lpstrFile,Type: LPTSTR
文件路径,作为输入时是默认选择的文件,作为输出为用户选择的文件路径
可以读到这个是一个输出成员,而且从数据类型LPTSTR也可以看到是非常量的字符串,所以我们需要给他做个缓冲区,让API填数据
按照要求,做缓冲区的话最小大小为256,不过我这里就采用MAX_PATH常量值(表示文件路径的可能的最大长度),260
同时他说,如果要避免成为默认选择的文件,最好给缓冲区全部填\0
代码:.lpstrFile = String(260, 0)

nMaxFile,Type: DWORD
lpstrFile的缓冲区大小
这个不必废话了,lpstrFile我们的缓冲区用的是260,自然就填260了
代码:.nMaxFile = 260

lpstrFileTitle,Type: LPTSTR
返回的文件名,作为输出成员(例如C:\a\b\c\1.txt,文件名就是1.txt)
我们不关心这个文件名,即使关心我们也可以用VB的函数自己获得,不需要,填NULL
代码:.lpstrFileTitle = vbNullString

nMaxFileTitle,Type: DWORD
lpstrFileTitle的缓冲区长度
代码:.nMaxFileTitle = 0

lpstrInitialDir,Type: LPCTSTR
初始文件夹
可以指定一个路径,不过直接填NULL好了,打开对话框有路径记忆功能,会自动设置为上次选择的文件的路径
代码:.lpstrInitialDir = vbNullString

lpstrTitle,Type: LPCTSTR
打开对话框的标题
随便搞个标题上去吧,看个人心情
代码:.lpstrTitle = "选择一个文件来打开"

Flags,Type: DWORD
打开对话框的一些性质
下面列了一堆可选的性质,名字下面是十六进制值,右边是解释
我们大体选择了以下几个我们想要的性质:
OFN_EXPLORER:使用系统自带的对话框模板,win7和vista下看起来会很漂亮
OFN_FILEMUSTEXIST:选择的文件必须存在
OFN_HIDEREADONLY:隐藏只读的多选框
OFN_PATHMUSTEXIST:用户在输入框输入的路径必须存在
这些常数可以在API Viewer 2004里面查到他们的值,当然一般来说网页都会给出来,复制就是了
使用多个常数的时候,用Or连接
代码:.flags = &H80000 Or &H1000 Or &H4 Or &H800

nFileOffset,Type: WORD
文件名在lpstrFile中的偏移,输出成员
我们对文件名没什么兴趣,而且这个是个输出成员,那我们就不用写代码了
代码:无

nFileExtension,Type: WORD
文件后缀在lpstrFile中的偏移,输出成员
同没兴趣,无代码
代码:无

lpstrDefExt,Type: LPCTSTR
默认的后缀名,当用户没有输入后缀名的时候自动加上去
对此没什么兴趣,按照要求填个NULL
代码:.lpstrDefExt = vbNullString

lpTemplateName,Type: LPCTSTR
打开对话框使用的模板名称
我们使用系统默认的模板,所以这个也没必要,填NULL
代码:.lpTemplateName = vbNullString

好吧终于搞定这些Members了!!
这个网页的其他几节意义都不大,没什么重要信息,我就不说了

好吧回到GetOpenFileName这个网页,我们填完参数了,继续忘下看

Return value:
Type: BOOL
这个是对返回值的解释,也是挺重要的部分
一般返回值会确定API是否执行成功,虽然大部分人调用API都不管这个返回值,但是按照规范应该是判断返回值看是否调用成功
如果用户成功按了确定按钮,那么返回值就是非0,lpstrFile成员包含了用户选择的文件路径;如果点了取消,那么就是0
这样的话,我们把调用和判断返回的代码写出来吧:
If GetOpenFileName(ofn) Then
Else
End If
现在只是调用了GetOpenFileName,但是调用完什么都不做
好吧,既然说了用户选择的文件路径是在lpstrFile里面,那么我们就可以直接拿来用了
但是,有一点必须注意,lpstrFile里面包含了我们分配缓冲区时候多出来的chr(0)
如果不把这些删掉的话,那么出来的路径就有问题了,后面跟着一大堆的chr(0)
声明一个String型变量szPath,用来保存我们处理完之后的文件路径
Dim szPath As String
szPath = Left(ofn.lpstrFile, InStr(ofn.lpstrFile, Chr(0)) - 1)
MsgBox szPath
搞定了用户按确定的代码,现在来做用户点取消的代码,直接一个msgbox显示就好了
MsgBox "没有选择文件"

Remarks:
这部分通常包括很详细的API调用说明,一般有很重要的信息
不过在这里没什么有意义的东西

Requirements:
Minimum supported client/server是这个API对Windows系统版本的最低要求,这里都是Windows 2000
Header就是VC6里面的头文件,这里是Comdlg32.h,如果你有装Visual C++ 6.0的话,找到这个头文件,就可以找到这个API及相关的C语言声明了
Unicode and ANSI names这个是不同编码版本的API名称,这个编码的问题不在本文的讨论范围



好啦经历千辛万苦终于按照步骤做完了,整个窗体的代码就是这个样子(窗体有一个按钮Command1):

Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" (ByRef pOpenfilename As OPENFILENAME) As Long

Private Type OPENFILENAME
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    lpstrFilter As String
    lpstrCustomFilter As String
    nMaxCustFilter As Long
    nFilterIndex As Long
    lpstrFile As String
    nMaxFile As Long
    lpstrFileTitle As String
    nMaxFileTitle As Long
    lpstrInitialDir As String
    lpstrTitle As String
    flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    lpstrDefExt As String
    lCustData As Long
    lpfnHook As Long
    lpTemplateName As String
End Type

Private Sub Command1_Click()
    Dim ofn As OPENFILENAME
    Dim szPath As String
    With ofn
        .lStructSize = LenB(ofn)
        .hwndOwner = Me.hWnd
        .hInstance = 0
        .lpstrFilter = "文本文件" & Chr(0) & "*.TXT" & Chr(0) & "所有文件" & Chr(0) & "*.*" & Chr(0) & Chr(0)
        .lpstrCustomFilter = vbNullString
        .nMaxCustFilter = 0
        .nFilterIndex = 0
        .lpstrFile = String(260, 0)
        .nMaxFile = 260
        .lpstrFileTitle = vbNullString
        .nMaxFileTitle = 0
        .lpstrInitialDir = vbNullString
        .lpstrTitle = "选择一个文件来打开"
        .flags = &H80000 Or &H1000 Or &H4 Or &H800
        .lpstrDefExt = vbNullString
        .lpTemplateName = vbNullString
    End With
    If GetOpenFileName(ofn) Then
        szPath = Left(ofn.lpstrFile, InStr(ofn.lpstrFile, Chr(0)) - 1)
        MsgBox szPath
    Else
        MsgBox "没有选择文件"
    End If
End Sub

运行测试,一切正常!

好了本文就到这里结束了,希望能帮助到大家的API学习
最后说一句,API不能整天靠网上百度下来的例子代码复制粘贴,自己去MSDN看来写代码,收获更多
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

学习api的使用方式 的相关文章

随机推荐

  • 手把手教你在Github上建立自己的个人博客网站

    概述 之前闲着没事 就利用Github建了一个个人博客网站 效果还不错 今天就来分享一下 建立自己个人博客网站的好处 1 面试装逼 这个不必多说 2 把平时积累的知识和项目记录下来 方便日后查看使用 3 不受其他博客平台的限制 准备工作 开
  • Realsense D435保存图像

    你可以走慢一点 xff0c 但脚步不能停下来 Realsense是我使用的第3款深度传感器 xff0c 前两款分别是Orbbec和Kinect v2 xff0c 奥比中光的深度传感器只需要USB接口 xff0c 但深度图的效果并不好 xff
  • Realsense T265简单测试

    为啥才是周三 xff01 xff01 软硬件配置 CPU xff1a Intel Core i7 7820HQ CPU 64 2 90GHz 8 内存 xff1a 16G 系统版本 xff1a Ubuntu16 04 LTS 64位 深度传
  • 生成随机数方法总结

    使用srand time NULL 或srand time 0 设置当前的系统时间值为随机数种子 xff0c 需要在头文件处使用 include lt cstdlib gt 和 include lt ctime gt 要取得 a b 的随机
  • 尚硅谷_JavaScript_学习笔记

    JavaScript简介 JavaScript 简介 xff1a JavaScript 是一种基于对象和事件驱动并具有相对安全性的客户端脚本语言 xff0c 是一种动态 弱类型 基于原型的语言 xff0c 内置支持类 它的解释器被称为 Ja
  • SQL语句拼接常加 where 1=1 的原因

    数据库在进行查询的时候 xff0c 经常看到有的人使用where 1 61 1和1 61 0 1 61 2等的查询 xff0c 这种条件在执行前 xff0c 就会被计算出true 或者false xff0c 1 61 2实际解释为 NULL
  • 如何完全屏蔽Chrome的提示:"请停用以开发者模式运行的扩展程序"

    参考链接 xff1a chrome怎么安装非官方市场的插件 xff1f https www zhihu com question 24027794 屏蔽Google Chrome安装第三方插件之后反复提示 请停用以开发者模式运行的扩展程序
  • Win7中出错:无法启动此程序,因为计算机中丢失api-ms-win-crt-runtime-|1-1-0.dll

    安装完 Python 后 xff0c 配置好 Python 目录于 Path xff0c 然后 CMD 命令下输入 python 验证是否配置成功 xff0c 但是竟然出现结果跳出对话框 xff0c 出错 xff1a 无法启动此程序 xff
  • rviz global status显示为error的问题解决

    rviz global status显示为error的问题解决 运行ros官方教程中程序rosrun rviz rviz d rospack find turtle tf rviz turtle rviz rviz 发现出现的结果 xff0
  • Chrome浏览器各个版本区别及离线安装包下载

    chrome现在分为 Stable Beta Dev Canary xff08 金丝雀 xff09 Chromium 五个版本 这五个版本的不同在于功能 稳定性 更新速度等方面 Chromium的更新速度很快 xff0c 每隔数小时即有新的
  • 【总结】浏览器 User-Agent 大全

    一 基础知识 Http Header之User Agent User Agent中文名为用户代理 xff0c 是Http协议中的一部分 xff0c 属于头域的组成部分 xff0c User Agent也简称UA 它是一个特殊字符串头 xff
  • Visual Studio 2017各版本安装包离线下载、安装全教程

    微软最近发布了正式版Visual Studio 2017并公开了其下载方式 xff0c 不过由于VS2017采用了新的模块化安装方案 xff0c 所以微软官方并未提供ISO镜像 xff0c 但是官方提供了如何进行离线下载的方案给需要进行离线
  • Python基础入门笔记(一)

    前言 xff08 认识Python xff09 既然学习 Python xff0c 那么至少得了解下这门语言 xff0c 知道 Python 代码执行过程吧 Python 的历史有兴趣的百度百科下就有 xff0c 这个不多说了 1 我们先来
  • Spring学习笔记1

    前言 Spring框架的学习路线 xff1a Spring第一天 xff1a Spring的IOC容器之XML的方式 xff0c Spring框架与Web项目整合Spring第二天 xff1a Spring的IOC容器之注解的方式 xff0
  • GitHub学生包的介绍与申请

    1 Github学生包介绍 1 Github学生包是什么 xff1f GitHub 学生包是一个由 GitHub 免费提供给学生的福利 xff0c 里面包括了计算机专业可能用到的很多付费资源 xff0c 其中包含一系列网站服务的打折 代金券
  • (二)GitHub的使用随记

    一 Git及GitHub的使用 1 突破GitHub单个大文件上传限制 GitHub 上新建的仓库容量大小限制在 1G xff0c 单个文件不能超过 100M xff0c 有 50M 的文件 xff0c 就会警告了 可通过以下命令查找超过
  • 总结一个月以来调试STM32底盘踩过的坑

    深坑1 xff1a 基本配置方法 xff1b 配置PWM输出 xff0c TIM4有四路PWM输出 xff0c 依葫芦画瓢开始配置 xff0c 配置完后 xff0c 开始测试 xff0c 啥都没有啊 xff0c 很是伤心 xff0c 开始查
  • Android开发60条技术经验总结

    1 全部Activity可继承自BaseActivity xff0c 便于统一风格与处理公共事件 xff0c 构建对话框统一构建器的建立 xff0c 万一需要整体变动 xff0c 一处修改到处有效 2 数据库表段字段常量和SQL逻辑分离 x
  • 无人机利用视觉slam实现位置估计

    无人机利用视觉slam实现室内位置估计 自己近期所做的以及思考的东西 我们实验室买了阿木的p200 带t265 无人机用于无人机的控制研究 xff0c 通过阿木实验室的ros功能包px4 command可以 无脑的实现飞机的悬停功能 xff
  • 学习api的使用方式

    网上有很多API教程 xff0c 但是都是针对单个API的使用来讲解 xff0c 但是如果遇到网上没有教程的API呢 xff1f 这篇教程的目的就是这样 xff1a 当遇到一个不会的API的时候 xff0c 懂得如何利用资料学会使用这个AP