Advertisement
alien_fx_fiend

Infinite Canvas Genuine (Rewrite AI Code (Not Finite Like Previously !!))

Mar 18th, 2025 (edited)
450
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.85 KB | Source Code | 0 0
  1. ==++ Here's the full code for (file 1/2) "Infinite-Canvas.cpp"::: ++==
  2. ```Infinite-Canvas.cpp
  3. #define NOMINMAX
  4. #define WIN32_LEAN_AND_MEAN
  5. #include <windows.h>
  6. #include <windowsx.h>
  7. #include <commctrl.h>
  8. #include <commdlg.h>
  9. #include <cmath>
  10. #include <vector>
  11. #include <mutex>
  12. #include <fstream>
  13. #include <thread>
  14. #include <algorithm>
  15. #include "resource.h"
  16.  
  17. #pragma comment(lib, "comctl32.lib")
  18.  
  19. struct DrawPoint {
  20.    int x, y;
  21.    DWORD timestamp;
  22.    DrawPoint() : x(0), y(0), timestamp(0) {}
  23.    DrawPoint(int px, int py) : x(px), y(py), timestamp(GetTickCount()) {}
  24. };
  25.  
  26. struct SerializedStroke {
  27.    std::vector<DrawPoint> points;
  28.    COLORREF color;
  29.    int brushSize;
  30.    bool isEraser;
  31. };
  32.  
  33. std::mutex strokeMutex;
  34. std::vector<SerializedStroke> strokeHistory;
  35. std::vector<DrawPoint> strokeBuffer;
  36. const double MIN_DISTANCE = 2.0;
  37.  
  38. COLORREF currentBrushColor = RGB(24, 123, 205);
  39. int brushSize = 10;
  40. bool isDrawing = false;
  41. bool isEraserMode = false;
  42. bool isPaintbrushSelected = true;
  43. bool isSpacePressed = false;
  44. POINT lastMousePos = { 0, 0 };
  45.  
  46. int scrollX = 0;
  47. int scrollY = 0;
  48. float gridZoomFactor = 1.0f;
  49. bool showGrid = true;
  50. bool useAlphaGrid = false;
  51. int gridOpacity = 255;
  52. const int GRID_SIZE = 100;
  53.  
  54. HINSTANCE hInst;
  55. HWND hWnd;
  56. HWND hStatusBar = NULL;
  57. DWORD lastStatusUpdateTime = 0;
  58. const DWORD STATUS_UPDATE_INTERVAL = 50;
  59. HDC hStatusBufferDC = NULL;
  60. HBITMAP hStatusBufferBitmap = NULL;
  61.  
  62. const wchar_t* STATE_FILE = L"canvas_state2.bin";
  63. bool isLoading = false;
  64.  
  65. // Save the current canvas settings and strokes to disk.
  66. void SaveCanvasState() {
  67.    std::ofstream file(STATE_FILE, std::ios::binary | std::ios::out);
  68.    if (!file)
  69.        return;
  70.    file.write(reinterpret_cast<const char*>(&gridZoomFactor), sizeof(float));
  71.    file.write(reinterpret_cast<const char*>(&showGrid), sizeof(bool));
  72.    file.write(reinterpret_cast<const char*>(&useAlphaGrid), sizeof(bool));
  73.    file.write(reinterpret_cast<const char*>(&gridOpacity), sizeof(int));
  74.    file.write(reinterpret_cast<const char*>(&currentBrushColor), sizeof(COLORREF));
  75.    file.write(reinterpret_cast<const char*>(&brushSize), sizeof(int));
  76.    {
  77.        std::lock_guard<std::mutex> lock(strokeMutex);
  78.        size_t strokeCount = strokeHistory.size();
  79.        file.write(reinterpret_cast<const char*>(&strokeCount), sizeof(size_t));
  80.        for (const auto& stroke : strokeHistory) {
  81.            std::vector<DrawPoint> optimizedPoints;
  82.            if (!stroke.points.empty()) {
  83.                optimizedPoints.push_back(stroke.points[0]);
  84.                for (size_t i = 1; i < stroke.points.size(); ++i) {
  85.                    const DrawPoint& prev = optimizedPoints.back();
  86.                    const DrawPoint& curr = stroke.points[i];
  87.                    double dx = curr.x - prev.x;
  88.                    double dy = curr.y - prev.y;
  89.                    double distance = sqrt(dx * dx + dy * dy);
  90.                    if (distance >= MIN_DISTANCE)
  91.                        optimizedPoints.push_back(curr);
  92.                }
  93.            }
  94.            size_t pointCount = optimizedPoints.size();
  95.            file.write(reinterpret_cast<const char*>(&pointCount), sizeof(size_t));
  96.            if (pointCount > 0)
  97.                file.write(reinterpret_cast<const char*>(optimizedPoints.data()), pointCount * sizeof(DrawPoint));
  98.            file.write(reinterpret_cast<const char*>(&stroke.color), sizeof(COLORREF));
  99.            file.write(reinterpret_cast<const char*>(&stroke.brushSize), sizeof(int));
  100.            file.write(reinterpret_cast<const char*>(&stroke.isEraser), sizeof(bool));
  101.        }
  102.    }
  103.    file.close();
  104. }
  105.  
  106. // Asynchronously load the saved canvas state from disk.
  107. void LoadCanvasStateAsync(HWND hwnd) {
  108.    isLoading = true;
  109.    std::thread([hwnd]() {
  110.        std::ifstream file(STATE_FILE, std::ios::binary | std::ios::in);
  111.        if (!file) {
  112.            isLoading = false;
  113.            return;
  114.        }
  115.        try {
  116.            file.read(reinterpret_cast<char*>(&gridZoomFactor), sizeof(float));
  117.            file.read(reinterpret_cast<char*>(&showGrid), sizeof(bool));
  118.            file.read(reinterpret_cast<char*>(&useAlphaGrid), sizeof(bool));
  119.            file.read(reinterpret_cast<char*>(&gridOpacity), sizeof(int));
  120.            file.read(reinterpret_cast<char*>(&currentBrushColor), sizeof(COLORREF));
  121.            file.read(reinterpret_cast<char*>(&brushSize), sizeof(int));
  122.            size_t strokeCount = 0;
  123.            file.read(reinterpret_cast<char*>(&strokeCount), sizeof(size_t));
  124.            std::vector<SerializedStroke> loadedStrokes;
  125.            for (size_t i = 0; i < strokeCount && file.good(); ++i) {
  126.                SerializedStroke stroke;
  127.                size_t pointCount = 0;
  128.                file.read(reinterpret_cast<char*>(&pointCount), sizeof(size_t));
  129.                if (pointCount > 0 && pointCount < 1000000) {
  130.                    for (size_t j = 0; j < pointCount; ++j) {
  131.                        DrawPoint point;
  132.                        file.read(reinterpret_cast<char*>(&point.x), sizeof(int));
  133.                        file.read(reinterpret_cast<char*>(&point.y), sizeof(int));
  134.                        file.read(reinterpret_cast<char*>(&point.timestamp), sizeof(DWORD));
  135.                        stroke.points.push_back(point);
  136.                    }
  137.                    file.read(reinterpret_cast<char*>(&stroke.color), sizeof(COLORREF));
  138.                    file.read(reinterpret_cast<char*>(&stroke.brushSize), sizeof(int));
  139.                    file.read(reinterpret_cast<char*>(&stroke.isEraser), sizeof(bool));
  140.                    loadedStrokes.push_back(stroke);
  141.                }
  142.            }
  143.            {
  144.                std::lock_guard<std::mutex> lock(strokeMutex);
  145.                strokeHistory = std::move(loadedStrokes);
  146.            }
  147.        }
  148.        catch (...) {
  149.            isLoading = false;
  150.            return;
  151.        }
  152.        file.close();
  153.        isLoading = false;
  154.        InvalidateRect(hwnd, NULL, TRUE);
  155.        }).detach();
  156. }
  157.  
  158. // Draw a smooth stroke using the given points (adjusted by the view offsets).
  159. void DrawSmoothStroke(HDC hdc, const std::vector<DrawPoint>& points, bool isEraser, COLORREF strokeColor, int strokeSize, int offsetX, int offsetY) {
  160.    if (points.empty())
  161.        return;
  162.    COLORREF color = isEraser ? RGB(255, 255, 255) : strokeColor;
  163.    HBRUSH brush = CreateSolidBrush(color);
  164.    HPEN pen = CreatePen(PS_SOLID, 1, color);
  165.    HBRUSH oldBrush = (HBRUSH)SelectObject(hdc, brush);
  166.    HPEN oldPen = (HPEN)SelectObject(hdc, pen);
  167.    if (points.size() == 1) {
  168.        const DrawPoint& pt = points[0];
  169.        Ellipse(hdc, pt.x - offsetX - strokeSize, pt.y - offsetY - strokeSize,
  170.            pt.x - offsetX + strokeSize, pt.y - offsetY + strokeSize);
  171.    }
  172.    else {
  173.        for (size_t i = 1; i < points.size(); ++i) {
  174.            const DrawPoint& prev = points[i - 1];
  175.            const DrawPoint& curr = points[i];
  176.            double dx = curr.x - prev.x;
  177.            double dy = curr.y - prev.y;
  178.            double distance = sqrt(dx * dx + dy * dy);
  179.            if (distance > 0) {
  180.                int steps = std::max(1, (int)(distance / 2));
  181.                for (int step = 0; step <= steps; ++step) {
  182.                    double t = step / (double)steps;
  183.                    int x = (int)(prev.x + dx * t);
  184.                    int y = (int)(prev.y + dy * t);
  185.                    Ellipse(hdc, x - offsetX - strokeSize, y - offsetY - strokeSize,
  186.                        x - offsetX + strokeSize, y - offsetY + strokeSize);
  187.                }
  188.            }
  189.        }
  190.    }
  191.    SelectObject(hdc, oldBrush);
  192.    SelectObject(hdc, oldPen);
  193.    DeleteObject(brush);
  194.    DeleteObject(pen);
  195. }
  196.  
  197. // Draw grid lines relative to the current view offsets.
  198. void DrawGrid(HDC hdc, const RECT& clientRect) {
  199.    SetBkMode(hdc, TRANSPARENT);
  200.    HPEN gridPen = CreatePen(PS_SOLID, 1, RGB(255, 140, 0));
  201.    HPEN oldPen = (HPEN)SelectObject(hdc, gridPen);
  202.    int scaledGridSize = (int)(GRID_SIZE * gridZoomFactor);
  203.    int modX = scrollX % scaledGridSize;
  204.    if (modX < 0)
  205.        modX += scaledGridSize;
  206.    int startX = -modX;
  207.    for (int x = startX; x < (int)clientRect.right; x += scaledGridSize) {
  208.        MoveToEx(hdc, x, 0, NULL);
  209.        LineTo(hdc, x, clientRect.bottom);
  210.    }
  211.    int modY = scrollY % scaledGridSize;
  212.    if (modY < 0)
  213.        modY += scaledGridSize;
  214.    int startY = -modY;
  215.    for (int y = startY; y < (int)clientRect.bottom; y += scaledGridSize) {
  216.        MoveToEx(hdc, 0, y, NULL);
  217.        LineTo(hdc, clientRect.right, y);
  218.    }
  219.    SelectObject(hdc, oldPen);
  220.    DeleteObject(gridPen);
  221. }
  222.  
  223. void InitializeStatusBuffer(HWND hStatus) {
  224.    if (hStatusBufferDC) {
  225.        DeleteDC(hStatusBufferDC);
  226.        DeleteObject(hStatusBufferBitmap);
  227.    }
  228.    HDC hdc = GetDC(hStatus);
  229.    RECT rect;
  230.    GetClientRect(hStatus, &rect);
  231.    hStatusBufferDC = CreateCompatibleDC(hdc);
  232.    hStatusBufferBitmap = CreateCompatibleBitmap(hdc, rect.right, rect.bottom);
  233.    SelectObject(hStatusBufferDC, hStatusBufferBitmap);
  234.    ReleaseDC(hStatus, hdc);
  235. }
  236.  
  237. void UpdateStatus(HWND hwnd) {
  238.    DWORD currentTime = GetTickCount();
  239.    if (currentTime - lastStatusUpdateTime < STATUS_UPDATE_INTERVAL)
  240.        return;
  241.    lastStatusUpdateTime = currentTime;
  242.    if (!hStatusBar)
  243.        return;
  244.    if (!hStatusBufferDC) {
  245.        InitializeStatusBuffer(hStatusBar);
  246.    }
  247.    RECT statusRect;
  248.    GetClientRect(hStatusBar, &statusRect);
  249.    wchar_t status[512];
  250.    BYTE r = GetRValue(currentBrushColor);
  251.    BYTE g = GetGValue(currentBrushColor);
  252.    BYTE b = GetBValue(currentBrushColor);
  253.    // Here you can adjust what "Canvas Pos" means. For example, using scrollX and scrollY:
  254.    swprintf_s(status, 512,
  255.        L"Mode: %s | Brush: %d | Color: RGB(%d,%d,%d) | Grid: %s%s | Zoom: %.1fx | Opacity: %d%% | Canvas Pos: (%d,%d)",
  256.        isEraserMode ? L"Eraser" : L"Draw",
  257.        brushSize,
  258.        r, g, b,
  259.        showGrid ? L"On" : L"Off",
  260.        useAlphaGrid ? L"(Alpha)" : L"",
  261.        gridZoomFactor,
  262.        (gridOpacity * 100) / 255,
  263.        scrollX, scrollY    // Use scrollX and scrollY directly
  264.    );
  265.    SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)status);
  266. }
  267.  
  268. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  269.    switch (uMsg) {
  270.    case WM_CREATE:
  271.    {
  272.        hStatusBar = CreateWindowEx(
  273.            0,
  274.            STATUSCLASSNAME,
  275.            NULL,
  276.            WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
  277.            0, 0, 0, 0,
  278.            hwnd,
  279.            (HMENU)0,
  280.            hInst,
  281.            NULL
  282.        );
  283.        if (hStatusBar) {
  284.            int statwidths[] = { -1 };
  285.            SendMessage(hStatusBar, SB_SETPARTS, 1, (LPARAM)statwidths);
  286.            UpdateStatus(hwnd); // Update the status bar text on creation.
  287.        }
  288.        LoadCanvasStateAsync(hwnd);
  289.        return 0;
  290.    }
  291.    case WM_KEYDOWN:
  292.    {
  293.        if (GetKeyState(VK_MENU) & 0x8000)
  294.            return DefWindowProc(hwnd, uMsg, wParam, lParam);
  295.        if (wParam == VK_SPACE && !isSpacePressed) {
  296.            isSpacePressed = true;
  297.            GetCursorPos(&lastMousePos);
  298.            ScreenToClient(hwnd, &lastMousePos);
  299.            SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  300.            SetCapture(hwnd);
  301.        }
  302.        else if (wParam == 0x50) {
  303.            isPaintbrushSelected = true;
  304.            isEraserMode = false;
  305.            UpdateStatus(hwnd);
  306.        }
  307.        else if (wParam == 0x45) {
  308.            isPaintbrushSelected = false;
  309.            isEraserMode = true;
  310.            UpdateStatus(hwnd);
  311.        }
  312.        else if (wParam == 'Q') {
  313.            CHOOSECOLOR cc = { sizeof(CHOOSECOLOR) };
  314.            static COLORREF customColors[16] = { 0 };
  315.            cc.hwndOwner = hwnd;
  316.            cc.rgbResult = currentBrushColor;
  317.            cc.lpCustColors = customColors;
  318.            cc.Flags = CC_FULLOPEN | CC_RGBINIT;
  319.            if (ChooseColor(&cc))
  320.                currentBrushColor = cc.rgbResult;
  321.            UpdateStatus(hwnd);
  322.        }
  323.        else if (wParam == VK_ADD || wParam == VK_OEM_PLUS) {
  324.            brushSize = std::min(50, brushSize + 5);
  325.            UpdateStatus(hwnd);
  326.        }
  327.        else if (wParam == VK_SUBTRACT || wParam == VK_OEM_MINUS) {
  328.            brushSize = std::max(5, brushSize - 5);
  329.            UpdateStatus(hwnd);
  330.        }
  331.        else if (wParam == 0x43) {
  332.            std::lock_guard<std::mutex> lock(strokeMutex);
  333.            strokeHistory.clear();
  334.            InvalidateRect(hwnd, NULL, TRUE);
  335.        }
  336.        else if (wParam == VK_HOME) {
  337.            scrollX = 0;
  338.            scrollY = 0;
  339.            UpdateStatus(hwnd);
  340.            InvalidateRect(hwnd, NULL, FALSE);
  341.        }
  342.        else if (wParam == 'G') {
  343.            showGrid = !showGrid;
  344.            UpdateStatus(hwnd);
  345.            InvalidateRect(hwnd, NULL, FALSE);
  346.        }
  347.        else if (wParam == 'A') {
  348.            useAlphaGrid = !useAlphaGrid;
  349.            UpdateStatus(hwnd);
  350.            InvalidateRect(hwnd, NULL, FALSE);
  351.        }
  352.        else if (wParam == VK_PRIOR) {
  353.            gridZoomFactor *= 1.1f;
  354.            UpdateStatus(hwnd);
  355.            InvalidateRect(hwnd, NULL, FALSE);
  356.        }
  357.        else if (wParam == VK_NEXT) {
  358.            gridZoomFactor *= 0.9f;
  359.            if (gridZoomFactor < 0.1f)
  360.                gridZoomFactor = 0.1f;
  361.            UpdateStatus(hwnd);
  362.            InvalidateRect(hwnd, NULL, FALSE);
  363.        }
  364.        else if (wParam == VK_OEM_6 && useAlphaGrid) {
  365.            gridOpacity = std::min(255, gridOpacity + 15);
  366.            UpdateStatus(hwnd);
  367.            InvalidateRect(hwnd, NULL, FALSE);
  368.        }
  369.        else if (wParam == VK_OEM_4 && useAlphaGrid) {
  370.            gridOpacity = std::max(0, gridOpacity - 15);
  371.            UpdateStatus(hwnd);
  372.            InvalidateRect(hwnd, NULL, FALSE);
  373.        }
  374.        else if (wParam == VK_ESCAPE) {
  375.            if (isSpacePressed) {
  376.                isSpacePressed = false;
  377.                ReleaseCapture();
  378.            }
  379.            SaveCanvasState();
  380.            PostQuitMessage(0);
  381.            return 0;
  382.        }
  383.        else if (wParam == VK_F1) {
  384.            MessageBox(hwnd, L"Infinite Canvas Doodle App (Infinite canvas with session serialization)", L"Information", MB_OK | MB_ICONINFORMATION);
  385.            return 0;
  386.        }
  387.        return 0;
  388.    }
  389.    case WM_KEYUP:
  390.    {
  391.        if (wParam == VK_SPACE) {
  392.            isSpacePressed = false;
  393.            SetCursor(LoadCursor(NULL, IDC_ARROW));
  394.            ReleaseCapture();
  395.            return 0;
  396.        }
  397.        return 0;
  398.    }
  399.    case WM_LBUTTONDOWN:
  400.    {
  401.        isDrawing = true;
  402.        int worldX = GET_X_LPARAM(lParam) + scrollX;
  403.        int worldY = GET_Y_LPARAM(lParam) + scrollY;
  404.        strokeBuffer.clear();
  405.        strokeBuffer.push_back(DrawPoint(worldX, worldY));
  406.        SetCapture(hwnd);
  407.        InvalidateRect(hwnd, NULL, FALSE);
  408.        return 0;
  409.    }
  410.    case WM_LBUTTONUP:
  411.    {
  412.        if (isDrawing) {
  413.            isDrawing = false;
  414.            SerializedStroke stroke;
  415.            stroke.points = strokeBuffer;
  416.            stroke.color = currentBrushColor;
  417.            stroke.brushSize = brushSize;
  418.            stroke.isEraser = isEraserMode;
  419.            {
  420.                std::lock_guard<std::mutex> lock(strokeMutex);
  421.                strokeHistory.push_back(stroke);
  422.            }
  423.            strokeBuffer.clear();
  424.            ReleaseCapture();
  425.            InvalidateRect(hwnd, NULL, FALSE);
  426.            SaveCanvasState();
  427.            UpdateStatus(hwnd);
  428.        }
  429.        return 0;
  430.    }
  431.    case WM_MOUSEMOVE:
  432.    {
  433.        int x = GET_X_LPARAM(lParam);
  434.        int y = GET_Y_LPARAM(lParam);
  435.        if (isSpacePressed) {
  436.            RECT clientRect;
  437.            GetClientRect(hwnd, &clientRect);
  438.            int deltaX = x - lastMousePos.x;
  439.            int deltaY = y - lastMousePos.y;
  440.            scrollX -= deltaX;
  441.            scrollY -= deltaY;
  442.            lastMousePos.x = x;
  443.            lastMousePos.y = y;
  444.            UpdateStatus(hwnd);  // <-- Added to update Canvas Pos
  445.            InvalidateRect(hwnd, NULL, FALSE);
  446.        }
  447.        else if (isDrawing && (wParam & MK_LBUTTON)) {
  448.            int worldX = x + scrollX;
  449.            int worldY = y + scrollY;
  450.            if (strokeBuffer.empty())
  451.                strokeBuffer.push_back(DrawPoint(worldX, worldY));
  452.            else {
  453.                const DrawPoint& lastPt = strokeBuffer.back();
  454.                double dx = worldX - lastPt.x;
  455.                double dy = worldY - lastPt.y;
  456.                double distance = sqrt(dx * dx + dy * dy);
  457.                if (distance >= MIN_DISTANCE)
  458.                    strokeBuffer.push_back(DrawPoint(worldX, worldY));
  459.            }
  460.            InvalidateRect(hwnd, NULL, FALSE);
  461.        }
  462.        return 0;
  463.    }
  464.    case WM_SIZE:
  465.    {
  466.        RECT rcClient;
  467.        GetClientRect(hwnd, &rcClient);
  468.        if (hStatusBar)
  469.        {
  470.            RECT rcSB;
  471.            SendMessage(hStatusBar, SB_GETRECT, 0, (LPARAM)&rcSB);
  472.            int sbHeight = rcSB.bottom - rcSB.top;
  473.            MoveWindow(hStatusBar, 0, rcClient.bottom - sbHeight, rcClient.right, sbHeight, TRUE);
  474.        }
  475.        UpdateStatus(hwnd); // Refresh the status bar text when window resizes.
  476.        InvalidateRect(hwnd, NULL, TRUE);
  477.        return 0;
  478.    }
  479.    case WM_PAINT:
  480.    {
  481.        PAINTSTRUCT ps;
  482.        HDC hdc = BeginPaint(hwnd, &ps);
  483.        RECT clientRect;
  484.        GetClientRect(hwnd, &clientRect);
  485.        HDC memDC = CreateCompatibleDC(hdc);
  486.        HBITMAP memBitmap = CreateCompatibleBitmap(hdc, clientRect.right, clientRect.bottom);
  487.        HBITMAP oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);
  488.        HBRUSH whiteBrush = CreateSolidBrush(RGB(255, 255, 255));
  489.        FillRect(memDC, &clientRect, whiteBrush);
  490.        DeleteObject(whiteBrush);
  491.        if (showGrid)
  492.            DrawGrid(memDC, clientRect);
  493.        {
  494.            std::lock_guard<std::mutex> lock(strokeMutex);
  495.            for (const auto& stroke : strokeHistory)
  496.                DrawSmoothStroke(memDC, stroke.points, stroke.isEraser, stroke.color, stroke.brushSize, scrollX, scrollY);
  497.        }
  498.        if (isDrawing && !strokeBuffer.empty())
  499.            DrawSmoothStroke(memDC, strokeBuffer, isEraserMode, currentBrushColor, brushSize, scrollX, scrollY);
  500.        BitBlt(hdc, 0, 0, clientRect.right, clientRect.bottom, memDC, 0, 0, SRCCOPY);
  501.        SelectObject(memDC, oldBitmap);
  502.        DeleteObject(memBitmap);
  503.        DeleteDC(memDC);
  504.        EndPaint(hwnd, &ps);
  505.        return 0;
  506.    }
  507.    case WM_SETCURSOR:
  508.    {
  509.        if (LOWORD(lParam) == HTCLIENT) {
  510.            if (isSpacePressed) {
  511.                SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  512.                return TRUE;
  513.            }
  514.            else if (isPaintbrushSelected || isEraserMode) {
  515.                SetCursor(LoadCursor(NULL, IDC_CROSS));
  516.                return TRUE;
  517.            }
  518.        }
  519.        return DefWindowProc(hwnd, uMsg, wParam, lParam);
  520.    }
  521.    case WM_DESTROY:
  522.    {
  523.        SaveCanvasState();
  524.        PostQuitMessage(0);
  525.        return 0;
  526.    }
  527.    default:
  528.        return DefWindowProc(hwnd, uMsg, wParam, lParam);
  529.    }
  530.    return 0;
  531. }
  532.  
  533. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) {
  534.    INITCOMMONCONTROLSEX icex = { sizeof(INITCOMMONCONTROLSEX), ICC_BAR_CLASSES };
  535.    InitCommonControlsEx(&icex);
  536.    const wchar_t CLASS_NAME[] = L"InfiniteCanvasClass";
  537.    WNDCLASS wc = {};
  538.    wc.lpfnWndProc = WindowProc;
  539.    wc.hInstance = hInstance;
  540.    wc.lpszClassName = CLASS_NAME;
  541.    wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
  542.    RegisterClass(&wc);
  543.    hInst = hInstance;
  544.    hWnd = CreateWindowEx(0, CLASS_NAME,
  545.        L"Infinite Canvas Doodle App (P=Brush, E=Eraser, C=Clear, +/�=BrushSize, Space+Drag=Scroll, Home=Center, Q=Color, G=Grid, A=Alpha, PgUp=ZoomIn, PgDn=ZoomOut, F1=About)",
  546.        WS_OVERLAPPEDWINDOW | WS_MAXIMIZE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  547.        NULL, NULL, hInstance, NULL);
  548.    if (hWnd == NULL)
  549.        return 0;
  550.    //ShowWindow(hWnd, nCmdShow);
  551.    ShowWindow(hWnd, SW_SHOWMAXIMIZED);
  552.    MSG msg = {};
  553.    while (GetMessage(&msg, NULL, 0, 0)) {
  554.        TranslateMessage(&msg);
  555.        DispatchMessage(&msg);
  556.    }
  557.    return 0;
  558. }
  559. ```
  560.  
  561. ==++ Here's the full code for (file 2/2) "resource.h"::: ++==
  562. ```resource.h
  563. //{{NO_DEPENDENCIES}}
  564. // Microsoft Visual C++ generated include file.
  565. // Used by DoodleApp.rc
  566. //
  567. #define IDI_ICON1                       101
  568.  
  569. // Next default values for new objects
  570. //
  571. #ifdef APSTUDIO_INVOKED
  572. #ifndef APSTUDIO_READONLY_SYMBOLS
  573. #define _APS_NEXT_RESOURCE_VALUE        102
  574. #define _APS_NEXT_COMMAND_VALUE         40001
  575. #define _APS_NEXT_CONTROL_VALUE         1001
  576. #define _APS_NEXT_SYMED_VALUE           101
  577. #endif
  578. #endif
  579. ```
Advertisement
Comments
Add Comment
Please, Sign In to add comment
Advertisement