dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13

Thread: Draw an image continously using pixel value in vc++

  1. #1
    Join Date
    Nov 2011
    Location
    India
    Posts
    308

    Draw an image continously using pixel value in vc++

    Hi,

    I drawn an image(384W x 384 H) by pixel value using setpixel method in Onpaint().

    It drawn an image but i want to draw continuously. so i used InvalidateRect(0);

    After using this method, the image was drawn but my other controls (Button, Tab) are hidden in the window.

    1. is Setpixel method correct to draw an image continuously using Onpaint() and InvalidateRect(0) method ?

    2. With out using InvalidateRect(0) method, how to draw an image continuously by pixel value ?

    3. Which method is best to draw an image using pixel value ?

    Regards,

    SaraswathiSrinath.

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    19,525

    Re: Draw an image continously using pixel value in vc++

    Where do you call InvalidateRect from? Hope, not from the OnPaint handler?
    Victor Nijegorodov

  3. #3
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,207

    Re: Draw an image continously using pixel value in vc++

    ...and I hope you don't call InvalidateRect(0) for each pixel.
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: http://codexpert.ro/blog/author/ovidiu-cucu/

  4. #4
    Join Date
    Nov 2011
    Location
    India
    Posts
    308

    Re: Draw an image continously using pixel value in vc++

    sorry. I'm fresher in MFC. I used Invalidate(0); method in Onpaint method itself.

    i used two method. 1. Setpixel & 2. BitBlt method.

    Setpixel code as follows & Bitblt method code was uploaded. Kindly find & give a solution for these kind of problems.



    void MainDlg::OnPaint()
    {

    CPaintDC pdc(this);

    int a = 1, b = 1, c = 1;
    for(int X=0;X<384;X++)
    {
    for(int Y=0;Y<384;Y=Y+4)
    {
    SetPixelV(pdc,400+X,45+Y,RGB(a,b,c));
    a = a+b; b = b+c; c = c+a;
    }
    }

    // UpdateWindow();

    Invalidate(0);

    }




    Regards,

    Saraswathisrinath.
    Attached Files Attached Files

  5. #5
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Draw an image continously using pixel value in vc++

    The correct place to draw a background image is in the OnEraseBkgnd handler. There is no need to call Invalidate().

    Your code has two things (at least) wrong: painting inside OnPaint for a dialog (which is almost always wrong), and calling Invalidate inside OnPaint (which will cause an infinite loop).

    Mike

  6. #6
    Join Date
    Nov 2011
    Location
    India
    Posts
    308

    Re: Draw an image continously using pixel value in vc++

    Thank you so much.

    can u give any simple example code using OnEraseBkgnd handler.

    But i like to draw an image continuously using pixels values, Its not a back ground image.

    it will be draw continuously minimum 30 times per minute.

    is possible to draw these type of image using OnEraseBkgnd handler method?

    Pls clear me.


    Regards

    Saraswathisrinath.
    Last edited by saraswathisrinath; November 30th, 2011 at 12:28 AM.

  7. #7
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    19,525

    Re: Draw an image continously using pixel value in vc++

    "30 times per minute" means every 2 seconds.
    Just create a timer with 2 seconds interval and call Invalidate from within the timer handler...
    Victor Nijegorodov

  8. #8
    Join Date
    May 2006
    Location
    Dresden, Germany
    Posts
    458

    Re: Draw an image continously using pixel value in vc++

    Hi,

    Could you please give us more information abot what you're trying to achieve (not how)?

    Quote Originally Posted by saraswathisrinath View Post
    Hi,

    I drawn an image(384W x 384 H) by pixel value using setpixel method in Onpaint().
    No, in the code you've posted you draw some lines of pixels. You neither have a bitmap/image there nor are you drawing one.

    Quote Originally Posted by saraswathisrinath View Post
    It drawn an image but i want to draw continuously. so i used InvalidateRect(0);
    I don't know what you mean by "continously". I can guess with the help of my magic balls that you want to paint a color gradient or something similar.

    Search codeguru or other programming sites for "color gradient". There are a lot of working examples.

    Like VictorN alredy stated calling InvalidateRect (and UpdateWindow) inside an OnPaint handler is wrong.

    Please get some more knowledge about how drawing has to be implemented in Windows (shortended/simplified): Windows "knows" when a certain window (or a part of it) has to be redrawn. It then sends a WM_PAINT to that window. That results - in the case of a MFC window - in a call of OnPaint.
    What is Invalidate() / InvalidateRect() / UpdateWindow() for?
    These functions have to be called if the contents (the stuff to be drawn) has changed. An application will tell the Windows window manager that a window (or a part of it) has to be re-drawn. Since they will (usually) force sending WM_PAINT's you must not call these functions inside an OnPaint handler!

    Quote Originally Posted by saraswathisrinath View Post
    After using this method, the image was drawn but my other controls (Button, Tab) are hidden in the window.
    A dialog (window) is a special case. Although it is possible to draw something in it's OnPaint handler, that is (almost always) the wrong approach (like MikeAThon stated). Consider a dialog window as a container holding some controls. The appearance (drawing) of the dialog should be implemented inside the controls. To make a long story short: That is the best way to handle different sizes of the same dialog in different circumstances (installed font sizes, ...).

    With regards
    PA

  9. #9
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,207

    Re: Draw an image continously using pixel value in vc++

    My two cents notes, completing what is already discussed.

    Generally it's not a brilliant idea to directly draw in the client area of a dialog, except the case you want to fill it with some fancy brush.
    That case, indeed, the best place is in WM_ERASEBKGND message handler.
    Example
    Code:
    BOOL CMyDialog::OnEraseBkgnd(CDC* pDC) 
    {
       CBrush* pbrushOld = pDC->SelectObject(&m_brushBack);
       CRect rect;
       pDC->GetClipBox(&rect);
       pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
       pDC->SelectObject(pbrushOld);	
    	
       return TRUE; // no further default processing
    }
    I have given the above example just FYI.
    If you have a graph/image to show in a dialog, it's better to make a custom, ActiveX or simpler, a static control.
    For a static control, do the following:
    1. Derive your own class from CStatic, let's say it CStaticImage.
    2. In CStaticImage class handle WM_ERASEBKGND and WM_PAINT messages.
    3. In the WM_ERASEBKGND function handler do nothing; just return TRUE to prevent default processing.
      Code:
      BOOL CStaticImage::OnEraseBkgnd(CDC* pDC) 
      {
         return TRUE;
      }
    4. Perform the drawing in WM_PAINT handler. If the drawing is complex, it's preferable to use a memory device context to draw then bit-blit its contents into the destination device context.
      Code:
      void CStaticImage::OnPaint() 
      {
         CPaintDC dc(this); // device context for painting
      
         CDC dcMem;
         dcMem.CreateCompatibleDC(&dc);
         const int nSavedDC = dcMem.SaveDC();
         
         CRect rc;
         GetClientRect(rc);
      
         CBitmap bmp;
         bmp.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
         dcMem.SelectObject(&bmp);
      
         // just for demo purpose:
         dcMem.Rectangle(0, 0, rc.Width(), rc.Height());
         dcMem.Ellipse(2, 2, 100, 50);
         dcMem.SetPixel(10, 10, RGB(0,0,255));
         // do all other drawing here...
      
         // when the drawing is complete, bit-blit into the target DC
         dc.BitBlt(0, 0, rc.Width(), rc.Height(), &dcMem, 0, 0, SRCCOPY);
      
         dcMem.RestoreDC(nSavedDC);
      }
    5. Finally, put the picture control into the dialog window.
      • In the resource editor, add a static (picture control) to dialog template; change its ID from IDC_STATIC to something else, e.g. IDC_STATIC_IMAGE.
      • Using the Wizard, add to dialog class a control member variable for IDC_STATIC_IMAGE, let's say it m_staticImage; be sure that m_staticImage is of type CStaticImage and "StaticImage.h" header is included.

    That's all.
    Note that above code is just for demo purpose and you have to adapt it for your concrete needs.
    Further, you can add other methods to CStaticImage in order to pass drawig parameters, force redraw, and so on.

    Another one note:
    InvalidateRect(0) invalidates (marks for painting) the whole client area of the window. If the drawing is very complex, may be preferable to pass only the area which effectively has to be painted at one moment. And, as already discussed here, it has no sense to call InvalidateRect inside the WM_PAINT message handler (it does not lead into an infinite loop, as long as it does not send WM_PAINT message but, it has no sense).

    And a final one:
    Drawing something pixel by pixel may be not a good practical idea. Try to find and use "higher level" GDI functions.
    Last edited by ovidiucucu; November 30th, 2011 at 05:25 AM.
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: http://codexpert.ro/blog/author/ovidiu-cucu/

  10. #10
    Join Date
    Nov 2011
    Location
    India
    Posts
    308

    Re: Draw an image continously using pixel value in vc++

    Hi Victor,

    sorry for the late reply. i already used the bitblt method & created a timer and call Invalidate(0); from within the timer handler (Kindly refer : MainDlg.cpp).

    But other controls of the window has hidden like buttons.

    Can you give any sample project.

    Regards,

    Saraswathisrinath

  11. #11
    Join Date
    Nov 2011
    Location
    India
    Posts
    308

    Re: Draw an image continously using pixel value in vc++

    Quote Originally Posted by ProgramArtist View Post
    Hi,

    Could you please give us more information abot what you're trying to achieve (not how)?



    No, in the code you've posted you draw some lines of pixels. You neither have a bitmap/image there nor are you drawing one.



    I don't know what you mean by "continously". I can guess with the help of my magic balls that you want to paint a color gradient or something similar.

    Search codeguru or other programming sites for "color gradient". There are a lot of working examples.

    Like VictorN alredy stated calling InvalidateRect (and UpdateWindow) inside an OnPaint handler is wrong.

    Please get some more knowledge about how drawing has to be implemented in Windows (shortended/simplified): Windows "knows" when a certain window (or a part of it) has to be redrawn. It then sends a WM_PAINT to that window. That results - in the case of a MFC window - in a call of OnPaint.
    What is Invalidate() / InvalidateRect() / UpdateWindow() for?
    These functions have to be called if the contents (the stuff to be drawn) has changed. An application will tell the Windows window manager that a window (or a part of it) has to be re-drawn. Since they will (usually) force sending WM_PAINT's you must not call these functions inside an OnPaint handler!



    A dialog (window) is a special case. Although it is possible to draw something in it's OnPaint handler, that is (almost always) the wrong approach (like MikeAThon stated). Consider a dialog window as a container holding some controls. The appearance (drawing) of the dialog should be implemented inside the controls. To make a long story short: That is the best way to handle different sizes of the same dialog in different circumstances (installed font sizes, ...).

    With regards
    PA
    hi,

    sorry for the late reply.

    1. I'm receiving data from (Using serial communication) RS232.

    I don't know vc++. Now only studying with the help of google.

    2. continuously means, I'm continuously receiving data from the serial port.

    So i like to draw that data in Onpaint() method.

    3. For that, first i used setpixel() method + invalidate(0); in onpaint of method.

    Then i used Bitblt method & created a timer and called the invalidate(0); within the timer.

    Now data are drawn continuously but other controls of the dialog box like buttons are hidden in the main window.


    Regards,

    Saraswathisrinath

  12. #12
    Join Date
    Nov 2011
    Location
    India
    Posts
    308

    Re: Draw an image continously using pixel value in vc++

    Quote Originally Posted by ovidiucucu View Post
    My two cents notes, completing what is already discussed.

    Generally it's not a brilliant idea to directly draw in the client area of a dialog, except the case you want to fill it with some fancy brush.
    That case, indeed, the best place is in WM_ERASEBKGND message handler.
    Example
    Code:
    BOOL CMyDialog::OnEraseBkgnd(CDC* pDC) 
    {
       CBrush* pbrushOld = pDC->SelectObject(&m_brushBack);
       CRect rect;
       pDC->GetClipBox(&rect);
       pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
       pDC->SelectObject(pbrushOld);	
    	
       return TRUE; // no further default processing
    }
    I have given the above example just FYI.
    If you have a graph/image to show in a dialog, it's better to make a custom, ActiveX or simpler, a static control.
    For a static control, do the following:
    1. Derive your own class from CStatic, let's say it CStaticImage.
    2. In CStaticImage class handle WM_ERASEBKGND and WM_PAINT messages.
    3. In the WM_ERASEBKGND function handler do nothing; just return TRUE to prevent default processing.
      Code:
      BOOL CStaticImage::OnEraseBkgnd(CDC* pDC) 
      {
         return TRUE;
      }
    4. Perform the drawing in WM_PAINT handler. If the drawing is complex, it's preferable to use a memory device context to draw then bit-blit its contents into the destination device context.
      Code:
      void CStaticImage::OnPaint() 
      {
         CPaintDC dc(this); // device context for painting
      
         CDC dcMem;
         dcMem.CreateCompatibleDC(&dc);
         const int nSavedDC = dcMem.SaveDC();
         
         CRect rc;
         GetClientRect(rc);
      
         CBitmap bmp;
         bmp.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
         dcMem.SelectObject(&bmp);
      
         // just for demo purpose:
         dcMem.Rectangle(0, 0, rc.Width(), rc.Height());
         dcMem.Ellipse(2, 2, 100, 50);
         dcMem.SetPixel(10, 10, RGB(0,0,255));
         // do all other drawing here...
      
         // when the drawing is complete, bit-blit into the target DC
         dc.BitBlt(0, 0, rc.Width(), rc.Height(), &dcMem, 0, 0, SRCCOPY);
      
         dcMem.RestoreDC(nSavedDC);
      }
    5. Finally, put the picture control into the dialog window.
      • In the resource editor, add a static (picture control) to dialog template; change its ID from IDC_STATIC to something else, e.g. IDC_STATIC_IMAGE.
      • Using the Wizard, add to dialog class a control member variable for IDC_STATIC_IMAGE, let's say it m_staticImage; be sure that m_staticImage is of type CStaticImage and "StaticImage.h" header is included.

    That's all.
    Note that above code is just for demo purpose and you have to adapt it for your concrete needs.
    Further, you can add other methods to CStaticImage in order to pass drawig parameters, force redraw, and so on.

    Another one note:
    InvalidateRect(0) invalidates (marks for painting) the whole client area of the window. If the drawing is very complex, may be preferable to pass only the area which effectively has to be painted at one moment. And, as already discussed here, it has no sense to call InvalidateRect inside the WM_PAINT message handler (it does not lead into an infinite loop, as long as it does not send WM_PAINT message but, it has no sense).

    And a final one:
    Drawing something pixel by pixel may be not a good practical idea. Try to find and use "higher level" GDI functions.

    hi,

    Sorry for the delay.

    Thank you so much. i will try this logic in my project.

    Regards,

    Saraswathisrinath

  13. #13
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Draw an image continously using pixel value in vc++

    Quote Originally Posted by saraswathisrinath View Post
    2. continuously means, I'm continuously receiving data from the serial port.

    So i like to draw that data in Onpaint() method.
    The display of data is the whole raison d'Ítre of a control. Dialogs merely house controls. Dialogs should never be treated as if they WERE controls.

    So, it's generally wrong to display changing data in the OnPaint method of the dialog.

    One correct approach would be to derive a class from (say) a static control, and modify the OnPaint of the static control so that it had access to your data and could display your data as desired (graphic, text, compass rose, whatever). Then, place the static control as a child of the dialog. When new data is received, simply call Invalidate on the static, and you're done.

    Mike

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)