用DLL為應(yīng)用程序預(yù)留待擴(kuò)展技巧接口
發(fā)表時(shí)間:2024-06-19 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]動(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