이번에는 DC에 대해서 공부해보았습니다. 이것은 화면 처리, 그래픽를 담당하는 GDI 모듈에 의해 관리되는 구조체입니다. 화면에 출력을 하기 위해서는 반드시 DC가 있어야 합니다. DC는 그리기에 필요한 다양한 정보들의 저장소 역활, 그리기 함수들이 참조하는 원점의 정보를 제공하고, 윈도우끼리의 출력 결과가 서로를 방해하지 않도록 완충역할을 하게 됩니다.
이 DC를 얻는 방법은 두가지가 있습니다. 첫번째는 GetDC함수를 사용하는 방법, 또 다른 한가지는 WM_PAINT 메시지 처리 루틴에서 BeginPaint 함수를 통해서 얻는 방법이 있습니다.
GetDC 함수 사용하여 DC얻는방법
HDC GetDC(HWND hWnd);
int ReleaseDC(HWND hWnd,HDC hDC);
BeginPaint 함수 사용하여 DC얻는방법
HDC BeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint);
BOOL EndPaint(HWND hWnd, CONST PAINTSTRUCT *lpPaint);
이 둘다 얻은 DC를 다 쓰고 나서는 확실히 처리를 해야 효율적인 메모리관리가 가능해집니다.
그럼 우선 GetDC를 이용하여 마우스 왼쪽 클릭시 사각형을 윈도우에 출력하는 소스를 만들어 보도록 하죠.
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("DCTest");
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdParam, 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;
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 (int)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_LBUTTONDOWN:
hdc = GetDC(hWnd);
Rectangle(hdc, 50, 100, 400, 300);
ReleaseDC(hWnd, hdc);
return 0;
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
다음과 같이 만들게 되면 마우스 오른쪽 클릭시 다음과 같이 사각형이 출력되는 것을 볼수가 있습니다.
여기서 한가지 문제점이 생기는 것을 볼수가 있죠. 벌써 눈치 채신분들도 있을겁니다. 어떤 문제인고 하니 윈도우의 창의 크기를 조절하거나 해당 윈도우를 다른 윈도우창으로 가렸다가 빼게 되면 사각형이 감쪽같이 사라지게 되는 것을 볼수가 있습니다. 물론 다시 클릭을 하게 되면 보여지게 되지만요. 이 문제점을 해결하는 것이 WM_PAINT 메시지 루틴에서 처리 하는 것이지요.
WndProc 부분을 다음과 같이 수정을 해주세요
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);
Rectangle(hdc, 50, 100, 400, 300);
EndPaint(hWnd, &ps);
return 0;
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
그러면 창이 가려지고 최소화를 시켰다가 다시 올려도 사각형이 여전히 그려져 있는것을 볼수가 있죠. 이것은 다른것이 아니고 WM_PAINT 메시지 루틴이 윈도우가 가려졌다가 다시 나올 때마다 메시지가 호출 되기 때문에 일어나는 것입니다. 아직 문제점이 있긴 합니다. 마우스 왼쪽 버튼 클릭시 나타나야 하지만 무조건 생겨나게 되죠. 큰 문제점인데요...아직 여기까지밖에 공부를 못했어요 ㅜ_ㅜ
그런 이유로 여기서 마치려고 합니다~. API를 공부하면서 참 여러가지로 느끼는게 많은데요. 너무나 많이 부족하다는 것과 배움은 즐겁다는거...늦은 시간인데도 계속 공부하게되네요 ㅎㅎ
암튼 쉬운걸 이렇게 어려워 하다니 좀그렇긴 합니다만...이렇게 공부하다보면 언젠가는 더 실력이 늘어 있겠죠!!
그 미래를 위해 화이팅입니다!!!
p.s : 마우스 클릭시에 사각형이 그려지고 없어지지 않게 하려면 어떻게 해야될까요??
출처 : API 정복
'API' 카테고리의 다른 글
1초에 한번씩 캡쳐 화면 파일로 저장하기 (0) | 2010.03.27 |
---|---|
디렉토리 생성 (0) | 2010.03.27 |
Win API Timer (0) | 2010.03.21 |
캡쳐 화면 BMP로 저장하기 (0) | 2010.03.14 |
메뉴의 단축키, 액셀러레이터 생성 (0) | 2010.03.12 |
메뉴 만들기 (1) | 2010.03.11 |
포커스가 있는 윈도우 캡쳐 (0) | 2010.03.10 |
API로 구현한 전체화면 캡쳐 소스 (0) | 2010.03.09 |
버튼 생성 (0) | 2010.03.06 |
API의 첫 시작 (0) | 2010.03.05 |