< 투명 오브젝트 >

 

만약 도형의 테두리나 내부를 그리고 싶지 않을 경우에는 투명 오브젝트를 사용하면 된다.

 

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, 2020150150);
 
        SelectObject(hdc, GetStockObject(NULL_BRUSH));
        Ellipse(hdc, 22020350150);
 
        SelectObject(hdc, MyBrush);
        SelectObject(hdc, GetStockObject(NULL_PEN));
        Ellipse(hdc, 42020550150);
 
        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(15604121));
        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(15604121));
            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(15604121));
        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

 

상기 코드는 아까 선 그리던 코드와 동일한 기능이지만 색상이 있는 원을 대상으로 그리는 코드이다.

+ Recent posts