Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <vector>
- #include <windows.h>
- using namespace std;
- struct Brushstroke;
- struct Eraserstroke;
- void DrawBrush(HDC hdc, int x, int y);
- void Erase(HDC hdc, int x, int y);
- void ClearDrawing(HDC hdc, int width, int height);
- void DrawSmoothBrush(HDC hdc, int x, int y);
- bool isPaintbrushSelected = true;
- POINT previousPoint;
- HDC hdc, memDC;
- HBITMAP memBitmap;
- HWND hWnd;
- struct Brushstroke {
- int x;
- int y;
- int size;
- COLORREF color;
- };
- struct Eraserstroke {
- int x;
- int y;
- int size;
- COLORREF color;
- };
- std::vector<Brushstroke> storedBrushstrokes;
- std::vector<Eraserstroke> storedEraserstrokes;
- void RedrawStrokes() {
- for (const auto& brushstroke : storedBrushstrokes) {
- HGDIOBJ originalBrush = SelectObject(memDC, CreateSolidBrush(brushstroke.color));
- HGDIOBJ originalPen = SelectObject(memDC, GetStockObject(NULL_PEN));
- Ellipse(memDC, brushstroke.x - brushstroke.size, brushstroke.y - brushstroke.size,
- brushstroke.x + brushstroke.size, brushstroke.y + brushstroke.size);
- DeleteObject(SelectObject(memDC, originalBrush));
- DeleteObject(SelectObject(memDC, originalPen));
- }
- for (const auto& erasepoint : storedEraserstrokes) {
- HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255));
- SelectObject(memDC, GetStockObject(NULL_PEN));
- SelectObject(memDC, hBrush);
- Ellipse(memDC, erasepoint.x - erasepoint.size, erasepoint.y - erasepoint.size,
- erasepoint.x + erasepoint.size, erasepoint.y + erasepoint.size);
- DeleteObject(hBrush);
- }
- }
- LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- HINSTANCE hInst;
- bool isDrawing = false;
- bool isErasing = false;
- bool isClearing = false;
- bool isEraserSelected = false;
- int brushSize = 10;
- void DrawBrush(HDC hdc, int x, int y) {
- HGDIOBJ originalBrush = SelectObject(hdc, CreateSolidBrush(RGB(255, 0, 0)));
- HGDIOBJ originalPen = SelectObject(hdc, GetStockObject(NULL_PEN));
- Ellipse(hdc, x - brushSize, y - brushSize, x + brushSize, y + brushSize);
- DeleteObject(SelectObject(hdc, originalBrush));
- DeleteObject(SelectObject(hdc, originalPen));
- }
- void Erase(HDC hdc, int x, int y) {
- HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255));
- SelectObject(hdc, GetStockObject(NULL_PEN));
- SelectObject(hdc, hBrush);
- Ellipse(hdc, x - brushSize, y - brushSize, x + brushSize, y + brushSize);
- DeleteObject(hBrush);
- }
- void ClearDrawing(HDC hdc, int width, int height) {
- RECT rect = { 0, 0, width, height };
- HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255));
- FillRect(hdc, &rect, hBrush);
- DeleteObject(hBrush);
- storedBrushstrokes.clear();
- storedEraserstrokes.clear();
- }
- void DrawSmoothBrush(HDC hdc, int x, int y) {
- if (isDrawing && (isPaintbrushSelected || isEraserSelected)) {
- int numPoints = 3;
- POINT currentPoint = { x, y };
- for (int i = 1; i <= numPoints; i++) {
- float t = (float)i / (float)numPoints;
- int smoothX = (int)(previousPoint.x + t * (currentPoint.x - previousPoint.x));
- int smoothY = (int)(previousPoint.y + t * (currentPoint.y - previousPoint.y));
- if (isPaintbrushSelected) {
- DrawBrush(hdc, smoothX, smoothY);
- Brushstroke newBrushstroke;
- newBrushstroke.x = smoothX;
- newBrushstroke.y = smoothY;
- newBrushstroke.size = brushSize;
- newBrushstroke.color = RGB(255, 0, 0);
- storedBrushstrokes.push_back(newBrushstroke);
- }
- else if (isEraserSelected) {
- Erase(hdc, smoothX, smoothY);
- Eraserstroke newEraserstroke;
- newEraserstroke.x = smoothX;
- newEraserstroke.y = smoothY;
- newEraserstroke.size = brushSize;
- newEraserstroke.color = RGB(255, 255, 255);
- storedEraserstrokes.push_back(newEraserstroke);
- }
- }
- previousPoint = currentPoint;
- }
- }
- LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- switch (uMsg) {
- case WM_CREATE:
- {
- RECT rect;
- GetClientRect(hwnd, &rect);
- HDC hdc = GetDC(hwnd);
- memDC = CreateCompatibleDC(hdc);
- memBitmap = CreateCompatibleBitmap(hdc, rect.right - rect.left, rect.bottom - rect.top);
- SelectObject(memDC, memBitmap);
- ReleaseDC(hwnd, hdc);
- HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255));
- FillRect(memDC, &rect, hBrush);
- DeleteObject(hBrush);
- isPaintbrushSelected = true;
- }
- break;
- case WM_KEYDOWN:
- if (wParam == VK_ADD) {
- brushSize += 5;
- }
- else if (wParam == VK_SUBTRACT) {
- if (brushSize > 5) {
- brushSize -= 5;
- }
- }
- else if (wParam == 0x43) {
- if (!(GetKeyState(VK_CONTROL) & 0x8000)) {
- isClearing = true;
- }
- }
- else if (wParam == 0x50) {
- isPaintbrushSelected = true;
- isEraserSelected = false;
- }
- else if (wParam == 0x45) {
- isEraserSelected = true;
- isPaintbrushSelected = false;
- }
- break;
- case WM_LBUTTONDOWN:
- if (isPaintbrushSelected || isEraserSelected) {
- previousPoint.x = LOWORD(lParam);
- previousPoint.y = HIWORD(lParam);
- }
- isDrawing = true;
- break;
- case WM_LBUTTONUP:
- isDrawing = false;
- break;
- case WM_MOUSEMOVE:
- if (isDrawing && isPaintbrushSelected) {
- int x = LOWORD(lParam);
- int y = HIWORD(lParam);
- DrawSmoothBrush(memDC, x, y);
- InvalidateRect(hwnd, NULL, FALSE);
- Brushstroke newBrushstroke;
- newBrushstroke.x = x;
- newBrushstroke.y = y;
- newBrushstroke.size = brushSize;
- newBrushstroke.color = RGB(255, 0, 0);
- storedBrushstrokes.push_back(newBrushstroke);
- }
- else if (isDrawing && isEraserSelected) {
- int x = LOWORD(lParam);
- int y = HIWORD(lParam);
- Erase(memDC, x, y);
- InvalidateRect(hwnd, NULL, FALSE);
- Eraserstroke newEraserStroke;
- newEraserStroke.x = x;
- newEraserStroke.y = y;
- newEraserStroke.size = brushSize;
- newEraserStroke.color = RGB(255, 255, 255);
- storedEraserstrokes.push_back(newEraserStroke);
- }
- else if (isClearing) {
- HDC hdc = GetDC(hwnd);
- RECT rect;
- GetClientRect(hwnd, &rect);
- ClearDrawing(hdc, rect.right, rect.bottom);
- ReleaseDC(hwnd, hdc);
- isClearing = false;
- }
- break;
- case WM_SIZE:
- {
- static bool isMinimized = false;
- if (wParam == SIZE_MINIMIZED)
- {
- isMinimized = true;
- }
- else if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED)
- {
- if (isMinimized)
- {
- isMinimized = false;
- }
- InvalidateRect(hwnd, NULL, TRUE);
- }
- RECT rect;
- GetClientRect(hwnd, &rect);
- if (memDC)
- {
- DeleteDC(memDC);
- DeleteObject(memBitmap);
- }
- HDC hdc = GetDC(hwnd);
- memDC = CreateCompatibleDC(hdc);
- memBitmap = CreateCompatibleBitmap(hdc, rect.right - rect.left, rect.bottom - rect.top);
- SelectObject(memDC, memBitmap);
- ReleaseDC(hwnd, hdc);
- HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255));
- FillRect(memDC, &rect, hBrush);
- DeleteObject(hBrush);
- RedrawStrokes();
- }
- break;
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- HDC hdc = BeginPaint(hwnd, &ps);
- BitBlt(hdc, 0, 0, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, memDC, 0, 0, SRCCOPY);
- EndPaint(hwnd, &ps);
- }
- break;
- case WM_SETCURSOR:
- if (LOWORD(lParam) == HTCLIENT) {
- SetCursor(LoadCursor(NULL, IDC_ARROW));
- return TRUE;
- }
- break;
- case WM_DESTROY:
- DeleteDC(memDC);
- DeleteObject(memBitmap);
- PostQuitMessage(0);
- return 0;
- default:
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
- }
- return 0;
- }
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
- const wchar_t CLASS_NAME[] = L"DoodleAppClass";
- WNDCLASS wc = { };
- wc.lpfnWndProc = WindowProc;
- wc.hInstance = hInstance;
- wc.lpszClassName = CLASS_NAME;
- RegisterClass(&wc);
- hInst = hInstance;
- HWND hwnd = CreateWindowEx(
- 0,
- CLASS_NAME,
- L"Doodle App",
- WS_OVERLAPPEDWINDOW | WS_MAXIMIZE,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- NULL,
- NULL,
- hInstance,
- NULL
- );
- hdc = GetDC(hwnd);
- if (hwnd == NULL) {
- return 0;
- }
- ShowWindow(hwnd, SW_SHOWMAXIMIZED);
- MSG msg = {};
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement