반응형
이제 기본적인 비트맵을 출력해봤으니 더블 버퍼에 대해서 알아보도록 하겠습니다.
먼저 아래 코드를 작성해보겠습니다.
void DrawIMG()
{
InvalidateRect( _hWnd , NULL ,TRUE);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
static RECT rc = {0 ,250 , 100 , 350};
switch (iMessage)
{
case WM_CREATE:
{
SetTimer (hWnd , 1 , 25 ,NULL);
break;
}
case WM_TIMER:
{
DrawIMG();
rc.left += 1;
rc.right += 1;
break;
}
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
Rectangle(hdc , rc.left , rc.top , rc.right , rc.bottom);
for (int i = 0 ; i < 25 ; i++)
{
Rectangle(hdc , rc.left , rc.top + i * 10 , rc.right , rc.bottom + i * 10 );
}
for (int i = 0 ; i < 25 ; i++)
{
Rectangle(hdc , rc.left , rc.top - i * 10 , rc.right , rc.bottom - i * 10 );
}
EndPaint(hWnd , &ps);
break;
}
case WM_DESTROY:
KillTimer(hWnd ,1);
PostQuitMessage(0);
break;
}
return (DefWindowProc(hWnd, iMessage, wParam, lParam));
}
// 결과 |
해당 파일을 실행하면 0 좌표에서 총 51개의 사각형이 초당 1픽셀씩 우측으로 이동합니다.
다만, 이럴경우 화면을 1초에 한번씩 다시 그리는(업데이트)하는 부분이 생겨서 화면이 깜빡이게 됩니다.
다른 함수로 그리는 부분을 뺀거나 InvalidateRect에서 갱신될 부분을 지정해준다면 조금은 감소하기는
하지만 정확한 방법은 될 수 없습니다. InvalidateRect의 마지막 매게 변수를 TRUE에서 FALSE로 바꾸면
배경을 다시 그리지 않아 깜빡이지는 않지만 지나간 곳에 검은색(기존에 사각형 픽셀)이 남게 됩니다.
이럴 경우 이미지를 다른곳에서 그려 복사해 넣는 방식인 더블 버퍼 방식을 사용해야 합니다.
이 이야기 어디서 들어본것 같지 않습니까?
그렇습니다. 즉 비트맵과 동일한 방법을 사용하면 됩니다.
비트맵을 하나 생성해서 사각형들을 그리고 복사해서 출력해주면 됩니다.
----//전역 변수
HBITMAP MyBitmap;
RECT rc = {0 ,250 , 100 , 350};
----//
void DrawBitmap(HDC hdc,int x,int y,HBITMAP hBit)
{
HDC MemDC;
HBITMAP OldBitmap;
int bx,by;
BITMAP bit;
MemDC=CreateCompatibleDC(hdc);
OldBitmap=(HBITMAP)SelectObject(MemDC, hBit);
GetObject(hBit,sizeof(BITMAP),&bit);
bx=bit.bmWidth;
by=bit.bmHeight;
BitBlt(hdc,0,0,bx,by,MemDC,0,0,SRCCOPY);
SelectObject(MemDC,OldBitmap);
DeleteDC(MemDC);
}
void DrawIMG()
{
RECT crt;
HDC hdc , hMemDC;
HBITMAP OldBit;
GetClientRect ( _hWnd , &crt);
hdc = GetDC( _hWnd);
if ( MyBitmap == NULL)
{
MyBitmap = CreateCompatibleBitmap (hdc , crt.right, crt.bottom);
}
hMemDC = CreateCompatibleDC(hdc);
OldBit = (HBITMAP) SelectObject(hMemDC , MyBitmap);
FillRect(hMemDC , &crt , GetSysColorBrush (COLOR_WINDOW));
Rectangle(hMemDC , rc.left , rc.top , rc.right , rc.bottom);
for (int i = 0 ; i < 25 ; i++)
{
Rectangle(hMemDC , rc.left , rc.top + i * 10 , rc.right , rc.bottom + i * 10 );
}
for (int i = 0 ; i < 25 ; i++)
{
Rectangle(hMemDC , rc.left , rc.top - i * 10 , rc.right , rc.bottom - i * 10 );
}
SelectObject (hMemDC , OldBit);
DeleteDC (hMemDC);
ReleaseDC ( _hWnd , hdc);
rc.left += 1;
rc.right += 1;
InvalidateRect( _hWnd , NULL ,FALSE);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch (iMessage)
{
case WM_CREATE:
{
SetTimer (hWnd , 1 , 25 ,NULL);
break;
}
case WM_TIMER:
{
DrawIMG();
break;
}
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
if (MyBitmap)
DrawBitmap (hdc , 0 , 0 , MyBitmap);
EndPaint(hWnd , &ps);
break;
}
case WM_DESTROY:
if (MyBitmap)
{
DeleteObject(MyBitmap);
}
PostQuitMessage(0);
KillTimer(hWnd ,1);
break;
}
return (DefWindowProc(hWnd, iMessage, wParam, lParam));
}
// 결과 |
반응형
'프로그래밍 관련 > Win API' 카테고리의 다른 글
WIndows API - #9-7 그래픽 처리 - (여러개의 DC 이미지 출력하기) (2) | 2015.10.09 |
---|---|
WIndows API - #9-6 그래픽 처리 - (더블 버퍼링 - 자세히 보기)(2) (0) | 2015.09.07 |
WIndows API - #9-4 그래픽 처리 - (비트맵 출력)(2) - 코드 살펴보기 (0) | 2015.09.06 |
WIndows API - #9-3 그래픽 처리 - (비트맵 출력) (1) (0) | 2015.09.06 |
WIndows API - #9 -2. 그래픽 처리 (Old를 같이 쓰는 이유) (2) (0) | 2015.09.03 |