일하러 갈 곳이 없는 사람은 그 사람이 어떤 신분의 사람이든 간에 참으로 상상할 수 없을 만큼 골치 아픈 존재다. -조지 버나드 쇼
1 사용법 #
- WNDCLASS 또는 WNDCLASSEX의 hbrBackground 속성값을 브러시핸들이 아닌 NULL로 지정해야합니다. 이렇게 하면 매번 WM_PAINT가 발생할 경우 화면을 다시 그리는 것을 막아줍니다. (하지만 화면을 지우고 그리지 않으므로 마치 잔상으로 인해 지저분하게 보이게 됩니다)
- 그런다음 모든 GDI 처리를 OFFSCREEN->GetHDC()를 통해 얻을 수 있는 메모리 비트맵에 집중합니다. 모든 그리기 작업이 끝난후 OFFSCREEN->ApplyToScreen(hdc)를 통해 그려진 결과를 화면에 출력합니다.
2.1 OffscreenManager.h #
// OffscreenManager.h: GDI Offscreen 관리용 클래스
//
//////////////////////////////////////////////////////////////////////
#ifndef ___GDI_OFFSCREEN_H___
#define ___GDI_OFFSCREEN_H___
#include <windows.h>
struct OffscreenManager
{
private :
HWND hwndOwner; // Offscreen이 적용된 윈도우의 핸들
HDC hdcOffscreen;
HBITMAP hbmOffscreen, hbmOld;
int off_w, off_h; // Offscreen의 폭과 높이
void Initialize(HWND hwnd, int w, int h);
void Finalize();
public:
OffscreenManager(HWND hwnd);
virtual ~OffscreenManager();
public:
// Offscreen의 사이즈를 변경한다
void Resize(int width, int height);
// Offscreen을 화면에 적용한다
void ApplyToScreen(HDC hdc);
// Offscreen의 DC 핸들을 구한다
inline HDC GetHDC() {return hdcOffscreen;};
// Offscreen을 지정된 색으로 지운다
void Clear(COLORREF Color);
// 싱글톤 스태틱 메소드
static void init(HWND hwnd_);
static OffscreenManager *instance();
};
#define OFFSCREEN (OffscreenManager::instance())
#define OFFSCREEN_INIT(X) OffscreenManager::init(X)
#endif
2.2 OffscreenManager.cpp #
#include "OffscreenManager.hpp"
static OffscreenManager *g_instance = NULL;
// 싱글톤 스태틱 메소드
void OffscreenManager::init(HWND hwnd_) {
if (!g_instance) g_instance = new OffscreenManager( hwnd_ );
}
OffscreenManager *OffscreenManager::instance() {
return g_instance;
}
void OffscreenManager::Initialize(HWND hwnd, int w, int h)
{
HDC hdc = GetDC(hwnd);
hdcOffscreen = CreateCompatibleDC(NULL);
hbmOffscreen = CreateCompatibleBitmap(hdc, w, h);
hbmOld = (HBITMAP) SelectObject(hdcOffscreen, hbmOffscreen);
off_w = w;
off_h = h;
ReleaseDC(hwnd, hdc);
}
void OffscreenManager::Finalize()
{
SelectObject(hdcOffscreen, hbmOld);
DeleteObject(hbmOffscreen);
DeleteDC(hdcOffscreen);
}
OffscreenManager::OffscreenManager(HWND hwnd)
{
RECT rc;
hwndOwner = hwnd;
HDC hdc = GetDC(hwndOwner);
GetClientRect(hwndOwner, &rc);
Initialize(hwndOwner, rc.right-rc.left, rc.bottom-rc.top);
ReleaseDC(hwndOwner, hdc);
}
OffscreenManager::~OffscreenManager()
{
Finalize();
}
// Offscreen의 사이즈를 변경한다
void OffscreenManager::Resize(int width, int height)
{
Finalize();
Initialize(hwndOwner, width, height);
}
// Offscreen을 화면에 적용한다
void OffscreenManager::ApplyToScreen(HDC hdc)
{
BitBlt(hdc, 0, 0, off_w, off_h, hdcOffscreen, 0, 0, SRCCOPY);
}
// Offscreen을 지정된 색으로 지운다
void OffscreenManager::Clear(COLORREF Color)
{
RECT rc = {0, 0, 0, 0};
rc.right = off_w;
rc.bottom = off_h;
HBRUSH hbrClearBrush = CreateSolidBrush(Color);
FillRect(hdcOffscreen, &rc, hbrClearBrush);
DeleteObject(hbrClearBrush);
}









![[http]](/wiki/imgs/http.png)
