win32api双缓冲的使用例子(画线条)

来源:互联网 发布:淘宝网韩都衣舍 编辑:程序博客网 时间:2024/06/07 12:04
#include <Windows.h>#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") #include <cmath>#include <vector>typedef std::pair<POINT, POINT> LINE;typedef std::vector<std::pair<POINT, POINT> > LINELIST;HINSTANCEg_hInstance = nullptr;HWNDg_hMainWnd = nullptr;RECTg_rc;intg_width;intg_height;LINELISTg_linelist;boolg_leftBtnDown = false;POINTg_p1;POINTg_p2;void InitWindow(HINSTANCE hInstance, int nCmdShow);void MessageLoop();void Clean(HDC hdc);void Draw(HDC hdc);int Quit();LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow){InitWindow(hInstance, nCmdShow);MessageLoop();UnregisterClass(L"class1", hInstance);return 0;}void InitWindow(HINSTANCE hInstance, int nCmdShow){WNDCLASSEX wcex = {};wcex.cbSize = sizeof(WNDCLASSEX);wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);wcex.hbrBackground = (HBRUSH)COLOR_WINDOWFRAME;wcex.lpfnWndProc = MainWndProc;wcex.hInstance = hInstance;wcex.lpszClassName = L"class1";wcex.style = CS_HREDRAW | CS_VREDRAW;RegisterClassEx(&wcex);RECT rc = {0, 0, 1280, 720};AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);g_hMainWnd = CreateWindowEx(WS_EX_LEFT, L"class1", L"", WS_OVERLAPPEDWINDOW, 0, 0,rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, hInstance, nullptr);ShowWindow(g_hMainWnd, nCmdShow);}LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){PAINTSTRUCT ps;switch (uMsg){case WM_LBUTTONDOWN:{g_leftBtnDown = true;GetCursorPos(&g_p1);ScreenToClient(hWnd, &g_p1);}break;case WM_MOUSEMOVE:{if (g_leftBtnDown){GetCursorPos(&g_p2);ScreenToClient(hWnd, &g_p2);InvalidateRect(hWnd, &g_rc, FALSE);}}break;case WM_LBUTTONUP:{GetCursorPos(&g_p2);ScreenToClient(hWnd, &g_p2);g_linelist.push_back(LINE(g_p1, g_p2));g_leftBtnDown = false;InvalidateRect(hWnd, &g_rc, FALSE);}break;case WM_PAINT:{// 双重缓冲BeginPaint(hWnd, &ps);HDC hMemDC = CreateCompatibleDC(ps.hdc);// 内存设备上下文(内存DC)HBITMAP hBitMap = CreateCompatibleBitmap(ps.hdc, g_rc.right - g_rc.left, g_rc.bottom - g_rc.top);SelectObject(hMemDC, hBitMap);// TODO: 绘制在内存设备上下文上Clean(hMemDC);Draw(hMemDC);// 双重缓冲BitBlt(ps.hdc, 0, 0, g_rc.right - g_rc.left, g_rc.bottom - g_rc.top, hMemDC, 0, 0, SRCCOPY);DeleteDC(hMemDC);DeleteObject(hBitMap);EndPaint(hWnd, &ps);}break;case WM_KEYDOWN:{switch (wParam){case VK_ESCAPE:{if (MessageBox(hWnd, L"确认退出?", L"提示", MB_OKCANCEL) == IDOK){return Quit();}}break;default:break;}}break;case WM_SIZE:{GetClientRect(hWnd, &g_rc);g_width = g_rc.right - g_rc.left;g_height = g_rc.bottom - g_rc.top;}break;case WM_DESTROY:{return Quit();}break;default:return DefWindowProc(hWnd, uMsg, wParam, lParam);}return 0;}void Draw(HDC hdc){SelectObject(hdc, (HPEN)GetStockObject(BLACK_PEN));for (unsigned i = 0; i < g_linelist.size(); i++){MoveToEx(hdc, g_linelist[i].first.x, g_linelist[i].first.y, nullptr);LineTo(hdc, g_linelist[i].second.x, g_linelist[i].second.y);}if (!g_leftBtnDown)return;HPEN hDashPen = CreatePen(PS_DASH, 1, RGB(0, 0, 0));SelectObject(hdc, hDashPen);MoveToEx(hdc, g_p1.x, g_p1.y, nullptr);LineTo(hdc, g_p2.x, g_p2.y);DeleteObject(hDashPen);}void Clean(HDC hdc){FillRect(hdc, &g_rc, (HBRUSH)GetStockObject(WHITE_BRUSH));}void MessageLoop(){MSG msg = {};while (GetMessage(&msg, nullptr, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}}int Quit(){g_linelist.swap(LINELIST());PostQuitMessage(0);return 1;}


0 0