多个人一起开发,划分成多个模块,想使用dll的方式,独立成多个project编译成dll来调用,望给出相关帮助。谢谢。

解决方案 »

  1.   

    在DLL中使用资源(一) 
        现在最常看见的关于DLL的问题就是如何在DLL中使用对话框,这是一个很普遍的关于如何在DLL中使用资源的问题。这里我们从Win32 DLL和MFC DLL两个方面来分析并解决这个问题。 1.Win32 DLL 
        在Win32 DLL中使用对话框很简单,你只需要在你的DLL中添加对话框资源,而且可以在对话框上面设置你所需要的控件。然后使用DialogBox或者CreateDialog这两个函数(或相同作用的其它函数)来创建对话框,并定义你自己的对话框回调函数处理对话框收到的消息。下面通过一个具体实例来学习如何在Win32 DLL中使用对话框,可以按照以下步骤来完成这个例子: 1)在VC菜单中File->New新建一个命名为UseDlg的Win32 Dynamic-Link Library工程,下一步选择A simple DLL project。 2)在VC菜单中Insert->Resource添加一个ID为IDD_DLG_SHOW的Dialog资源,将此Dialog上的Cancel按钮去掉,仅保留OK按钮。再添加一个ID为IDD_ABOUTBOX的对话框,其Caption为About。保存此资源,将资源文件命名为UseDlg.rc。并将resource.h和UseDlg.rc加入到工程里面。 3)在UseDlg.app中包含resource.h,并添加如下代码: HINSTANCE hinst = NULL; HWND hwndDLG = NULL; BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); BOOL CALLBACK AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); extern "C" __declspec(dllexport) void ShowDlg(); BOOL APIENTRY DllMain( HANDLE hModule,             DWORD ul_reason_for_call,             LPVOID lpReserved                   ) {     switch(ul_reason_for_call)     {     case DLL_PROCESS_ATTACH:        hinst = (HINSTANCE)hModule;     case DLL_PROCESS_DETACH:        break;     }   return TRUE; } extern "C" __declspec(dllexport) void ShowDlg() {     hwndDLG = CreateDialog(hinst,MAKEINTRESOURCE(IDD_DLG_SHOW), NULL,(DLGPROC)DlgProc);     ShowWindow(hwndDLG, SW_SHOW); } BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {   switch(message)   {     case WM_INITDIALOG:        return TRUE;             case WM_COMMAND:        if(LOWORD(wParam)==IDOK) DialogBox(hinst,MAKEINTRESOURCE(IDD_ABOUTBOX), hDlg,(DLGPROC)AboutProc);        return TRUE;         case WM_CLOSE:        DestroyWindow(hDlg);        hwndDLG = NULL;        return TRUE;   }   return FALSE; } BOOL CALLBACK AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {     switch(message)   {        case WM_CLOSE:            EndDialog(hDlg,NULL);            hwndDLG = NULL;            return TRUE;   }   return FALSE; } 4)编译生成UseDlg.dll和UseDlg.lib。 接下来我们建立调用此DLL的应用程序,其步骤如下: 1)在VC菜单中File->New新建一个命名为Use的MFC AppWizard(exe)工程,下一步选择Dialog Based之后点击Finish按钮。 2)在主对话框上面添加一个按钮,之后双击此按钮,会弹出Add Member Function的对话框,直接点击OK进入void CUseDlg::OnButton1()函数。并在此函数内添加一个函数调用:ShowDlg();。 3)紧跟在#include语句后面加上如下代码: extern "C" __declspec(dllexport) void ShowDlg(); #pragma comment(lib,"debug/UseDlg") 4)将上面UseDlg工程中生成的UseDlg.dll和UseDlg.lib两个文件复制到Use工程的Debug目录内。 5)编译生成Use.exe。     运行Use.exe,点击Button1按钮,可以看到一个名称为Dialog的非模态对话框弹出。点击上面的按钮,可以弹出模态对话框About。运行成功。     让我们来回顾一下在Win32 DLL中使用对话框的过程。 在DLL中,我们定义了两个对话框资源:IDD_DLG_SHOW和IDD_ABOUTBOX,并且导出了函数ShowDlg。在函数ShowDlg之中使用CreateDialog函数创建了非模态对话框IDD_DLG_SHOW,并指定了该对话框的回调函数DlgProc。在DlgProc之中处理了WM_INITDIALOG、WM_COMMAND和WM_CLOSE消息,以响应用户对对话框所做的动作。在处理按钮动作的时候,使用DialogBox函数创建IDD_ABOUTBOX这个模态对话框,指定其回调函数为AboutProc,并且在AboutProc中处理其相应消息。 在EXE中,我们使用隐式链接的方法来调用DLL,并使用DLL中导出的ShowDlg函数来调用DLL中的对话框。     在Win32 DLL中使用对话框就是这么简单,下面让我们来看一下在MFC DLL中如何使用对话框。 
    2.MFC DLL 
        在MFC DLL中使用对话框不像Win32 DLL中那么简单,主要是因为MFC程序中存在一个模块状态(Module State)的问题,也就是资源重复的问题。(此处的术语模块是指一个可执行程序,或指其操作不依赖于应用程序的其余部分但使用MFC运行库的共享副本的一个DLL(或一组DLL)。我们所创建的MFC DLL就是这种模块的一个典型实例。)     在每个模块(EXE或DLL)中,都存在一种全局的状态数据,MFC依靠这种全局的状态数据来区分不同的模块,以执行正确的操作。这种数据包括:Windows实例句柄(用于加载资源),指向应用程序当前的CWinApp和CWinThread对象的指针,OLE模块引用计数,以及维护Windows对象句柄与相应的MFC对象实例之间连接的各种映射等。但当应用程序使用多个模块时,每个模块的状态数据不是应用程序范围的。相反,每个模块具有自已的MFC状态数据的私有副本。这种全局的状态数据就叫做MFC模块状态。 模块的状态数据包含在结构中,并且总是可以通过指向该结构的指针使用。当代码在执行时进入了某一个模块时,只有此模块的状态为“当前”或“有效”状态时,MFC才能正确的区分此模块并执行正确的操作。 例如,MFC应用程序可以使用下面代码从资源文件中加载字符串: CString str; str.LoadString(IDS_MYSTRING); 使用这种代码非常方便,但它掩盖了这样一个事实:即此程序中IDS_MYSTRING可能不是唯一的标识符。一个程序可以加载多个DLL,某些DLL可能也用IDS_MYSTRING标识符定义了一个资源。MFC怎样知道应该加载哪个资源呢?MFC使用当前模块状态查找资源句柄。如果当前模块不是我们要使用的正确模块,那么就会产生不正确的调用或者错误。 按照MFC库的链接方法,一个MFC DLL有两种使用MFC库的方法:静态链接到MFC的DLL和动态链接到MFC的DLL。下面我们就按照这两种类型的MFC DLL来介绍如何切换当前模块状态以正确的在MFC DLL中使用资源。 1、静态链接到MFC的DLL 静态链接到MFC的规则DLL与MFC库静态链接,则此时MFC库不能共享,所以MFC总是使用它所链接的DLL的模块状态。这样也就不存在管理模块状态的问题。但使用这种方法的缺点是DLL程序将会变大,而且会在程序中留下重复代码。下面给出的例子验证了这一点。本例可以按照以下步骤来完成: 1)在VC菜单中File->New新建一个命名为DLLStatic的MFC AppWizard的工程,下一步选择Regular DLL with MFC statically linked。 2)在工程中添加一个对话框资源,其ID为:IDD_ABOUTBOX。并在resource.h之中将IDD_ABOUTBOX 的数值改为100。 3)在DLLStatic.cpp中定义如下函数: void ShowDlg() {     CDialog dlg(IDD_ABOUTBOX);     dlg.DoModal(); } 4)在DLLStatic.def文件中的EXPORTS语句中添加一行:ShowDlg,以导出ShowDlg函数。 5)编译生成DLLStatic.dll和DLLStatic.lib。 继续使用上一节中的Use工程,将前面生成的DLLStatic.dll和DLLStatic.lib两个文件复制到工程的Debug目录内,并将 extern "C" __declspec(dllexport) void ShowDlg(); #pragma comment(lib,"debug/UseDlg") 这两行改为: void ShowDlg(); #pragma comment(lib,"debug/DLLStatic") 编译并运行Use.exe。点击按钮,可以看到DLLStatic中的模态对话框弹出。 本例中,可以注意到DLL中所定义的About对话框资源与EXE中所定义的About对话框资源ID完全相同,但是当我们点击Use.exe上面的按钮时,弹出的是DLL中的模态对话框。说明,当使用静态链接到MFC的规则DLL时,不存在管理模块状态的问题。 
    (ZZ)
      

  2.   

    MFC 7.0 版提供对附属 DLL 的增强支持,该功能有助于创建针对多种语言进行本地化的应用程序。附属 DLL 是一个纯资源 DLL,它包含应用程序的针对特定语言进行本地化的资源。当应用程序开始执行时,MFC 自动加载最适合于环境的本地化资源。例如,可能有一个具有英语语言资源的应用程序,该应用程序还有两个附属 DLL,其中一个包含资源的法语译本,另一个包含资源的德语译本。当该应用程序在英语语言系统上运行时,它使用英语资源。如果在法语系统上运行,则它使用法语资源;如果在德语系统上运行,则使用德语资源。为了支持 MFC 应用程序中的本地化资源,MFC 试图加载一个附属 DLL,它包含本地化为特定语言的资源。附属 DLL 被命名为 ApplicationNameXXX.dll,其中 ApplicationName 是使用 MFC 的 .exe 或 .dll 的名称,而 XXX 是资源语言的由三个字母组成的代码(例如,“ENU”或“DEU”)。MFC 试图按顺序加载下列每种语言的资源 DLL,当找到一个时停止: (仅适用于 Windows 2000 或更高版本)当前用户的默认用户界面语言,该语言从 GetUserDefaultUILanguage() Win32 API 返回。 
    (仅适用于 Windows 2000 或更高版本)当前用户的默认用户界面语言,没有任何特定的次语言(也就是说,ENC [加拿大英语] 变为 ENU [美国英语])。 
    系统的默认用户界面语言。在 Windows 2000 或更高版本上,这从 GetSystemDefaultUILanguage() API 返回。在其他平台上,这是操作系统本身的语言。 
    系统的默认用户界面语言,没有任何特定的次语言。 
    具有 3 字母代码 LOC 的“虚设”语言。 
    如果 MFC 未找到任何附属 DLL,则它使用包含在应用程序本身中的任何资源。作为示例,假设应用程序 LangExample.exe 使用 MFC 并且正在 Windows 2000 多用户界面系统上运行;系统的用户界面语言是 ENU [美国英语] 并且当前用户的用户界面语言设置为 FRC [加拿大法语]。MFC 将按下面的顺序查找下面的 DLL: LangExampleFRC.dll(用户的用户界面语言)。 
    LangExampleFRA.dll(用户的用户界面语言,不带次语言;在此示例中为法语(法国))。 
    LangExampleENU.dll(系统的用户界面语言)。 
    LangExampleLOC.dll。 
    如果没找到这些 DLL 中的任何一个,则 MFC 将只是使用 LangExample.exe 中的资源。
      

  3.   

    TN057: Localization of MFC ComponentsSee Also
    Technical Notes by Number | Technical Notes by Category
    Note   The following technical note has not been updated since it was first included in the online documentation. As a result, some procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for the topic of interest in the online documentation index.
    This note describes some of the designs and procedures you can use to localize your component, if it an application or an OLE control or a DLL that uses MFC.OverviewThere are really two issues to resolve when localizing a component that uses MFC. First, you must localize your own resources — strings, dialogs, and other resources that are specific to your component. Most components built using MFC also include and use a number of resources that are defined by MFC. You must provide localized MFC resources as well. Fortunately, several languages are already provided by MFC itself.In addition, your component should be prepared to run in its target environment (European or DBCS-enabled environment). For the most part, this depends on your application treating characters with the high bit set correctly and handling strings with double byte characters. MFC is enabled, by default, for both of these environments, such that it is possible to have a single worldwide binary that is used on all platforms with just different resources plugged in at setup time.Localizing your Component's ResourcesLocalizing your application or DLL should involve simply replacing the resources with resources that match the target language. For your own resources, this is relatively simple: edit the resources in the resource editor and build your application. If your code is written properly there will be no strings or text that you wish to localize hard-coded into your C++ source code – all localization can be done by simply modifying resources. In fact, you can implement your component such that all providing a localized version does not even involve a build of the original code. This is more complex, but is well worth it and is the mechanism chosen for MFC itself. It is also possible to localize an application by loading the EXE or DLL file into the resource editor and editing the resources directly. While possible, it is requires reapplication of those changes each time you build a new version of your application.One way to avoid that is to locate all resources in a separate DLL, sometimes called a satellite DLL. This DLL is then loaded dynamically at runtime and the resources are loaded from that DLL instead of from the main module with all your code. MFC directly supports this approach. Consider an application called MYAPP.EXE; it could have all of its resources located in a DLL called MYRES.DLL. In the application's InitInstance it would perform the following to load that DLL and cause MFC to load resources from that location:CMyApp::InitInstance()
    {
       // one of the first things in the init code
       HINSTANCE hInst = LoadLibrary("myres.dll");
       if (hInst != NULL)
          AfxSetResourceHandle(hInst);   // other initialization code would follow
       .
       .
       .
    }
    From then on, MFC will load resources from that DLL instead of from myapp.exe. All resources, however, must be present in that DLL; MFC will not search the application's instance in search of a given resource. This technique applies equally well to regular DLLs as well as OLE Controls. Your setup program would copy the appropriate version of MYRES.DLL depending upon which resource locale the user would like.It is relatively easy to create a resource only DLL. You create a DLL project, add your .RC file to it, and add the necessary resources. If you have an existing project that does not use this technique, you can copy the resources from that project. After adding the resource file to the project, you are almost ready to build the project. The only thing you must do is set the linker options to include /NOENTRY. This tells the linker that the DLL has no entry point – since it has no code, it has no entry point.Note   The resource editor in Visual C++ 4.0 and later supports multiple languages per .RC file. This can make it very easy to manage your localization in a single project. The resources for each language are controlled by preprocessor directives generated by the resource editor.
    Using the Provided MFC Localized ResourcesAny MFC application that you build reuses two things from MFC: code and resources. That is, MFC has various error messages, built-in dialogs, and other resources that are used by the MFC classes. In order to completely localize your application, you need to localize not only your application's resources, but also the resources that come directly from MFC. MFC provides a number of different language resource files automatically, so that if the language you are targeting is one of the languages MFC already supports, you just need to make sure you use those localized resources. As of this writing, MFC supports Chinese, German, Spanish, French, Italian, Japanese, and Korean. The files which contain these localized versions are in the MFC\INCLUDE\L.* (the 'L' stands for localized) directories. The German files are in MFC\INCLUDE\L.DEU, for example. To cause your application to use these RC files instead of the files located in MFC\INCLUDE, add a /IC:\PROGRAM FILES\MICROSOFT VISUAL STUDIO .NET 2003\VC7\MFC\INCLUDE\L.DEU to your RC command line (this is just an example; you would need to substitute your locale of choice as well as the directory into which you installed Visual C++).The above instructions will work if your application links statically with MFC. Most applications link dynamically (because that is the AppWizard default). In this scenario, not only the code is dynamically linked – so are the resources. As a result, you can localize your resources in your application, but the MFC implementation resources will still be loaded from the MFC7x.DLL (or a later version) or from MFC7xLOC.DLL if it exists. You can approach this from two different angles.The more complex approach is to ship one of the localized MFC7xLOC.DLLs (such as MFC7xDEU, for German, MFC7xESP.DLL for Spanish, etc.), or a later version, and install the appropriate MFC7xLOC.DLL into the system directory when the user installs your application. This can be very complex for both the developer and the end user and as such is not recommended. See Technical Note 56 for more information on this technique and its caveats.The simplest and safest approach is to include the localized MFC resources in your application or DLL itself (or its satellite DLL if you are using one). This avoids the problems of installing MFC7xLOC.DLL properly. To do so, you follow the same instructions for the static case given above (setting the RC command line properly to point to the localized resources), except that you must also remove the /D_AFXDLL define that was added by AppWizard. When /D_AFXDLL is defined, AFXRES.H (and the other MFC RC files) do not actually define any resources (because they will be pulled from the MFC DLLs instead).
      

  4.   

    http://community.csdn.net/Expert/topic/3081/3081869.xml?temp=1.737612E-02