分享
 
 
 

用DLL为应用程序预留待扩展功能接口

王朝厨房·作者佚名  2007-01-04
窄屏简体版  字體: |||超大  

动态链接函数库(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);

}

/*下面过滤函数,把菜单消息的来源分成两类,即应用程序本身的菜单消息和来自功能扩展部分的菜单消息。应用程序把值在MIN_FMT至MAX_FMT之间的菜单消息留给待扩展程序使用。如果有来自扩展程序的消息,就通过接口函数LpExtProc()把该消息传送给扩展程序,由扩展程序负责处理该消息*/

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_FMT199

#define EXTPROC_LOAD 200

#define IDM_COMMAND1 201

#define IDM_COMMAND2 202

#define IDM_COMMAND3 203

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

; 应用程序的模块定义文件PRAC.DEF

NAME PRAC

DESCRIPTION’demonstrate a different system menu’

EXETYPEWINDOWS

STUB’WINSTUB.EXE’

CODEPRELOAD MOVEABLE DISCARDABLE

DATA PRELOAD MOVEABLE MULTIPLE

HEAPSIZE 1024

STACKSIZE 8192

EXPORTSMainWndProc

; 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---*/

若要扩展上面应用程序的功能,在不改动上述程序的情况下,只需将功能扩展部分的代码编写成动态链接函数库,编译成.DLL文件,并在PRAC.INI文件中加入下面语句,即可达到扩展功能的目的。在PRAC.INI中加入:

[AddApp]

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

扩展功能的动态链接函数库代码如下:

/*-----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;

}

}

/*函数FMExtensionProc()即为扩展功能的处理函数,当过滤函数检索到有来自扩展功能的菜单消息时,就调用该函数进行处理。在此仅以设置打印机、选择字体来说明扩展功能的处理过程,读者可根据自己的需要修改*/

void FAR PASCAL FMExtensionProc(HWND hWndFMExt , WORD wMessage)

{

PRINTDLGpd;

CHOOSEFONT fnt;

LOGFONT lf;

CHOOSECOLOR chclr;

DWORD dwColor;

DWORD dwCustClrs[16];

int i;

switch(wMessage)

{

/*处理FMEVENT_LOAD消息,加载用户扩展功能菜单FMExtMenu*/

case EXTPROC_LOAD:

hExtMenu = LoadMenu(FMExtInst,"FMExtMenu");

hMenu = GetMenu(hWndFMExt);

AppendMenu(hMenu,MF_POPUP,hExtMenu ,"扩展功能(&E)");

SetMenu(hWndFMExt,hMenu);

break;

/*下面是用户可自定义的扩展功能代码*/

case IDM_PRINTERSETUP: //设置打印机

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_SELECTFONT102

#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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有