winmain 구성 그림그려보기

2015. 4. 11. 09:43프로그래밍/ETC

728x90
728x90

1. 서론

기존의 winmain 구성에서 교수님이 말씀하시길

init, update, render, release 4개를 항상 구현해주는게 좋다고 하셨다.

게임을 구현할때 함수 단위로 쪼개서 편리하게 구현할 수 있다.


2. 그림 그려보기

keynote 환경에서 직접 그린 그림이다.

(물론 옥스포드 노트에 손으로 먼저 그려봤다.)

정의, 등록, 윈도우 생성을 하고

윈도우를 보여주기전에 init를 실행한다.

init 내부에서 대부분 초기에 필요한 값들을 지정해준다.

윈도우를 보여주고 메세지 루프로 들어간다.


콜백함수 내에서 update, render를 통해

주기적으로 값을 업데이트하고 화면에 그려주는 역할을 한다.


릴리즈는 프로그래머가 수동으로 정리해줘야 할 것들을 해제해준다.



3. 정리 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// ShowerGame.cpp : 응용 프로그램에 대한 진입점을 정의합니다.
//
 
#include "stdafx.h"
#include "ShowerGame.h"
 
//< 헤더 파일
#include <windows.h>            //윈도우 헤더파일 인크루드
 
//< 전역변수(인스턴스 핸들과 클래스이름, 윈도우 이름, 윈도우 핸들
HINSTANCE    g_hInst;                        //인스턴스의 핸들선언(운영체제에서 정해줄 번호)
HWND        g_hWnd;                            //윈도우의 핸들(윈도우를 대표하는 번호)
 
//< 유니코드, 바이트에 다 둘 다 반응할 수 있는 TCHAR형 타입
TCHAR          g_ClassName[128= _T("Shower");        //클래스 이름
TCHAR          g_WinName[128= _T("Shower");            //윈도우 이름
 
//< 함수 정의
//< 초기화
bool init( void );
//< 갱신
void    update( void );
//< 렌더(렌더링)
void    render( HDC hdc );
//< 정리
void    release( void );
 
//< 윈도우 정의 및 등록
void    registWnd( void );
//< 윈도우 생성 및 보여주기
bool createWnd( void );
 
//< 콜백함수
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
 
//< 메인 앤트리 함수
// apientry            ==  winmain함수의 호출 방식을 의미한다
// hInstance        ==    프로그램의 인스턴스 핸들이다(윈도우즈 운영체제에서 정해줄 윈도우의 코드번호(고유명사)).
// hPrevInstance    ==    바로 앞에 실행된 프로그램의 인스턴스 핸들.
// lpszCmdParam        ==    실행 직후에 열 파일의 경로가 전달된다.
// nCmdShow            ==  윈도우를 화면에 출력할 방법(윈도우를 활성화 하여 보여준다라는 의미,또는 숨긴다.)
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance
          ,LPSTR lpszCmdParam, int nCmdShow)
{
    
    //< 1. 윈도우 클래스 정의, 2. 작성
    registWnd();
 
    //< 3. 윈도우 생성
    if(createWnd() == 0)
    {
        return 0;
    }
 
    //< 초기화
    if(init() == 0)
    {
        return 0;
    }
 
    //< 4. 윈도우를 화면에 보여준다
    ShowWindow(g_hWnd, nCmdShow);
 
    //< 5. 메시지 루프
    MSG            Message;        //메세지 구조체 선언    
    //GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterJanus, UINT wMsgFilterMAx)메시지큐에서 읽어들인  메세지가 WM_QUIT면 false 리턴 나머지는 true 리턴
    //lpMsg : 메시지의 주소
    //hWnd : 윈도우의 핸들 0이면 모든 윈도우의 메시지를 가져오고, 핸들 값을 지정하면 그핸들값에 포함된 메시지만 가져온다.
    //wMsgFilterJanus, wMsgFilterMAx : 메시지를 읽어들일 범위 최소값 최대값(사용할경우 시스템이 무한루프에 빠질수 있다.)
    // 4 메세지 루프(사용자로부터의 메시지를 처리한다 !메시지 구동시스템)
    while(GetMessage(&Message,0,0,0))
    {
        TranslateMessage(&Message);// 키보드 입력 메시지를 관리한다(a라는  키가 눌렸을때 a라는 키가 눌렸다는 메세지를 만들어낸다.)
        DispatchMessage(&Message); // 메시지를 가지고 프로시져함수를 호출하는 역활 
    }
//    Release(); (해제 해주는곳)
    
    return Message.wParam;
}
 
//<함수 구현
//< 초기화
bool init()
{
    return true;  
}
 
//< 업데이트
void update()
{
 
}
 
//< 랜더링
void render()
{
 
}
 
//< 정리
void release()
{
 
}
 
//< 1. 윈도우 클래스 작성, 2. 등록
void registWnd()
{
    WNDCLASS    WndClass;        //윈도우 클래스 선언
     //< 1. 윈도우 클래스 작성 (윈도우의 속성을 정의 한다)
    WndClass.cbClsExtra        = 0;                                    //윈도우즈가 내부적으로 사용할 여분메모리    
    WndClass.cbWndExtra        = 0;                                    //윈도우즈가 내부적으로 사용할 여분메모리
    WndClass.hbrBackground    = (HBRUSH)GetStockObject(WHITE_BRUSH);    //배경색상 지정
    WndClass.hCursor        = LoadCursor(NULL,IDC_ARROW);            //커서를 설정한다(리소스를 통해서 원하는 그래픽를 등록 할수도 있다)
    WndClass.hIcon            = LoadIcon(NULL,IDI_APPLICATION);        //아이콘을 읽는다(리소스를 통해서 원하는 그래픽를 등록 할수도 있다)
    WndClass.hInstance        = g_hInst;                            //윈도우 클래스의 인스턴스(윈도우즈 운영체제에서 정해줄 윈도우의 코드번호(고유명사))
    WndClass.lpfnWndProc    = (WNDPROC)WndProc;                        //윈도우 프로시저의 이름(윈도우의 메시지 처리 함수를 지정)
    WndClass.lpszClassName    = g_ClassName;                            //윈도우 클래스의 이름(어디까지나 클래스 이름일 뿐이다)
    WndClass.lpszMenuName    = NULL;                                    //메뉴의 이름(리소스 에디터 의해 별도로 만들어짐, 사용을 안하면 NULL)
    WndClass.style            = CS_HREDRAW | CS_VREDRAW;                //윈도우의 스타일(윈도우의 크기가 변할때 다시 그린다.)
 
    //< 2. 클래스를 등록한다 (정의한 윈도우 클래스를 등록한다)
    RegisterClass(&WndClass);     
}
 
//< 3. 윈도우 생성
bool createWnd(void)
{
     //< 3. 윈도우를 만든다 (메모리 상에 윈도우를 생성한다)
 
    int            nWidth, nHeight;//윈도우 크기  
    
    nWidth = WINSIZE_X + GetSystemMetrics(SM_CXFRAME) * 2;
    nHeight = WINSIZE_Y + GetSystemMetrics(SM_CYFRAME ) * 2 +
        GetSystemMetrics(SM_CYCAPTION);
 
    g_hWnd = CreateWindow(g_ClassName,                // 윈도우클래스 문자열 
                          g_WinName,                // 타이틀바에 나타날 문자열
                          WS_OVERLAPPEDWINDOW,        // 윈도우의 형태 옵션(OR 연산자 사용)타이틀바, 스크롤바, 크기조절가능 등등
                          START_X, START_Y,            // 윈도우 시작위치
                          nWidth, nHeight,            // 윈도우 크기
                          NULL,                        // 부모윈도우의 핸들 (부모 윈도우가 없고 자신이 최상위 윈도우 일때 NULL)
                          (HMENU)NULL,                // 메뉴의 핸들 (메뉴를 사용 안하므로 NULL)            
                          g_hInst,                // 인스턴스
                          NULL);                    // createStruct라는 구조체의 주소 (여러개의 윈도우를 만들때 사용 되나 거의 사용하지 않는다.)
 
    if(g_hWnd == 0) { return false; }
    return true;
}
 
 
 
//< 프로시저 함수 구현, 메세지 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,
                         LPARAM lParam)
{
    HDC            hdc;
    PAINTSTRUCT    ps;
    
    
    switch(iMessage)
    {
        case WM_TIMER:
        
        break;
 
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            
            EndPaint(hWnd, &ps);
        break;
 
        case WM_LBUTTONDOWN:
            
        
        break;
 
        case WM_RBUTTONDOWN:
            
        break;
 
        case WM_KEYDOWN:
            switch(wParam)
            {
                //(esc key)
                case VK_ESCAPE:
                    PostQuitMessage(0);
                break;
            }
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        return 0;
    }
 
    //wndProc에서 처리 되지 않은 나머지 메시지들을 처리해준다.
    // 윈도우크기 변경이나, 이동 등를 처리해준다.
    return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}
cs


728x90
반응형