Game Programming I Windows 프로그래밍 (1) March 27, 2006 목표 윈도우프로그래밍에서이용되는이벤트구동프로그래밍모델의이해 Direct3D 를이용하는윈도우어플리케이션의작성을위한최소한의코드이해
윈도우 (Win32) 어플리케이션 Direct3D API ( 어플리케이션프로그래밍인터페이스 ) 를이용하기위해필요 Win32 API 를이용해작성 C 프로그래밍언어로공개된저수준함수와구조체의집합 우리가작성한어플리케이션과운영체제 (OS) 가서로통신하도록도와줌 핵심테마 창을제어하는것 메뉴, 도구모음, 스크롤바, 버튼, 대화상자컨트롤 둘러보기 자원 (Resources) CPU 사이클, 메모리, 모니터화면등 다수의어플리케이션은자원을공유 이벤트 (Events), 메시지큐, 메시지, 메시지루프 이벤트구동프로그래밍모델 ( event-driven programming model ) 이벤트발생 메시지전달 메시지큐에추가 메시지루프가메시지확인 해당하는창의윈도우프로시저로메시지전달
어플리케이이벤트구동프로그래밍모델 이벤트 어어플메플메리시리시케지케지이션션큐이션큐A B C 메시지큐어플리케이션 A 메시지루프 어플리케이션 B 메시지루프 어플리케이션 C 메시지루프 윈도우프로시저 A1 윈도우프로시저 B1 윈도우프로시저 C1 윈도우프로시저 C2 GUI (Graphical User Interface) 그래픽사용자인터페이스 윈도우의캡션바메뉴바 툴바 대화상자 버튼컨트롤 상태바 윈도우클라이언트영역 크기조절바
MS Visual C++ 6.0 File New 2 3 1
New Win32 Application New Win32 Application
ClassView FileView
File New 1 2 New C++ File
Hello main.cpp #include <windows.h> HWND MyMWindowHandle = 0; LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); int WINAPI WinMain( HINSTANCE hinstance, HINSTANCE, LPSTR, int nshowcmd ) { // Create the main window } // Main message loop LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { }
WNDCLASS 와등록 // Registers the window class WNDCLASS wc; wc.style = CS_HREDRAW CS_VREDRAW; wc.lpfnwndproc = (WNDPROC)WndProc; wc.cbclsextra = 0; wc.cbwndextra = 0; wc.hinstance = hinstance; wc.hicon = LoadIcon( hinstance, IDI_APPLICATION ); wc.hcursor = LoadCursor( 0, IDC_ARROW ); wc.hbrbackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); wc.lpszmenuname = 0; wc.lpszclassname = szclassname; RegisterClass(&wc); MSDN Library (1)
MSDN Library (2) MSDN Library (3)
윈도우만들기와보여주기 // Create the main window MyMWindowHandle = CreateWindow( szclassname, "Hello", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hinstance, 0 ); if(!mymwindowhandle ) return false; ShowWindow( MyMWindowHandle, nshowcmd ); UpdateWindow( MyMWindowHandle ); 메시지루프 // Main message loop MSG msg; while( GetMessage( &msg, 0, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage (&msg ); } UnregisterClass( szclassname, wc.hinstance ); return msg.wparam;
윈도우프로시저 LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { switch( msg ) { case WM_LBUTTONDOWN: MessageBox( 0, "Hello, World!!!", "Hello", MB_OK ); break; case WM_KEYDOWN: if( wparam == VK_ESCAPE ) { DestroyWindow( MyMWindowHandle ); } break; case WM_DESTROY: PostQuitMessage( 0 ); break; default: return DefWindowProc( hwnd, msg, wparam, lparam ); } return 0; } MessageBox 함수 API 함수 int int MessageBox MessageBox ( HWND HWND hwnd, hwnd, LPCTSTR LPCTSTRlpText, LPCTSTR LPCTSTRlpCaption, UINT UINT utype utype ); ); hwnd 소유주윈도우의핸들 (null 가능 ) lptext 메시지상자에넣을텍스트 lpcaption 메시지상자의제목에넣을텍스트 utype 메시지상자의스타일 (MB_OK, MB_OKCANCLE, MB_YESNO, MB_ICONINFORMATION, MB_ICONQUESTION, ) 리턴값 IDOK, IDCANCLE, IDYES, IDNO,
향상된메시지루프 int Run( ) { MSG msg; while( true ) { if( ::PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) { if( msg.message == WM_QUIT ) break; } ::TranslateMessage( &msg ); ::DispatchMessage (&msg ); } else // 게임코드를실행한다. } return msg.wparam; 연습과제 (1) 윈도우어플리케이션에서다음을변경시키시오. 윈도우배경색상 아이콘 커서 윈도우의크기 메시지상자의내용 새로운메시지상자를생성하시오. 마우스우측버튼을클릭했을때, 메시지상자생성 키보드의 Enter키를눌렀을때, 메시지상자생성
선그리기 선 (Line) 두점사이의이동경로 마우스로드래그하는경로를따라생성 알고리즘 마우스왼쪽버튼이눌렸을때의위치 (x, y) 를저장 (x 1, y 1 ) 마우스가드래그된위치 (x, y) 와 (x 1, y 1 ) 사이의경로를직선으로그림 (x, y) 를 (x 1, y 1 ) 에저장 마우스왼쪽버튼이올라갈때까지계속반복 Creating Variables
Window Procedure (1) Window Procedure (2)
Result (1) 사각형그리기 펜 (pen) 과브러쉬 (brush) 의색상변경 create select delete HPEN CreatePen (( int intfnpenstyle, int intnwidth,, COLOREF crcolor ); ); PS_SOLID PS_DASH PS_DOT PS_DASHDOT PS_DASHDOTDOT HBRUSH CreateSolidBrush ( ( COLOREF crcolor ); ); HBRUSH CreateHatchBrush ( int fnstyle, COLORREF crcolor );
MSDN CreatePen MSDN CreateHatchBrush
Creating a Function Window Procedure
DrawRect( ) Result (2)
사각형움직이기 타이머 (Timer) 정해진간격으로시간을측정해주는내부함수 ( 단위 : milliseconds) 함수 SetTimer ( ), KillTimer ( ) 이벤트 WM_TIMER 알고리즘 WM_TIMER 통지를받을때마다사각형의위치를변경시킴 MSDN Timers
New Definition Creating a Timer
Window Procedure Killing a Timer
DrawRect( ) InvalidateRect( )
Result (3) Erasing the Background
Result (4) 연습과제 (2) 사각형을세로나대각선으로움직이도록만드시오. 사각형이윈도우의끝에부딪히면반대방향으로바꿔움직이도록만드시오. RECT RECT rect; rect; GetClientRect( MyMWindowHandle,, &rect& &rect ); ); rect.left, rect.top, rect.right, rect.bottom