`
muw76muw
  • 浏览: 12948 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

调用API函数

 
阅读更多

调用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)
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics