Thread: Draw Program Not Working

  1. #1
    A source of questions... Benji Wiebe's Avatar
    Join Date
    Mar 2011
    Durham, Kansas

    Draw Program Not Working

    This program is supposed to draw a randomly colored dot (connected by a line of the same color) at a random location on the screen when I click "Start", then exit when I click ESCAPE. When I click "Start", though, nothing happens.
    //FILE: main.c
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include <wingdi.h>
    #include <stdlib.h>
    #include "resource.h"
    #include <stdio.h>
    #define WM_START 12342649
    HINSTANCE hInst;
    void draw(HDC, int, int, int, int);
    int x=1, y=1;
    HDC me;
    BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
        case WM_INITDIALOG:
            //SetBkColor(GetDC(NULL), RGB(0,0,0));
            return TRUE;
        case WM_CLOSE:
            EndDialog(hwndDlg, 0);
            return TRUE;
        case WM_COMMAND:
            case 2222:
                MessageBox(hwndDlg, "start", "", MB_OK);
                while(!(GetKeyState(VK_ESCAPE)&0b10000000)) {
                    draw(me, 10, 10, x, y);
                EndDialog(hwndDlg, 0);
                return TRUE;
        return FALSE;
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
        hInst = hInstance;
        // The user interface is a modal dialog box
        return DialogBox(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DialogProc);
    void draw(HDC dc, int x, int y, int xpos, int ypos)
        //int ca=0, cb=0, cd=0;
        COLORREF color;
        //HPEN pen=CreatePen(PS_SOLID, 20);
        LOGBRUSH mbrush;
        COLORREF rnd=RGB(rand()&0xFF, rand()&0xFF, rand()&0xFF);
        HBRUSH brush=CreateBrushIndirect(&mbrush);
        SelectObject(dc, (HGDIOBJ)brush);
        LineTo(dc, xpos, ypos);
        //color=RGB(xpos, 0, 0);
        int xx, yy;
        for(xx=0; xx<x; xx++)
            for(yy=0; yy<y; yy++)
                SetPixel(dc, xx+xpos, yy+ypos, color);
    //FILE: resource.h
    #include <windows.h>
    // ID of Main Dialog
    #define DLG_MAIN 101
    //FILE: resource.rc
    #include "resource.h"
    DLG_MAIN DIALOGEX 6, 5, 194, 106
    CAPTION ""
     PUSHBUTTON      "Start", 2222/*ID*/, 7, 7, 47, 22
    What is wrong????? (Probably alot)
    NOTE: Some of these functions I have just started using today.
    Ever notice how fast Windows runs?
    Neither did I.
    Which is why I switched to Linux.

  2. #2
    Registered User
    Join Date
    Mar 2005
    Take a look at some Win API reference manual, it will be a great help.

    Why the MessageBox is not displayed on start-click? See the WM_COMMAND composition:

    wNotifyCode = HIWORD(wParam); // notification code 
    wID = LOWORD(wParam);         // item, control, or accelerator identifier 
    hwndCtl = (HWND) lParam;      // handle of control
    You have to check out the LOWORD(wParam). Now you have the MessageBox right.

    The next is the drawing part: do not block the program on a 'while' loop, use instead a timer and a global flag, and of course check the WM_PAINT message. The start button will set the flag to TRUE (or to a value that means: 'yeah, you can draw now'), and the stop will reset the flag to FALSE (or 'hey, do not draw please'). But why the timer? Because you need to refresh the window to receive the WM_PAINT message (that's not completelly true, because you can get the HDC whenever you want, but for the moment will be ok for us):

    UINT SetTimer(
        HWND hWnd,	// handle of window for timer messages
        UINT nIDEvent,	// timer identifier
        UINT uElapse,	// time-out value
        TIMERPROC lpTimerFunc 	// address of timer procedure, set it to NULL to process the WM_TIMER message
    You have to decide if you want to set the timer on program startup (and kill timer on shutdown), or only set the timer between start-stop commands (I think the second is better). When you have the timer running you can checkout the WM_TIMER message: refresh the window. Ok, not the whole window, only the old position and the new position: use two RECT structures to store the dot positions (old and new), and call InvalidateRect

    BOOL InvalidateRect(
        HWND hWnd,	// handle of window with changed update region  
        CONST RECT *lpRect,	// address of rectangle coordinates 
        BOOL bErase	// erase-background flag 
    Now you can checkout the WM_PAINT message; even the message have to do all the drawing stuff, the InvalidateRect will ensure that only the selected area will be modifyed (a big area means a big flickering). To process that message use BeginPaint and EndPaint (BeginPaint returns the display HDC handler, note that in your code you never setted up it). Use this HDC to fill in the background color the old dot position, and draw the new dot.

    Hope that will help; I think that the more important thing is to not block a message loop process with a 'while' loop

  3. #3
    train spotter
    Join Date
    Aug 2001
    near a computer
    Drawing the dots each paint msg will be very slow, using SetPixel will make it even slower. The drawing will also not remain after the system generates a paint msg (ie another window overlaps your window).

    You should create a back buffer, draw the dots to this and when you get a paint msg BitBlt() the back buffer to the screen buffer ('Double Buffer').

    I have posted plenty of code before showing exactly how do do this.

    PS Make sure your START button ID is the same in the RESOURCE.H file and CALLBACK, better to use the actual ID name [ie IDC_START] (as currently you appear to be using both 12342649 and 2222)

    Use the correct CASE ..... BREAK syntax (even if you have a return). It will make your code much more readable and prone to less errors.

    Do not call srand() more than once in the whole program. rand is a big list of numbers, srand is the index to start at. If you keep reseting it, you will get exactly the same 'random' number.

    Use the modulus function to get a number in the correrct range the first time [int iPercent = (int)(rand() % 100);//return a whole number between 0 and 99 ]
    Last edited by novacain; 06-11-2011 at 08:24 PM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. gpa program not working
    By matthughes in forum C Programming
    Replies: 8
    Last Post: 05-20-2007, 12:11 PM
  2. program not working...please look at this
    By JOlszewski in forum C Programming
    Replies: 3
    Last Post: 01-30-2006, 10:33 PM
  3. Program Not working Right
    By raven420smoke in forum C++ Programming
    Replies: 2
    Last Post: 09-16-2005, 03:21 AM
  4. Program not working right
    By blindman858 in forum C++ Programming
    Replies: 3
    Last Post: 04-17-2005, 09:37 AM
  5. Program not working
    By jat421 in forum C Programming
    Replies: 6
    Last Post: 03-20-2005, 08:28 PM