물론 라이브러리 파일은 확장자 lib파일로 만들어도 되나 DLL로 만들면 여러 가지 장점이 있다.
필자의 경우 모든내용을 DLL로 만들지는 않고(DLL파일을 만드는데도 노력이 들어가고 또한 DLL내부에 버그가 있는 경우 따로 컴파일을 해야하므로 관리에도 신경써야한다) 대화 상자를 여러 프로그램에서 사용하는 경우 많이 사용한다.
하나의 프로그램에서 대화 상자를 만들어서 사용하고 같은 대화 상자이어도 다른 프로그램에서 사용하기 위해서는 거의 새로 작성하는 것과 같은 노력이 들어 간다.
이 문제를 해결하는 방법으로 DLL을 만들어 사용하면 여러 프로그램에서 그냥 사용하면 된다.
그러나 DLL에 대화 상자를 넣기 위해서는 몇가지 세팅을 해야하는데 여기에서 DLL 제작법과 함께 설명한다.
Visual C++을 설치한 후 실행하면 다음 그림과 같다.
File 메뉴의 New(Ctrl+N)를 선택하면 다음과 같은 대화 상자가 생성된다.
좌측 항목을 MFC AppWizard(dll)을 선택하고 프로젝트이름을 설정한후 OK버튼 선택하면 다음과 같은 대화상자가 생성된다.
What type of DLL would you like to create항목의 세가지는 조금씩 다르게 프로젝트가 생성되는데 여기서는 가장 쉽게 DLL을 만들 수 있는 세 번째 확장 DLL의 형태로 제작한다.
MFC Extension DLL(using shared MFC DLL)을 설정하고 Finish버튼을 선택하면 다음과 같은 대화상자가 생성되어 현재까지의 설정을 보여준다.
OK버튼을 선택하면 프로젝트가 생성되고 Visual C++은 다음과 같이 바뀌어 화면에 표시된다.
실제 DLL을 만들 경우 대부분 만들고자 하는 .cpp와 .h파일이 있을 것이다. 만들고자 하는 .cpp파일들을 프로젝트에 추가하고 .h파일들을 하나로 합쳐서 class 선언문에 설정을 좀해주고 컴파일을 하면된다.
그러나 여기서는 새로 클래스를 추가하여 대화 상자 호출을 위한 제작을 해보도록 하겠다. class 선언문에 설정하는 부분 또한 추가한 class에서 설명할 것이니 참조하기 바란다(새로 클래스 추가하는 내용은 DLL과 관계없고 모든 프로그램에서 사용하는 내용이다).
우선 위 그림과 같이 프로젝트 트리의 ClassView 탭을 선택하여 생긴 화면의 최상위 트리에서 오른쪽 마우스를 클릭하여 생성된 팝업 메뉴에서 New Class를 선택하면 다음과 같은 대화 상자가 생성된다.
Class type을 Generic Class로 선택하면 대화 상자는 다음과 같이 변경된다.
Name에 생성하고자 하는 Class를 입력하면 Class가 추가된다(여기서는 CCommonDlg를 입력했다고 가정, CommonDlg.cpp가 이미 존재하므로 CommonDlg1.cpp가생성).
추가된 CommonDlg.h를 열어보면 다음과 같이 들어 있을 것이다.
// CommonDlg1.h: interface for the CCommonDlg class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_COMMONDLG1_H__15D47F43_73B7_41A9_81FA_AF49C68AE99B__INCLUDED_)
#define AFX_COMMONDLG1_H__15D47F43_73B7_41A9_81FA_AF49C68AE99B__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CCommonDlg
{
public:
CCommonDlg();
virtual ~CCommonDlg();
};
#endif // !defined
(AFX_COMMONDLG1_H__15D47F43_73B7_41A9_81FA_AF49C68AE99B__INCLUDED_)
여기에서 class 선언부인 class CCommonDlg의 class와 CCommonDlg사이에 AFX_EXT_CLASS를 입력하여 class AFX_EXT_CLASS CCommonDlg로 바꾸어 주면 앞에서 이야기한 class에 세팅은 끝이난다.
일반적으로 DLL을 제작하면 .lib파일이 같이 생성된다. 실제 사용시 .lib파일을 프로젝트에 추가해서 사용하도록 하는데 이 부분을 자동(프로젝트 트리에는 나타나지 않고 내부적으로 추가)으로 하는 코드가 다음과 같다.
#ifndef _COMMONDLG_DLL_MAKER
#ifdef _DEBUG
#pragma comment(lib, "CommonDlgD.lib")
#else
#pragma comment(lib, "CommonDlg.lib")
#endif // _DEBUG
#endif
#pragma comment(lib, "CommonDlg.lib")가 실제 위에서 설명한 .lib파일을 프로젝트에 추가가는 기능과 같은 기능을 수행하고 나머지는 몇가지 부가 기능을 수행한다.
우선 #ifndef _COMMONDLG_DLL_MAKER의 경우 _COMMONDLG_DLL_MAKER라는 것이 #define되어 있는 경우에만 실행하라는 내용인데, 이것은 DLL을 만드는 본 프로그램에서는 #pragma comment(lib, "CommonDlg.lib")가 실행되지 않도록 해줍니다.
물론 DLL을 만드는 프로젝트에 _COMMONDLG_DLL_MAKER라는 것을 #define해주어야 한다.
#pragma comment(lib, "CommonDlgD.lib")는 Debug 모드에서는 CommonDlgD.lib를 추가하도록 하라는 것이다. 물론 DLL을 만들 때 Debug모드 파일 생성은 CommonDlgD로 생성되도록 해야한다.
수정한 소스를 보면 다음과 같다.
// CommonDlg1.h: interface for the CCommonDlg class.
//
//////////////////////////////////////////////////////////////////////
#if !defined
(AFX_COMMONDLG1_H__15D47F43_73B7_41A9_81FA_AF49C68AE99B__INCLUDED_)
#define AFX_COMMONDLG1_H__15D47F43_73B7_41A9_81FA_AF49C68AE99B__INCLUDED_
#ifndef _COMMONDLG_DLL_MAKER
#ifdef _DEBUG
#pragma comment(lib, "CommonDlgD.lib")
#else
#pragma comment(lib, "CommonDlg.lib")
#endif // _DEBUG
#endif
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class AFX_EXT_CLASS CCommonDlg
{
public:
CCommonDlg();
virtual ~CCommonDlg();
};
#endif // !defined
(AFX_COMMONDLG1_H__15D47F43_73B7_41A9_81FA_AF49C68AE99B__INCLUDED_)
프로젝트 메뉴의 부메뉴 Settings를 선택하면 다음과 같은 대화 상자가 생성된다.
C/C++탭을 선택하여 Preprocessor definitions에 COMMONDLG_DLL_MAKER를 추가해 준다.
물론 Settings For을 Win32 Release로 선택하여 Release 모드에서도 똑같이 해주어야 한다.
Link탭을 선택하여 Output file name의 Debug/CommonDlg.dll을 Debug/CommonDlgD.dll로 수정해 준다.
이제 DLL에서 대화 상자 호출법에 대해서만 설명하면 된다.
CCommonDlg에 ExecuteSetCommDlg()라는 함수를 만들어 CSetCommDlg라는 대화 상자(대화상자 생성 참조)를 호출한다고 가정하면 일반적으로 다음과 같이 구성할 것이다.
BOOL CCommonDlg::ExecuteSetCommDlg()
{
CSetCommDlg dlg;
BOOL bStatus = FALSE;
if(dlg.DoModal()==IDOK){
...
bStatus = TRUE;
}
return bStatus;
}
이 경우 대화 상자 호출이 제대로 되는 경우가 있고 그렇지 않은 경우가 있다.
그것은 실행파일에서 사용한 리소스 ID에 따라서 다른데, 만약 DLL과 중복되는 리소스 ID를 사용하는 실행파일에서는 제대로 대화 상자가 호출되지 않을 것이다. 이 것을 수정하여 실행파일의 리소스와 관계없이 독립적으로 수행되도록 구성하려면 다음과 같이 Source를 수정하면 된다.
BOOL CCommonDlg::ExecuteSetCommDlg()
{
HINSTANCE hInstResourceClient = AfxGetResourceHandle();
#ifdef _DEBUG
AfxSetResourceHandle(::GetModuleHandle("CommonDlgD.dll"));
#else
AfxSetResourceHandle(::GetModuleHandle("CommonDlg.dll"));
#endif
CSetCommDlg dlg;
BOOL bStatus = FALSE;
if(dlg.DoModal()==IDOK){
...
bStatus = TRUE;
}
AfxSetResourceHandle(hInstResourceClient);
return bStatus;
}
'▣ 참고 > C++' 카테고리의 다른 글
C++ RESOURCE 사용 (0) | 2008.11.12 |
---|---|
C++ 대화 상자 (0) | 2008.11.12 |
C++ 프로그램 배포하기 (0) | 2008.11.12 |