김상형 저자님께서 작성하신 윈도우즈 API 정복 3장 출력에 대한 내용입니다.
< DC (Device Context) >
윈도우즈는 세 가지 동적 연결 라이브러리(DLL)로 구성되어 있다.
- KERNEL : 메모리를 관리하고 프로그램을 실행시키는 DLL.
- USER : 유저 인터페이스와 윈도우를 관리하는 DLL.
- GDI : 화면 처리와 그래픽을 담당하는 DLL.
이 세 개의 DLL 중 화면에 원하는 정보를 출력하려면 GDI(Graphic Device Interface) 모듈을 통해야 하며, GDI 모듈은 출력에
필요한 모든 정보를 가지는 데이터 구조체인 DC(Device Context)를 관리한다.
DC의 필요성은 다음과 같다.
- 화면에 그릴 정보를 함수 인자로 넘길 때 DC의 핸들만 넘겨주면 간편하게 사용할 수 있게 된다.
- DC에는 생성된 윈도우를 기준으로 하는 원점 좌표를 가지고 있기 때문에 윈도우의 위치에 신경쓰지 않아도 된다.
- DC는 출력이 가능한 영역에만 출력을 내 보내기 때문에 윈도우가 겹치는 문제에 대해 신경쓰지 않아도 된다.
이와 같이 DC가 그리기에 필요한 여러 가지 정보와 안전 장치 역할을 하기 때문에 모든 그리기 함수는 DC의 핸들을
첫 번째 인수로 전달받는다.
< WM_PAINT 메시지 >
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 |
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
DWORD WINAPI ThreadFunc(LPVOID);
HINSTANCE g_hInst;
HWND hWndMain;
LPSTR lpszClass="TextOut";
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,0,0,0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
switch(iMessage) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_RBUTTONDOWN:
hdc = GetDC(hWnd);
TextOut(hdc, 100, 100, TEXT("Beautiful Korea"), 15);
ReleaseDC(hWnd, hdc);
return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
} |
cs |
오른쪽 버튼 클릭시 화면에 문자열을 출력하는 프로그램이다.
그러나 이 프로그램은 문자열을 다른 윈도우로 가리거나 문자열이 모니터 화면 밖으로 나가도록 윈도우를 움직이면, 가려진 문자열
부분은 화면상에서 완전히 지워지고 다시 그려지지 않는 문제점을 가지고 있다.
이유는 운영체제가 개별 윈도우의 화면을 보관 및 복구해 주지 않기 때문이며, 지워진 화면을 복구하는 것은 프로그램 자신이 직접
해야한다.
그래서 위와 같은 문제를 해결하기 위해서는 마우스 오른쪽 버튼이 클릭 될 때 출력하는 것이 아니라 화면이 지워질 때마다 문자열을
출력해야 한다. 그러므로 화면이 지워질 때 호출되는 WM_PAINT 메시지를 사용하면 된다.
운영체제는 개별 윈도우의 화면을 보관해 주지는 않지만 윈도우의 일부가 지워졌다는 정보는 개별 윈도우에게 알려주며 그 방법은
WM_PAINT 메시지를 보내주는 것이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 |
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch(iMessage) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 100, 100, TEXT("Beautiful Korea"), 15);
EndPaint(hWnd, &ps);
return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
} |
cs |
위와 같이 코드를 수정하면 출력한 문자열은 지워져도 항상 다시 복구된다.
'Programming > Window UI' 카테고리의 다른 글
6. 폰트 & 텍스트 색상 & 글자 회전시키기 (0) | 2017.10.30 |
---|---|
5. 비트맵 & 메모리 DC & ScretchBlt (0) | 2017.10.30 |
4. 투명 오브젝트 & 그리기 모드. (0) | 2017.10.30 |
3. GDI 오브젝트 & 펜 & 브러시 & Old의 의미. (0) | 2017.10.26 |
2. DC를 얻는 방법. (0) | 2017.10.26 |