明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

用DLL為應(yīng)用程序預(yù)留待擴(kuò)展技巧接口

[摘要]動(dòng)態(tài)鏈接函數(shù)庫(kù)(Dynamic Link Library 簡(jiǎn)稱DLL)是組成Windows系統(tǒng)的重要元素之一。Windows將構(gòu)成其系統(tǒng)的大部分程序代碼、數(shù)據(jù)以及經(jīng)常用到的資源,以動(dòng)態(tài)鏈接函數(shù)庫(kù)(二進(jìn)制文件)的形式存貯在磁盤(pán)里。本文主要介紹如何在應(yīng)用程序中預(yù)留待擴(kuò)展功能接口,以及利用DLL編寫(xiě)這類(lèi)...
動(dòng)態(tài)鏈接函數(shù)庫(kù)(Dynamic Link Library 簡(jiǎn)稱DLL)是組成Windows系統(tǒng)的重要元素之一。Windows將構(gòu)成其系統(tǒng)的大部分程序代碼、數(shù)據(jù)以及經(jīng)常用到的資源,以動(dòng)態(tài)鏈接函數(shù)庫(kù)(二進(jìn)制文件)的形式存貯在磁盤(pán)里。本文主要介紹如何在應(yīng)用程序中預(yù)留待擴(kuò)展功能接口,以及利用DLL編寫(xiě)這類(lèi)擴(kuò)展功能代碼的方法。  

應(yīng)用實(shí)例  
  在開(kāi)發(fā)應(yīng)用程序的時(shí)候考慮到以后可能要添加某些新的功能,為避免修改源程序所帶來(lái)的麻煩,我們可以在開(kāi)發(fā)應(yīng)用程序的過(guò)程中先預(yù)留一個(gè)擴(kuò)展功能接口,以后需要擴(kuò)展功能時(shí),只要把擴(kuò)展功能部分的代碼單獨(dú)編譯成DLL即可。下面是一個(gè)示例程序,該示例程序分為應(yīng)用程序和擴(kuò)展功能兩部分,當(dāng)應(yīng)用程序收到WM_CREATE消息時(shí),檢查是否有擴(kuò)展功能,若有則裝入;否則返回。該程序在Windows 95下,用Borland c++ 4.5調(diào)試通過(guò)。  

  /*------PRAC.C 應(yīng)用程序部分------*/  

  #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"; //裝入應(yīng)用程序菜單  

      wndclass.lpszClassName = "Application";  

      if ( ! RegisterClass (&wndclass) )  

       return FALSE;  

     }  

   hWnd = CreateWindow ( "Extend Function" ,  

              "應(yīng)用程序示例",  

              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;  

  }  

  /*---------- 主窗口函數(shù) WndProc()-------------*/  

  long FAR PASCAL MainWndProc(HWND hWnd, WORD message,  

                    WORD wParam, LONG lParam)  

  {  

   static HANDLE hLibrary;  

   char szBuf[80];  

   switch(message)  

   {  

     case WM_CREATE:  

     /*讀應(yīng)用程序的初始化文件prac.ini,檢查是否有擴(kuò)展功能的動(dòng)態(tài)鏈接庫(kù),若沒(méi)有則返回;若有則裝入該動(dòng)態(tài)鏈接函接數(shù)庫(kù),并取得接口函數(shù)的地址,對(duì)接口函數(shù)進(jìn)行初始化*/  

       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:  

       /*函數(shù)MsgFilter( )用來(lái)過(guò)濾菜單消息*/  

       MsgFilter(hWnd , wParam);  

       switch (wParam)  

       {  

         case IDM_COMMAND1: //處理應(yīng)用程序  

         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);  

  }  

/*下面過(guò)濾函數(shù),把菜單消息的來(lái)源分成兩類(lèi),即應(yīng)用程序本身的菜單消息和來(lái)自功能擴(kuò)展部分的菜單消息。應(yīng)用程序把值在MIN_FMT至MAX_FMT之間的菜單消息留給待擴(kuò)展程序使用。如果有來(lái)自擴(kuò)展程序的消息,就通過(guò)接口函數(shù)LpExtProc()把該消息傳送給擴(kuò)展程序,由擴(kuò)展程序負(fù)責(zé)處理該消息*/  

  void MsgFilter(HWND hWnd , WPARAM wParam)  

  {  

   if((wParam >= MIN_FMT)&&(wParam <= MAX_FMT))

    LpExtProc(hWnd , wParam);

   return;

  }

  /*---------------- End of PRAC.C-----------------*/

  /*----------- PRAC.H ----------*/

  #define MIN_FMT       100

  #define MAX_FMT      199

  #define EXTPROC_LOAD   200

  #define IDM_COMMAND1   201

  #define IDM_COMMAND2   202

  #define IDM_COMMAND3   203

  /*---End of PRAC.H ---*/

  ; 應(yīng)用程序的模塊定義文件PRAC.DEF

  NAME     PRAC

  DESCRIPTION  'demonstrate a different system menu'

  EXETYPE    WINDOWS

  STUB      'WINSTUB.EXE'

  CODE      PRELOAD MOVEABLE DISCARDABLE

  DATA     PRELOAD MOVEABLE MULTIPLE

  HEAPSIZE   1024

  STACKSIZE   8192

  EXPORTS    MainWndProc

  ; End of PRAC.DEF

  /*---資源定義文件PRAC.RC---*/

  #include "prac.h"

  OurOwnMenu MENU

  BEGIN

   MENUITEM "Command&1",   IDM_COMMAND1

   MENUITEM "Command&2",   IDM_COMMAND2

   MENUITEM "Command&3",   IDM_COMMAND3

  END

  /*---End of PRAC.RC---*/

  若要擴(kuò)展上面應(yīng)用程序的功能,在不改動(dòng)上述程序的情況下,只需將功能擴(kuò)展部分的代碼編寫(xiě)成動(dòng)態(tài)鏈接函數(shù)庫(kù),編譯成.DLL文件,并在PRAC.INI文件中加入下面語(yǔ)句,即可達(dá)到擴(kuò)展功能的目的。在PRAC.INI中加入:

 。跘ddApp]

  AddMyapp=c:\win95\system\extproc.dll

  擴(kuò)展功能的動(dòng)態(tài)鏈接函數(shù)庫(kù)代碼如下:

  /*-----EXTPROC_DLL.c-----*/

  #include <windows.h>  

  #include <commdlg.h>  

  #include "extproc_dll.h"  

  HMENU hMenu , hExtMenu;  

  HWND hWndExt = NULL;  

  int FAR PASCAL LibMain(HANDLE hModule , WORD wDataSeg,  

              WORD HeapSize , LPSTR lpszCmdLine)  

  {  

   if(HeapSize != 0)  

    UnlockData(0);  

   return 1;  

  }  

  int FAR PASCAL WEP(int SystemExit)  

  {  

   switch (SystemExit)  

    {  

     case WEP_SYSTEM_EXIT:  

                 return 1;  

     case WEP_FREE_DLL:  

                 return 1;  

     default:  

         return 1;  

    }  

  }  

  /*函數(shù)FMExtensionProc()即為擴(kuò)展功能的處理函數(shù),當(dāng)過(guò)濾函數(shù)檢索到有來(lái)自擴(kuò)展功能的菜單消息時(shí),就調(diào)用該函數(shù)進(jìn)行處理。在此僅以設(shè)置打印機(jī)、選擇字體來(lái)說(shuō)明擴(kuò)展功能的處理過(guò)程,讀者可根據(jù)自己的需要修改*/  

  void FAR PASCAL FMExtensionProc(HWND hWndFMExt , WORD wMessage)  

  {  

   PRINTDLG  pd;  

   CHOOSEFONT fnt;  

   LOGFONT lf;  

   CHOOSECOLOR chclr;  

   DWORD dwColor;  

   DWORD dwCustClrs[16];  

   int i;  

   switch(wMessage)  

     {  

     /*處理FMEVENT_LOAD消息,加載用戶擴(kuò)展功能菜單FMExtMenu*/  

      case EXTPROC_LOAD:  

         hExtMenu = LoadMenu(FMExtInst,"FMExtMenu");  

         hMenu = GetMenu(hWndFMExt);  

         AppendMenu(hMenu,MF_POPUP,hExtMenu ,"擴(kuò)展功能(&E)");  

         SetMenu(hWndFMExt,hMenu);  

         break;  

     /*下面是用戶可自定義的擴(kuò)展功能代碼*/  

      case IDM_PRINTERSETUP: //設(shè)置打印機(jī)  

        pd.lStructSize = sizeof(PRINTDLG);  

        pd.hwndOwner = hWndFMExt;  

        pd.hDevMode  = NULL;  

        pd.hDevNames = NULL;  

        pd.Flags = PD_RETURNDC PD_SELECTION PD_PRINTSETUP;  

        pd.nCopies   = 1;  

        PrintDlg((LPPRINTDLG)&pd);  

        break;  

      case IDM_SELECTFONT: //選擇字體  

        fnt.lStructSize = sizeof(CHOOSEFONT);  

        fnt.hwndOwner = hWndFMExt;  

        fnt.hDC     = NULL;  

        fnt.lpLogFont = &lf;  

        fnt.Flags   = CF_SCREENFONTS CF_EFFECTS;  

        fnt.rgbColors = RGB(0,255,255);  

        fnt.lCustData = 0L;  

        fnt.nFontType = SCREEN_FONTTYPE;  

        fnt.nSizeMin  = 0;  

        fnt.nSizeMax  = 0;  

        ChooseFont(&fnt);  

        break;  

     }  

   return;  

  }  

  /*------------End of EXTPROC_DLL.C------------*/  

  /*----- EXTPROC_DLL.H -----*/  

  #define IDM_PRINTERSETUP 101  

  #define IDM_SELECTFONT  102  

  #define EXTPROC_LOAD   200  

  void FAR PASCAL _export FMExtensionProc(HWND,WORD);  

  /*-----End of EXTPROC_DLL.H -----*/  

  ;資源文件EXTPROC_dll.RC  

  #include "windows.h"  

  #include "extproc_dll.h"  

  FMExtMenu MENU DISCARDABLE  

  BEGIN  

   MENUITEM "Printer&Setup" ,IDM_PRINTERSETUP  

   MENUITEM "Select&Font"  ,IDM_SELECTFONT  

  END  

  ;End of EXTPROC_DLL.RC  

  ;模塊定義文件EXTPROC_DLL.DEF  

  LIBRARY EXTPROC  

  DESCRIPTION 'File Manager Extension DLL'  

  EXETYPE WINDOWS  

  CODE PRELOAD MOVEABLE DISCARDABLE  

  DATA PRELOAD SINGLE SHARED  

  HEAPSIZE 1024  

  EXPORTS  

   WEP @1 RESIDENTNAME  

   FMExtensionProc @2  

  ;End of EXTPROC_DLL.DEF