2014-03-28 35 views
1
#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; 
} 

现在,我做的代码来绘制线,如果我选用DDA它会用蓝色的钢笔,如果我选用中点它会通过红色绘制行绘制线,多色的GDI C++

这发生在根据变量算法,算法变量改变的问题,但行颜色没有改变,代码中有东西是不合逻辑的,但我无法检测到它。

任何帮助吗?

+0

为了将来的参考 - 给出演示问题的示例代码是一个巨大的帮助,当有很多源代码需要查看时很难找到问题。如果您能够将示例程序减少到证明问题所需的最低限度,它会有所帮助。谢谢! –

回答

2

每次将消息发送到窗口过程时,都会创建一个新的algo实例。只要窗口过程返回,对算法响应用户事件的任何更改都会被丢弃。

还有其他各种问题太:

  • 您(直接使用new[])从来没有自由,你分配INT阵列,并手动分配内存是现代C通常是不必要++。请尝试使用std::vector<int>
  • 您的if (algorithm == 0)else块看起来几乎相同。重复的代码是不好的。
  • 您将创建一支新笔(并且永不释放它),并在每次迭代时致电BeginPaint/EndPaint。这很慢并泄漏GDI资源。