Question

#include <windows.h>
#include <iostream>

using namespace std;

#define ID_DDA 9001
#define ID_MID 9002
#define ID_UNDO 9003
#define ID_REDO 9004

HPEN hPen;
PAINTSTRUCT ps ;
int firstX , firstY , lastX , lastY;
int numClicks = 0;

class algo
{
    HWND hwnd;
    int algorithm;
    int x,y,size,sizeRemoved;
    int *x1Data;
    int *y1Data;
    int *x2Data;
    int *y2Data;
    int *x1Removed;
    int *y1Removed;
    int *x2Removed;
    int *y2Removed;

    void Draw()
    {
        for (int i=0;i<size;i++)
        {
            if (algorithm == 0)
            {
                BeginPaint(hwnd , &ps );
                hPen = CreatePen(PS_SOLID,3,RGB(0,0,255));
                SelectObject(ps.hdc, hPen);
                MoveToEx(ps.hdc, x1Data[i], y1Data[i], NULL);
                LineTo(ps.hdc, x2Data[i], y2Data[i]);
                EndPaint(hwnd , & ps);
            }

            else
            {
                BeginPaint(hwnd , &ps );
                hPen = CreatePen(PS_SOLID,3,RGB(255,0,0));
                SelectObject(ps.hdc, hPen);
                MoveToEx(ps.hdc, x1Data[i], y1Data[i], NULL);
                LineTo(ps.hdc, x2Data[i], y2Data[i]);
                EndPaint(hwnd , & ps);
            }   
        }
    }

    public:

    algo(HWND hwnd)
    {
        this->hwnd = hwnd;
        x1Data = new int [1];
        y1Data = new int [1];
        x2Data = new int [1];
        y2Data = new int [1];
        x1Removed = new int [1];
        y1Removed = new int [1];
        x2Removed = new int [1];
        y2Removed = new int [1];
        size=0;
        sizeRemoved=0;
        algorithm = 0;
    }

    void setHWND (HWND hwnd)
    {
        this->hwnd = hwnd;
    }   

    void ChangeAlgo(int num)
    {
        algorithm = num;

        size = 0;
        sizeRemoved = 0;

        int * tempx1 = new int [1];
        int * tempy1 = new int [1];
        int * tempx2 = new int [1];
        int * tempy2 = new int [1];
        int * tx1 = new int [1];
        int * ty1 = new int [1];
        int * tx2 = new int [1];
        int * ty2 = new int [1];

        x1Data = tempx1;
        y1Data = tempy1;
        x2Data = tempx2;
        y2Data = tempy2;

        x1Removed = tx1;
        y1Removed = ty1;
        x2Removed = tx2;
        y2Removed = ty2;
    }

    int getAlgo ()
    {
        return algorithm;
    }

    void undo ()
    {   
        x1Removed[sizeRemoved] = x1Data[size];
        y1Removed[sizeRemoved] = y1Data[size];
        x2Removed[sizeRemoved] = x2Data[size];
        y2Removed[sizeRemoved] = y2Data[size];

        sizeRemoved++;

        int * tempx1 = new int [size];
        int * tempy1 = new int [size];
        int * tempx2 = new int [size];
        int * tempy2 = new int [size];

        for (int i=0;i<size;i++)
        {
            tempx1[i] = x1Data[i];
            tempy1[i] = y1Data[i];
            tempx2[i] = x2Data[i];
            tempy2[i] = y2Data[i];
        }

        x1Data = tempx1;
        y1Data = tempy1;
        x2Data = tempx2;
        y2Data = tempy2;
        size--;

        int * tx1 = new int [sizeRemoved + 1];
        int * ty1 = new int [sizeRemoved + 1];
        int * tx2 = new int [sizeRemoved + 1];
        int * ty2 = new int [sizeRemoved + 1];

        for (int i=0;i<sizeRemoved;i++)
        {
            tx1[i] = x1Removed[i];
            ty1[i] = y1Removed[i];
            tx2[i] = x2Removed[i];
            ty2[i] = y2Removed[i];
        }

        x1Removed = tx1;
        y1Removed = ty1;
        x2Removed = tx2;
        y2Removed = ty2;

        Draw();
    }

    void redo ()
    {
        x1Data[size] = x1Removed[sizeRemoved - 1];
        y1Data[size] = y1Removed[sizeRemoved - 1];
        x2Data[size] = x2Removed[sizeRemoved - 1];
        y2Data[size] = y2Removed[sizeRemoved - 1];
        size++;
        int * tempx1 = new int [size+1];
        int * tempy1 = new int [size+1];
        int * tempx2 = new int [size+1];
        int * tempy2 = new int [size+1];

        for (int i=0;i<size;i++)
        {
            tempx1[i] = x1Data[i];
            tempy1[i] = y1Data[i];
            tempx2[i] = x2Data[i];
            tempy2[i] = y2Data[i];
        }

        tempx1 = x1Data;
        tempy1 = y1Data;
        tempx2 = x2Data;
        tempy2 = y2Data;

        int * tx1 = new int [sizeRemoved];
        int * ty1 = new int [sizeRemoved];
        int * tx2 = new int [sizeRemoved];
        int * ty2 = new int [sizeRemoved];


        for (int i=0;i<sizeRemoved;i++)
        {
            tx1[i] = x1Removed[i];
            ty1[i] = y1Removed[i];
            tx2[i] = x2Removed[i];
            ty2[i] = y2Removed[i];
        }

        sizeRemoved--;

        x1Removed = tx1;
        y1Removed = ty1;
        x2Removed = tx2;
        y2Removed = ty2;

        Draw();


    }

    void Draw (int x1, int y1 , int x2 , int y2)
    {
        BeginPaint(hwnd , &ps );
        for (int i=0;i<size;i++)
        {
            if (algorithm == 0)
            {
                hPen = CreatePen(PS_SOLID,3,RGB(0,0,255));
                SelectObject(ps.hdc, hPen);
                MoveToEx(ps.hdc, x1Data[i], y1Data[i], NULL);
                LineTo(ps.hdc, x2Data[i], y2Data[i]);
            }

            else
            {
                //BeginPaint(hwnd , &ps );
                hPen = CreatePen(PS_SOLID,3,RGB(255,0,0));
                SelectObject(ps.hdc, hPen);
                MoveToEx(ps.hdc, x1Data[i], y1Data[i], NULL);
                LineTo(ps.hdc, x2Data[i], y2Data[i]);
                //EndPaint(hwnd , & ps);
            }   
        }

        if (algorithm == 0)
        {
            //BeginPaint(hwnd , &ps );
            hPen = CreatePen(PS_SOLID,3,RGB(0,0,255));
            SelectObject(ps.hdc, hPen);
            MoveToEx(ps.hdc, x1, y1, NULL);
            LineTo(ps.hdc, x2, y2);
            //EndPaint(hwnd , & ps);
        }

        else
        {
            //BeginPaint(hwnd , &ps );
            hPen = CreatePen(PS_SOLID,3,RGB(255,0,0));
            SelectObject(ps.hdc, hPen);
            MoveToEx(ps.hdc, x1, y1, NULL);
            LineTo(ps.hdc, x2, y2);
            //EndPaint(hwnd , & ps);
        }
        EndPaint(hwnd , & ps);

        x1Data[size] = x1;
        y1Data[size] = y1;
        x2Data[size] = x2;
        y2Data[size] = y2;
        size++;
        int * tempx1 = new int [size+1];
        int * tempy1 = new int [size+1];
        int * tempx2 = new int [size+1];
        int * tempy2 = new int [size+1];

        for (int i=0;i<size;i++)
        {
            tempx1[i] = x1Data[i];
            tempy1[i] = y1Data[i];
            tempx2[i] = x2Data[i];
            tempy2[i] = y2Data[i];
        }

        tempx1 = x1Data;
        tempy1 = y1Data;
        tempx2 = x2Data;
        tempy2 = y2Data;

    }
};

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "WindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Graphics",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nFunsterStil);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    algo Object(hwnd);
    switch (message)                  /* handle the messages */
    {
        case WM_CREATE:
        {
            HMENU hMenu, hSubMenu;

            hMenu = CreateMenu();

            hSubMenu = CreatePopupMenu();
            AppendMenu(hSubMenu, MF_STRING, ID_DDA, "DDA");
            AppendMenu(hSubMenu, MF_STRING, ID_MID, "Mid-Point");
            AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hSubMenu, "Algorithm");

            hSubMenu = CreatePopupMenu();
            AppendMenu(hSubMenu, MF_STRING, ID_UNDO, "Undo");
            AppendMenu(hSubMenu, MF_STRING, ID_REDO, "Redo");
            AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hSubMenu, "Edit");

            SetMenu(hwnd, hMenu);
        }
        break;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case ID_DDA:
                    Object.ChangeAlgo(0);
                    LPCSTR name;
                    if (Object.getAlgo() == 0)
                    {
                        name = "DDA";
                    }
                     MessageBox(hwnd, name, "Algorithm Changed", MB_OK);
                break;
                case ID_MID:
                    Object.ChangeAlgo(1);
                    if (Object.getAlgo() == 1)
                    {
                        name = "Mid-point";
                    }
                    MessageBox(hwnd, name, "Algorithm Changed", MB_OK);
                break;
            }
        break;

        case WM_LBUTTONDOWN : 
        {
            int XPos  = LOWORD(lParam);
            int YPos = HIWORD(lParam);
            if(numClicks == 0)
            {
                firstX = XPos ;
                firstY = YPos ;
                numClicks++;

            }
            else if(numClicks == 1)
            {
                lastX = XPos ;
                lastY = YPos ;
                numClicks = 0;
                InvalidateRect(hwnd , NULL , true );
                Object.Draw(firstX , firstY , lastX , lastY);
                Object.setHWND(hwnd);

            }
            break ;
        }

        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

Now, I am Doing Code To Draw Line, if I choosed DDA it'll draw it by blue pen, if I choosed Mid-Point it'll Draw it by Red Line

and this happens according to the Variable Algorithm, The Problem that Algorithm variable is changed, But The Line Color isn't Changed, there's something in the code is unlogical but I can't detect it.

Any help ?

Was it helpful?

Solution

You're creating a new algo instance every time a message is dispatched to your window procedure. Any changes to the algorithm in response to a user event are discarded as soon as the window procedure returns.

There are various other problems too:

  • You never free the int arrays you allocate, and manually allocating memory (directly using new[]) is often unnecessary in modern C++. Try using std::vector<int> instead.
  • Your if (algorithm == 0) and else blocks look virtually identical. Duplicating code is bad.
  • You create a new pen (and never free it) and call BeginPaint / EndPaint on every iteration. This is slow and leaks GDI resources.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top