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