U E D R , A S I H C RSS

5인용C++스터디/윈도우에그림그리기

GDI


GDI(Graphics Device Interface)란 윈도우의 클라이언트 영역에 그리기를 하는데 사용되는 함수이다. 비디오 출력과 프린터에 그래픽 출력을 책임지고 있는 부분이다. 사용자가 Windows용으로 작성하는 응용 프로그램이 GDI를 사용하여 시각적인 정보를 출력할 뿐 아니라 Windows 자체도 GDI를 사용하여 메뉴, 스크롤 바, 아이콘, 그리고 마우스 커서 같은 사용자 인터페이스 아이템의 시각적인 출력을 수행한다.

DC


DC(Device Context)는 GDI에 의해 내부적으로 관리되는 데이터 구조체이며 그래픽 작업을 하기 위해서 필요한 것이다. 그림을 그리고자 할 때에는 반드시 먼저 DC에 대한 핸들을 얻어야 한다. 프로그램에 이 핸들을 주는 것으로 Windows는 사용자가 그 장치를 사용할 수 있도록 허가해 준다. 그러면 핸들을 GDI 함수의 인자로 사용하여 현재 그리고자 하는 장치를 Windows가 식별할 수 있도록 한다.

  • 핸들 : 윈도우 핸들이라는 말은 말그대로 핸들이다.
    예를 들면 자동차를 운전할때 자동차핸들을 좌/우로 움직이면서 자동차를 조작하듯이 윈도우에서 핸들은 윈도우를 조작하기 위한 것입니다.

DC 핸들 얻기


DC 핸들을 얻고 해제하는 가장 일반적인 방법은 WM_PAINT 메시지 처리 도중 BeginPaintEndPaint 호출을 사용하는 것이다.

hdc = BeginPaint (hwnd, &ps);
른 명령들
EndPaint (hwnd, &ps);

첫번째 인자는 프로그램의 윈도우에 대한 핸들이다.
변수 ps는 PAINTSTRUCT 형식의 구조체이다. PAINTSTRUCT 구조체에는 윈도우 프로시저가 클라이언트 영역을 그리는 데 사용할 수 있는 정보들이 저장되어 있다.

WM_PAINT


보통 프로그램이 WinMain에서 UpdateWindow를 호출할 때 발생한다. 이것은 윈도우 프로시저로 하여금 클라이언트 영역에 무엇인가를 그리게 한다.

WM_PAINT 처리는 거의 항상 BeginPaint에 대한 호출로 시작된다.

hdc = BeginPaint (hwnd, &ps);

그리고 다음과 같이 EndPaint를 호출하여 끝난다.

EndPaint (hwnd, &ps);

두 경우에 있어서 첫번째 인자는 프로그램의 윈도우에 대한 핸들이다. 두번째 인자는 PAINTSTRUCT 형식의 구조체에 대한 포인터이다. PAINTSTRUCT 구조체에는 윈도우 프로시저가 클라이언트 영역을 그리는 데 사용할 수 있는 정보들이 저장되어 있다.

WndProcBeginPaint를 호출하고 난 후 GetClientRect를 호출한다.

GetClientRect(hwnd, &rect);

첫번째 인자는 프로그램 윈도우에 대한 핸들이다. 두번째 인자는 RECT형식의 사각형 구조체에 대한 포인터이다.

예제

~cpp 
#include <windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow)
{
	HWND hWnd;
	WNDCLASS wc;
	MSG mSg;
	char szTitleName[]="Drawing Line";
	char szClassName[]="it is a class";

	wc.cbClsExtra=NULL;
	wc.cbWndExtra=NULL;
	wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.hCursor=LoadCursor(NULL,IDC_ARROW);
	wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
	wc.hInstance=hInst;
	wc.lpfnWndProc=WndProc;
	wc.lpszClassName=szClassName;
	wc.lpszMenuName=NULL;
	wc.style=NULL;

	RegisterClass(&wc);

	hWnd=CreateWindow(szClassName,szTitleName, WS_OVERLAPPEDWINDOW,100,90,320,240,NULL,NULL,hInst,NULL);

	ShowWindow(hWnd,nCmdShow);
	UpdateWindow(hWnd);

	while(GetMessage(&mSg,NULL,0,0))
	{
		TranslateMessage(&mSg);
		DispatchMessage(&mSg);
	}
	return mSg.wParam;
}

LRESULT CALLBACK WndProc(
						 HWND hWnd,
						 UINT uMsg,
						 WPARAM wParam,
						 LPARAM lParam)
{
	HDC hDC;
	HPEN hPen;
	PAINTSTRUCT ps;
	static int nSX,nSY,nEX,nEY;
	static POINT pt;
	static BOOL bTF;

	switch(uMsg)
	{
	case WM_LBUTTONDOWN:
		{
			bTF = TRUE;
			nSX=LOWORD(lParam);
			nSY=HIWORD(lParam);
		}
		return FALSE;

	case WM_LBUTTONUP:
		{
			bTF=FALSE;
			nEX=LOWORD(lParam);
			nEY=HIWORD(lParam);
			InvalidateRect(hWnd,NULL,FALSE);
		}
		return FALSE;

	case WM_PAINT:
		{
			if(bTF==FALSE)
			{
				hPen=CreatePen(PS_SOLID,0,RGB(0,0,0));
				hDC=BeginPaint(hWnd,&ps);
				SelectObject(hDC,hPen);
                                    SelectObject(hDC, GetStockObject(NULL_BRUSH));
 				MoveToEx(hDC,nSX,nSY,&pt);
				LineTo(hDC,nEX,nEY);
				DeleteObject(hPen);
				EndPaint(hWnd,&ps);
			}
		}
			return FALSE;
	case WM_DESTROY:
		PostQuitMessage(0);
		return FALSE;
		}
		return DefWindowProc(hWnd,uMsg,wParam,lParam);
	}
~cpp 
                               hPen=CreatePen(PS_SOLID,0,RGB(0,0,0)); 
                               hDC=BeginPaint(hWnd,&ps); 
                               Ellipse(hDC,nSX,nSY,nEX,nEY);
                               EndPaint(hWnd,&ps); 

  • CreatePen() : 펜을 생성하는 함수.
  • SelectObject() : CreatePen()으로 만든 펜을 사용하도록 지정해준다.
  • LineTO() : 선을 그리는 역할.
  • DeleteObject() : CreatePen()함수로 생성한 펜을 지우는 역할.

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:22:19
Processing time 0.0286 sec