==================================================================================================
[실행화면]
- 초기화면
- X축 이동
- Y축 이동
: 더블 버퍼링을 활용해서 스크롤을 이동시켜 그림을 이동시켰을때 생기는 화면의 깜빡임을 제거했다.
==================================================================================================
[소스코드]
#include <windows.h>
#include <windowsx.h>
#define BALL_SIZE 10
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL WinMain_OnCreate(HWND, LPCREATESTRUCT);
void WinMain_OnPaint(HWND);
void WinMain_OnHScroll(HWND, HWND, UINT, int);
void WinMain_OnVScroll(HWND, HWND, UINT, int);
void WinMain_OnTimer(HWND, UINT);
void WinMain_OnDestroy(HWND);
//int getTrackPos(HWND, int);
int APIENTRY WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd )
{
MSG msg;
HWND hwnd;
WNDCLASS wndclass = {0};
wndclass.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = TEXT("WinMain");
wndclass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndclass);
hwnd = CreateWindow (
TEXT("WinMain"),
TEXT("WinMain"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
(HMENU) NULL,
hInstance,
NULL
);
ShowWindow(hwnd, nShowCmd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
static int sx = 230, sy = 130;
HBITMAP hBit;
enum{ID_HSCROLL1, ID_VSCROLL1};
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
switch(iMessage) // 메시지 크랙커
{
HANDLE_MSG(hwnd, WM_CREATE, WinMain_OnCreate);
HANDLE_MSG(hwnd, WM_PAINT, WinMain_OnPaint);
HANDLE_MSG(hwnd, WM_HSCROLL, WinMain_OnHScroll);
HANDLE_MSG(hwnd, WM_VSCROLL, WinMain_OnVScroll);
HANDLE_MSG(hwnd, WM_TIMER, WinMain_OnTimer);
HANDLE_MSG(hwnd, WM_DESTROY, WinMain_OnDestroy);
}
return (DefWindowProc(hwnd, iMessage, wParam, lParam));
}
BOOL WinMain_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
MoveWindow(hwnd, 300, 200, 500, 300, TRUE);
CreateWindow( // 수평 스크롤 생성
TEXT("scrollbar"),
NULL,
WS_CHILD | WS_VISIBLE | SBS_HORZ,
20,
10,
430,
25,
hwnd,
(HMENU) ID_HSCROLL1,
GetModuleHandle(0),
NULL
);
CreateWindow( // 수직 스크롤 생성
TEXT("scrollbar"),
NULL,
WS_CHILD | WS_VISIBLE | SBS_VERT,
450,
35,
25,
220,
hwnd,
(HMENU) ID_VSCROLL1,
GetModuleHandle(0),
NULL
);
SetScrollRange(GetDlgItem(hwnd, ID_HSCROLL1), SB_CTL, 45, 430, TRUE);
SetScrollPos(GetDlgItem(hwnd, ID_HSCROLL1), SB_CTL, sx, TRUE);
SetScrollRange(GetDlgItem(hwnd, ID_VSCROLL1), SB_CTL, 60, 230, TRUE);
SetScrollPos(GetDlgItem(hwnd, ID_VSCROLL1), SB_CTL, sy, TRUE);
SetTimer(hwnd, 1, 25, NULL); // Java의 더블 버퍼링 구현에서 Thread.Sleep(...)과 같은 역할
return TRUE;
}
void WinMain_OnPaint(HWND hwnd)
{
char resultCheck[200];
HDC hdc, hMemDC;
HBITMAP OldBit;
RECT rect;
PAINTSTRUCT ps;
// 그려진 비트맵 개체를 메모리 DC로 받아서 화면에 출력!
hdc = BeginPaint(hwnd, &ps);
hMemDC = CreateCompatibleDC(hdc);
OldBit = (HBITMAP)SelectObject(hMemDC, hBit);
GetClientRect(hwnd, &rect); // 작업영역 획득!
// 화면DC와 메모리DC 영역 복사
BitBlt(hdc, 0, 40, rect.right-50, rect.bottom, hMemDC, 0, 40, SRCCOPY);
SelectObject(hMemDC, OldBit);
DeleteDC(hMemDC); // 리소스 해제
EndPaint(hwnd, &ps); // 리소스 해제
wsprintf(resultCheck, "%d, %d", sx, sy); // 좌표 세팅
SetWindowText(hwnd, resultCheck); // 윈도우 캡션에 좌표 출력
}
void WinMain_OnHScroll(HWND hwnd, HWND hwndCtl, UINT code, int pos)
{
switch(code)
{
case SB_LINELEFT :
sx = max(45, sx-20);
break;
case SB_LINERIGHT :
sx = min(430, sx+20);
break;
case SB_PAGELEFT :
sx = max(45, sx-60);
break;
case SB_PAGERIGHT :
sx = min(430, sx+60);
break;
case SB_THUMBTRACK :
sx = pos; // getTrackPos(hwnd, ID_HSCROLL1);
break;
}
SetScrollPos(hwndCtl, SB_CTL, sx, TRUE);
}
void WinMain_OnVScroll(HWND hwnd, HWND hwndCtl, UINT code, int pos)
{
switch(code)
{
case SB_LINEUP :
sy = max(60, sy-20);
break;
case SB_LINEDOWN :
sy = min(230, sy+20);
break;
case SB_PAGEUP :
sy = max(60, sy-60);
break;
case SB_PAGEDOWN :
sy = min(230, sy+60);
break;
case SB_THUMBTRACK :
sy = pos; //getTrackPos(hwnd, ID_VSCROLL1);
break;
}
SetScrollPos(hwndCtl, SB_CTL, sy, TRUE);
}
void WinMain_OnTimer(HWND hwnd, UINT id)
{
HDC hdc, MemDC;
RECT rect;
HBITMAP OldbitMap;
HBRUSH hBrush, OldBrush;
GetClientRect(hwnd, &rect);
hdc = GetDC(hwnd);
MemDC = CreateCompatibleDC(hdc); // 화면 DC에 대응하는 메모리 DC 생성
if (hBit == NULL) // 전역변수 hBit가 생성이 되어 있지 않다면.. 생성
hBit = CreateCompatibleBitmap(hdc, rect.right, rect.bottom);
OldbitMap = (HBITMAP)SelectObject(MemDC, hBit);
FillRect(MemDC, &rect, GetSysColorBrush(COLOR_3DFACE)); // 화면 배경
hBrush = CreateSolidBrush(RGB(0, 0, 255)); // 공 색깔에 해당하는 브러쉬 개체 생성
OldBrush = (HBRUSH)SelectObject(MemDC, hBrush); // 이전의 브러쉬 저장
Ellipse(MemDC, sx-BALL_SIZE, sy-BALL_SIZE, sx+BALL_SIZE, sy+BALL_SIZE);
// 이전의 브러쉬로 돌려 놓고 사용했던 브러쉬 자원 해제
DeleteObject(SelectObject(MemDC, OldBrush));
SelectObject(MemDC, OldbitMap);
DeleteDC(MemDC);
ReleaseDC(hwnd, hdc);
InvalidateRect(hwnd, NULL, FALSE); // WM_PAINT 메시지를 발생시킴
}
void WinMain_OnDestroy(HWND hwnd)
{
PostQuitMessage(0);
}
/*
int getTrackPos(HWND hwnd, int id)
{
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_TRACKPOS;
GetScrollInfo(GetDlgItem(hwnd, id), SB_CTL, &si);
return si.nTrackPos;
}
*/
==================================================================================================
'IT_Programming > MFC · API' 카테고리의 다른 글
[API] 메모리 공유 (0) | 2009.09.07 |
---|---|
[API] WIN32 API에서 ODBC (오라클,MS-SQL,MDB) 사용하기 - CQuery Class (0) | 2009.08.09 |
[펌] 유니코드를 위한 Win API | MFC 프로그래밍 (0) | 2009.07.31 |
[API] 슈퍼 클래싱 (Super Classing) (0) | 2009.07.29 |
[API] 서브 클래싱( SUB CLASSING ) (0) | 2009.07.29 |