WM_PAINT + SetPixel() - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

WM_PAINT + SetPixel()

Hi, I was wondering what is wrong with this code?

BOOL Test = FALSE;

case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
if (Test == FALSE)
SetPixel(hdc, 20, 20, 0x000000FF);
else
SetPixel(hdc, 200, 20, 0x0000FF00);
EndPaint(hWnd, &ps);
break;

case WM_LBUTTONDOWN:
Test = TRUE;
break;

What the code is supposed to do is clear. If the user doesn't leftclick in the Clientarea, a Red pixel is drawn at 20, 20. Else a green one is drawn at 200, 20.
I'm writing a digitalising program, so I don't know how many points I have to mark, but I thought that this code would draw a red pixel and after a leftclick a green one. The interesting thing is, that the red one stays there, but after scrolling the green one disappears. I want them both to stay, but how can I do that. What's wrong with my code???
Pls help.

Comments

  • AsmGuru62AsmGuru62 Posts: 6,519Member
    You need an object which will contain all your data to be painted - then paint them all in response to WM_PAINT. Now, when you clicking - modify this object (array, most likely) and then refresh the client area like this:
    [code]
    void RefreshAll (HWND hWnd)
    {
    InvalidateRect (hWnd, NULL, TRUE);
    UpdateWindow (hWnd); // This will call your WM_PAINT response
    }
    [/code]

  • PeacemanPeaceman Posts: 43Member
    : You need an object which will contain all your data to be painted - then paint them all in response to WM_PAINT. Now, when you clicking - modify this object (array, most likely) and then refresh the client area like this:
    : [code]
    : void RefreshAll (HWND hWnd)
    : {
    : InvalidateRect (hWnd, NULL, TRUE);
    : UpdateWindow (hWnd); // This will call your WM_PAINT response
    : }
    : [/code]
    :
    Yeah, but what the problem is, is that I'm writing a digitalising program which draws little crosses to the position where the user left-clicks. As I don't know how many crosses he's going to set, I cant define them before, or did I misunderstand you???

  • AsmGuru62AsmGuru62 Posts: 6,519Member
    : : You need an object which will contain all your data to be painted - then paint them all in response to WM_PAINT. Now, when you clicking - modify this object (array, most likely) and then refresh the client area like this:
    : : [code]
    : : void RefreshAll (HWND hWnd)
    : : {
    : : InvalidateRect (hWnd, NULL, TRUE);
    : : UpdateWindow (hWnd); // This will call your WM_PAINT response
    : : }
    : : [/code]
    : :
    : Yeah, but what the problem is, is that I'm writing a digitalising program which draws little crosses to the position where the user left-clicks. As I don't know how many crosses he's going to set, I cant define them before, or did I misunderstand you???
    :

    I see, then you have to design a dynamic array of objects where you will be re-allocating more items if needed - it is the only way... if you will use MFC or ATL then you already have this class: ATL has vector, MFC has CPtrArray. Otherwise you have to do it yourself.


  • DariusDarius Posts: 1,666Member
    : Hi, I was wondering what is wrong with this code?
    :
    : BOOL Test = FALSE;
    :
    : case WM_PAINT:
    : hdc = BeginPaint(hWnd, &ps);
    : if (Test == FALSE)
    : SetPixel(hdc, 20, 20, 0x000000FF);
    : else
    : SetPixel(hdc, 200, 20, 0x0000FF00);
    : EndPaint(hWnd, &ps);
    : break;
    :
    : case WM_LBUTTONDOWN:
    : Test = TRUE;
    : break;
    :
    : What the code is supposed to do is clear. If the user doesn't leftclick in the Clientarea, a Red pixel is drawn at 20, 20. Else a green one is drawn at 200, 20.
    : I'm writing a digitalising program, so I don't know how many points I have to mark, but I thought that this code would draw a red pixel and after a leftclick a green one. The interesting thing is, that the red one stays there, but after scrolling the green one disappears. I want them both to stay, but how can I do that. What's wrong with my code???
    : Pls help.
    :

    If the Test=FALSE is inside your WinProc then the program is doing what you're telling it. Otherwise, I'm not sure what the problem is. If you want the Red dot to stay even after they click, then you need code like the following...

    SetPixel(hdc,20,20,RED);
    if(Test) SetPixel(hdc,200,20,GREEN);

    If the Test=FALSE is inside your WinProc then what's happening is that it is (obviously) resetting the Test flag to FALSE in which case it will only draw the RED pixel. The change will only be noticed when WM_PAINT is called again, which will occur when the client area changes or need to be rewritten.

    To have a dynamic array of points, you'll need to use a vector or a linked-list. The standard template library has both. Once you do that you can add each point to the vector/list when you handle the WM_LBUTTONDOWN event (or whenever) and then using for_each apply a DrawCross() functor to each POINT in the vector/list.

    "No Bad Religion song can make your life complete."
    -No Direction, Bad Religion


  • PeacemanPeaceman Posts: 43Member
    Why can't I create a temp Bitmap, then copy the other one into it and then write the pixels to the new bitmap and then just show that one. What functions would I use for that?
    thx for any reply.


  • DariusDarius Posts: 1,666Member
    : Why can't I create a temp Bitmap, then copy the other one into it and then write the pixels to the new bitmap and then just show that one. What functions would I use for that?
    : thx for any reply.
    :
    :
    This is code I ripped from Win32.hlp from Borland.

    Basically, instead of doing the screen you'd get the dc from your clientarea. Then you would treat it as a double buffer. Write all your changes to the BITMAP and make the WM_PAINT handler just Blt the BITMAP to your clientarea.
    [code]
    /*
    * Create a normal DC and a memory DC for the entire screen. The
    * normal DC provides a "snapshot" of the screen contents. The
    * memory DC keeps a copy of this "snapshot" in the associated
    * bitmap.
    */

    hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL);
    hdcCompatible = CreateCompatibleDC(hdcScreen);

    /* Create a compatible bitmap for hdcScreen. */

    hbmScreen = CreateCompatibleBitmap(hdcScreen,
    GetDeviceCaps(hdcScreen, HORZRES),

    GetDeviceCaps(hdcScreen, VERTRES));

    if (hbmScreen == 0)
    errhandler("hbmScreen", hwnd);

    /* Select the bitmaps into the compatible DC. */

    if (!SelectObject(hdcCompatible, hbmScreen))
    errhandler("Compatible Bitmap Selection", hwnd);

    /* Hide the application window. */

    ShowWindow(hwnd, SW_HIDE);

    /*
    * Copy color data for the entire display into a
    * bitmap that is selected into a compatible DC.

    */

    if (!BitBlt(hdcCompatible,
    0,0,
    bmp.bmWidth, bmp.bmHeight,
    hdcScreen,
    0,0,
    SRCCOPY))

    errhandler("Screen to Compat Blt Failed", hwnd);

    /* Redraw the application window. */

    ShowWindow(hwnd, SW_SHOW);
    [/code]

    "No Bad Religion song can make your life complete."
    -No Direction, Bad Religion


Sign In or Register to comment.