순천향대학교컴퓨터학부이상정 1 학습내용 디바이스컨텍스트 WM_PAINT 선, 도형그리기 GDI 객체 펜, 브러쉬 순천향대학교컴퓨터학부이상정 2
디바이스컨텍스트 순천향대학교컴퓨터학부이상정 3 디바이스컨텍스트 (1) 윈도우즈에서화면출력 ( 텍스트출력과차이점 ) 화면을사용할수있는권한이제약 자신이차지하는영역에만그림을그릴수있다. 좌표를계산하는방법이다르다 자기의윈도우즈의좌표를기준으로출력 출력은장치에영향받지않는다. 어떤그래픽카드인지, 어떤프린터인지에상관없이같은출력함수를사용 디바이스드라이버에의해장치독립성을확보 디바이스컨텍스트 (DC, Device Context) 는윈도우에서화면등출력에필요한모든정보를가지는도구 ( 구조체정의 ) 논리적으로생각하면그림을그리기위한도구들의집합 DC의구성요소는종이 ( 비트맵 ), 펜, 브러쉬 ( 붓 ), 팔레트, 폰트 순천향대학교컴퓨터학부이상정 4
디바이스컨텍스트 (2) 디바이스컨텍스트의역할 윈도우가차지하는영역내에서만출력되도록제한 윈도우의화면위치정보를가지며, 그래픽함수가지정하는윈도우기준좌표를물리적인화면상의좌표로정확히계산 장치독립적인출력을할수있어각출력장치가모두동일한함수사용 화면, 프린터, 메타파일 그래픽에서사용하는여러속성저장 선의색상, 모양, 글꼴,... 순천향대학교컴퓨터학부이상정 5 화면출력 윈도우화면출력절차 화면에대한디바이스컨텍스트핸들을구함 BeginPaint(), GetDC() 함수 GDI 객체를이용해원하는출력 펜, 브러쉬, 폰트등지정 모든출력장치에동일 디바이스컨텍스트제거 EndPaint()(BeginPaint() 로디바이스컨텍스트를얻은경우 ) ReleaseDC()(GetDC() 로디바이스컨텍스트를얻은경우 ) 순천향대학교컴퓨터학부이상정 6
WM_PAINT (1) 윈도우가다시그려져야하는시점 무효영역의발생 무효영역은윈도우의보이지않던영역이사용자에게노출된영역 전체윈도우다시그려야할때 WM_PAINT 메시지전송하여다시그림 순천향대학교컴퓨터학부이상정 7 WM_PAINT (2) WM_PAINT 메시지처리 BeginPaint () 호출 무효영역유효화하여클리핑 (Clipping) 영역계산 그리기작업의범위제한영역 클리핑영역을다시그리거나입력커서를감춘다 응용프로그램이사용가능하도록디바이스컨텍스트핸들을가져온다. EndPaint() 호출 디바이스컨텍스트해제 입력커서를다시표시 ( 필요한경우 ) WM_PAINT 메시지처리프로시저에서아무일도안하더라도 BeginPaint() 와 EndPaint() 를호출해야함 프로그램에서윈도우를다시그려야할경우 WM_PAINT 메시지직접게시또는전송은금지 InvalidateRect () 함수호출하여다시그림 순천향대학교컴퓨터학부이상정 8
디바이스컨텍스트관련 API (1) HDC GetDC( HWND hwnd ); 지정된윈도우의디바이스컨텍스트리턴 int ReleaseDC( HWND hwnd, HDC hdc ); 지정된윈도우의디바이스컨텍스트해제 해제가성공이면0이아닌값리턴 HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lppaint ); 그리기작업을준비하고, LPPAINTSTRUCT에관련정보저장 지정된윈도우의디바이스컨텍스트리턴 BOOL EndPaint( HWND hwnd, CONST PAINTSTRUCT* lppaint ); 지정된윈도우의그리기종료 디바이스컨텍스해제 순천향대학교컴퓨터학부이상정 9 디바이스컨텍스트관련 API (2) BOOL InvalidateRect( HWND hwnd, const RECT* lprect, BOOL berase ); 지정된윈도우의영역을다시그림 berase: true이면화면을지우고배경을다시그리고, false이면수정된부분만그림 int DrawText( HDC hdc, LPCTSTR lpstring, int ncount, LPRECT lprect, UNIT uformat ); 지정된텍스트 (lpstring) 를지정된영역 (lprect) 에출력 uformat: 텍스트출력형식 ( 정렬, 한줄표시등 ) BOOL ExtTextOut( HDChdc, int X, X int Y, Y UINT fuoptions, const RECT* lprc, LPCTSTR lpstring, UINT cbcount, const int* lpdx ); 지정된영역 (lprc) 의좌표 (X,Y) 에텍스트 (lpstring) 출력 fuoptions: 배경색표시여부지정 cbcount: 출력할문자열길이 lpdx: 문자간의간격지정 순천향대학교컴퓨터학부이상정 10
윈도우좌표 BOOL GetClientRect( HWNDhWnd, LPRECT lprect ); 지정된윈도우의클라이언트영역을 lprect 에저장 typedef struct t _RECT LONG left; LONG top; LONG right; LONG bottom; } RECT; 순천향대학교컴퓨터학부이상정 11 예제 19: 디바이스컨텍스트예 윈도우에다음을출력 현재의시간을출력 스크린을터치하면윈도우클라이언트의좌표출력 순천향대학교컴퓨터학부이상정 12
예제 19: 코드 (1) LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) switch (message) case WM_LBUTTONDOWN: RECT rect; WCHAR sztext[1024]=l""; hdc = GetDC(hWnd); GetClientRect(hWnd, &rect); wsprintf(sztext, t L"RECT: (%d,%d), %d) (%d, %d)", rect.left, tl rect.top, tt rect.right, rect.bottom); tb tt ExtTextOut(hdc, 10,150, 0, &rect, sztext, lstrlen(sztext), NULL); ReleaseDC(hWnd, hdc); } break; case WM_COMMAND: 순천향대학교컴퓨터학부이상정 13 예제 19: 코드 (2) case WM_PAINT: SYSTEMTIME stlocal; WCHAR szlocal [1024]=L""; GetLocalTime(&stLocal); wsprintf(szlocal, L"Local Time - " L"%04d.%02d.%02d %02d:%02d:%02d", stlocal.wyear, stlocal.wmonth, stlocal.wday, stlocal.whour, stlocal.wminute, stlocal.wsecond); hdc = BeginPaint(hWnd, &ps); ExtTextOut(hdc, 10,50, 0, NULL, szlocal, lstrlen(szlocal), NULL); EndPaint(hWnd, &ps); } break; 순천향대학교컴퓨터학부이상정 14
선, 도형그리기 순천향대학교컴퓨터학부이상정 15 선그리기 (1) 선그리기 API WINGDIAPI BOOL WINAPI MoveToEx( HDC hdc, int X, int Y, LPPOINT lppoint ); 지정된위치로이동 이전위치는 lppoint 에저장 WINGDIAPI BOOL WINAPI LineTo( HDC hdc, int nxend, int nyend ); 현재위치에서지정된위치까지선을그림 순천향대학교컴퓨터학부이상정 16
선그리기 (2) BOOL Polyline( HDC hdc, const POINT* lppt, int cpoints ); lppt에기술된점을연결하여그림 cpoints: 점의개수 typedef struct tagpoint LONG x; LONG y; // 왼쪽상단 y } POINT; 예 POINT pts[2]; pts[0].x = 0; pts[0].y = 0; pts[1].x = 50; pts[1].y = 100; Polyline (hdc, pts, 2); 순천향대학교컴퓨터학부이상정 17 도형그리기 도형그리기 API BOOL Rectangle( HDC hdc, int nleftrect, int ntoprect, int nrightrect, int nbottomrect ); 사각형을그림 BOOL Ellipse( HDC hdc, int nleftrect, int ntoprect, int nrightrect, int nbottomrect ); 타원을그림 BOOL Polygon( HDC hdc, const POINT* lppoints, int ncount ); 다각형을그림 처음의점의좌표와마지막점의좌표를연결하는것을제외하고는 Polyline() 함수와동일 순천향대학교컴퓨터학부이상정 18
예제 20: 선, 도형그리기예 실행시작시선과다각선을그리고, 스크린을터치하면사각형, 타원, 다각형을더그리는예 순천향대학교컴퓨터학부이상정 19 예제 20: 코드 (1) LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) switch (message) case WM_LBUTTONDOWN: hdc = GetDC(hWnd); // 사각형그리기 Rectangle(hdc, 110, 30, 190, 70); // 타원그리기 Ellipse(hdc, 110, 80, 180, 120); // 다각형그리기 POINT ptarray[6]; ptarray[0].x = 47; ptarray[0].y = 180; ptarray[1].x = 10; ptarray[1].y = 205; ptarray[2].x = 10; ptarray[2].y = 235; ptarray[3].x = 47; ptarray[3].y = 260; ptarray[4].x = 85; ptarray[4].y = 235; ptarray[5].x = 85; ptarray[5].y = 205; Polygon(hdc, ptarray, 6); ReleaseDC(hWnd, hdc); } break; case WM_COMMAND: 순천향대학교컴퓨터학부이상정 20
예제 20: 코드 (2) case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // 선그리기 MoveToEx(hdc, 30, 30, NULL); LineTo(hdc, 90, 90); // 다각선그리기 POINT ptarray[6] = 47, 100}, 10, 125}, 10, 155}, 47, 180}, 85, 155}, 85,125}}; Polyline(hdc, ptarray, 6); EndPaint(hWnd, d &ps); } break; 순천향대학교컴퓨터학부이상정 21 GDI 객체 순천향대학교컴퓨터학부이상정 22
GDI 객체 (1) GDI (Graphic Device Interface) 객체는그래픽을출력할때사용되는도구로펜, 브러쉬, 비트맵, 폰트등이포함 DC가처음만들어질때 GDI 오브젝트는모두디폴트로설정 GDI 사용절차 ( 펜사용예 ) 1. 펜을생성, CreatePen() 또는 GetStockObject() MyPen 2. 선택, SelectObject() hdc 펜 브러시 hdc MyPen 브러시 리턴 대입 3. 선, 도형등을그림 OldPen 4. 이전펜복구, SelectObject() 5. 펜삭제, DeleteObject() (CreatePen() 생성인경우 ) 순천향대학교컴퓨터학부이상정 23 GDI 객체 (2) GDI 관련 API HGDIOBJ SelectObject( HDC hdc, HGDIOBJ hgdiobj ); 디바이스컨텍스트 hdc에 GDI 객체 hgdiobj( 펜, 브러쉬등 ) 적용 이전 GDI 객체를리턴 HGDIOBJ GetStockObject( int fnobject ); 미리지정된펜, 브러쉬, 폰트등의 GDI 객체반환 fnobject WHITE_PEN BLACK_PEN NULL_PEN BLACK_BRUSH GRAY_BRUSH NULL_BRUSH WHITE_BRUSH DKGRAY_BRUSH LTGRAY_BRUSH BOOL DeleteObject( HGDIOBJ hobject ); 생성된 GDO 객체를제거 순천향대학교컴퓨터학부이상정 24
펜 (pen) 선과도형의외곽선모양을지정 펜API HPEN CreatePen( int fnpenstyle, int nwidth, COLORREF crcolor ); 펜을생성 fnpenstyle: 의형태, PS_DASH PS_SOLID SOLID PS_NULL nwidth : 선의굵기 crcolor : 색상 색상표현 : 32비트정수, 3개의 8비트 (0-255) 값 red, green, blue 사용 typedef DWORD COLORREF; #define RGB(r,g,b) ((COLORREF)(((BYTE)(r) ((WORD)((BYTE)(g))<<8)) (((DWORD)(BYTE)(b))<<16))) 빨강색실선 Pen 예 hpen = CreatePen (PS _ SOLID, 1, RGB (255, 0, 0)) 순천향대학교컴퓨터학부이상정 25 색상 RGB 색상 RGB 색상 RGB(0,0,0) 검정 RGB(128,128,128) 진회색 RGB(0,0,255) 파랑 RGB(0,0,128) 진파랑 RGB(0,255,0) 연두 RGB(0,128,0) 초록 RGB(0,255,255) 시안 RGB(0,128,128) 진하늘 RGB(25500) RGB(255,0,0) 빨강 RGB(12800) RGB(128,0,0) 진빨강 RGB(255,0,255) 연홍색 RGB(128,0,128) 분홍 RGB(255,255,0) 갈색 RGB(128,128,0) 노랑 RGB(192,192,192) 192) RGB(255,255,255) 255) 연회색 흰색 순천향대학교컴퓨터학부이상정 26
브러쉬 (brush) 도형내부또는윈도우배경을채울때사용 브러쉬 API HBRUSH CreateSolidBrush( COLORREF crcolor ); 브러쉬를생성 순천향대학교컴퓨터학부이상정 27 예제 21: 선, 도형그리기예 2 예제 20 의그리기에선의색, 도형의배경색을다음과같이표시 순천향대학교컴퓨터학부이상정 28
예제 21: 코드 (1) LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) int wmid, wmevent; PAINTSTRUCT ps; HDC hdc; HPEN MyPen, OldPen; HBRUSH MyBrush, OldBrush; switch (message) case WM_LBUTTONDOWN: hdc = GetDC(hWnd); // GDI 펜, 브러쉬객체생성, 선택 MyPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255)); OldPen = (HPEN)SelectObject(hdc, MyPen); MyBrush = CreateSolidBrush(RGB(0, 255, 0)); OldBrush = (HBRUSH)SelectObject(hdc, MyBrush); // 사각형그리기 Rectangle(hdc, 110, 30, 190, 70); // 타원그리기 Ellipse(hdc, 110, 80, 180, 120); 순천향대학교컴퓨터학부이상정 29 예제 21: 코드 (2) // GDI 펜, 브러쉬복구, 제거 SelectObject(hdc, OldPen); DeleteObject(MyPen); SelectObject(hdc, OldBrush); DeleteObject(MyBrush); // GDI 펜, 브러쉬객체생성, 선택 MyPen = CreatePen(PS_SOLID, 5, RGB(128, 128, 128)); // 회색 OldPen = (HPEN)SelectObject(hdc, MyPen); MyBrush = CreateSolidBrush(RGB(255, 255, 0)); // 노란색 OldBrush = (HBRUSH)SelectObject(hdc, MyBrush); // 다각형그리기 POINT ptarray[6]; ptarray[0].x = 47; ptarray[0].y = 180; ptarray[1].x = 10; ptarray[1].y = 205; ptarray[2].x = 10; ptarray[2].y = 235; ptarray[3].x = 47; ptarray[3].y = 260; ptarray[4].x = 85; ptarray[4].y = 235; ptarray[5].x = 85; ptarray[5].y = 205; Polygon(hdc, ptarray, 6); 순천향대학교컴퓨터학부이상정 30
// GDI 펜, 브러쉬복구, 제거 SelectObject(hdc, OldPen); DeleteObject(MyPen); SelectObject(hdc, OldBrush); DeleteObject(MyBrush); ReleaseDC(hWnd, hdc); } break; case WM_COMMAND: case WM_PAINT PAINT: hdc = BeginPaint(hWnd, &ps); // GDI 펜객체생성, 선택 MyPen = CreatePen(PS _ SOLID, 3, RGB(255, 0, 0)); OldPen = (HPEN)SelectObject(hdc, MyPen); // 선그리기 MoveToEx(hdc, 30, 30, NULL); LineTo(hdc, 90, 90); // 다각선그리기 POINT ptarray[6] = 47, 100}, 10, 125}, 10, 155}, 47, 180}, 85, 155}, 85,125}}; Polyline(hdc, ptarray, 6); // GDI 펜복구, 제거 SelectObject(hdc, OldPen); DeleteObject(MyPen); EndPaint(hWnd, &ps); } break; 순천향대학교컴퓨터학부이상정 31 예제 21: 코드 (3) 예제 22: 자유그리기예 (1) 아래와같이터치스크린위에서터치하면서움직이면선이그려지는예 순천향대학교컴퓨터학부이상정 32
예제 22: 자유그리기예 (2) WM_LBUTTONDOWN, WM_MOUSEMOVE, MOUSEMOVE WM_LBUTTONUP 메시지에대해아래와같이처리하여그려줌 nowp 1. WM_LBUTTONDOWN, nowp 좌표기억 2. WM_MOUSEMOVE, MOUSEMOVE MoveToEx() 함수사용하여이점으로이동 3. WM_MOUSEMOVE, LineTo() 함수사용하여선그리기, nowp 를이점으로지정 point 4. WM_LBUTTONUP, 그리기종료 순천향대학교컴퓨터학부이상정 33 예제 22: 코드 (1) BOOL bpaint = FALSE; // 터치여부저장 POINT nowp; // 선분의시작점저장 LRESULT CALLBACK ACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) int wmid, wmevent; PAINTSTRUCT ps; HDC hdc; case WM_MOUSEMOVE MOUSEMOVE: if (bpaint) hdc = GetDC(hWnd); switch (message) case WM_LBUTTONDOWN: bpaint = TRUE; nowp.x = LOWORD(lParam); nowp.y = HIWORD(lParam); break; case WM_LBUTTONUP: bpaint = FALSE; break; 순천향대학교컴퓨터학부이상정 34 POINT pt; pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); MoveToEx(hdc, nowp.x, nowp.y, NULL); LineTo(hdc, pt.x, pt.y); nowp. x = pt.x; nowp.y = pt.y; } break;
과제 5 예제 22 의자유그리기예제에아래와같이 Line 과 Color 메뉴를추가하여선의굵기와색을지정하여그리는프로그램을작성하라. 순천향대학교컴퓨터학부이상정 35