发信人: mark7312(小马哥) 
整理人: wenbobo(2002-12-24 09:08:38), 站内信件
 | 
 
 
动态链接函数库(Dynamic Link Library 简称DLL)是组成Windows系统的重要元素之一。Windows将构成其系统的大部分程序代码、数据以及经常用到的资源,以动态链接函数库(二进制文件)的形式存贮在磁盘里。本文主要介绍如何在应用程序中预留待扩展功能接口,以及利用DLL编写这类扩展功能代码的方法。 
 
 应用实例 
   在开发应用程序的时候考虑到以后可能要添加某些新的功能,为避免修改源程序所带来的麻烦,我们可以在开发应用程序的过程中先预留一个扩展功能接口,以后需要扩展功能时,只要把扩展功能部分的代码单独编译成DLL即可。下面是一个示例程序,该示例程序分为应用程序和扩展功能两部分,当应用程序收到WM_CREATE消息时,检查是否有扩展功能,若有则装入;否则返回。该程序在Windows 95下,用Borland c++ 4.5调试通过。 
 
   /*------PRAC.C 应用程序部分------*/ 
 
   #include <windows.h> 
 
   #include "prac.h" 
 
   int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int); 
 
   long FAR PASCAL MainWndProc(HWND, WORD, WORD, LONG); 
 
   void MsgFilter(HWND , WPARAM ); 
 
   FARPROC LpExtProc ; 
 
   /*------- WinMain() -------*/ 
 
   int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance, 
 
              LPSTR lpszCmdLine, int nCmdShow) 
 
   { 
 
    MSG   msg; 
 
    HWND   hWnd; 
 
    WNDCLASS wndclass; 
 
    if ( ! hPrevInstance ) 
 
      { 
 
       wndclass.style = CS_HREDRAW | CS_VREDRAW; 
 
       wndclass.lpfnWndProc = MainWndProc; 
 
       wndclass.cbClsExtra = 0; 
 
       wndclass.cbWndExtra = 0; 
 
       wndclass.hInstance = hInstance; 
 
       wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); 
 
       wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); 
 
       wndclass.hbrBackground = GetStockObject (WHITE_BRUSH); 
 
       wndclass.lpszMenuName = "OurOwnMenu"; //装入应用程序菜单 
 
       wndclass.lpszClassName = "Application"; 
 
       if ( ! RegisterClass (&wndclass) ) 
 
        return FALSE; 
 
      } 
 
    hWnd = CreateWindow ( "Extend Function" , 
 
               "应用程序示例", 
 
               WS_OVERLAPPEDWINDOW, 
 
               CW_USEDEFAULT, 
 
               CW_USEDEFAULT, 
 
               CW_USEDEFAULT, 
 
               CW_USEDEFAULT, 
 
               NULL, 
 
               NULL, 
 
               hInstance, 
 
               NULL); 
 
    If (!hWnd ) 
 
      return FALSE; 
 
    ShowWindow (hWnd, nCmdShow); 
 
    UpdateWindow (hWnd); 
 
    while ( GetMessage (&msg, NULL, 0, 0) ) 
 
      { 
 
       TranslateMessage (&msg); 
 
       DispatchMessage (&msg); 
 
      } 
 
    return msg.wParam; 
 
   } 
 
   /*---------- 主窗口函数 WndProc()-------------*/ 
 
   long FAR PASCAL MainWndProc(HWND hWnd, WORD message, 
 
                     WORD wParam, LONG lParam) 
 
   { 
 
    static HANDLE hLibrary; 
 
    char szBuf[80]; 
 
    switch(message) 
 
    { 
 
      case WM_CREATE: 
 
      /*读应用程序的初始化文件prac.ini,检查是否有扩展功能的动态链接库,若没有则返回;若有则装入该动态链接函接数库,并取得接口函数的地址,对接口函数进行初始化*/ 
 
        GetPrivateProfileString("MyApp" , "AddMyapp" , "" , 
 
                  szBuf,sizeof(szBuf) , "prac.ini"); 
 
        if (szBuf[0] != '\0') 
 
        if ((hLibrary = LoadLibrary(szBuf)) >= 32) 
 
         { 
 
          LpExtProc=(FARPROC)GetProcAddress(hLibrary, 
 
                   MAKEINTRESOURCE(2)); 
 
          LpExtProc(hWnd , EXTPROC_LOAD); 
 
         } 
 
        else 
 
         MessageBox(hWnd,"Load library failed!","Error",MB_OK); 
 
        break; 
 
      case WM_COMMAND: 
 
        /*函数MsgFilter( )用来过滤菜单消息*/ 
 
        MsgFilter(hWnd , wParam); 
 
        switch (wParam) 
 
        { 
 
          case IDM_COMMAND1: //处理应用程序 
 
          case IDM_COMMAND2: //定义的菜单功 
 
          case IDM_COMMAND3: //能,此处省略。 
 
        } 
 
        return 0; 
 
      case WM_DESTROY: 
 
        if(hLibrary != NULL) 
 
        FreeLibrary(hLibrary); 
 
        PostQuitMessage(0); 
 
        break; 
 
    } 
 
    return DefWindowProc(hWnd, message, wParam, lParam); 
 
   } 
 
 
  ---- 小马哥
  
 美丽的梦和美丽的诗一样,都是可遇而不可求的,
 常常在最没能料到的时候里出现
       | 
 
 
 |