이번에는 MFC 프로그래밍에서 bitmap에 대한 것을 알아보도록 하겠습니다.
.
.
.
bitmap은 이미지 파일로
MFC 프로그래밍에서 출력하는 방법으로는 아래와 같습니다.
.
.
.
.
.
MFC로 만들기
1. [리소스 추가] -> Bitmap -> [새로 만들기]
2. 빈 화면 -> 그리기
.
.
.
bitmap 속성
비트맵 편집기 속성
Width, Height : 비트맵 크기, 수정 가능
Colors : 사용하는 컬러 수로 32비트까지 지원 가능
.
.
비트맵 노드 속성
ID : 비트맵에 대한 식별자, 수정 가능
File name : 비트맵 파일을 저장할 파일 이름
.
.
Bitmap 파일 불러오기
[리소스 추가] -> [Bitmap] -> [가져오기]
내 컴퓨터에 있는 이미지를 가져올 수 있습니다.
.
.
.
BItBlt 함수 속성
BOOL BitBlt(
HDC hdc,
int nXD, int nYD,
int nW, int nH,
HDC memdc,
int nXS, int nYS,
DWORD dwRop
);
.
.
.
StretchBlt 함수 속성
BOOL StretchBlt(
HDC hdc,
int nXD, int nYD, int nW, int nH,
HDC memdc,
int nXS, int nYS, int nWS, int nHS,
DWORD dwRop
);
.
.
.
윈도 화면에 꽉 찬 Bitmap 출력 (StretchBlt 이용)
#include <windows.h>
#include <TCHAR.H>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
// UNICODE 사용시 wWinMain() 형태
// hPrevInstance 이전 인스턴스 항상 0값
// lpszCmdLine > 외부에서 (내부로) 입력받는 변수
// nCmdShow 윈도우 출력 형태에 관련한 값
{
HWND hwnd;
MSG msg;
WNDCLASS WndClass;
WndClass.style = CS_HREDRAW | CS_VREDRAW; //height, vertical redraw
WndClass.lpfnWndProc = WndProc; // Proc 설정
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 형변환
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = _T("Window Class Name");
RegisterClass(&WndClass); // WndClass 등록
hwnd = CreateWindow(_T("Window Class Name"),
_T("Jung-Stroy"), //
WS_OVERLAPPEDWINDOW, // 윈도우 스타일
600, 400, // 창출력좌표 x, y
600, 400, // 창크기 x, y축
NULL, // 부모 윈도우
NULL, // 메뉴바 핸들
hInstance, // 인스턴스
NULL // 여분, NULL
);
ShowWindow(hwnd, nCmdShow); // 윈도우 출력, WM_PAINT 출력내용 가져옴
UpdateWindow(hwnd); // WM_PAINT 출력내용 발생해서 출력하도록
// hwnd 핸들을 통해 보여주고 갱신
//ShowWindow(hwnd, SW_SHOW); // 위와 같음
//UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0)) // 메시지 큐의 메시지를 가져옴
{
TranslateMessage(&msg); // 키입력에 반응하는 메시지 변환, WM_KEYDOWN (키가 눌릴때) WM_CHAR 메시지 발생
DispatchMessage(&msg); // WndProc() 함수 호출과 WndProc()으로 메세지 전달
} // 종료는 WM_QUIT 발생할때 FALSE 리턴하면서 종료
return (int)msg.wParam; // wParam, lParam 윈도우 크기가 어떻게 변했는지, 변경된 클라이언트, 키보드, 마우스 값
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam)
// WinDef.h 에서 정의
// wPram > unsigned ptr, lParam > long ptr
{
HDC hdc, memdc;
PAINTSTRUCT ps;
static HBITMAP hBitmap;
BITMAP bm;
RECT rect;
static int nx, ny;
switch (iMsg)
{
case WM_CREATE:
hBitmap = (HBITMAP)LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance, MAKEINTRESOURCE(IDB_BITMAP5_2));
break;
case WM_PAINT:
GetClientRect(hwnd, &rect); // 윈도우 크기를 받아온다.
GetObject(hBitmap, sizeof(bm), &bm);
hdc = BeginPaint(hwnd, &ps);
memdc = CreateCompatibleDC(hdc);
SelectObject(memdc, hBitmap);
StretchBlt(hdc, 0, 0, rect.right, rect.bottom, memdc, 0, 0,bm.bmWidth , bm.bmHeight, SRCCOPY);
DeleteDC(memdc);
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
.
.
.
크기를 자유자재로 움직일 수 있음.
.
.
.
이번에는 비트맵 파일이 윈도 화면에 연속해서 나타나게 함으로 바둑판 모양으로 윈도 배경에 나타나도록 하는 코드를 알아보도록 하겠습니다.
.
.
.
코드 (BitBlt 함수 이용)
#include <windows.h>
#include <TCHAR.H>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
// UNICODE 사용시 wWinMain() 형태
// hPrevInstance 이전 인스턴스 항상 0값
// lpszCmdLine > 외부에서 (내부로) 입력받는 변수
// nCmdShow 윈도우 출력 형태에 관련한 값
{
HWND hwnd;
MSG msg;
WNDCLASS WndClass;
WndClass.style = CS_HREDRAW | CS_VREDRAW; //height, vertical redraw
WndClass.lpfnWndProc = WndProc; // Proc 설정
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 형변환
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = _T("Window Class Name");
RegisterClass(&WndClass); // WndClass 등록
hwnd = CreateWindow(_T("Window Class Name"),
_T("Jung-Story"), //
WS_OVERLAPPEDWINDOW, // 윈도우 스타일
600, 400, // 창출력좌표 x, y
600, 400, // 창크기 x, y축
NULL, // 부모 윈도우
NULL, // 메뉴바 핸들
hInstance, // 인스턴스
NULL // 여분, NULL
);
ShowWindow(hwnd, nCmdShow); // 윈도우 출력, WM_PAINT 출력내용 가져옴
UpdateWindow(hwnd); // WM_PAINT 출력내용 발생해서 출력하도록
// hwnd 핸들을 통해 보여주고 갱신
//ShowWindow(hwnd, SW_SHOW); // 위와 같음
//UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0)) // 메시지 큐의 메시지를 가져옴
{
TranslateMessage(&msg); // 키입력에 반응하는 메시지 변환, WM_KEYDOWN (키가 눌릴때) WM_CHAR 메시지 발생
DispatchMessage(&msg); // WndProc() 함수 호출과 WndProc()으로 메세지 전달
} // 종료는 WM_QUIT 발생할때 FALSE 리턴하면서 종료
return (int)msg.wParam; // wParam, lParam 윈도우 크기가 어떻게 변했는지, 변경된 클라이언트, 키보드, 마우스 값
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam)
// WinDef.h 에서 정의
// wPram > unsigned ptr, lParam > long ptr
{
HDC hdc, memdc;
PAINTSTRUCT ps;
static HBITMAP hBitmap;
RECT rect;
int i, j;
switch (iMsg)
{
case WM_CREATE:
hBitmap = (HBITMAP)LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance, MAKEINTRESOURCE(IDB_BITMAP5_2));
break;
case WM_PAINT:
GetClientRect(hwnd, &rect); // 윈도우 크기를 받아온다.
hdc = BeginPaint(hwnd, &ps);
memdc = CreateCompatibleDC(hdc);
SelectObject(memdc, hBitmap);
for (i = 0; i <= rect.right / 100; i++) {
for (j = 0; j <= rect.bottom / 100; j++) {
BitBlt(hdc, i * 100, j * 100, 100, 100,memdc,0,0,SRCCOPY);
}
}
DeleteDC(memdc);
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
.
.
.
실행 화면
.
.
.
이번에는 아무버튼이나 클릭 시 윈도 화면에서 이미지가 움직이면서 바운드되는 것을 알아보도록 하겠습니다.
코드
#include <windows.h>
#include <TCHAR.H>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam);
HINSTANCE hInst; // 그림을 그리기 위한 inst.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
// UNICODE 사용시 wWinMain() 형태
// hPrevInstance 이전 인스턴스 항상 0값
// lpszCmdLine > 외부에서 (내부로) 입력받는 변수
// nCmdShow 윈도우 출력 형태에 관련한 값
{
HWND hwnd;
MSG msg;
WNDCLASS WndClass;
hInst = hInstance;
WndClass.style = CS_HREDRAW | CS_VREDRAW; //height, vertical redraw
WndClass.lpfnWndProc = WndProc; // Proc 설정
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 형변환
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = _T("Window Class Name");
RegisterClass(&WndClass); // WndClass 등록
hwnd = CreateWindow(_T("Window Class Name"),
_T("Jung-Stroy"), //
WS_OVERLAPPEDWINDOW, // 윈도우 스타일
600, 400, // 창출력좌표 x, y
600, 400, // 창크기 x, y축
NULL, // 부모 윈도우
NULL, // 메뉴바 핸들
hInstance, // 인스턴스
NULL // 여분, NULL
);
ShowWindow(hwnd, nCmdShow); // 윈도우 출력, WM_PAINT 출력내용 가져옴
UpdateWindow(hwnd); // WM_PAINT 출력내용 발생해서 출력하도록
// hwnd 핸들을 통해 보여주고 갱신
//ShowWindow(hwnd, SW_SHOW); // 위와 같음
//UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0)) // 메시지 큐의 메시지를 가져옴
{
TranslateMessage(&msg); // 키입력에 반응하는 메시지 변환, WM_KEYDOWN (키가 눌릴때) WM_CHAR 메시지 발생
DispatchMessage(&msg); // WndProc() 함수 호출과 WndProc()으로 메세지 전달
} // 종료는 WM_QUIT 발생할때 FALSE 리턴하면서 종료
return (int)msg.wParam; // wParam, lParam 윈도우 크기가 어떻게 변했는지, 변경된 클라이언트, 키보드, 마우스 값
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam)
// WinDef.h 에서 정의
// wPram > unsigned ptr, lParam > long ptr
{
HDC hdc, memdc;
PAINTSTRUCT ps;
static HBITMAP hBitmap;
static int x, y, sX, sY;
RECT rect;
switch (iMsg)
{
case WM_CREATE:
hBitmap = (HBITMAP)LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP5_2));
x = 0;
y = 0;
sX = 20;
sY = 20;
InvalidateRgn(hwnd,NULL,true);
break;
case WM_KEYDOWN:
if (wParam) {
SetTimer(hwnd, 0, 100, NULL);
}
case WM_TIMER:
GetClientRect(hwnd, &rect); // 윈도우 크기 받아오기
x = x + sX;
y = y + sY;
if (x + 100 > rect.right || x < 0) {
sX = -1 * sX;
x = x + sX;
}
if (y + 100 > rect.bottom || y < 0) {
sY = -1 * sY;
y = y + sY;
}
hdc = GetDC(hwnd);
memdc = CreateCompatibleDC(hdc);
SelectObject(memdc, hBitmap);
BitBlt(hdc, x, y, 100, 100, memdc, 60, 60, SRCCOPY);
DeleteDC(memdc);
ReleaseDC(hwnd, hdc);
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
hdc = GetDC(hwnd);
memdc = CreateCompatibleDC(hdc);
SelectObject(memdc, hBitmap);
BitBlt(hdc, x, y, 100, 100, memdc, 60, 60, SRCCOPY);
DeleteDC(memdc);
ReleaseDC(hwnd, hdc);
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
KillTimer(hwnd, 0);
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
.
.
.
실행 화면
.
.
.
.
더블 버퍼링
위에서 사용한 비트맵 이미지를 여러 개 이용하여 동영상을 나타낼 때 사용이 됩니다.
.
.
.
이미지를 순서대로 화면 디바이스 컨택스트에 출력합니다.
예를 들어 풍경 위에 날아가는 비행기를 표현한다면
풍경 이미지를 먼저 출력
그다음에 비행기 이미지를 출력
날아가는 모습을 나타내고자 한다면 풍경 이미지 출력과 새 이미지 출력을 번갈아가며 계속 수행하면 됩니다.
.
.
.
이러한 더블 더퍼링은 이미지를 계속 출력해 주어야 하기 때문에 화면이 자주 깜빡거리는 문제점이 있습니다.
.
.
.
이런 문제점을 해결해 주기 위해서는
메모리 디바이스 콘텍스트를 하나 더 사용하면 됩니다.
추가된 메모리 디바이스 콘텍스트에 그리기를 원하는 그림들을 모두 출력한 다음 화면 디바이스 콘텍스트로 한꺼번에 옮기는 방법을 이용합니다.
.
.
이러한 절차로 이루어지기 때문에 추가된 메모리 디바이스 콘텍스트가 추가된 버퍼 역할을 하기 때문에 이 방법을 더블 버퍼링이라고 부릅니다!
.
.
더블 버퍼링 로드맵
.
.
.
.
.
.
.
위의 이미지를 이용한 더블 버퍼링 (애니메이션) 예제
#include <windows.h>
#include <TCHAR.H>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam);
HINSTANCE hInst; // 그림을 그리기 위한 inst.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
// UNICODE 사용시 wWinMain() 형태
// hPrevInstance 이전 인스턴스 항상 0값
// lpszCmdLine > 외부에서 (내부로) 입력받는 변수
// nCmdShow 윈도우 출력 형태에 관련한 값
{
HWND hwnd;
MSG msg;
WNDCLASS WndClass;
hInst = hInstance;
WndClass.style = CS_HREDRAW | CS_VREDRAW; //height, vertical redraw
WndClass.lpfnWndProc = WndProc; // Proc 설정
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 형변환
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = _T("Window Class Name");
RegisterClass(&WndClass); // WndClass 등록
hwnd = CreateWindow(_T("Window Class Name"),
_T("Jung-Story"),
WS_OVERLAPPEDWINDOW, // 윈도우 스타일
600, 400, // 창출력좌표 x, y
600, 400, // 창크기 x, y축
NULL, // 부모 윈도우
NULL, // 메뉴바 핸들
hInstance, // 인스턴스
NULL // 여분, NULL
);
ShowWindow(hwnd, nCmdShow); // 윈도우 출력, WM_PAINT 출력내용 가져옴
UpdateWindow(hwnd); // WM_PAINT 출력내용 발생해서 출력하도록
// hwnd 핸들을 통해 보여주고 갱신
//ShowWindow(hwnd, SW_SHOW); // 위와 같음
//UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0)) // 메시지 큐의 메시지를 가져옴
{
TranslateMessage(&msg); // 키입력에 반응하는 메시지 변환, WM_KEYDOWN (키가 눌릴때) WM_CHAR 메시지 발생
DispatchMessage(&msg); // WndProc() 함수 호출과 WndProc()으로 메세지 전달
} // 종료는 WM_QUIT 발생할때 FALSE 리턴하면서 종료
return (int)msg.wParam; // wParam, lParam 윈도우 크기가 어떻게 변했는지, 변경된 클라이언트, 키보드, 마우스 값
}
void Animation(int xPos, int yPos, HDC hdc) {
HDC memdc;
HBITMAP RunBit[10], hBit, oldBit;
static int count;
int i;
count++;
count = count % 10;
RunBit[0] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R1));
RunBit[1] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R2));
RunBit[2] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R3));
RunBit[3] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R3));
RunBit[4] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R3));
RunBit[5] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R3));
RunBit[6] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R3));
RunBit[7] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R3));
RunBit[8] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R9));
RunBit[9] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R10));
memdc = CreateCompatibleDC(hdc);
hBit = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP5_20));
oldBit = (HBITMAP)SelectObject(memdc, hBit);
BitBlt(hdc, 0, 0, 819, 614, memdc, 0, 0, SRCCOPY);
SelectObject(memdc, RunBit[count]);
BitBlt(hdc, xPos, yPos, 180, 240, memdc, 0, 0, SRCCOPY);
SelectObject(memdc, oldBit);
for (i = 0; i < 10; i++)
DeleteObject(RunBit[i]);
DeleteDC(memdc);
DeleteObject(hBit);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam)
// WinDef.h 에서 정의
// wPram > unsigned ptr, lParam > long ptr
{
HDC hdc;
PAINTSTRUCT ps;
static int xPos;
switch (iMsg)
{
case WM_CREATE:
xPos = -100;
SetTimer(hwnd, 1, 100, NULL);
break;
case WM_TIMER:
xPos += 10;
if (xPos > 819) xPos = -100;
InvalidateRgn(hwnd, NULL, true);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
Animation(xPos, 300, hdc);
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
.
.
.
실행화면
.
.
.
위의 예제 문제점
캐릭터와 함께 사각형 모양이 나오는 걸 볼 수 있습니다.
해결을 하기 위해 마스크 이미지를 이용합니다.
마스크는 캐릭터와 같은 모양의 그림자 이미지입니다.
.
.
.
마스크 이용 애니메이션 예제
#include <windows.h>
#include <TCHAR.H>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam);
HINSTANCE hInst; // 그림을 그리기 위한 inst.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
// UNICODE 사용시 wWinMain() 형태
// hPrevInstance 이전 인스턴스 항상 0값
// lpszCmdLine > 외부에서 (내부로) 입력받는 변수
// nCmdShow 윈도우 출력 형태에 관련한 값
{
HWND hwnd;
MSG msg;
WNDCLASS WndClass;
hInst = hInstance;
WndClass.style = CS_HREDRAW | CS_VREDRAW; //height, vertical redraw
WndClass.lpfnWndProc = WndProc; // Proc 설정
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 형변환
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = _T("Window Class Name");
RegisterClass(&WndClass); // WndClass 등록
hwnd = CreateWindow(_T("Window Class Name"),
_T("Jung-Story"), //
WS_OVERLAPPEDWINDOW, // 윈도우 스타일
600, 400, // 창출력좌표 x, y
600, 400, // 창크기 x, y축
NULL, // 부모 윈도우
NULL, // 메뉴바 핸들
hInstance, // 인스턴스
NULL // 여분, NULL
);
ShowWindow(hwnd, nCmdShow); // 윈도우 출력, WM_PAINT 출력내용 가져옴
UpdateWindow(hwnd); // WM_PAINT 출력내용 발생해서 출력하도록
// hwnd 핸들을 통해 보여주고 갱신
//ShowWindow(hwnd, SW_SHOW); // 위와 같음
//UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0)) // 메시지 큐의 메시지를 가져옴
{
TranslateMessage(&msg); // 키입력에 반응하는 메시지 변환, WM_KEYDOWN (키가 눌릴때) WM_CHAR 메시지 발생
DispatchMessage(&msg); // WndProc() 함수 호출과 WndProc()으로 메세지 전달
} // 종료는 WM_QUIT 발생할때 FALSE 리턴하면서 종료
return (int)msg.wParam; // wParam, lParam 윈도우 크기가 어떻게 변했는지, 변경된 클라이언트, 키보드, 마우스 값
}
void Animation(int xPos, int yPos, HDC hdc) {
HDC memdc;
HBITMAP RunBit[10], hBit, oldBit,Mask[10];
static int count;
int i;
count++;
count = count % 10;
RunBit[0] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R1));
RunBit[1] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R2));
RunBit[2] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R3));
RunBit[3] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R3));
RunBit[4] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R3));
RunBit[5] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R3));
RunBit[6] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R3));
RunBit[7] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R3));
RunBit[8] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R9));
RunBit[9] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_R10));
Mask[0] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_M1));
Mask[1] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_M2));
Mask[2] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_M3));
Mask[3] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_M4));
Mask[4] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_M5));
Mask[5] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_M6));
Mask[6] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_M7));
Mask[7] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_M8));
Mask[8] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_M9));
Mask[9] = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_M10));
memdc = CreateCompatibleDC(hdc);
hBit = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP5_20));
oldBit = (HBITMAP)SelectObject(memdc, hBit);
BitBlt(hdc, 0, 0, 819, 614, memdc, 0, 0, SRCCOPY);
SelectObject(memdc, Mask[count]);
BitBlt(hdc, xPos, yPos, 180, 240, memdc, 0, 0, SRCAND);
SelectObject(memdc, RunBit[count]);
BitBlt(hdc, xPos, yPos, 180, 240, memdc, 0, 0, SRCPAINT);
SelectObject(memdc, oldBit);
for (i = 0; i < 10; i++) {
DeleteObject(RunBit[i]);
DeleteObject(Mask[i]);
}
DeleteDC(memdc);
DeleteObject(hBit);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam)
// WinDef.h 에서 정의
// wPram > unsigned ptr, lParam > long ptr
{
HDC hdc;
PAINTSTRUCT ps;
static int xPos;
switch (iMsg)
{
case WM_CREATE:
xPos = -100;
SetTimer(hwnd, 1, 100, NULL);
break;
case WM_TIMER:
xPos += 10;
if (xPos > 819) xPos = -100;
InvalidateRgn(hwnd, NULL, true);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
Animation(xPos, 300, hdc);
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
.
.
.
실행화면
.
.
.
이렇게 오늘은 MFC의 더블 버퍼링과 마스크 bitmap에 대해서 알아보았습니다.
'윈도우 프로그래밍 > MFC_프로그래밍' 카테고리의 다른 글
윈도우 프로그래밍 (MFC 리소스 윈도우 메뉴 만들기 개념 및 예제) (0) | 2021.04.14 |
---|---|
윈도우 프로그래밍 ( MFC 프로그래밍 제어 메시지 (키보드,마우스 입출력)처리 및 예제 ) (0) | 2021.04.02 |
윈도우 프로그래밍 (MFC프로그래밍 구조 및 입출력 개념 or 예제) (0) | 2021.03.30 |