1.5.1 SDI 기반 MFC 응용 프로그램의 시작 MFC
2008/06/22 00:28 http://blog.naver.com/ndkarn/120053203183 |
1] CSDI_SequenceApp()
눈에 보이지 않는 코드들에 의해서 응용 프로그램 객체는 생성될 거싱며, 이 시점에서 응용 프로그램 객체의 생성자가 호출된다.
2] CSDI_SeqenceApp::InitApplication()
이 멤버 함수는 현재 MFC에서 더 이상 사용하지 않는 구시대의 유물과도 같은 것이다. 현재는 InitInstance()함수로 이관 되었다. 그 이름에서 짐작할 수 있듯이, 본래 이함수는 응용 프로그램 자체를 초기화하는 역할을 수행했었다.
3] CSDI_SequenceApp::InitInstance()
MFC에서 이 함수의 역할은 매우 중요하다. 응용 프로그램이 초기화되는 부분이며, 이와 관련한 코드들이 집결되는 곳이다. 그러므로 여러분들은 이부분에 코딩할 일이 상당히 많이 있다. 다음의 것들이 아주 대표적인 예이다.
*응용 프로그램의 설정 정보 로딩(예: 윈도우 크기, 옵션, 스타일 등)
*스플래시 윈도우 초기화(일반적으로 출력은 CMainFrame의 OnCreate() 함수)
*응용 프로그램의 중복 실행 방지
*트라이얼 버전의 기간 검사 루틴
*운영체제의 버전을 확인하고 프로그램 실행 허용 여부 결정(예: 응용 프로그램을 Windows 2000에서만 실행되도록 하는 경우)
*프로그램 사용자 인증 부분(예: 관리자만 프로그램을 실행하도록 하고 싶은 경우)
*프로그램 실행시 인자로 전달되는 매개 변수 처리
InitIstance() 함수에서는 몇몇 중요한 멤버 함수를 호출하고 있는데, 그 함수들의 이름과 기능은 아래와 같다.
■ AddDocTemplate()
도큐먼트 템플릿 객체를 응용 프로그램 객체에 등록한다.
■ ParseCommandLine()
매개 변수에 따라서 기본적인 명령을 수행하기에 앞서 내용을 분석한다.
■ ProcessShellCommand()
매개 변수로 전달된 프로그램 실행 옵션이나 열어야 하는 문서를 지정한 경우, 파일의 열기 혹은 빈 문서의 생성과 같은 작업을 진행한다. 대표적인 예로 MS 워드나 액셀 파일을 더블 클릭한다면, 자동으로 워드나 엑셀이 실행되고 파일을 로딩하여 보여준다.
4] CSDI_SequenceDoc::CSDI_SequenceDoc()
도큐먼트 객체의 생성자를 호출하면 응용 프로그램 객체에 이어 두 번째로 생성된다. 중요한 것은 현재까지 사용자 인터페이스와 관련한 객체, 즉 윈도우 객체는 아무것도 생성되지 않았다.
5] CMainFrame::CMainFrame()
응용 프로그램 인터페이스의 틀이 되는 프레임 윈도우 객체를 생성한다. 객체가 생성되었을 뿐, 아직 아무것도 만들어지거나 나타난느 것은 없다. 필자는 간혹 여기에 응용 프로그램과 관련한 설정 정보를 읽어 들이는 코드를 넣기도 했다. 그리고 아직 배우지 않았지만 모달리스 다리얼로그 객체를 생성했던 기억도 있다. 물론 이 코드들은 전부 INitInstance() 함수에 넣는 것이 바람직할 것으로 생각된다.
6] CMainFrame::LoadFrame()
LoadFrme() 함수는 CFrame Wnd 객체가 생성된 후, 이 응용 프로그램 윈도우와 관련한 메뉴, 가속기, 아이콘과 같은 리소스들을 로딩하고 윈도우를생성한다 역시 아직 홤녀에는 아무 것도 보이지 않는다. 아직도 호출되어야 하는 삼수들이 많이 남은 까닭이다.
7] CMainFrame::PreCreateWindow()
이름 그대로 윈도우가 생성되기 직전에 호출되는 함수이다. 이 함수는앞서 본 적이 있다. 이번에는 조금 더 자세하게 설명을 할까 한다.
이 함수의 역할 중 가장 중요한 것은 생성되는 윈도우의 스타일 정의 혹은 변경이다. 기본적으로 생성되는 윈도우는 아주 흔하게 볼 수 있는 모든 요소를 가지고 있다. 이러한 사항들을 변경하고자 한다면 인자로 전달된 CREATESTRUCT 구조체의 값을 변경하면 된다.
이 구조체의 선언은 다음과 같다.
------------------------------------------------------------------
typedef struct tagCREATESTRUCTW{
LPVOID IpCreateParams;
HANDLE hInstnce;
HMENU hMenu;
HWND hwndParent;
int cy;
int cx;
int y;
int x;
LONG style;
LPCSTR IpszName;
LPCSTR lpszClass;
DWORD dwExStyle;
}CREATESTRucTW, *PCREATESTRUcTW, *LPCREATESTRUCTW;
-------------------------------------------------------------------
lpCreateParams은 윈도우를 생성하는데 사용되는 데이터를 가리키는 포인터이며, hInstance는 응용 프로그램의 인스턴스 값이다. hMenu 멤버는 생성되는 윈도우에 붙을 메뉴의 핸들이다. SDI프로그램에서 이 값을 NULL로 하면 메뉴는 생성되지 않을 것이다.
hwndparent멤버는 부모 윈도우의 핸들 값이 들어가는데, 여기서는 NULL이다. 이 윈도우 핸들 값이 NULL이면 응용 프로그램의 최상위 윈도우, 즉 프레임이 되는 것이다. 그러므로 이 값은 차일드 윈도우가 아닌 프레임 윈도우는 NULL값을 갖는다.
cy,cx값은 각각 생성되는 윈도우의 높이와 촉을 나타낸다. x,y 값은 윈도우가 생성되고 화면에 나타날 때, 왼쪽 위 부분 모서리 끝의 좌표이다.
style과 dwExStyle 멤버는 생성되는 윈도우의 기본 스타일 및 확장 스타일을 정의하는데, 여기에 올 수 있는 값이 너무 많은 관계로 지금은 설명을 생략한다.
이 외에 lpszName 멤버는윈도우의 이름을 정의하는 문자열 포인터이며, lpszClass 멤버는 윈도우 클래스 이름을 명시하는 멤버이다.
8] CMainFrame::PreSubclassWindow()
이 함수는 서브 클래싱 직전에 호출되는 함수인데, 서브 클래싱이란 윈도우 프로시저 함수를 따로 두는 것을 의미한다.
9] CMainFrame::OnCreate() - Call
OnCreate()함수는 WM_CREATE 메시지를 받았을 때 호출되는 메시지 핸들러이다. LoadFrame() 함수가 호출되면서 윈도우가 생성되고, 그때 WM_CREATE 메시지는 자동으로 발생한다. 이 함수에서 하는 일은 CMainFrame 객체 내에 있는 몇몇 차일드 윈도우(툴바나 상태 표시줄등)를 생성하는 일들을 한다. 이 함수 내에서 상위 클래스의 OnCreate() 함수를 명시적으로 호출함으로써, (CFrameWnd::OnCreate(lpCreateStruct)) 다른 함수들이 또 다시 호출된다.
1. CMainFrame::OnCreate() - Call
OnCreateClient()함수는 상위 클래스의 명시적 호출로 인해 호출되는 첫 번째 함수인데, 함수의 주된 역할은 클라이언트 뷰를 생성하는 일이다. SDI 프로그램은 클라이언트 뷰가 한 개이다. 그러나 변칙적으로 여러개를 둘 수도 있는데, 이런 경우 이 함수에서 해당 클라이언트 뷰들을 생성하여야 한다. 이에 대해서는 별도의 예제들이 있을 것이니 그때 잘 참고하기 바란다.
■ CSDI_SequenceView::CSDI_SequenceView()
클라이언트 뷰의 생성자가 호출된다.
■ CSDI_SequenceView::Create() - Call
클라이언트의 윈도우를 생성한다. 그리고 이 함수의 호출결과로 아래의 함수들이 추가로 호출된다. 계속되는 함수 호출에 헷갈려 할지 모르겠다. 간단히 중간 정리를 하자면 프레임 윈도우의 OnCreate() 함수가 OnCreateClient() 함수를 호출했고, 그 함수가 클라이언트 뷰 윈도우를 생성하기 위해 클라이언트 뷰의 Create() 함수를 호출했다. 결과적으로 아직 플레임 윈도우의 생성이 완전히 끝난 상태가 아니다.
*CSDI_SequenceView::PreCreateWindow()
앞서 프레임 윈도우 생성시의 함수와 같은 역할이다.
*CSDI_SequenceView::PreSubclassWindow()
앞서 프레임 윈도우 생성시의 함수와 같은 역할이다.
*CSDI_SequenceView::OnCreate()
클라이언트 뷰에 WM_CREATE 메시지가 전달되고, 그 메시지 핸들러가 호출된 것이다. 결국 각각의 윈도우는 자기만의 메시지 핸들러를 두게되며, 자신에게 해당되는 메시지를 받아 처리한다.
*CSDI_SequenceView::OnShowWindow()
OnShowWindow() 함수는 윈도우가 화면에 나타나거나 사라질 때 호출된다. 좀더 정확히는 WM_SHOWWINDOW 메시지에 대한 핸들러이다.
■ CSDI_SequenceView::Create() - Return
클라이언트 뷰 윈도우의 생성이 완료되었다.
2. CMainFrame::OnCreateClient() - Return
프레임 윈도우는 클라이언트 뷰를 생성하는 작업을 끝냈다.
3. CMainFrame - m_wndToolBar.CreateEx
프레임 윈도우는 또 다른 차일드 윈도우인 툴바 윈도우를 생성한다.
4. CMainFrame - m_wndStatusBar.Create
프레임 윈도우는 또 다른 차일드 윈도우인 상태 표시줄 윈도우를 생성한다. 만일 여러분이 프레임 윈도우에서 새로운 차일드 윈도우 객체를 멤버로 두고 생성할 것이라면, 여기에 그 윈도우를 새성하는 코드를 넣어야 한다. 나중에 배우게 될 컨트롤 바와 같은 것들을 생성할 때도 여기에 코딩할 것이다.
10] CMainFrame::OnCreate() - Return
프레임 윈도우의 생성도 이제 완료되었다.
11] CSDI_SequenceDoc::OnNewDocument()
현재 프로그램이 실행될 때 엑셀이나 워드처럼 응용 프로그램과 연결된 데이터 파일을 오픈한 경우가 아니므로 빈문서, 즉 새 문서를 연다. 관련된 것이 없다고 하더라도 SDI의 구조를 가졌기 때문에 내부적으로 문서를 만든다.
12] CSDI_SequenceView::OnInitialUpdate()
클라이언트 뷰의 생성이 완료되면 응용 프로그램의 프레임 윈도우는 자신의 클라이언트 뷰에 WM_INITIALUPDATE 메시지를 보내게 되고, 그 메시지를 받은 클라이언트 뷰는 이 메시지 핸들러를 호출한다.
이 함수의 역할은 매우 중요하다. 엑셀의 경우를 생각해보자. 엑셀은 어떤 숫자 데이터들을 잔뜩 가지고 있을 것이다. 그리고 그것을 자신의 클라이언트 뷰 화면에 표시를 하게 되는데, 이때 단순히 숫자만 보여주는 것이 아니라 때에 따라 비주얼한 차트도 보여주게 된다. 결국 도큐먼트 객체는 저장된 파일의 숫자 데이터 같은 것들을 처리하는 역할을 담당하고, 뷰 화면은 그 도튜먼트 객체가 가진 숫자 데이터를 화면에 표시하는 것이다. 그러기 위햇 스스로 여러가지 것들을 초기화 해야 할 것이다. 예를 들어 화면을 깨끗이 지워 준다거나 하는 일들을 해야 할 것이다. 인터넷 익스플로러를 생각해 보자. 우리가 HTML 파일을 더블 클릭해서 열 때 이미 브라우저가 실행 중이라면, 그 브라우저에 있던 내용들은 사라지고 HTML 파일의 내용이 새롭게 나타날 것이다.
따라서 이 메시지 핸들러는 새로운 문서가 열릴 때마다 호출된다. 그러나 응용 프로그램과 연결된 문서가 존재하지 않고 파일을 열 일이 없다면, 딱 한 번만 수행될 것이다. 이에 대해서도 나중에 또 언급할 것이다. 그때는 예제를 통해서 확인할 수 있을 것이므로 확실하게 이해가 갈 것이다.
이렇게 해서 모든 초기화는 완료되었다.
13] CMainFrame::OnActiveApp(), CMainFrame::OnActive()
초기화가 완료된 후, 응용 프로그램은 활성화되어 모니터 화면의 맨 위로 나타나게 될 것이다. 두 함수는 화면에 응용 프로그램이 나타나는 것까지로 보면 되겠다.
14] CMainFrame::OnShowWindow()
응용 프로그램이 활성화되고 프레임 윈도우가 화면에 나타나게 된다. 작업 표시줄에 자신의 항목도 하나 생겼을 것이고, 자랑스럽게(?) 모니터 화면에서 맨 위에 보여질 것이다.
이렇게 해서 모든 초기화가 완료되고 응용 프로그램이 수행되었다. 이제부터는 이벤트에 대한 메시지가 발생할 때 이를 처리하는 부분이 필요하다.
'MFC' 카테고리의 다른 글
dll : vc의 msdn - 한글 (0) | 2008.09.04 |
---|---|
[MSDN] 리소스 전용 DLL 만들기 - 한글 해석 (1) | 2008.09.04 |
[MSDN] AFX_EXT_CLASS를 사용하여 내보내기 및 가져오기 - msdn 해석 (2) | 2008.09.04 |
SDI 기반 MFC 응용 프로그램의 종료과정 - 순차적 정리 자료...읽어볼만하다. (0) | 2008.09.03 |
스레드 정리 잘 된 글 2 (1) | 2008.09.03 |
스레드 정리 잘 된 글 (0) | 2008.09.03 |
MFC에 고유의 명령(Command) 메시지 특징 (0) | 2008.09.02 |