< 투명 오브젝트 >
만약 도형의 테두리나 내부를 그리고 싶지 않을 경우에는 투명 오브젝트를 사용하면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 |
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
int i;
HBRUSH MyBrush, OldBrush;
HPEN MyPen, OldPen;
switch(iMessage) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
for (i=0; i<250; i+=5) {
MoveToEx(hdc, 0, i, NULL);
LineTo(hdc, 600, i);
}
MyBrush = CreateSolidBrush(RGB(0,255,0));
OldBrush = (HBRUSH)SelectObject(hdc, MyBrush);
MyPen = CreatePen(PS_SOLID, 5, RGB(255,0,0));
OldPen = (HPEN)SelectObject(hdc, MyPen);
Ellipse(hdc, 20, 20, 150, 150);
SelectObject(hdc, GetStockObject(NULL_BRUSH));
Ellipse(hdc, 220, 20, 350, 150);
SelectObject(hdc, MyBrush);
SelectObject(hdc, GetStockObject(NULL_PEN));
Ellipse(hdc, 420, 20, 550, 150);
DeleteObject(SelectObject(hdc, OldPen));
DeleteObject(SelectObject(hdc, OldBrush));
EndPaint(hWnd, &ps);
return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
} |
cs |
상기 코드를 실행시키면 첫 번째 원은 테두리와 내부 색도 채워져 있고, 두 번째 원은 내부가 투명이라 뒤에 배경이 보이며,
세 번째 원은 내부는 채워져 있으나 태두리가 그려져 있지 않다.
GDI의 그리기 함수들은 항상 선택된 오브젝트를 무조건 사용하도록 되어 있으며 테두리만 따로 그리는 함수나 도형 내부만
채우는 함수는 별도로 제공되지 않는다. 그래서 둘 중 하나만 그리고 싶은 경우에 투명 오브젝트를 사용한다.
< 그리기 모드 >
윈도우즈에서 사용하는 디폴트 그리기 모드는 R2_COPYPEN 모드이다. 그래서 그려지는 그림이 기존 그림을 덮어버린다.
그리기 모드를 변경하는 함수와 현재 설정된 그리기 모드를 구하는 함수는 다음과 같다.
1
2 |
int SetROP2(HDC hdc, int rop2);
int GetROP2(HDC hdc); |
cs |
HDC hdc 인자는 그리기 모드를 변경하고자 하는 DC의 핸들이며, int rop2 인자는 그리기 모드값이다.
여러가지 종류가 있지만 대부분 사용하지 않으며 R2_NOT (반전 모드)만 중간 중간 사용된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 |
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
static int sx, sy, oldx, oldy;
static BOOL bNowDraw = FALSE;
HDC hdc;
switch(iMessage) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_LBUTTONDOWN:
sx = LOWORD(lParam);
sy = HIWORD(lParam);
oldx = sx;
oldy = sy;
bNowDraw = TRUE;
return 0;
case WM_MOUSEMOVE:
if (bNowDraw == TRUE) {
hdc = GetDC(hWnd);
SetROP2(hdc, R2_NOT);
MoveToEx(hdc,sx,sy,NULL);
LineTo(hdc, oldx, oldy);
oldx = LOWORD(lParam);
oldy = HIWORD(lParam);
MoveToEx(hdc, sx,sy,NULL);
LineTo(hdc, oldx, oldy);
ReleaseDC(hWnd, hdc);
}
return 0;
case WM_LBUTTONUP:
bNowDraw = FALSE;
hdc = GetDC(hWnd);
MoveToEx(hdc,sx,sy,NULL);
LineTo(hdc, oldx, oldy);
ReleaseDC(hWnd, hdc);
return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
} |
cs |
상기 코드는 파워포인트에서 선을 만들 때 마우스 움직임에 따라 임시 선이 생기고 마우스 버튼을 때면 최종 선이 화면에
그려지는 코드이다.
왼쪽 마우스를 클릭한 상태에서 마우스를 움직이면 R2_NOT 모드로 변경하여 선을 그리는데 기존에 그려졌던 임시 선을 지워주기
위해서 반전 모드로 그려주는 것이다.
흑백 화면에서는 R2_NOT이 이런 작을 가능하게 해주는 가장 편리한 방법이며 컬러 환경에서는 R2_NOTXORPEN이 가장 편리하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 |
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
static int sx, sy, oldx, oldy;
static BOOL bNowDraw = FALSE;
HPEN MyPen, OldPen;
HBRUSH MyBrush, OldBrush;
HDC hdc;
PAINTSTRUCT ps;
switch(iMessage) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_LBUTTONDOWN:
sx = LOWORD(lParam);
sy = HIWORD(lParam);
oldx = sx;
oldy = sy;
hdc = GetDC(hWnd);
MyBrush = CreateSolidBrush(RGB(255,0,255));
MyPen = CreatePen(PS_SOLID, 5, RGB(156, 04, 121));
OldBrush = (HBRUSH)SelectObject(hdc, MyBrush);
OldPen = (HPEN)SelectObject(hdc, MyPen);
SetROP2(hdc, R2_NOTXORPEN);
Ellipse(hdc, sx-50, sy-50, sx+50, sy+50);
bNowDraw = TRUE;
SelectObject(hdc, OldBrush);
SelectObject(hdc, OldPen);
DeleteObject(MyBrush);
DeleteObject(MyPen);
ReleaseDC(hWnd, hdc);
return 0;
case WM_MOUSEMOVE:
if (bNowDraw == TRUE) {
hdc = GetDC(hWnd);
MyBrush = CreateSolidBrush(RGB(255,0,255));
MyPen = CreatePen(PS_SOLID, 5, RGB(156, 04, 121));
OldBrush = (HBRUSH)SelectObject(hdc, MyBrush);
OldPen = (HPEN)SelectObject(hdc, MyPen);
SetROP2(hdc, R2_NOTXORPEN);
Ellipse(hdc, oldx-50, oldy-50, oldx+50, oldy+50);
oldx = LOWORD(lParam);
oldy = HIWORD(lParam);
Ellipse(hdc, oldx-50, oldy-50, oldx+50, oldy+50);
SelectObject(hdc, OldBrush);
SelectObject(hdc, OldPen);
DeleteObject(MyBrush);
DeleteObject(MyPen);
ReleaseDC(hWnd, hdc);
}
return 0;
case WM_LBUTTONUP:
bNowDraw = FALSE;
hdc = GetDC(hWnd);
MyBrush = CreateSolidBrush(RGB(255,0,255));
MyPen = CreatePen(PS_SOLID, 5, RGB(156, 04, 121));
OldBrush = (HBRUSH)SelectObject(hdc, MyBrush);
OldPen = (HPEN)SelectObject(hdc, MyPen);
Ellipse(hdc, oldx-50, oldy-50, oldx+50, oldy+50);
SelectObject(hdc, OldBrush);
SelectObject(hdc, OldPen);
DeleteObject(MyBrush);
DeleteObject(MyPen);
ReleaseDC(hWnd, hdc);
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
} |
cs |
상기 코드는 아까 선 그리던 코드와 동일한 기능이지만 색상이 있는 원을 대상으로 그리는 코드이다.
'Programming > Window UI' 카테고리의 다른 글
6. 폰트 & 텍스트 색상 & 글자 회전시키기 (0) | 2017.10.30 |
---|---|
5. 비트맵 & 메모리 DC & ScretchBlt (0) | 2017.10.30 |
3. GDI 오브젝트 & 펜 & 브러시 & Old의 의미. (0) | 2017.10.26 |
2. DC를 얻는 방법. (0) | 2017.10.26 |
1. DC & WM_PAINT 메시지. (0) | 2017.10.26 |