调用API函数
2010年11月26日
通常来说API函数都是封装在动态链接库当中的,在程序的开发过程中并没有调用动态链接库,而只要包含库函数的头文件就可以调用API函数了,这是因为编译器会利用头文件和LIB文件到动态链接库中去寻找相应的函数并把函数加入到程序当中。
LIB文件是动态链接库输出函数信息的输入库文件,每一个LIB文件都会对应一个动态链接库,两都一个是.lib,一人是.dll它们存放的地方是不同的一个是在VC++的LIB目录下,一个是在系统目录\system32下。
那么如何去调用动态链接库中的函数呢?
比如要去调用kernel32.dll中的函数GetDiskFreeSpaceExA函数来显示磁盘中的剩余空间可以做好下的步骤:
1,typedef BOOL (WINAPI *MyFunc)(LPCSTR RootName,PULARGE_INTEGER pulA,PULARGE_INTEGER pulB,
PULARGE_INTEGER pulFreeBytes);
这里给定了自己的函数给出了函数的名称参数,这里的参数是和kernel32.dll中的函数GetDiskFreeSpaceExA函数的一样的
2,ULARGE_INTEGER a,b,c; 在这里定义某些变量在调用函数的时候会用到,这个不是必须的因为函数的参数是不一样的
3,HMODULE hModule = ::LoadLibrary("system32\\kernel32.dll"); 用全局函数LoadLibrary去加载动态链接库其中参数就指定了这个库文件所在地方及名称
如果这里加载成功的话它会返加一个模块句柄,如果不成功的话它返回的是NULL
4,MyFunc diskspace = (MyFunc)GetProcAddress(hModule,"GetDiskFreeSpaceExA");
这里定义了一个自己的函灵敏diskspace,它用到函数GetProcAddress得到其参指定的函数的入口,如果这样子调用成功的话它会返回一个非0值,
5,diskspace("C:\\",&a,&b,&c);
这里用到自己定义的函数传入指定的参数,这里我们可以理解为diskspace的地址就是GetDiskFreeSpaceExA地址这两个是一样的因而在前面我们用typedef的时候参数一定要和库函数的一样
6,最后一步是在我们用完了这个库之后我们要去释放它用全局函数FreeLibrary(hModule)
我们常常不用API来开发应用程序是因它比较繁琐,对开发人员的要求较高,而用MFC开发则正好相反,MFC已给我们做好了框架封装好了API等这样子相对来说简单些,但是由于MFC做的框架不是针对某一个或是某一类来进行的而是针对所有的应用程序来说的因而用它的话开发程序的体积就会大些,相对来说程序的执行速度会慢些。
使用Win32 API函数来开发应用程序的话要用到RegisterClass,CreateWindow,GetMessage,TranslateMessage,DispatchMessage等函数,这些函数是用来注册一个窗口类,创建一个窗口,处理消息循环来用的,我们要注意的就是在调用CreateWindow时第一个指定的函数一定是一个窗口类名称,一个没有通过RegisterClass注册的窗口类是无效的窗口类,因而在创建一个窗口的时候我们要去做的前题工作是去注册一个窗口类,而RegisterClass就只有一个参数那就是一个WNDCLASS结构的指针,因而我们要去先初始化自己特定的WNDCLASS的成员,而CreateWindow则通过我们注册时指定的特定窗口的属性去创建窗口,因而也可以说创建一个窗口是由WNDCLASS和CreateWindow共同完成的。这里还只是做出了一个程序的舞台我们如果只做这么多的话窗口是产生了还没有消息循环这会导致窗口一出现就消逝了,我们这里消息循环也就是一个while循环在它之中我们不断地用GetMessage获得消息,然后用TranslateMessage,DispatchMessage去转换传递消息,窗口还要有一个可以处理消息的地方消息传送到这里这个就是消息处理函数也就是一个回调函数,要用回调CALLBACK是因而不光我们的程序会去调用这个函数系统也会调用这个函数。
#include "Windows.h"
HANDLE ghInstance;
LRESULT CALLBACK MainWndProc(HWND hwndMain,UINT msg,
WPARAM wParam,LPARAM lParam);
int PASCAL WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,LPSTR lpszCmdLine,
int nCmdShow)
{
WNDCLASS wc;
MSG msg;
if(!hPrevInstance)
{
//注册窗口类
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.hCursor = LoadCursor(NULL,IDI_APPLICATION);
wc.hIcon = LoadIcon(NULL,IDC_ARROW);
wc.hInstance = hInstance;
wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.lpszClassName = "GenericAppClass";
wc.lpszMenuName = "GenericAppMenu";
wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
RegisterClass(&wc);
}
ghInstance = hInstance;
//创建窗口
HWND hwndMain = CreateWindow("GenericAppClass",
"Super Video",
WS_POPUP|WS_OVERLAPPEDWINDOW,0,0,500,500,
NULL,NULL,hInstance,NULL);
ShowWindow(hwndMain,nCmdShow);
UpdateWindow(hwndMain);
//消息循环
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK MainWndProc(HWND hwndMain,UINT msg,
WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_COMMAND:
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwndMain,msg,wParam,lParam);
}
上面的这个程序就是用Win32 API开发应用程序的一个框架模式。
这里我们要做Win32 API的时候我们应用VC++6.0的时候要把资源文件的.rc和resource.h文件都加入进来才会显示!!!!
#include "Windows.h"
#include "resource.h"
#include "shlobj.h" //这是在使用BROWSEINFO结构时要加入的应文件
HWND dlg;
HANDLE hinst;
//每一个窗体都要有一个回调函数对于一个对话框来说的话也不例外
BOOL CALLBACK DlgProc(HWND hwnd,UINT message,WPARAM wParam,
LPARAM lParam);
BOOL WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine,int nCmdShow)
{
hinst = hInstance;
//显示资源中的对话框
dlg = CreateDialog(NULL,MAKEINTRESOURCE(IDD_DIALOG1),NULL,(DLGPROC)DlgProc);
//把对话框显示出来
ShowWindow(dlg,nCmdShow);
SetWindowPos(dlg,HWND_TOP,200,200,350,180,SWP_SHOWWINDOW);
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return TRUE;
}
//消息处理函数的实现
BOOL CALLBACK DlgProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
return TRUE;
case WM_RBUTTONDOWN:
POINT pt;
pt.x = LOWORD(lParam); //获得鼠标水平位置
pt.y = HIWORD(lParam); //获得鼠标垂直位置
HMENU menu;
HMENU sub;
menu = LoadMenu((HINSTANCE)hinst,"IDR_MENU1");
sub = GetSubMenu(menu,0);
//客户坐标转为屏幕坐标
ClientToScreen(hwnd,&pt);
//显示出右键菜单
TrackPopupMenu(sub,TPM_LEFTALIGN | TPM_LEFTBUTTON,pt.x,pt.y,0,hwnd,NULL);
return TRUE;
case WM_CLOSE:
DestroyWindow(hwnd);
dlg = NULL;
PostQuitMessage(0);
return TRUE;
case WM_COMMAND:
switch(wParam)
{
case IDC_BUTTON1:
BROWSEINFO bi; //定义这个结构在SHBrowseForFolder中应用
char buffer[MAX_PATH];
ZeroMemory(buffer,MAX_PATH);
bi.hwndOwner = hwnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = buffer;
bi.lpszTitle = "选择一个文件夹";
bi.ulFlags = BIF_EDITBOX;
bi.lpfn = NULL;
bi.lParam = 0;
bi.iImage = 0;
LPITEMIDLIST pList = NULL;
if((pList = SHBrowseForFolder(&bi))!=NULL)
{
char path[MAX_PATH];
ZeroMemory(path,MAX_PATH);
SHGetPathFromIDList(pList,path);
SetWindowText(GetDlgItem(hwnd,IDC_EDIT1),path);//在编辑框中输入文本
DlgDirList(hwnd,path,IDC_LIST1,0,DDL_READONLY|DDL_ARCHIVE|
DDL_HIDDEN|DDL_READWRITE);//让列表框中显示选中的文件夹中的内容
}
}
}
return FALSE;
}
在上面这个例子中我们用一个CreateDialog加上资源来实现创建对话框的功能,再通过ShowWindow来显示对话框,注意每一个窗体都有一个回调函数用来处理消息,对于对话框来说的话它也要有一个回调函数,
当我们在对话框中点了按钮之后我们想出现一个浏览文件的对话框我们可以通过SHBrowseForFolder函数调用BROWSEINFO去实现,BROWSEINFO是一个结构体,BROWSEINFO结构中包含有用户选中目录的重要信息:
typedef struct_browseinfo
{
HWND hwndOwner; //浏览文件夹的父窗口句柄
LPCITEMIDLIST pidlRoot; //ITEMIDLIST结构的指针,包含浏览时的初始根目录,而且只有被指定的目录和其子目录才显示在浏览文件夹 对话框中。该成员变量可以是NULL,在此时桌面目录将被使用。
LPSTR pszDisplayName; //文件夹名称用来保存用户选中的文件夹
LPCSTR lpszTitle; //该浏览文件夹对话框对话框的显示文本,用来提示该浏览文件夹对话框的功能、作用和目的。
UINT ulFlags; //标志位描述了对话框的选项可以是0
BFFCALLBACK lpfn; //应用程序定义的浏览对话框回调函数的地址。当对话框中的事件发生时,该对话框将调用回调函数。该参数可 用为NULL。
LPARAM lParam; //对话框传给回调函灵敏的参数
int iImage; //与选中目录相关的图像。该图像将被指定为系统图像列表中的索引值
}BROWSEINFO,*PBROWSEINFO,*LPBROWSEINFO;
对于这里的函数SHBrowseForFolder利用一个BROWSEINFO就可以实现打开一个文件夹,但是要注意的就是这个函数并不返回文件夹的名称而是一个LPITEMIDLIST对象,然后可以通过SHGetPathFromIDList函数从LPITEMIDLIST对象中获得文件夹的名称,SHGetPathFromIDList(pList,path);
最后我们用DlgDirList让列表框中显示文件夹中的内容。DlgDirList(hwnd,path,IDC_LIST1,0,DDL_READONLY|DDL_ARCHIVE|
DDL_HIDDEN|DDL_READWRITE)
发表评论
-
跨平台自动化测试部署
2012-01-20 09:42 439跨平台自动化测试部署 ... -
接下来做什么
2012-01-20 09:42 732接下来做什么 2010年10 ... -
如何开展灰盒测试[4]:接口测试实战――测试跨主机的模块接口
2012-01-20 09:42 901如何开展灰盒测试[4]:接口测试实战――测试跨主机的模块接口 ... -
跨平台编程和QT
2012-01-20 09:42 905跨平台编程和QT 2011年03 ... -
人民日报:中国企业未参与菲律宾石油开采竞标
2012-01-19 14:46 666人民日报:中国企业未参 ... -
人民日报:中国企业没有参与菲律宾南海石油开采竞标
2012-01-19 14:46 627人民日报:中国企业没有 ... -
第二届《全国京剧票友万里行艺术团》欧洲行开始报名
2012-01-19 14:46 843第二届《全国京剧票友 ... -
出口埃及记
2012-01-19 14:46 618出口埃及记 2010年11月28 ... -
消息处理函数
2012-01-17 04:31 714消息处理函数 2010年07 ... -
从VC6到VC9移植代码问题总结收藏
2012-01-17 04:30 603从VC6到VC9移植代码问题 ... -
窗口和消息
2012-01-17 04:30 556窗口和消息 2011年06月27 ... -
vs2008使用点滴
2012-01-17 04:30 1906vs2008使用点滴 2011年02 ... -
2009亚太最具社会责任感华商领袖颁奖盛典8月2日隆重举行
2012-01-16 03:21 5922009亚太最具社会责任感华商领袖颁奖盛典8月2日隆重举行 ... -
林 伦 伦:关于海外潮学研究的几点看法和建议
2012-01-16 03:21 1268林 伦 伦:关于海外潮学研究的几点看法和建议 2011年03 ... -
011-5-20越南平阳沉船惨案陈述
2012-01-16 03:21 631011-5-20越南平阳沉船惨案陈述 2011年05月30日 ...
相关推荐
vb调用api函数工具软件,可查找API函数,软件包含数百个VB调用API函数实现各种功能
VB之精彩编程参阅资料-调用API函数设计About窗口
powerbbuilder调用api函数详解,
vb调用API函数的声明 在VB中声明API函数有两种方法:如果我们只在某个窗体中使用API函数,我们可以在窗体代码的General部分声明它: 声明的语法是: Private Declare Function ... Private Declare Sub..... ...
这是一个使用Python ctypes和tkinter模块设计, 用API函数管理电脑其他窗口的工具, 应用了ctypes模块调用API函数, tkinter库实现用户界面。 程序中,用户选择一个窗口,即可更改这个窗口的标题、边框样式、透明度等...
VB6.0 调用系统API函数。控制显示器的关闭
VB调用API函数方法,以一简单的例题做详细说明。非常适合初学者想了解API函数的朋友
Delphi__调用API函数实现数据发送.rarDelphi__调用API函数实现数据发送.rarDelphi__调用API函数实现数据发送.rar
调用API函数映射网络驱动器调用API函数映射网络驱动器调用API函数映射网络驱动器调用API函数映射网络驱动器调用API函数映射网络驱动器调用API函数映射网络驱动器
调用api函数打开或是关闭光驱调用api函数打开或是关闭光驱
在C#中调用API函数. 在C#中调用API函数. 在C#中调用API函数.
1C#中调用API函数方法.pdf
VB 调用API函数设计关于窗体,看第一眼,我还以为是调用Windows系统的关于窗口,仔细看,定义了自己的信息,这个例子可看作是VB使用API函数的例子,了解一些用法,关于本例子中的API用法,可看以下代码: ...
[161]vc调用api函数进行串口通讯,能够实现对omronPLC的串口通讯,能够实现对omronPLC的数据区的读取和写入.[161]vc调用api函数进行串口通讯,能够实现对omronPLC的串口通讯,能够实现对omronPLC的数据区的读取和写入....
学习在VisualFoxPro中调用API函数的方法
asp.net 调用API函数! 很值得下载看看!资源免费,大家分享!!
压缩包里是个.cs的源文件,是关于调用API函数的,这个是看网上作业,比较简单
strokeit调用api函数.lua,strokeit调用api函数.lua,strokeit调用api函数.lua,strokeit调用api函数.lua,
C#中如何调用API函数,使用托管方式调用DLL,实现屏幕捕捉