언어/기타
2007.01.08 09:11

[C++] WinAPI를 이용한 GUI 프로그래밍

조회 수 1202 추천 수 3 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

안녕하세요. 이번 시간에는 실질적으로 게임을 윈도우상에 표현하기 위한 기초를 쌓는 시간이 되겠습니다.


 


게임뿐만 아니라 WindowsOS 상에서 그래픽처리를 하기 위해서는 윈도우개념의 GUI 프로그래밍이 필요한 것이지요.


 


 


 


윈도우  프로그램은 WinMain 함수 내부에서


 


메세지처리 -> 그래픽처리


 


의 무한루프를 돌고 있습니다. 메세지 처리란, 키 입력이나 시스템에서 발생한 요청들을 처리하는 것이며,


 


그래픽처리는 화면에 그림을 그리는 부분을 처리하는 것이지요.


 


 


고로 우리가 프로그램을 이용하면서 키가 눌리자 마자 프로그램이 반응 하는 것처럼 보이지만, 사실은 1루프 늦게 반응을 하는 것이지요.


 


위 루프 함수만 완성을 해 두면 윈도우 프로그래밍을 할 준비가 된 것입니다.


 


 


 


 


그리고 그 윈도우 프로그래밍을 하기위해 프로그램 제일 상단에는


 


#include <windows.h>


 


를 써 줍니다. 윈도우를 사용하기위한 헤더파일이지요.


 


 


그래픽 처리를 할 paint함수를 만들어보도록 하죠.


 


void paint(HWND hWnd)


{


 HDC hdc;
 PAINTSTRUCT ps;
 RECT rt={100,100,400,300};
 char str[]="안녕하세요. 윈도우 프로그래밍에 입문 하신것을 축하드립니다. "
  "앞으로 게임을 제작하기위한 첫 일보를 내딛으셨군요."
  "앞으로도 정진해주세요. ^^";


  hdc=BeginPaint(hWnd,&ps); // 우리가 가진 윈도우에 그림을 그리도록 요청하는 것입니다.
  DrawText(hdc,str,-1,&rt,DT_CENTER | DT_WORDBREAK); // rt 범위에 str 문자열을 출력하는 부분입니다.
//  SetTextAlign(hdc, TA_CENTER);
//  TextOut(hdc,200,60,"Hi",2);
//  TextOut(hdc,200,80,"My name is Zeprod",17);
//  TextOut(hdc,200,100,"Welcome to windows!",19);


// 위의 주석처리한 부분은 지정좌표에 문자열을 강제로 출력하는 부분입니다.


// hdc를 이용해, 도형을 출력하거나, 그림파일을 불러와 그림을 출력할수도 있습니다.
  EndPaint(hWnd,&ps); //  다그렸다고 말합니다.
  return 0;


}


 


 


주석을 보시면 간단합니다.


 


그후에는 윈도우프로그램의 시작점, 윈도우의 메세지처리 함수를 만듭니다.


 


LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
 POINT pt;
 //메세지가 들어오면 실행되는 함수
    switch( msg ) //메세지별로 분배해줍니다.
    {
        case WM_DESTROY: //WM_DESTROY 메세지라면?
            PostQuitMessage( 0 ); //프로그램을 전체 종료하라고하고.
            return 0; //프로시저를 끕니다.
  case WM_KEYDOWN :
   switch( wParam )
   {
    case VK_ESCAPE : // ESC키가 눌렸을 경우
     PostMessage( hWnd, WM_DESTROY, 0, 0L ); // WM_DESTROY메세지를 보낸다. (프로그램이 꺼지겠죠?)
     break;
   }
   break;


   case WM_PAINT: //윈도우를 그리란 명령이 온다면, paint함수를 불러줍시다.
            paint(hWnd);
    }


    return DefWindowProc( hWnd, msg, wParam, lParam );
}


 


위의 함수를 통해서 키보드입력, 마우스 클릭등을 처리할 수 있으며, 그 것을 판별하는 값들에 대한것은 약간의 검색이 필요합니다.


 


 


INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
    /* 우리가 사용할 윈도우를 입력합시다. 대입하는부분의 3번째 인자는 MsgProg, 우리가 방금 만들었던 메세지 처리


     * 함수로군요.


     * 함수의 이름은 그 함수를 가르키는 포인터라고 부르는데, 이것을 넘겨줌으로써 OS가 저 함수를 호출해줄 수 있도록 하기


     * 위함입니다.


    */
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      L"Test", NULL }; // Test라는 부분은 윈도우를 대표하는 문자열 키값과 비슷하게 알아두시면 됩니다.


 


    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);


    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);


    // 위의 3줄은 윈도우에 표시될 항목을 따로 지정하는 방법입니다.


    // 마우스커서, Icon, 배경색을 지정하는 부분입니다.



    RegisterClassEx( &wc ); // 우리가 만든 윈도우 클래스를 윈도우에 등록해주는 함수입니다.


    // 우리 프로그램의 그래픽적인 윈도우를 만듭니다.
    HWND hWnd = CreateWindow( L"Test", L"제목표시줄",
                              WS_OVERLAPPEDWINDOW, X좌표, Y좌표, 너비, 높이,
                              NULL, NULL, wc.hInstance, NULL ); //Test를 입력하고 이후에는 여러가지 항목을 명시해주는 것으로 끝납니다.
 
 
 
  ShowWindow( hWnd, SW_SHOWDEFAULT ); // 이제 윈도우를 눈에 보이도록 하죠.
  UpdateWindow( hWnd ); // 윈도우를 재차 그립니다.


   // 메세지 루프로 들어갑니다.
   MSG msg;
   ZeroMemory( &msg, sizeof(msg) ); //메모리 초기화 00000000....0000~~~...0000
   while( msg.message!=WM_QUIT )
   {
    if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) //윈도우 메세지가 튀어나왔다.
    {
     TranslateMessage( &msg );
     DispatchMessage( &msg ); //윈도우 자체 기능을 수행하기 위함
    }


    else // 그게 아닐경우 그림을 그려주면 그뿐입니다.


        paint(hWnd); // 페인트 함수를 호출합니다.
   }
    UnregisterClass( L"Test", wc.hInstance );
    return 0;
}


 


 


위의 코드들을 보시면, 제일 처음말한, 메세지처리->그래픽처리 루프를 반복해서 돌게 된다는 것을 알 수 있습니다.


 


일반적인 Window 코드에서 약간 변경을 주었는데, 그것은 메세지처리부분에서 paint 명령을 처리할 뿐만아니라, 메세지가 없을때에도 그림을 갱신하도록 한 것입니다.


 


이것은 게임을 만들기위해 꼭 필요한 부분으로, 아무 조작을 하지 않아도 화면이 바뀔 수 있도록 한 것입니다.


 


 


 


 


HBITMAP MyBitmap, OldBitmap;


  hdc = BeginPaint(hWnd, &ps);
  MemDC=CreateCompatibleDC(hdc);
  MyBitmap=LoadBitmap(g_hInst, L"Test.bmp");
  OldBitmap=(HBITMAP)SelectObject(MemDC, MyBitmap);
  BitBlt(hdc, 0,0,123,160,MemDC,0,0,SRCCOPY);
  SelectObject(MemDC,OldBitmap);
  DeleteObject(MyBitmap);
  DeleteDC(MemDC);
  EndPaint(hWnd, &ps);


위 코드는 paint 함수내에서 bmp파일을 읽어와 출력하는 부분입니다.


 


 


 


위 세부분을 이용한다면 코드 노가다를 통해 모든 프로그램을 만들 수 있습니다.


 


윈도우에 그림출력을 하고, 그림위치에 마우스가 있는지, 눌렸는지 등을 검사해서 그림으로 버튼을 만들 수도 있으며,


 


전역변수나 다른 화면관리 객체를 이용하여, 현재 보여줘야할 그림들, 현재 입력받아야할 부분들을 현재 상태에따라 다르게 변경할수도 있을테지요.


 


 


이런 응용은 프로그래머의 창작성에 열어두는 것입니다.


 


 


 


PS. 현재 코드에서는 유니코드 기반 프로젝트에서 제작하는 것임을 알려드리며, 일반 멀티바이트 체제에서는 L""등의 표시를 ""로 변경하시면 문제없이 동작하게 됩니다.


이것은 유니코드에서 일반 문자열을 LP*STR형으로 캐스팅해주는 명령어로써, 일반 프로젝트에서는 필요가 없기 때문입니다.

?

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
784 언어/기타 blitz basic 리닥터즈 2007.01.11 1201
783 언어/기타 소개글 [산타클로스~수해와 수영] Vermond 2007.01.10 1303
782 RPG Maker 범위 공격 : [y >= x^2] 을 이용 1 file Spegel 2007.01.10 2048
» 언어/기타 [C++] WinAPI를 이용한 GUI 프로그래밍 Zeprod 2007.01.08 1202
780 언어/기타 대기 가다없는 2007.01.08 992
779 RPG Maker [RMXP] 펫 소환 강좌 file 연필군 2007.01.07 635
778 언어/기타 도박 시스템 file 연필군 2007.01.07 566
777 언어/기타 잠입 게임 아이디어 아르킨 2007.01.07 1302
776 RPG Maker 데미지의 최소값, 최대값을 설정해보자! ver 1.0 『연금술사』 2007.01.07 1466
775 RPG Maker [RMXP] 벽 소환 이벤트를 만들자 file 연필군 2007.01.06 476
774 RPG Maker 플레이어의 건강을 배려하는 세심한 NPC[용도는...모르겠음-_-] file EverSmileMan 2007.01.02 1293
773 언어/기타 [C++] 객체 지향 프로그래밍 (OOP) -3- Zeprod 2007.01.02 949
772 언어/기타 이번에도 잡담입니다만-_-;; 아란 2007.01.01 1014
771 언어/기타 스크립트를 이용하여 텍스트색상과 갯수를 바꿔보자 ! file 준돌 2006.12.30 575
770 언어/기타 원형 거리 측정 Zeprod 2006.12.30 1206
769 언어/기타 [자료구조] Binary Search Tree Zeprod 2006.12.29 1181
768 언어/기타 [C++] 객체 지향 프로그래밍 (OOP) -2- Zeprod 2006.12.28 901
767 언어/기타 그저 비주얼 베이직에 낚인 것에 대한 잡담 아란 2006.12.27 992
766 RPG Maker 스크립트 실행여부를 알아보거나 스크립트를 봉인시켜보자 1 A. 미스릴 2006.12.26 774
765 언어/기타 스타포지의 추가 설명 다크세이버™ 2006.12.26 441
Board Pagination Prev 1 ... 7 8 9 10 11 12 13 14 15 16 ... 51 Next
/ 51






[개인정보취급방침] | [이용약관] | [제휴문의] | [후원창구] | [인디사이드연혁]

Copyright © 1999 - 2016 INdiSide.com/(주)씨엘쓰리디 All Rights Reserved.
인디사이드 운영자 : 천무(이지선) | kernys(김원배) | 사신지(김병국)