LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static DWORD st = 0; static DWORD dt = 0; static DWORD update_dt = 0; static DWORD update_delay = 10; static HDC hMainDC = NULL; static HDC hMemDC = NULL; static HBITMAP hMemBitmap = NULL; static HBITMAP hOldMemBitmap = NULL; static Point ptStart; static Point ptEnd; static bool bDrawLine = false; static std::list<Ball*> marble; static const int quantity = 4; if (uMsg == WM_CREATE) { Rect rc; ::GetClientRect(hWnd, &rc); hMainDC = ::GetDC(hWnd); hMemDC = ::CreateCompatibleDC(hMainDC); hMemBitmap = ::CreateCompatibleBitmap(hMainDC, rc.width(), rc.height()); hOldMemBitmap = ::Select(hMemDC, hMemBitmap); for (int i = 0; i < quantity; i++) { Ball* pBall = new Ball; pBall->Attach(hWnd); pBall->SetSize(15); if (i == Ball::white) { pBall->SetPosition(Point((rc.right - rc.left)/8 * 1, (rc.bottom - rc.top)/2)); pBall->SetColor(RGB(255,255,255)); } else if (i == Ball::red1) { pBall->SetPosition(Point((rc.right - rc.left)/8 * 2, (rc.bottom - rc.top)/2)); pBall->SetColor(RGB(255,0,0)); } else if (i == Ball::red2) { pBall->SetPosition(Point((rc.right - rc.left)/8 * 6, (rc.bottom - rc.top)/2)); pBall->SetColor(RGB(255,0,0)); } else if (i == Ball::yellow) { pBall->SetPosition(Point((rc.right - rc.left)/8 * 6, (rc.bottom - rc.top)/6 * 2)); pBall->SetColor(RGB(255,255,0)); } marble.push_back(pBall); } // for (int i = 0; i < quantity; i++) st = ::GetTickCount(); ::SetTimer(hWnd, 0, 10, NULL); return 0; } else if (uMsg == WM_DESTROY) { std::list<Ball*>::iterator it; for (it = marble.begin(); it != marble.end();) { delete *it; it = marble.erase(it); } ::KillTimer(hWnd, 0); ::Select(hMemDC, hOldMemBitmap); ::DeleteObject(hMemBitmap); ::DeleteDC(hMemDC); ::ReleaseDC(hWnd, hMainDC); ::PostQuitMessage(0); return 0; } else if (uMsg == WM_PAINT) { Rect rc; ::GetClientRect(hWnd, &rc); PAINTSTRUCT ps; HDC hdc = ::BeginPaint(hWnd, &ps); ::SetDCBrushColor(hMemDC, RGB(80,181,53)); ::FillRect(hMemDC, &rc, (HBRUSH)::GetStockObject(DC_BRUSH)); if (bDrawLine) { ::MoveToEx(hMemDC, ptStart.x, ptStart.y, NULL); ::LineTo(hMemDC, ptEnd.x, ptEnd.y); } std::list<Ball*>::iterator it; for (it = marble.begin(); it != marble.end(); it++) { (*it)->Draw(hMemDC); } ::BitBlt(hdc, 0, 0, rc.width(), rc.height(), hMemDC, 0, 0, SRCCOPY); ::EndPaint(hWnd, &ps); return 0; } else if (uMsg == WM_ERASEBKGND) { return 1; } else if (uMsg == WM_LBUTTONDOWN) { ::GetCursorPos(&ptStart); ptStart = ptStart.ToClient(hWnd); ptEnd = ptStart; std::list<Ball*>::iterator it; for (it = marble.begin(); it != marble.end(); it++) { (*it)->CheckShoot(ptStart); } bDrawLine = true; return 0; } else if (uMsg == WM_MOUSEMOVE) { if (bDrawLine) { ::GetCursorPos(&ptEnd); ptEnd = ptEnd.ToClient(hWnd); Rect rc; ::GetClientRect(hWnd, &rc); ::InvalidateRect(hWnd, &rc, TRUE); } return 0; } else if (uMsg == WM_LBUTTONUP) { bDrawLine = false; ::GetCursorPos(&ptEnd); ptEnd = ptEnd.ToClient(hWnd); std::list<Ball*>::iterator it; for (it = marble.begin(); it != marble.end(); it++) { (*it)->SetDirection(Vector(ptEnd - ptStart) / 10); } return 0; } else if (uMsg == WM_TIMER) { Rect rc; ::GetClientRect(hWnd, &rc); if (update_dt > update_delay) { int count = update_dt / update_delay; for (int i = 0; i < count; i++) { std::list<Ball*>::iterator it; for (it = marble.begin(); it != marble.end(); ) { (*it)->Input(dt); (*it)->Update(dt, marble); it++; } } update_dt %= update_delay; } update_dt += dt; dt = ::GetTickCount() - st; st = ::GetTickCount(); ::InvalidateRect(hWnd, &rc, TRUE); return 0; } return ::DefWindowProc(hWnd,uMsg,wParam,lParam); }
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static DWORD st = 0; static DWORD dt = 0; static DWORD update_dt = 0; static DWORD update_delay = 20; static HDC hMainDC = NULL; static HDC hMemDC = NULL; static HBITMAP hMemBitmap = NULL; static HBITMAP hOldMemBitmap = NULL; static bool bDrawLine = false; static Point ptStart; static Point ptEnd; if (uMsg == WM_CREATE) { Rect rc; ::GetClientRect(hWnd, &rc); hMainDC = ::GetDC(hWnd); hMemDC = ::CreateCompatibleDC(hMainDC); hMemBitmap = ::CreateCompatibleBitmap(hMainDC, rc.width(), rc.height()); hOldMemBitmap = ::Select(hMemDC, hMemBitmap); BallDepot.Attach(hWnd); st = ::GetTickCount(); ::SetTimer(hWnd, 1, 10, NULL); return 0; } else if (uMsg == WM_DESTROY) { BallDepot.clear(); ::KillTimer(hWnd, 1); ::Select(hMemDC, hOldMemBitmap); ::DeleteObject(hMemBitmap); ::DeleteDC(hMemDC); ::ReleaseDC(hWnd, hMainDC); ::PostQuitMessage(0); return 0; } else if (uMsg == WM_PAINT) { Rect rc; ::GetClientRect(hWnd, &rc); PAINTSTRUCT ps; HDC hdc = ::BeginPaint(hWnd, &ps); // TODO ::SetDCBrushColor(hMemDC, RGB(100,100,150)); ::FillRect(hMemDC, &rc, (HBRUSH)::GetStockObject(DC_BRUSH)); if (bDrawLine) { ::MoveToEx(hMemDC, ptStart.x, ptStart.y, NULL); ::LineTo(hMemDC, ptEnd.x, ptEnd.y); } BallDepot.Draw(hMemDC); ::BitBlt(hdc, 0, 0, rc.width(), rc.height(), hMemDC, 0, 0, SRCCOPY); ::EndPaint(hWnd, &ps); return 0; } else if (uMsg == WM_ERASEBKGND) { return 1; } else if (uMsg == WM_LBUTTONDOWN) { ::GetCursorPos(&ptStart); ptStart = ptStart.ToClient(hWnd); ptEnd = ptStart; bDrawLine = true; return 0; } else if (uMsg == WM_MOUSEMOVE) { if (bDrawLine) { ::GetCursorPos(&ptEnd); ptEnd = ptEnd.ToClient(hWnd); Rect rc; ::GetClientRect(hWnd, &rc); ::InvalidateRect(hWnd, &rc, TRUE); } return 0; } else if (uMsg == WM_LBUTTONUP) { bDrawLine = false; ::GetCursorPos(&ptEnd); ptEnd = ptEnd.ToClient(hWnd); if (ptStart == ptEnd) return 0; Ball* pBall = new Ball; pBall->Attach(hWnd); pBall->SetDirection(Vector(ptEnd - ptStart)/5); pBall->SetSize(20); pBall->SetPosition(ptStart); BallDepot.push(pBall); return 0; } else if (uMsg == WM_TIMER) { Rect rc; ::GetClientRect(hWnd, &rc); // TODO... BallDepot.Input(dt); BallDepot.Update(dt); dt = ::GetTickCount() - st; st = ::GetTickCount(); ::InvalidateRect(hWnd, &rc, TRUE); return 0; } return ::DefWindowProc(hWnd,uMsg,wParam,lParam); }