GDI ¶
GDI(Graphics Device Interface)란 윈도우의 클라이언트 영역에 그리기를 하는데 사용되는 함수이다. 비디오 출력과 프린터에 그래픽 출력을 책임지고 있는 부분이다. 사용자가 Windows용으로 작성하는 응용 프로그램이 GDI를 사용하여 시각적인 정보를 출력할 뿐 아니라 Windows 자체도 GDI를 사용하여 메뉴, 스크롤 바, 아이콘, 그리고 마우스 커서 같은 사용자 인터페이스 아이템의 시각적인 출력을 수행한다.
DC ¶
DC(Device Context)는 GDI에 의해 내부적으로 관리되는 데이터 구조체이며 그래픽 작업을 하기 위해서 필요한 것이다. 그림을 그리고자 할 때에는 반드시 먼저 DC에 대한 핸들을 얻어야 한다. 프로그램에 이 핸들을 주는 것으로 Windows는 사용자가 그 장치를 사용할 수 있도록 허가해 준다. 그러면 핸들을 GDI 함수의 인자로 사용하여 현재 그리고자 하는 장치를 Windows가 식별할 수 있도록 한다.
- 핸들 : 윈도우 핸들이라는 말은 말그대로 핸들이다.
 예를 들면 자동차를 운전할때 자동차핸들을 좌/우로 움직이면서 자동차를 조작하듯이 윈도우에서 핸들은 윈도우를 조작하기 위한 것입니다.
 
 
DC 핸들 얻기 ¶
WM_PAINT ¶
WM_PAINT 처리는 거의 항상 BeginPaint에 대한 호출로 시작된다.
hdc = BeginPaint (hwnd, &ps);
그리고 다음과 같이 EndPaint를 호출하여 끝난다.
EndPaint (hwnd, &ps);
두 경우에 있어서 첫번째 인자는 프로그램의 윈도우에 대한 핸들이다. 두번째 인자는 PAINTSTRUCT 형식의 구조체에 대한 포인터이다. PAINTSTRUCT 구조체에는 윈도우 프로시저가 클라이언트 영역을 그리는 데 사용할 수 있는 정보들이 저장되어 있다.
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);
	}













