Thread: C++ drawing rectanges

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    1

    C++ drawing rectanges

    I am trying to create a program that will draw multiple rectanges on a window each time the left mouse button is pressed(another rectange, of random size, will be added each time the mouse is clicked).

    I have managed to get one rectange to appear however, however each time I click again it is replaced by another random rectange, I wish for multiple random rectanges appearing on screen.

    Code:
    // Rectange2.cpp : Defines the entry point for the application.
    //
    #include
    "stdafx.h"
    #include
    "Rectange2.h"
    #define
     MAX_LOADSTRING 100
    // Global Variables:
    HINSTANCE hInst;                                
    // current instance
    TCHAR szTitle[MAX_LOADSTRING];                    
    // The title bar text
    TCHAR szWindowClass[MAX_LOADSTRING];
    // the main window class name
    bool
     draw = false;
    int
     *test;
    int
     *test2;
    int
     colour[3];
    int
     size[4];
    int
     counter = 0;
        
    // Forward declarations of functions included in this code module:
    ATOM                MyRegisterClass(HINSTANCE hInstance);
    BOOL                InitInstance(HINSTANCE, 
    int);
    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
    void
     paint(HDC hdc,LPARAM lpram , int *colour, int *size);
    void
     mouseClick(int *pColour, int *pSize);
    void
     RefreshWnd (HWND hWnd, RECT* pArea);
     
    int
     APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         
    int       nCmdShow)
    {
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
         
    // TODO: Place code here.
        MSG msg;
        HACCEL hAccelTable;
        
    // Initialize global strings
        LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
        LoadString(hInstance, IDC_RECTANGE2, szWindowClass, MAX_LOADSTRING);
        MyRegisterClass(hInstance);
        
    // Perform application initialization:
        
    if (!InitInstance (hInstance, nCmdShow))
        {
            
    return FALSE;
        }
        hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_RECTANGE2));
        
    // Main message loop:
        
    while (GetMessage(&msg, NULL, 0, 0))
        {
            
    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        
    return (int) msg.wParam;
    }
     
     
    //
    //  FUNCTION: MyRegisterClass()
    //
    //  PURPOSE: Registers the window class.
    //
    //  COMMENTS:
    //
    //    This function and its usage are only necessary if you want this code
    //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
    //    function that was added to Windows 95. It is important to call this function
    //    so that the application will get 'well formed' small icons associated
    //    with it.
    //
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
        WNDCLASSEX wcex;
        wcex.cbSize = 
    sizeof(WNDCLASSEX);
        wcex.style            = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = WndProc;
        wcex.cbClsExtra        = 0;
        wcex.cbWndExtra        = 0;
        wcex.hInstance        = hInstance;
        wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_RECTANGE2));
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName    = MAKEINTRESOURCE(IDC_RECTANGE2);
        wcex.lpszClassName    = szWindowClass;
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
        
    return RegisterClassEx(&wcex);
    }
    //
    //   FUNCTION: InitInstance(HINSTANCE, int)
    //
    //   PURPOSE: Saves instance handle and creates main window
    //
    //   COMMENTS:
    //
    //        In this function, we save the instance handle in a global variable and
    //        create and display the main program window.
    //
    BOOL InitInstance(HINSTANCE hInstance, 
    int nCmdShow)
    {
       HWND hWnd;
       hInst = hInstance; 
    // Store instance handle in our global variable
       hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
       
    if (!hWnd)
       {
          
    return FALSE;
       }
       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);
       
    return TRUE;
    }
    //
    //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  PURPOSE:  Processes messages for the main window.
    //
    //  WM_COMMAND    - process the application menu
    //  WM_PAINT    - Paint the main window
    //  WM_DESTROY    - post a quit message and return
    //
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        
    int wmId, wmEvent;
        PAINTSTRUCT ps;
        HDC hdc;
        test = colour;
        test2 = size;
        
        
    switch (message)
        {
        
    case WM_COMMAND:
            wmId    = LOWORD(wParam);
            wmEvent = HIWORD(wParam);
            
    // Parse the menu selections:
            
    switch (wmId)
            {
            
    case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                
    break;
            
    case IDM_EXIT:
                DestroyWindow(hWnd);
                
    break;
            
    default:
                
    return DefWindowProc(hWnd, message, wParam, lParam);
            }
            
    break;
        
    case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            
            
    if(draw == true )
                {
                
                    paint(hdc, lParam,test, test2);
                    draw = 
    false;
            
                }
            EndPaint(hWnd, &ps);
            
    // TODO: Add any drawing code here...
        
            
            
    break;
            
    case WM_LBUTTONDOWN:
                draw = 
    true;
     
                 mouseClick(test, test2);
                 RefreshWnd(hWnd,NULL);
                 
                 
            
    break;
        
    case WM_DESTROY:
            PostQuitMessage(0);
            
    break;
        
    default:
            
    return DefWindowProc(hWnd, message, wParam, lParam);
        }
        
    return 0;
    }
    // Message handler for about box.
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
        UNREFERENCED_PARAMETER(lParam);
        
    switch (message)
        {
        
    case WM_INITDIALOG:
            
    return (INT_PTR)TRUE;
        
    case WM_COMMAND:
            
    if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
            {
                EndDialog(hDlg, LOWORD(wParam));
                
    return (INT_PTR)TRUE;
            }
            
    break;
        }
        
    return (INT_PTR)FALSE;
    }
    void
     paint(HDC hdc,LPARAM lpram , int *colour, int *size )
    {
        
        
        
    // Fill a solid rectangle
        HBRUSH blueBrush = CreateSolidBrush(RGB(*colour,*(colour +1), *(colour +2)));
        RECT rect;
        rect.left = *size;
        rect.right = *(size + 1);
        rect.top = *(size + 2);
        rect.bottom = *(size + 3);
        FillRect(hdc, &rect, blueBrush);
        DeleteObject(blueBrush);
        
    }
    void
     mouseClick(int *pColour, int *pSize)
    {
        
        *pColour = rand() % 200;
        *(pColour + 1) = rand() % 200;
        *(pColour + 2) = rand() % 200;
     
        
        *pSize = rand() % -800 + 251;
        *(pSize + 1) = rand() % -800 + 251;
        *(pSize + 2) = rand() % -200 + 251;
        *(pSize + 3) = rand() % -200 + 251;
    }
     
    void
     RefreshWnd (HWND hWnd, RECT* pArea)
    {
        InvalidateRect (hWnd, pArea, TRUE);
        UpdateWindow (hWnd);
    }
    

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    One possibility is to simply pass FALSE as the last parameter to InvalidateRect. Passing TRUE, as you're doing, erases the background.

    A more far-reaching solution is to maintain a data structure that remembers all the rectangles drawn so far and redraws them in every paint event (or at least the ones intersecting the affected area).
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    I would use a compatible bitmap for something like that.

    It's a bit more code to set it up, but the bitmap is nonvolatile, and preserves everything drawn on it.
    Updating the client area just requires a simple bit blit within the WM_PAINT message handler. This
    automatically takes care of the redraws called for by the operating sytem (like moving the window)
    and the program's drawing with just a call to "InvalidateRect()" and the WM_PAINT handler.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. drawing gone
    By manzoor in forum C# Programming
    Replies: 0
    Last Post: 01-18-2009, 05:45 AM
  2. Drawing a Box
    By ssharish2005 in forum C Programming
    Replies: 3
    Last Post: 09-28-2006, 03:23 PM
  3. Drawing
    By fkheng in forum C Programming
    Replies: 3
    Last Post: 07-19-2003, 08:12 AM
  4. drawing using SDL
    By lambs4 in forum Game Programming
    Replies: 5
    Last Post: 03-06-2003, 10:34 AM
  5. Drawing
    By SushiFugu in forum Windows Programming
    Replies: 1
    Last Post: 02-15-2002, 06:13 PM