일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Dijkstra
- Hash
- MYSQL
- two pointer
- binary search
- union find
- 스토어드 프로시저
- 다익스트라
- 이진탐색
- Stored Procedure
- SQL
- String
- Trie
- Brute Force
- DP
- Two Points
- 그래프
Archives
- Today
- Total
codingfarm
6. 그래픽 - 그리기 모드 본문
1. 흑백에서의 그리기 모드
- 그리기 모드 : 도형이 그려질 때 원래 그려져 있던 그림과 새로 그려지는 그림과의 관계를 정의하는것
- ex : 예전 그림 위에 새그림 덮기, 적절히 혼합하기
가령 2개의 흑백 그림을 4가지 비트 연산으로 합처보면 아래와 같다.
2. 그리기 모드의 종류
- 그리기 모드를 변경하는 함수와 현재 설정된 그리기 모드를 구하는 함수는 아래와 같다.
1
2
|
int SetROP2( HDC hdc, int rop2 );
int GetROP2( HDC hdc);
|
cs |
hdc : 그리기 모드를 변경(또는 조사) 하고자 하는 DC의 핸들
rop2 : 변경할 그리기 모드 값
그리기 모드 | 설명 |
R2_BLACK | 항상 검정색이다. |
R2_WHITE | 항상 흰색이다. |
R2_NOP | 아무런 그리기도 하지 않는다. |
R2_NOT | 원래의 그림을 반전시킨다. |
R2_COPYPEN | 원래의 그림을 덮어버리고 새 그림을 그린다. |
R2_NOTCOPYPEN | 새 그림을 반전시켜 그린다. |
R2_MERGEPEN | OR연산으로 두 그림을 합친다. |
R2_MASKPEN | AND연산으로 겹치는 부분만 그린다. |
R2_XORPEN | XOR연산으로 겹치는 부분만 반전시킨다. |
디폴트 : R2_COPYPEN (그려지는 그림이 기존 그림을 덮는다)
이외에 여러가지 그리기 모드가 있지만 주로 NOT연산자를 중간중간에 넣은 것들이며 거의 사용되지 않는다.
3. 그리기 모드
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
74
75
76
77
78
79
80
81
|
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass = TEXT("RopMode");
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance
, LPSTR lpszCmdParam, int nCmdShow) {
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
g_hInst = hInstance;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hInstance = hInstance;
WndClass.lpfnWndProc = (WNDPROC)WndProc;
WndClass.lpszClassName = lpszClass;
WndClass.lpszMenuName = NULL;
WndClass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&WndClass);
hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, (HMENU)NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
while (GetMessage(&Message, NULL, 0, 0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return Message.wParam;
}
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_LBUTTONDOWN:
sx = LOWORD(lParam);
sy = HIWORD(lParam);
oldx = sx;
oldy = sy;
bNowDraw = TRUE;
return 0;
case WM_MOUSEMOVE:
if (bNowDraw) {
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;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
|
cs |
마우스를 드래그하면 이전에 클릭했던 좌표와 놓았던 좌표사이에 선이 그려지며, 마우스를 움직이는동안 실시간으로 그려질 선이 미리 보인다.
여기서 주목할만한 부분은, 그려저야할 선을 미리 보여주는 부분인데 마우스를 움직일때마다 전송되는 메시지 WM_MOUSEMOVE내에서 이루어지는 작업이다.
SetROP2 함수를 호출하여 그리기 모드를 R2_NOT으로 변경하고, (sx, sy)-(oldx, oldy) 선에 대해 반전연산을 적용한다. 그러면 이전에 그렸던 선이 지워지게된다. 그리고 현 지점을 oldx, oldy에 대입하고 새로운 선을 그리면 된다.
만약 ROP모드의 R2_NOT을 통해 색반전이 아니라 흰색펜으로 지운 후 검정펜으로 다시 그리면 어떻게 될까?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
case WM_MOUSEMOVE:
if (bNowDraw) {
hdc = GetDC(hWnd);
SelectObject(hdc, GetStockObject(WHITE_PEN));
MoveToEx(hdc, sx, sy, NULL);
LineTo(hdc, oldx, oldy);
oldx = LOWORD(lParam);
oldy = HIWORD(lParam);
SelectObject(hdc, GetStockObject(BLACK_PEN));
MoveToEx(hdc, sx, sy, NULL);
LineTo(hdc, oldx, oldy);
ReleaseDC(hWnd, hdc);
}
return 0;
|
cs |
마우스를 따라 선을 이동시킬 때 이미 그려진 그림의 보존이 전혀 안되는것을 확인할 수 있다.
이 예제는 마우스의 이동에 의해 임시적인 선을 그려놓을뿐, 어디에 선을 그려놓았는지를 기억하지 않으므로, 덮어 씌워진 선을 복구할 수 없으며, WM_PAINT를 처리하지도 않는다. 그리기 정보를 저장하는 방법은 추후 학습할것이다.
'Windows > 윈도우즈 API' 카테고리의 다른 글
6. 그래픽 - 폰트 (0) | 2021.12.25 |
---|---|
6. 그래픽 - 비트맵 (0) | 2021.05.05 |
6. 그래픽 - DC의 정보 수정 (0) | 2021.05.04 |
5. 리소스 - 문자열 테이블(string table) (0) | 2021.05.01 |
5. 리소스 - 액셀러레이터(Accelerator) (0) | 2021.05.01 |
Comments