国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
VC++動(dòng)態(tài)鏈接庫(kù)編程之MFC規(guī)則DLL

第4節(jié)我們對(duì)非MFC DLL進(jìn)行了介紹,這一節(jié)將詳細(xì)地講述MFC規(guī)則DLL的創(chuàng)建與使用技巧。

另外,自從本文開(kāi)始連載后,收到了一些讀者的e-mail。有的讀者提出了一些問(wèn)題,筆者將在本文的最后一次連載中選取其中的典型問(wèn)題進(jìn)行解答。由于時(shí)間的關(guān)系,對(duì)于讀者朋友的來(lái)信,筆者暫時(shí)不能一一回復(fù),還望海涵!由于筆者的水平有限,文中難免有錯(cuò)誤和紕漏,也熱誠(chéng)歡迎讀者朋友不吝指正!

5. MFC規(guī)則DLL

5.1 概述

MFC規(guī)則DLL的概念體現(xiàn)在兩方面:

(1) 它是MFC的

“是MFC的”意味著可以在這種DLL的內(nèi)部使用MFC;

(2) 它是規(guī)則的

“是規(guī)則的”意味著它不同于MFC擴(kuò)展DLL,在MFC規(guī)則DLL的內(nèi)部雖然可以使用MFC,但是其與應(yīng)用程序的接口不能是MFC。而MFC擴(kuò)展DLL與應(yīng)用程序的接口可以是MFC,可以從MFC擴(kuò)展DLL中導(dǎo)出一個(gè)MFC類(lèi)的派生類(lèi)。

Regular DLL能夠被所有支持DLL技術(shù)的語(yǔ)言所編寫(xiě)的應(yīng)用程序調(diào)用,當(dāng)然也包括使用MFC的應(yīng)用程序。在這種動(dòng)態(tài)連接庫(kù)中,包含一個(gè)從CWinApp繼承下來(lái)的類(lèi),DllMain函數(shù)則由MFC自動(dòng)提供。

Regular DLL分為兩類(lèi):

(1)靜態(tài)鏈接到MFC 的規(guī)則DLL

靜態(tài)鏈接到MFC的規(guī)則DLL與MFC庫(kù)(包括MFC擴(kuò)展 DLL)靜態(tài)鏈接,將MFC庫(kù)的代碼直接生成在.dll文件中。在調(diào)用這種DLL的接口時(shí),MFC使用DLL的資源。因此,在靜態(tài)鏈接到MFC 的規(guī)則DLL中不需要進(jìn)行模塊狀態(tài)的切換。

使用這種方法生成的規(guī)則DLL其程序較大,也可能包含重復(fù)的代碼。

(2)動(dòng)態(tài)鏈接到MFC 的規(guī)則DLL

動(dòng)態(tài)鏈接到MFC 的規(guī)則DLL 可以和使用它的可執(zhí)行文件同時(shí)動(dòng)態(tài)鏈接到 MFC DLL 和任何MFC擴(kuò)展 DLL。在使用了MFC共享庫(kù)的時(shí)候,默認(rèn)情況下,MFC使用主應(yīng)用程序的資源句柄來(lái)加載資源模板。這樣,當(dāng)DLL和應(yīng)用程序中存在相同ID的資源時(shí)(即所謂的資源重復(fù)問(wèn)題),系統(tǒng)可能不能獲得正確的資源。因此,對(duì)于共享MFC DLL的規(guī)則DLL,我們必須進(jìn)行模塊切換以使得MFC能夠找到正確的資源模板。

我們可以在Visual C++中設(shè)置MFC規(guī)則DLL是靜態(tài)鏈接到MFC DLL還是動(dòng)態(tài)鏈接到MFC DLL。如圖8,依次選擇Visual C++的project -> Settings -> General菜單或選項(xiàng),在Microsoft Foundation Classes中進(jìn)行設(shè)置。

 

圖8 設(shè)置動(dòng)態(tài)/靜態(tài)鏈接MFC DLL

5.2 MFC規(guī)則DLL的創(chuàng)建

我們來(lái)一步步講述使用MFC向?qū)?chuàng)建MFC規(guī)則DLL的過(guò)程,首先新建一個(gè)project,如圖9,選擇project的類(lèi)型為MFC AppWizard(dll)。點(diǎn)擊OK進(jìn)入如圖10所示的對(duì)話(huà)框。

 

圖9 MFC DLL工程的創(chuàng)建

 

圖10所示對(duì)話(huà)框中的1區(qū)選擇MFC DLL的類(lèi)別。

2區(qū)選擇是否支持automation(自動(dòng)化)技術(shù), automation 允許用戶(hù)在一個(gè)應(yīng)用程序中操縱另外一個(gè)應(yīng)用程序或組件。例如,我們可以在應(yīng)用程序中利用 Microsoft Word 或Microsoft Excel的工具,而這種使用對(duì)用戶(hù)而言是透明的。自動(dòng)化技術(shù)可以大大簡(jiǎn)化和加快應(yīng)用程序的開(kāi)發(fā)。

3區(qū)選擇是否支持Windows Sockets,當(dāng)選擇此項(xiàng)目時(shí),應(yīng)用程序能在 TCP/IP 網(wǎng)絡(luò)上進(jìn)行通信。 CWinApp派生類(lèi)的InitInstance成員函數(shù)會(huì)初始化通訊端的支持,同時(shí)工程中的StdAfx.h文件會(huì)自動(dòng)include <AfxSock.h>頭文件。

添加socket通訊支持后的InitInstance成員函數(shù)如下:

BOOL CRegularDllSocketApp::InitInstance()

{

if (!AfxSocketInit())

{

AfxMessageBox(IDP_SOCKETS_INIT_FAILED);

return FALSE;

}

return TRUE;

}

4區(qū)選擇是否由MFC向?qū)ё詣?dòng)在源代碼中添加注釋?zhuān)话阄覀冞x擇“Yes,please”。

 

圖10 MFC DLL的創(chuàng)建選項(xiàng)
 5.3 一個(gè)簡(jiǎn)單的MFC規(guī)則DLL

 

這個(gè)DLL的例子(屬于靜態(tài)鏈接到MFC 的規(guī)則DLL)中提供了一個(gè)如圖11所示的對(duì)話(huà)框。

 

圖11 MFC規(guī)則DLL例子

在DLL中添加對(duì)話(huà)框的方式與在MFC應(yīng)用程序中是一樣的。 在圖11所示DLL中的對(duì)話(huà)框的Hello按鈕上點(diǎn)擊時(shí)將MessageBox一個(gè)“Hello,pconline的網(wǎng)友”對(duì)話(huà)框,下面是相關(guān)的文件及源代碼,其中刪除了MFC向?qū)ё詣?dòng)生成的絕大多數(shù)注釋:

第一組文件:CWinApp繼承類(lèi)的聲明與實(shí)現(xiàn)

// RegularDll.h : main header file for the REGULARDLL DLL

#if !defined(AFX_REGULARDLL_H__3E9CB22B_588B_4388_B778_B3416ADB79B3__INCLUDED_)

#define AFX_REGULARDLL_H__3E9CB22B_588B_4388_B778_B3416ADB79B3__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__

#error include ’stdafx.h’ before including this file for PCH

#endif

#include "resource.h" // main symbols

class CRegularDllApp : public CWinApp

{

public:

CRegularDllApp();

DECLARE_MESSAGE_MAP()

};

#endif

// RegularDll.cpp : Defines the initialization routines for the DLL.

#include "stdafx.h"

#include "RegularDll.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

BEGIN_MESSAGE_MAP(CRegularDllApp, CWinApp)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CRegularDllApp construction

CRegularDllApp::CRegularDllApp()

{

}

/////////////////////////////////////////////////////////////////////////////

// The one and only CRegularDllApp object

CRegularDllApp theApp;

分析:

在這一組文件中定義了一個(gè)繼承自CWinApp的類(lèi)CRegularDllApp,并同時(shí)定義了其的一個(gè)實(shí)例theApp。乍一看,您會(huì)以為它是一個(gè)MFC應(yīng)用程序,因?yàn)镸FC應(yīng)用程序也包含這樣的在工程名后添加“App”組成類(lèi)名的類(lèi)(并繼承自CWinApp類(lèi)),也定義了這個(gè)類(lèi)的一個(gè)全局實(shí)例theApp。

我們知道,在MFC應(yīng)用程序中CWinApp取代了SDK程序中WinMain的地位,SDK程序WinMain所完成的工作由CWinApp的三個(gè)函數(shù)完成:

virtual BOOL InitApplication( );

virtual BOOL InitInstance( );

virtual BOOL Run( ); //傳說(shuō)中MFC程序的“活水源頭”

但是MFC規(guī)則DLL并不是MFC應(yīng)用程序,它所繼承自CWinApp的類(lèi)不包含消息循環(huán)。這是因?yàn)椋琈FC規(guī)則DLL不包含CWinApp::Run機(jī)制,主消息泵仍然由應(yīng)用程序擁有。如果DLL 生成無(wú)模式對(duì)話(huà)框或有自己的主框架窗口,則應(yīng)用程序的主消息泵必須調(diào)用從DLL 導(dǎo)出的函數(shù)來(lái)調(diào)用PreTranslateMessage成員函數(shù)。

另外,MFC規(guī)則DLL與MFC 應(yīng)用程序中一樣,需要將所有 DLL中元素的初始化放到InitInstance 成員函數(shù)中。

第二組文件 自定義對(duì)話(huà)框類(lèi)聲明及實(shí)現(xiàn)

#if !defined(AFX_DLLDIALOG_H__CEA4C6AF_245D_48A6_B11A_A5521EAD7C4E__INCLUDED_)

#define AFX_DLLDIALOG_H__CEA4C6AF_245D_48A6_B11A_A5521EAD7C4E__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// DllDialog.h : header file

/////////////////////////////////////////////////////////////////////////////

// CDllDialog dialog

class CDllDialog : public CDialog

{

// Construction

public:

CDllDialog(CWnd* pParent = NULL); // standard constructor

enum { IDD = IDD_DLL_DIALOG };

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

// Implementation

protected:

afx_msg void OnHelloButton();

DECLARE_MESSAGE_MAP()

};

#endif

// DllDialog.cpp : implementation file

#include "stdafx.h"

#include "RegularDll.h"

#include "DllDialog.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CDllDialog dialog

CDllDialog::CDllDialog(CWnd* pParent /*=NULL*/)

: CDialog(CDllDialog::IDD, pParent)

{}

void CDllDialog::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CDllDialog, CDialog)

ON_BN_CLICKED(IDC_HELLO_BUTTON, OnHelloButton)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CDllDialog message handlers

void CDllDialog::OnHelloButton()

{

MessageBox("Hello,pconline的網(wǎng)友","pconline");

}

分析:

這一部分的編程與一般的應(yīng)用程序根本沒(méi)有什么不同,我們照樣可以利用MFC類(lèi)向?qū)?lái)自動(dòng)為對(duì)話(huà)框上的控件添加事件。MFC類(lèi)向?qū)д諛訒?huì)生成類(lèi)似ON_BN_CLICKED(IDC_HELLO_BUTTON, OnHelloButton)的消息映射宏。

第三組文件 DLL中的資源文件

//{{NO_DEPENDENCIES}}

// Microsoft Developer Studio generated include file.

// Used by RegularDll.rc

//

#define IDD_DLL_DIALOG 1000

#define IDC_HELLO_BUTTON 1000

分析:

在MFC規(guī)則DLL中使用資源也與在MFC應(yīng)用程序中使用資源沒(méi)有什么不同,我們照樣可以用Visual C++的資源編輯工具進(jìn)行資源的添加、刪除和屬性的更改。

第四組文件 MFC規(guī)則DLL接口函數(shù)

#include "StdAfx.h"

#include "DllDialog.h"

extern "C" __declspec(dllexport) void ShowDlg(void)

{

CDllDialog dllDialog;

dllDialog.DoModal();

}

分析:

這個(gè)接口并不使用MFC,但是在其中卻可以調(diào)用MFC擴(kuò)展類(lèi)CdllDialog的函數(shù),這體現(xiàn)了“規(guī)則”的概類(lèi)。

與非MFC DLL完全相同,我們可以使用__declspec(dllexport)聲明或在.def中引出的方式導(dǎo)出MFC規(guī)則DLL中的接口。
   5.4 MFC規(guī)則DLL的調(diào)用

 

筆者編寫(xiě)了如圖12的對(duì)話(huà)框MFC程序來(lái)調(diào)用5.3節(jié)的MFC規(guī)則DLL,在這個(gè)程序的對(duì)話(huà)框上點(diǎn)擊“調(diào)用DLL”按鈕時(shí)彈出5.3節(jié)MFC規(guī)則DLL中的對(duì)話(huà)框。

 

圖12 MFC規(guī)則DLL的調(diào)用例子

下面是“調(diào)用DLL”按鈕單擊事件的消息處理函數(shù):

void CRegularDllCallDlg::OnCalldllButton()

{

typedef void (*lpFun)(void);

HINSTANCE hDll; //DLL句柄

hDll = LoadLibrary("RegularDll.dll");

if (NULL==hDll)

{

MessageBox("DLL加載失敗");

}

lpFun addFun; //函數(shù)指針

lpFun pShowDlg = (lpFun)GetProcAddress(hDll,"ShowDlg");

if (NULL==pShowDlg)

{

MessageBox("DLL中函數(shù)尋找失敗");

}

pShowDlg();

}

上述例子中給出的是顯示調(diào)用的方式,可以看出,其調(diào)用方式與第4節(jié)中非MFC DLL的調(diào)用方式?jīng)]有什么不同。

我們照樣可以在EXE程序中隱式調(diào)用MFC規(guī)則DLL,只需要將DLL工程生成的.lib文件和.dll文件拷入當(dāng)前工程所在的目錄,并在RegularDllCallDlg.cpp文件(圖12所示對(duì)話(huà)框類(lèi)的實(shí)現(xiàn)文件)的頂部添加:

#pragma comment(lib,"RegularDll.lib")

void ShowDlg(void);

并將void CRegularDllCallDlg::OnCalldllButton() 改為:

void CRegularDllCallDlg::OnCalldllButton()

{

ShowDlg();

}

5.5 共享MFC DLL的規(guī)則DLL的模塊切換

應(yīng)用程序進(jìn)程本身及其調(diào)用的每個(gè)DLL模塊都具有一個(gè)全局唯一的HINSTANCE句柄,它們代表了DLL或EXE模塊在進(jìn)程虛擬空間中的起始地址。進(jìn)程本身的模塊句柄一般為0x400000,而DLL模塊的缺省句柄為0x10000000。如果程序同時(shí)加載了多個(gè)DLL,則每個(gè)DLL模塊都會(huì)有不同的HINSTANCE。應(yīng)用程序在加載DLL時(shí)對(duì)其進(jìn)行了重定位。

共享MFC DLL(或MFC擴(kuò)展DLL)的規(guī)則DLL涉及到HINSTANCE句柄問(wèn)題,HINSTANCE句柄對(duì)于加載資源特別重要。EXE和DLL都有其自己的資源,而且這些資源的ID可能重復(fù),應(yīng)用程序需要通過(guò)資源模塊的切換來(lái)找到正確的資源。如果應(yīng)用程序需要來(lái)自于DLL的資源,就應(yīng)將資源模塊句柄指定為DLL的模塊句柄;如果需要EXE文件中包含的資源,就應(yīng)將資源模塊句柄指定為EXE的模塊句柄。

這次我們創(chuàng)建一個(gè)動(dòng)態(tài)鏈接到MFC DLL的規(guī)則DLL,在其中包含如圖13的對(duì)話(huà)框。

 

圖13 DLL中的對(duì)話(huà)框

另外,在與這個(gè)DLL相同的工作區(qū)中生成一個(gè)基于對(duì)話(huà)框的MFC程序,其對(duì)話(huà)框與圖12完全一樣。但是在此工程中我們另外添加了一個(gè)如圖14的對(duì)話(huà)框。

 

圖14 EXE中的對(duì)話(huà)框

圖13和圖14中的對(duì)話(huà)框除了caption不同(以示區(qū)別)以外,其它的都相同。

尤其值得特別注意,在DLL和EXE中我們對(duì)圖13和圖14的對(duì)話(huà)框使用了相同的資源ID=2000,在DLL和EXE工程的resource.h中分別有如下的宏:

//DLL中對(duì)話(huà)框的ID

#define IDD_DLL_DIALOG 2000

//EXE中對(duì)話(huà)框的ID

#define IDD_EXE_DIALOG 2000

與5.3節(jié)靜態(tài)鏈接MFC DLL的規(guī)則DLL相同,我們還是在規(guī)則DLL中定義接口函數(shù)ShowDlg,原型如下:

#include "StdAfx.h"

#include "SharedDll.h"

void ShowDlg(void)

{

CDialog dlg(IDD_DLL_DIALOG); //打開(kāi)ID為2000的對(duì)話(huà)框

dlg.DoModal();

}

而為應(yīng)用工程主對(duì)話(huà)框的“調(diào)用DLL”的單擊事件添加如下消息處理函數(shù):

void CSharedDllCallDlg::OnCalldllButton()

{

ShowDlg();

}

我們以為單擊“調(diào)用DLL”會(huì)彈出如圖13所示DLL中的對(duì)話(huà)框,可是可怕的事情發(fā)生了,我們看到是圖14所示EXE中的對(duì)話(huà)框!
  驚訝?

 

產(chǎn)生這個(gè)問(wèn)題的根源在于應(yīng)用程序與MFC規(guī)則DLL共享MFC DLL(或MFC擴(kuò)展DLL)的程序總是默認(rèn)使用EXE的資源,我們必須進(jìn)行資源模塊句柄的切換,其實(shí)現(xiàn)方法有三:

方法一 在DLL接口函數(shù)中使用:

AFX_MANAGE_STATE(AfxGetStaticModuleState());

我們將DLL中的接口函數(shù)ShowDlg改為:

void ShowDlg(void)

{

//方法1:在函數(shù)開(kāi)始處變更,在函數(shù)結(jié)束時(shí)恢復(fù)

//將AFX_MANAGE_STATE(AfxGetStaticModuleState());作為接口函數(shù)的第一//條語(yǔ)句進(jìn)行模塊狀態(tài)切換

AFX_MANAGE_STATE(AfxGetStaticModuleState());

CDialog dlg(IDD_DLL_DIALOG);//打開(kāi)ID為2000的對(duì)話(huà)框

dlg.DoModal();

}

這次我們?cè)冱c(diǎn)擊EXE程序中的“調(diào)用DLL”按鈕,彈出的是DLL中的如圖13的對(duì)話(huà)框!嘿嘿,彈出了正確的對(duì)話(huà)框資源。

AfxGetStaticModuleState是一個(gè)函數(shù),其原型為:

AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState( );

該函數(shù)的功能是在棧上(這意味著其作用域是局部的)創(chuàng)建一個(gè)AFX_MODULE_STATE類(lèi)(模塊全局?jǐn)?shù)據(jù)也就是模塊狀態(tài))的實(shí)例,對(duì)其進(jìn)行設(shè)置,并將其指針pModuleState返回。

AFX_MODULE_STATE類(lèi)的原型如下:

// AFX_MODULE_STATE (global data for a module)

class AFX_MODULE_STATE : public CNoTrackObject

{

public:

#ifdef _AFXDLL

AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion);

AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion,BOOL bSystem);

#else

AFX_MODULE_STATE(BOOL bDLL);

#endif

~AFX_MODULE_STATE();

CWinApp* m_pCurrentWinApp;

HINSTANCE m_hCurrentInstanceHandle;

HINSTANCE m_hCurrentResourceHandle;

LPCTSTR m_lpszCurrentAppName;

… //省略后面的部分

}

AFX_MODULE_STATE類(lèi)利用其構(gòu)造函數(shù)和析構(gòu)函數(shù)進(jìn)行存儲(chǔ)模塊狀態(tài)現(xiàn)場(chǎng)及恢復(fù)現(xiàn)場(chǎng)的工作,類(lèi)似匯編中call指令對(duì)pc指針和sp寄存器的保存與恢復(fù)、中斷服務(wù)程序的中斷現(xiàn)場(chǎng)壓棧與恢復(fù)以及操作系統(tǒng)線(xiàn)程調(diào)度的任務(wù)控制塊保存與恢復(fù)。

許多看似不著邊際的知識(shí)點(diǎn)居然有驚人的相似!

AFX_MANAGE_STATE是一個(gè)宏,其原型為:

AFX_MANAGE_STATE( AFX_MODULE_STATE* pModuleState )

該宏用于將pModuleState設(shè)置為當(dāng)前的有效模塊狀態(tài)。當(dāng)離開(kāi)該宏的作用域時(shí)(也就離開(kāi)了pModuleState所指向棧上對(duì)象的作用域),先前的模塊狀態(tài)將由AFX_MODULE_STATE的析構(gòu)函數(shù)恢復(fù)。

方法二 在DLL接口函數(shù)中使用:

AfxGetResourceHandle();

AfxSetResourceHandle(HINSTANCE xxx);

AfxGetResourceHandle用于獲取當(dāng)前資源模塊句柄,而AfxSetResourceHandle則用于設(shè)置程序目前要使用的資源模塊句柄。

我們將DLL中的接口函數(shù)ShowDlg改為:

void ShowDlg(void)

{

//方法2的狀態(tài)變更

HINSTANCE save_hInstance = AfxGetResourceHandle();

AfxSetResourceHandle(theApp.m_hInstance);

CDialog dlg(IDD_DLL_DIALOG);//打開(kāi)ID為2000的對(duì)話(huà)框

dlg.DoModal();

//方法2的狀態(tài)還原

AfxSetResourceHandle(save_hInstance);

}

通過(guò)AfxGetResourceHandle和AfxSetResourceHandle的合理變更,我們能夠靈活地設(shè)置程序的資源模塊句柄,而方法一則只能在DLL接口函數(shù)退出的時(shí)候才會(huì)恢復(fù)模塊句柄。方法二則不同,如果將ShowDlg改為:

extern CSharedDllApp theApp; //需要聲明theApp外部全局變量

void ShowDlg(void)

{

//方法2的狀態(tài)變更

HINSTANCE save_hInstance = AfxGetResourceHandle();

AfxSetResourceHandle(theApp.m_hInstance);

CDialog dlg(IDD_DLL_DIALOG);//打開(kāi)ID為2000的對(duì)話(huà)框

dlg.DoModal();

//方法2的狀態(tài)還原

AfxSetResourceHandle(save_hInstance);

//使用方法2后在此處再進(jìn)行操作針對(duì)的將是應(yīng)用程序的資源

CDialog dlg1(IDD_DLL_DIALOG); //打開(kāi)ID為2000的對(duì)話(huà)框

dlg1.DoModal();

}

在應(yīng)用程序主對(duì)話(huà)框的“調(diào)用DLL”按鈕上點(diǎn)擊,將看到兩個(gè)對(duì)話(huà)框,相繼為DLL中的對(duì)話(huà)框(圖13)和EXE中的對(duì)話(huà)框(圖14)。

方法三 由應(yīng)用程序自身切換

資源模塊的切換除了可以由DLL接口函數(shù)完成以外,由應(yīng)用程序自身也能完成。

現(xiàn)在我們把DLL中的接口函數(shù)改為最簡(jiǎn)單的:

void ShowDlg(void)

{

CDialog dlg(IDD_DLL_DIALOG); //打開(kāi)ID為2000的對(duì)話(huà)框

dlg.DoModal();

}

而將應(yīng)用程序的OnCalldllButton函數(shù)改為:

void CSharedDllCallDlg::OnCalldllButton()

{

//方法3:由應(yīng)用程序本身進(jìn)行狀態(tài)切換

//獲取EXE模塊句柄

HINSTANCE exe_hInstance = GetModuleHandle(NULL);

//或者HINSTANCE exe_hInstance = AfxGetResourceHandle();

//獲取DLL模塊句柄

HINSTANCE dll_hInstance = GetModuleHandle("SharedDll.dll");

AfxSetResourceHandle(dll_hInstance); //切換狀態(tài)

ShowDlg(); //此時(shí)顯示的是DLL的對(duì)話(huà)框

AfxSetResourceHandle(exe_hInstance); //恢復(fù)狀態(tài)

//資源模塊恢復(fù)后再調(diào)用ShowDlg

ShowDlg(); //此時(shí)顯示的是EXE的對(duì)話(huà)框

}

方法三中的Win32函數(shù)GetModuleHandle可以根據(jù)DLL的文件名獲取DLL的模塊句柄。如果需要得到EXE模塊的句柄,則應(yīng)調(diào)用帶有Null參數(shù)的GetModuleHandle。

方法三與方法二的不同在于方法三是在應(yīng)用程序中利用AfxGetResourceHandle和AfxSetResourceHandle進(jìn)行資源模塊句柄切換的。同樣地,在應(yīng)用程序主對(duì)話(huà)框的“調(diào)用DLL”按鈕上點(diǎn)擊,也將看到兩個(gè)對(duì)話(huà)框,相繼為DLL中的對(duì)話(huà)框(圖13)和EXE中的對(duì)話(huà)框(圖14)。

在下一節(jié)我們將對(duì)MFC擴(kuò)展DLL進(jìn)行詳細(xì)分析和實(shí)例講解,歡迎您繼續(xù)關(guān)注本系列連載。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
在DLL中使用資源(二)
dll的概念、dll導(dǎo)出類(lèi)(轉(zhuǎn))
VC++動(dòng)態(tài)鏈接庫(kù)編程之DLL典型實(shí)例
C、C++控制臺(tái)程序、Windows API程序、MFC程序理解與比較
MFC與ARX結(jié)合開(kāi)發(fā)完美的AutoCAD應(yīng)用程序
DLL導(dǎo)出資源問(wèn)題的解決
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服