资源MFC DLL的制作[在DLL中封装MFC对话框] 下载本文

内容发布更新时间 : 2024/11/19 18:25:57星期一 下面是文章的全部内容请认真阅读。

资源MFC DLL的制作[在DLL中封装MFC对话框]

UISTYLER中没有树列表控件的吧?对UG的二次开发中会常需要树列表控件,解决之道可以使用MFC中的树列表控件。

所涉及的知识:

(1)MFC模块状态的切换

(2)在DLL中封装一个非模态对话框,可被任何WIN32程序调用 (3)非模态对话框的销毁

(4)怎样将层次特征的信息自私树状列表控件中显示

一.要做的一些准备

1.粗通一些MFC和DLL的知识。

得知道什么是窗口对象,什么是程序对象,什么是事件,什么是消息,什么是消息映射及怎样实现消息映射。对于DLL,知道怎样输出一些函数就差不多了,怎样在应用程序中加载一个DLL,并使用它们提供的接口。

2.控件通知消息(Notification message)

控件中发生了一些事件,是在控件的父窗口中响应事件,而不是在控件的窗口中响应。程序实现时,就相应的将这些事件的处理统统放在控件对象的父窗口对象的消息成员函数中。控件通知消息只适用于标准的窗口控件如按钮、列表框、组合框、编辑框,以及树状视图、列表视图等公共控件。例如,单击或双击一个控件、在控件中选择部分文本、操作控件的滚动条都会产生通知消息。

3.用到的控件是Tree Control MSDN中的说法:

MFC 提供了两个封装树控件 (Tree Control) 的类:CTreeCtrl 和CTreeView。

CTreeView的使用过于复杂。Tree Control则是它的简化版本,主要用做对话框上的控件。

4. 采用的DLL格式:

由于我们只是想使用DLL导出的对话框资源,而且还想着有可能在非MFC环境中使用该对话框资源,规则的MFC DLL可以胜任,就没必要使用MFC扩展DLL了,另外如果使用了扩展的MFC DLL,那么你的应用程序也必须使用MFC库。

5.开发工具

能不用VC6就不用,用VS.net吧,它更支持ANSI C/C++,功能也更强大

二.建立一个可以包含MFC对话框的DLL

树形控件仅能以子窗口的形式出现,它要依附对话框这样的父窗口。 可以在UG二次开发的DLL项目中直接添加对话框资源和对话框类来实现,手段虽不怎么高明,但能实现所需的功能。但我觉得最好将与UG没有多大关系的功能分离出来,作为一个模块单独实现,这也是软件工程所鼓励的方式。

本文的方法是首先做一个DLL,让包含一个MFC对话框,这个DLL可以在UG二次开发的项目中被加载。被包含在DLL中的对话框通常称为资源对话框。

下面为建立可以包含对话框资源的DLL的过程。 1.建一个MFC Regular DLL项目 .

VS.net(没找到英文版,菜单只能给出中文名称)的建立一个DLL的过程如下:

[1]菜单 文件→新建→项目,在弹出的项目对话框的左栏,选择Visual C++项目,在右栏选择MFC DLL。然后在下面的文本框中输入项目的名字,确定,进入MFC DLL向导。 [2]MFC DLL向导,在\应用程序设置\中,选择'使用共享MFC DLL的规则DLL\,完成向导设置后,生成一个空的MFC DLL项目。

[3]菜单:项目→添加资源,在添加资源对话框中,选择\,然后点击按钮\新建\。VS.net会自动切换到资源视图界面,删去默认的\和\按钮。 [4]将默认的对话框ID修改成你能记得住的名字。 [5]添加对话框类CTreeDlg。 //--------------------

以上过程都是IDE在工作,下面就要动脑,动手了。 //-------------------

[6] 建立输出函数ShowTreeDlg DLL是无法自动进入内存开始运行的,要被其它可执行文件的加载才可以。对话框是在DLL中创建的,我们期望在UG二次开发的项目中,在某个UIStyler控件的触发下弹出这个DLL中创建的对话框。而常规的MFC DLL是无法导出MFC对象给其它应用程序使用的,只能通过输出函数来做。

向工程中添加两个文件ExportFunc.h和ExportFunc.CPP,我打算将输出函数的声明和定义统一放在这两个文件中,便于管理。代码实现如下: //-------------------------------------------- //ExportFunc.h,

//声明欲输出的函数

//------------------------------------------- #ifndef _EXPORTFunc_H #define _EXPORTFunc_H #ifdef _cplusplus extern \ #endif

void ShowTreeDlg(HWND hMainWnd); #ifdef _cplusplus }

#endif #endif

//-------------------------------------------- //ExportFunc.cpp文件 //定义输出函数

//-------------------------------------------

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //功能:DLL的输出函数,当其他应用程序加载该DLL后,调用这个函数,可以显示该DLL内建的对话框

//输入参数1:HWND hMainWnd,对话框父窗口的句柄

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void ShowTreeDlg(HWND hMainWnd) {

  AFX_MANAGE_STATE(AfxGetStaticModuleState());   CTreeDlg *pTreeDlg=new CTreeDlg;

  CWnd * pMainWnd=CWnd:: FromHandle(hMainWnd);   ASSERT(pMainWnd);

  BOOL retValue=pTreeDlg->Create(IDD_TREE,pMainWnd);   if(!retValue)   {

    AfxMessageBox(\创建包含树列表控件的对话框失败了!\   }

  pTreeDlg->ShowWindow(SW_SHOW); }

下面是模块定义文件的内容,通常我们是使用_declspec(dllexport)直接修饰输出的函数,这样导出的接口很容易就被查看DLL文件的工具观察到,保密性不够好。为了向外界隐藏你的DLL对外接口的名称,只有def文件可以做。 ; DlgWithTreeCtrl.def : 声明 DLL 的模块参数。

LIBRARY \

EXPORTS

    ; 此处可以是显式导出    ShowTreeDlg @1 NONAME