Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ==++ Here's the full source code for (file 1/1) of "main.cpp"::++==
- #define NOMINMAX
- #include <windows.h>
- #include <algorithm>
- #include <iostream>
- #include <vector>
- #include <commctrl.h>
- //#include <windows.h>
- #include <stdio.h>
- #include <iostream>
- #include "resource.h" // Add this with your other includes
- #pragma comment(lib, "comctl32.lib")
- using namespace std;
- // Forward Declarations
- //struct Brushstroke;
- //struct Eraserstroke;
- void DrawBrush(HDC hdc, int x, int y, bool isEraser = false);
- //void DebugDraw(HDC hdc);
- void Erase(HDC hdc, int x, int y);
- void ClearDrawing(HWND hwnd);
- void UpdateStatus(HWND hwnd);
- //void ClearDrawing(HDC hdc, int width, int height);
- //void DrawSmoothBrush(HDC hdc, int x, int y, bool isScreenDC);
- LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- // Add these global variables at the top
- int virtualWidth = 8192;
- int virtualHeight = 8192;
- int scrollX = 0; // Will be initialized properly in InitializeMemoryBitmap
- int scrollY = 0; // Will be initialized properly in InitializeMemoryBitmap
- int canvasWidth = 8192;
- int canvasHeight = 8192;
- bool isSpacePressed = false;
- bool isPanning = false; // Add this new variable
- POINT lastMousePos = { 0, 0 };
- POINT dragStart = { 0, 0 };
- // Add these global variables if not already present
- //std::vector<Brushstroke> storedBrushstrokes;
- //std::vector<Eraserstroke> storedEraserstrokes;
- HDC hMemoryDC = NULL;
- HBITMAP hMemoryBitmap = NULL;
- HBITMAP hOldBitmap = NULL; // Add this to store the old bitmap
- HINSTANCE hInst;
- //bool isPaintbrushSelected = true; // Add a global variable to track the selected tool
- // Define a vector to store the doodle points for the Paintbrush tool
- //std::vector<POINT> paintbrushDoodlePoints;
- //new mod code
- POINT previousPoint; // Add a new global variable to track the previous point
- // Declare hdc as a global variable
- HDC hdc;
- HWND hWnd; // Declare the window handle variable globally or within the appropriate scope
- //bool needsRedraw = true; // Add this line at the top of your file
- // Declare a global variable to specify the grid spacing
- //int gridSpacing = 20;
- bool isInitialized = false;
- bool isPaintbrushSelected = true;;
- bool isDrawing = false;
- bool isErasing = false;
- bool isClearing = false;
- bool isEraserMode = false;
- bool isEraserSelected = false;
- int minBrushSize = 5;
- int maxBrushSize = 50;
- int brushSize = 10;
- //POINT previousPoint;
- // Define a struct to store brushstroke information
- /*struct Brushstroke {
- int x;
- int y;
- int size;
- COLORREF color;
- // Add any other necessary properties for the brushstroke
- };*/
- // Define a struct to store eraserstroke information
- /*struct Eraserstroke {
- int x;
- int y;
- int size;
- COLORREF color;
- // Add any other necessary properties for the eraserstroke
- };*/
- // Declare a vector to store the brushstrokes
- //std::vector<Brushstroke> storedBrushstrokes;
- //std::vector<Eraserstroke> storedEraserstrokes;
- // Global variables to store the minimized brushstrokes
- //std::vector<Brushstroke> minimizedDrawnBrushstrokes;
- //std::vector<Eraserstroke> minimizedErasedBrushstrokes;
- // Function declaration for DrawGrid
- //void DrawGrid(HDC hdc, int spacing, COLORREF color); //drawgrid disableddefault
- // Optimized DrawGrid function to efficiently draw both vertical and horizontal lines
- // Add this function
- /*void CleanupOldStrokes() {
- const size_t MAX_STROKES = 100000;
- if (storedBrushstrokes.size() > MAX_STROKES) {
- storedBrushstrokes.erase(storedBrushstrokes.begin(),
- storedBrushstrokes.begin() + (storedBrushstrokes.size() - MAX_STROKES));
- }
- if (storedEraserstrokes.size() > MAX_STROKES) {
- storedEraserstrokes.erase(storedEraserstrokes.begin(),
- storedEraserstrokes.begin() + (storedEraserstrokes.size() - MAX_STROKES));
- }
- }*/
- //new gpt broken?
- /*void DrawBrush(HDC hdc, int x, int y) {
- // Debug output
- char debug[256];
- sprintf_s(debug, "DrawBrush called at: x=%d, y=%d\n", x, y);
- OutputDebugStringA(debug);
- HBRUSH redBrush = CreateSolidBrush(RGB(255, 0, 0));
- HPEN redPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
- if (!redBrush || !redPen) {
- OutputDebugStringA("Failed to create brush or pen\n");
- return;
- }
- HBRUSH oldBrush = (HBRUSH)SelectObject(hdc, redBrush);
- HPEN oldPen = (HPEN)SelectObject(hdc, redPen);
- if (!oldBrush || !oldPen) {
- OutputDebugStringA("Failed to select brush or pen\n");
- DeleteObject(redBrush);
- DeleteObject(redPen);
- return;
- }
- Ellipse(hdc, x - brushSize, y - brushSize, x + brushSize, y + brushSize);
- SelectObject(hdc, oldBrush);
- SelectObject(hdc, oldPen);
- DeleteObject(redBrush);
- DeleteObject(redPen);
- }*/
- // Add this function to initialize the memory bitmap
- // Add this function
- // Modify InitializeMemoryBitmap:
- void InitializeMemoryBitmap(HWND hwnd) {
- HDC hdc = GetDC(hwnd);
- if (!hdc) {
- return;
- }
- hMemoryDC = CreateCompatibleDC(hdc);
- if (!hMemoryDC) {
- ReleaseDC(hwnd, hdc);
- return;
- }
- hMemoryBitmap = CreateCompatibleBitmap(hdc, virtualWidth, virtualHeight);
- if (!hMemoryBitmap) {
- DeleteDC(hMemoryDC);
- ReleaseDC(hwnd, hdc);
- return;
- }
- hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hMemoryBitmap);
- // Fill with white background
- HBRUSH whiteBrush = CreateSolidBrush(RGB(255, 255, 255));
- RECT rect = { 0, 0, virtualWidth, virtualHeight };
- FillRect(hMemoryDC, &rect, whiteBrush);
- DeleteObject(whiteBrush);
- ReleaseDC(hwnd, hdc);
- isInitialized = true;
- // Draw coordinate guides
- HPEN guidePen = CreatePen(PS_SOLID, 1, RGB(200, 200, 200));
- SelectObject(hMemoryDC, guidePen);
- // Draw center lines
- MoveToEx(hMemoryDC, virtualWidth / 2, 0, NULL);
- LineTo(hMemoryDC, virtualWidth / 2, virtualHeight);
- MoveToEx(hMemoryDC, 0, virtualHeight / 2, NULL);
- LineTo(hMemoryDC, virtualWidth, virtualHeight / 2);
- // Draw border
- HPEN edgePen = CreatePen(PS_SOLID, 2, RGB(0, 0, 255));
- SelectObject(hMemoryDC, edgePen);
- Rectangle(hMemoryDC, 0, 0, virtualWidth - 1, virtualHeight - 1);
- DeleteObject(guidePen);
- DeleteObject(edgePen);
- // Initialize scroll position to center the canvas
- RECT clientRect;
- GetClientRect(hwnd, &clientRect);
- scrollX = (virtualWidth - clientRect.right) / 2;
- scrollY = (virtualHeight - clientRect.bottom) / 2;
- }
- // Initialize scroll position to center the canvas
- //RECT clientRect;
- //GetClientRect(hwnd, &clientRect);
- //scrollX = -virtualWidth / 2 + (clientRect.right / 2);
- //scrollY = -virtualHeight / 2 + (clientRect.bottom / 2);
- //}
- // Replace your DrawBrush function with this simpler version:
- void DrawBrush(HDC hdc, int x, int y, bool isEraser) {
- COLORREF color = isEraser ? RGB(255, 255, 255) : RGB(255, 0, 0);
- HBRUSH brush = CreateSolidBrush(color);
- HPEN pen = CreatePen(PS_SOLID, 1, color);
- HBRUSH oldBrush = (HBRUSH)SelectObject(hdc, brush);
- HPEN oldPen = (HPEN)SelectObject(hdc, pen);
- Ellipse(hdc, x - brushSize, y - brushSize, x + brushSize, y + brushSize);
- SelectObject(hdc, oldBrush);
- SelectObject(hdc, oldPen);
- DeleteObject(brush);
- DeleteObject(pen);
- }
- //old pre-gpt
- /*void DrawBrush(HDC hdc, int x, int y) {
- HBRUSH hBrush = CreateSolidBrush(RGB(255, 0, 0)); // Set the brush color to fully red
- SelectObject(hdc, GetStockObject(NULL_PEN)); // Set the pen to null to remove the border
- SelectObject(hdc, hBrush);
- Ellipse(hdc, x - brushSize, y - brushSize, x + brushSize, y + brushSize);
- DeleteObject(hBrush);
- }*/
- // Add this debug function
- /*void DebugDraw(HDC hdc) {
- HBRUSH redBrush = CreateSolidBrush(RGB(255, 0, 0));
- RECT testRect = { 100, 100, 200, 200 };
- FillRect(hdc, &testRect, redBrush);
- DeleteObject(redBrush);
- }*/
- /*void DrawBrush(HDC hdc, int x, int y) {
- HRGN hRgn = CreateEllipticRgn(x - brushSize, y - brushSize, x + brushSize, y + brushSize);
- FillRgn(hdc, hRgn, CreateSolidBrush(RGB(255, 0, 0)));
- DeleteObject(hRgn);
- }*/
- //broken old
- 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 Erase(HDC hdc, int x, int y) {
- HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255)); // Set the brush color to white
- HGDIOBJ hOldBrush = SelectObject(hdc, hBrush);
- Ellipse(hdc, x - brushSize, y - brushSize, x + brushSize, y + brushSize);
- SelectObject(hdc, hOldBrush);
- DeleteObject(hBrush);
- }*/
- //start test of new eraser
- /*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);
- }*/
- //end test of new eraser
- //start commented out testing new gpt function eraser
- /*void Erase(HDC hdc, int x, int y) {
- // HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255)); // Set the brush color to white
- // HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0)); // Set the brush color to black
- HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255)); // Set the brush color to white
- HPEN hPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255)); // Set the pen color to white
- HGDIOBJ hOldBrush = SelectObject(hdc, hBrush);
- HGDIOBJ hOldPen = SelectObject(hdc, hPen);
- Ellipse(hdc, x - brushSize, y - brushSize, x + brushSize, y + brushSize);
- SelectObject(hdc, hOldBrush);
- SelectObject(hdc, hOldPen);
- DeleteObject(hBrush);
- DeleteObject(hPen);
- }*/
- //end commented out testing new gpt function eraser
- void ClearCanvas(HWND hwnd) {
- HBRUSH whiteBrush = CreateSolidBrush(RGB(255, 255, 255));
- RECT rect = { 0, 0, virtualWidth, virtualHeight };
- FillRect(hMemoryDC, &rect, whiteBrush);
- DeleteObject(whiteBrush);
- InvalidateRect(hwnd, NULL, FALSE);
- }
- void ClearDrawing(HWND hwnd) {
- // Clear the canvas
- HBRUSH whiteBrush = CreateSolidBrush(RGB(255, 255, 255));
- RECT rect = { 0, 0, virtualWidth, virtualHeight };
- FillRect(hMemoryDC, &rect, whiteBrush);
- DeleteObject(whiteBrush);
- // Reset scroll position to center
- RECT clientRect;
- GetClientRect(hwnd, &clientRect);
- scrollX = (virtualWidth - clientRect.right) / 2;
- scrollY = (virtualHeight - clientRect.bottom) / 2;
- // Redraw coordinate guides and border
- // Draw coordinate guides
- HPEN guidePen = CreatePen(PS_SOLID, 1, RGB(200, 200, 200));
- SelectObject(hMemoryDC, guidePen);
- // Draw center lines
- MoveToEx(hMemoryDC, virtualWidth / 2, 0, NULL);
- LineTo(hMemoryDC, virtualWidth / 2, virtualHeight);
- MoveToEx(hMemoryDC, 0, virtualHeight / 2, NULL);
- LineTo(hMemoryDC, virtualWidth, virtualHeight / 2);
- // Draw border
- HPEN edgePen = CreatePen(PS_SOLID, 2, RGB(0, 0, 255));
- SelectObject(hMemoryDC, edgePen);
- Rectangle(hMemoryDC, 0, 0, virtualWidth - 1, virtualHeight - 1);
- DeleteObject(guidePen);
- DeleteObject(edgePen);
- // Force redraw
- InvalidateRect(hwnd, NULL, FALSE);
- }
- //newgptdelete
- /*void ClearDrawing(HWND hwnd) {
- RECT rect = { 0, 0, virtualWidth, virtualHeight };
- HBRUSH whiteBrush = CreateSolidBrush(RGB(255, 255, 255));
- FillRect(hMemoryDC, &rect, whiteBrush);
- DeleteObject(whiteBrush);
- scrollX = -virtualWidth / 2; // Reset to center
- scrollY = -virtualHeight / 2; // Reset to center
- InvalidateRect(hwnd, NULL, FALSE);
- }*/
- /*void ClearDrawing(HDC hdc, int width, int height) {
- RECT rect = { 0, 0, width, height };
- // HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255)); // Set the color to white
- // HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0)); // Set the color to black
- HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255)); // Set the color to white
- FillRect(hdc, &rect, hBrush);
- DeleteObject(hBrush);
- }*/
- //removing drawgrid
- /*void DrawGrid(HDC hdc, int spacing, COLORREF color) {
- RECT rect;
- GetClientRect(hWnd, &rect);
- HPEN hPen = CreatePen(PS_SOLID, 1, color);
- HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
- // Draw vertical lines
- for (int x = 0; x <= rect.right; x += spacing) {
- MoveToEx(hdc, x, 0, NULL);
- LineTo(hdc, x, rect.bottom);
- }
- // Draw horizontal lines
- for (int y = 0; y <= rect.bottom; y += spacing) {
- MoveToEx(hdc, 0, y, NULL);
- LineTo(hdc, rect.right, y);
- }
- SelectObject(hdc, hOldPen);
- DeleteObject(hPen);
- }*/
- //gpts old drawgrid
- /*void DrawGrid(HDC hdc, int spacing, COLORREF color) {
- RECT rect;
- GetClientRect(hWnd, &rect);
- HPEN hPen = CreatePen(PS_SOLID, 1, color);
- HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
- // Draw vertical lines
- for (int x = 0; x < rect.right; x += spacing) {
- MoveToEx(hdc, x, 0, NULL);
- LineTo(hdc, x, rect.bottom);
- }
- // Draw horizontal lines
- for (int y = 0; y < rect.bottom; y += spacing) {
- MoveToEx(hdc, 0, y, NULL);
- LineTo(hdc, rect.right, y);
- }
- SelectObject(hdc, hOldPen);
- DeleteObject(hPen);
- }*/
- //chatgpt disabled
- /*void DrawGrid(HDC hdc, int spacing, COLORREF color) {
- RECT rect;
- GetClientRect(hWnd, &rect);
- HPEN hPen = CreatePen(PS_SOLID, 1, color);
- HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
- // Draw vertical lines
- for (int x = 0; x < rect.right; x += spacing) {
- MoveToEx(hdc, x, 0, NULL);
- LineTo(hdc, x, rect.bottom);
- }
- // Draw horizontal lines
- for (int y = 0; y < rect.bottom; y += spacing) {
- MoveToEx(hdc, 0, y, NULL);
- LineTo(hdc, rect.right, y);
- }
- SelectObject(hdc, hOldPen);
- DeleteObject(hPen);
- }*/
- //temp disabled for relocated code
- /*int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, 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, //& ~WS_MINIMIZEBOX, Add WS_MAXIMIZE style
- // Disable the Minimize button
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- NULL,
- NULL,
- hInstance,
- NULL
- );
- //hdc = GetDC(hWnd); //gptadded
- if (hwnd == NULL) {
- return 0;
- }
- ShowWindow(hwnd, SW_SHOWMAXIMIZED); // Show the window maximized
- //old code
- //ShowWindow(hwnd, nCmdShow);
- MSG msg = { };
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return 0;
- }*/
- //new code
- /*void DrawSmoothBrush(HDC hdc, int x, int y) {
- if (!isDrawing) return;
- int currentX = x + scrollX;
- int currentY = y + scrollY;
- int prevX = previousPoint.x + scrollX;
- int prevY = previousPoint.y + scrollY;
- // Draw line between points for smoothness
- int numPoints = 10;
- for (int i = 0; i <= numPoints; i++) {
- float t = (float)i / numPoints;
- int drawX = prevX + (int)(t * (currentX - prevX));
- int drawY = prevY + (int)(t * (currentY - prevY));
- if (isPaintbrushSelected) {
- DrawBrush(hdc, drawX, drawY);
- }
- else if (isEraserSelected) {
- Erase(hdc, drawX, drawY);
- }
- }
- previousPoint.x = x;
- previousPoint.y = y;
- }*/
- // Update status text when tool changes:
- void UpdateStatus(HWND hwnd) {
- HWND hStatus = GetDlgItem(hwnd, 0);
- if (hStatus) {
- wchar_t status[256];
- swprintf_s(status, L"Mode: %s | Brush Size: %d",
- isEraserMode ? L"Eraser" : L"Draw", brushSize);
- SetWindowText(hStatus, status);
- }
- }
- LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- switch (uMsg) {
- case WM_CREATE:
- {
- InitializeMemoryBitmap(hwnd);
- if (hMemoryDC) {
- HBRUSH redBrush = CreateSolidBrush(RGB(255, 0, 0));
- RECT testRect = { 100, 100, 200, 200 };
- FillRect(hMemoryDC, &testRect, redBrush);
- DeleteObject(redBrush);
- InvalidateRect(hwnd, NULL, FALSE);
- }
- else {
- MessageBox(hwnd, L"Memory DC failed to initialize", L"Error", MB_OK);
- }
- UpdateStatus(hwnd); // Initial status update
- return 0;
- }
- case WM_KEYDOWN:
- {
- if (wParam == VK_SPACE && !isSpacePressed) {
- isSpacePressed = true;
- GetCursorPos(&lastMousePos);
- ScreenToClient(hwnd, &lastMousePos);
- SetCursor(LoadCursor(NULL, IDC_SIZEALL));
- SetCapture(hwnd); // Capture mouse when space is pressed
- return 0;
- }
- else if (wParam == 0x50) { // 'P' key
- isPaintbrushSelected = true;
- isEraserMode = false;
- UpdateStatus(hwnd);
- }
- else if (wParam == 0x45) { // 'E' key
- isPaintbrushSelected = false;
- isEraserMode = true;
- UpdateStatus(hwnd);
- }
- else if (wParam == VK_ADD || wParam == VK_OEM_PLUS) {
- brushSize = std::min(50, brushSize + 5);
- UpdateStatus(hwnd);
- }
- else if (wParam == VK_SUBTRACT || wParam == VK_OEM_MINUS) {
- brushSize = std::max(5, brushSize - 5);
- UpdateStatus(hwnd);
- }
- else if (wParam == 0x43) { // 'C' key
- if (!(GetKeyState(VK_CONTROL) & 0x8000)) {
- ClearDrawing(hwnd);
- }
- }
- else if (wParam == VK_ESCAPE) {
- if (hMemoryDC) {
- if (hOldBitmap) {
- SelectObject(hMemoryDC, hOldBitmap);
- }
- DeleteDC(hMemoryDC);
- }
- if (hMemoryBitmap) {
- DeleteObject(hMemoryBitmap);
- }
- PostQuitMessage(0);
- }
- else if (wParam == VK_F1) {
- MessageBox(hwnd, TEXT("I made an Infinite Canvas app using GDI and Memory DC, no need for bloated Godot Engine/ Frameworks or M$ Infinite Canvas Control! Eternity of effort paid off! (763 lines of code) by Entisoft Software (c) Evans Thorpemorton"), TEXT("Information"), MB_OK | MB_ICONINFORMATION);
- }
- return 0;
- }
- case WM_KEYUP:
- {
- if (wParam == VK_SPACE) {
- isSpacePressed = false;
- SetCursor(LoadCursor(NULL, IDC_ARROW));
- ReleaseCapture(); // Release mouse capture when space is released
- return 0;
- }
- }
- //break;
- // Update WM_LBUTTONDOWN handler:
- case WM_LBUTTONDOWN:
- {
- if (!isSpacePressed) {
- isDrawing = true;
- SetCapture(hwnd);
- // Get cursor position
- int x = LOWORD(lParam);
- int y = HIWORD(lParam);
- // Convert screen coordinates to canvas coordinates
- int canvasX = x + scrollX;
- int canvasY = y + scrollY;
- // Draw at the cursor position
- DrawBrush(hMemoryDC, canvasX, canvasY);
- // Draw on screen for immediate feedback
- HDC screenDC = GetDC(hwnd);
- DrawBrush(screenDC, x, y);
- ReleaseDC(hwnd, screenDC);
- }
- return 0;
- }
- //break;
- // Optional: Add this to WM_LBUTTONUP to ensure smooth lines start fresh:
- case WM_LBUTTONUP:
- {
- if (isPanning) {
- isPanning = false;
- ReleaseCapture();
- }
- if (isDrawing) {
- isDrawing = false;
- ReleaseCapture();
- }
- return 0;
- }
- //break;
- //new code
- // Modified WM_MOUSEMOVE handler:
- // Modify the WM_MOUSEMOVE handler:
- // Modify the WM_MOUSEMOVE case in WindowProc:
- case WM_MOUSEMOVE:
- {
- int x = LOWORD(lParam);
- int y = HIWORD(lParam);
- if (isSpacePressed) { // Removed the left click check
- RECT clientRect;
- GetClientRect(hwnd, &clientRect);
- int deltaX = x - lastMousePos.x;
- int deltaY = y - lastMousePos.y;
- scrollX = std::max(0, std::min<int>(virtualWidth - clientRect.right, scrollX - deltaX));
- scrollY = std::max(0, std::min<int>(virtualHeight - clientRect.bottom, scrollY - deltaY));
- lastMousePos.x = x;
- lastMousePos.y = y;
- InvalidateRect(hwnd, NULL, FALSE);
- }
- else if (isDrawing && (wParam & MK_LBUTTON)) {
- int canvasX = x + scrollX;
- int canvasY = y + scrollY;
- DrawBrush(hMemoryDC, canvasX, canvasY, isEraserMode);
- HDC screenDC = GetDC(hwnd);
- DrawBrush(screenDC, x, y, isEraserMode);
- ReleaseDC(hwnd, screenDC);
- }
- return 0;
- }
- //break;
- /* case WM_MOUSEMOVE:
- if (isDrawing) {
- HDC hdc = GetDC(hwnd);
- DrawBrush(hdc, LOWORD(lParam), HIWORD(lParam));
- ReleaseDC(hwnd, hdc);
- }
- else if (isErasing) {
- HDC hdc = GetDC(hwnd);
- Erase(hdc, LOWORD(lParam), HIWORD(lParam));
- ReleaseDC(hwnd, hdc);
- }
- 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:
- {
- // Handle status bar
- HWND hStatus = GetDlgItem(hwnd, 0);
- if (hStatus) {
- SendMessage(hStatus, WM_SIZE, 0, 0);
- UpdateStatus(hwnd); // Update after resize
- }
- // Handle window size changes
- if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED) {
- InvalidateRect(hwnd, NULL, TRUE);
- }
- return 0;
- }
- //LASTCLASS::
- /*if (wParam == SIZE_MINIMIZED) {
- minimizedDrawnBrushstrokes = storedBrushstrokes;
- minimizedErasedBrushstrokes = storedEraserstrokes;
- }
- else if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED) {
- storedBrushstrokes = minimizedDrawnBrushstrokes;
- storedEraserstrokes = minimizedErasedBrushstrokes;
- // Redraw the window
- InvalidateRect(hwnd, NULL, TRUE);
- }*/
- //gonnareplace winner!
- /*if (wParam == SIZE_MINIMIZED) {
- minimizedDrawnBrushstrokes = storedBrushstrokes;
- minimizedErasedBrushstrokes = storedEraserstrokes;
- }
- else if (wParam == SIZE_RESTORED) {
- storedBrushstrokes = minimizedDrawnBrushstrokes;
- storedEraserstrokes = minimizedErasedBrushstrokes;
- InvalidateRect(hwnd, NULL, TRUE);
- }*/
- //start chatgpt new modified code
- /*if (wParam == SIZE_MINIMIZED) {
- // Save the drawn and erased brushstrokes when minimizing
- minimizedDrawnBrushstrokes = storedBrushstrokes;
- minimizedErasedBrushstrokes = storedEraserstrokes;
- }
- else if (wParam == SIZE_RESTORED) {
- // Restore the minimized brushstrokes when restoring
- storedBrushstrokes = minimizedDrawnBrushstrokes;
- storedEraserstrokes = minimizedErasedBrushstrokes;
- // Trigger a repaint to redraw the brushstrokes
- InvalidateRect(hwnd, NULL, TRUE);
- }*/
- //end chatgpt new modified code
- //start working but no erase history code (adding brushstruct for eraser logic) fallbackcode
- /*if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED) {
- RECT rect;
- GetClientRect(hwnd, &rect);
- //ClearDrawing(hdc, rect.right, rect.bottom);
- }*/
- //end working but no erase history code fallbackcode
- //new replaced chatgpt
- /*if (wParam == SIZE_MAXIMIZED) {
- RECT rect;
- GetClientRect(hwnd, &rect);
- ClearDrawing(hdc, rect.right, rect.bottom);
- }*/
- /*else if (wParam == SIZE_RESTORED) {
- RECT rect;
- GetClientRect(hwnd, &rect);
- if (isPaintbrushSelected) {
- // Redraw the stored doodle contents for the Paintbrush tool
- for (const auto& point : paintbrushDoodlePoints) {
- // Use the stored points to redraw the doodle contents for the Paintbrush tool
- // Example: Draw a small circle at each point
- Ellipse(hdc, point.x - 2, point.y - 2, point.x + 2, point.y + 2);
- }
- }
- }*/
- //old code
- //new replaced chatgpt
- /*else if (wParam == SIZE_RESTORED) {
- RECT rect;
- GetClientRect(hwnd, &rect);
- // Handle resizing of contents when the window is restored
- // Add code to restore doodle contents here
- }
- else if (wParam == SIZE_MINIMIZED) {
- // Handle content when the window is minimized
- }*/
- //}
- //break;
- // Modified WM_PAINT handler:
- // Modify WM_PAINT to handle the centered view
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- HDC hdc = BeginPaint(hwnd, &ps);
- RECT clientRect;
- GetClientRect(hwnd, &clientRect);
- int windowWidth = clientRect.right - clientRect.left;
- int windowHeight = clientRect.bottom - clientRect.top;
- // Create double buffer
- HDC memDC = CreateCompatibleDC(hdc);
- HBITMAP memBitmap = CreateCompatibleBitmap(hdc, windowWidth, windowHeight);
- HBITMAP oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);
- // Clear background in memory DC
- HBRUSH whiteBrush = CreateSolidBrush(RGB(255, 255, 255));
- FillRect(memDC, &clientRect, whiteBrush);
- DeleteObject(whiteBrush);
- // Draw from memory DC to double buffer
- BitBlt(memDC, 0, 0, windowWidth, windowHeight,
- hMemoryDC, scrollX, scrollY, SRCCOPY);
- // Copy double buffer to screen
- BitBlt(hdc, 0, 0, windowWidth, windowHeight,
- memDC, 0, 0, SRCCOPY);
- // Cleanup
- SelectObject(memDC, oldBitmap);
- DeleteObject(memBitmap);
- DeleteDC(memDC);
- EndPaint(hwnd, &ps);
- return 0;
- }
- // added newly to set Normal Pointer & not Busy Pointer
- case WM_SETCURSOR:
- {
- if (LOWORD(lParam) == HTCLIENT) { // Only in client area
- if (isSpacePressed) {
- SetCursor(LoadCursor(NULL, IDC_SIZEALL));
- return TRUE;
- }
- else if (isPaintbrushSelected || isEraserMode) {
- SetCursor(LoadCursor(NULL, IDC_CROSS));
- return TRUE;
- }
- }
- return DefWindowProc(hwnd, uMsg, wParam, lParam); // Use default cursor for non-client area
- }
- case WM_DESTROY:
- {
- if (hMemoryDC) {
- if (hOldBitmap) {
- SelectObject(hMemoryDC, hOldBitmap);
- }
- DeleteDC(hMemoryDC);
- }
- if (hMemoryBitmap) {
- DeleteObject(hMemoryBitmap);
- }
- PostQuitMessage(0);
- return 0;
- }
- default:
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
- }
- return 0;
- }
- // Add this before WinMain
- INITCOMMONCONTROLSEX icex;
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) {
- // Initialize Common Controls
- icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
- icex.dwICC = ICC_BAR_CLASSES;
- InitCommonControlsEx(&icex);
- const wchar_t CLASS_NAME[] = L"DoodleAppClass";
- WNDCLASS wc = { };
- wc.lpfnWndProc = WindowProc;
- wc.hInstance = hInstance;
- wc.lpszClassName = CLASS_NAME;
- wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)); // Add this line
- RegisterClass(&wc);
- hInst = hInstance;
- // In WinMain, modify CreateWindowEx:
- HWND hwnd = CreateWindowEx(
- 0, // No extra styles needed
- CLASS_NAME,
- L"Infinite Canvas Doodle App (P=Brush E=Eraser C=Clear +-=BrushSize Space+Drag=Scroll F1=About)",
- WS_OVERLAPPEDWINDOW | WS_MAXIMIZE,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- NULL,
- NULL,
- hInstance,
- NULL
- );
- // Enable double buffering using SetWindowLong
- SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_COMPOSITED);
- //hdc = GetDC(hwnd);
- if (hwnd == NULL) {
- return 0;
- }
- // Add to WinMain after creating main window
- HWND hStatus = CreateWindowEx(
- 0,
- STATUSCLASSNAME,
- NULL,
- WS_CHILD | WS_VISIBLE,
- 0, 0, 0, 0,
- hwnd,
- NULL,
- hInstance,
- NULL
- );
- // Initial status update
- UpdateStatus(hwnd);
- ShowWindow(hwnd, SW_SHOWMAXIMIZED);
- //start chatgpt new modified code
- /*MSG msg = {};
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- if (msg.message == WM_SIZE) {
- if (msg.wParam == SIZE_MINIMIZED) {
- // Save the drawn and erased brushstrokes when minimizing
- std::vector<Brushstroke> minimizedDrawnBrushstrokes = storedBrushstrokes;
- std::vector<Eraserstroke> minimizedErasedBrushstrokes = storedEraserStrokes;
- }
- else if (msg.wParam == SIZE_RESTORED) {
- // Restore the minimized brushstrokes when restoring
- storedBrushstrokes = minimizedDrawnBrushstrokes;
- storedEraserStrokes = minimizedErasedBrushstrokes;
- // Trigger a repaint to redraw the brushstrokes
- InvalidateRect(hwnd, NULL, TRUE);
- }
- }
- }*/
- //end chatgpt new modified code
- //start working but no erase history code (adding brushstruct for eraser logic) fallbackcode
- MSG msg = {};
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- //end working but no erase history code fallbackcode
- return 0;
- }
Add Comment
Please, Sign In to add comment