[RESOLVED] Draw Image Using 2D Byte Array ? - Page 2
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 31

Thread: [RESOLVED] Draw Image Using 2D Byte Array ?

  1. #16
    Join Date
    Nov 2011
    Location
    India
    Posts
    128

    Re: Draw Image Using 2D Byte Array ?

    Hi,

    I'm used MFC Dialog, Both InvalidateRect(WindowHandle, NULL, false); & UpdateWindow(WindowHandle); commands are not working. WindowHandle means? & also arguments size are vary in that method.

    In my application, I'm getting continuous data from the OnTimer() Method & shake the window to plot the data.

    B'cos I don't know how to call the Paint method?
    Regards,

    SaraswathiSrinath

  2. #17
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,012

    Re: Draw Image Using 2D Byte Array ?

    1. In MFC you usually use MFC methods:
    CWnd::InvalidateRect or CWnd::Invalidate
    CWnd::UpdateWindow

    2. You never "call the Paint method" yourself! It is called by Windows as a response to your Invalidate or InvalidateRect calls.
    Victor Nijegorodov

  3. #18
    Join Date
    Nov 2011
    Location
    India
    Posts
    128

    Re: Draw Image Using 2D Byte Array ?

    Hi Mr.Victor,

    I read the CWnd::InvalidateRect page from MSDN.

    But flickering occurred while using the command.

    Code:
    CRect rect;
    	rect.left = 0;
    	rect.top  = 0;
    	rect.right = ClientWidth; //1000
    	rect.bottom = ClientHeight;//256
    
    	InvalidateRect(rect,1); //Refresh the area only but flickering occurred & buttons hidden if any other window appear.
    	//InvalidateRect(rect,0);// If any other window appear buttons are hidden.
    Please find the attachment and replace the .cpp from Dave.rar.

    Am I correct? or wrongly used the code?

    Please clear me. Waiting for your reply.
    Attached Files Attached Files
    Regards,

    SaraswathiSrinath

  4. #19
    Join Date
    Nov 2011
    Location
    India
    Posts
    128

    Re: Draw Image Using 2D Byte Array ?

    I used the command like below,

    Now, Flickering occurred the particular area (0, 0 ,1000, 256).
    Code:
    CRect rect;
    	rect.left = 0;
    	rect.top  = 0;
    	rect.right = ClientWidth; //1000
    	rect.bottom = ClientHeight;//256
    	InvalidateRect(&rect); 
    How can i draw an image without flickering?

    Anybody Please give an idea to solve my problem.
    Last edited by saraswathisrinath; March 4th, 2013 at 12:09 AM.
    Regards,

    SaraswathiSrinath

  5. #20
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,012

    Re: Draw Image Using 2D Byte Array ?

    What interval did you set in your SetTimer call?
    Victor Nijegorodov

  6. #21
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,883

    Re: Draw Image Using 2D Byte Array ?

    Quote Originally Posted by saraswathisrinath View Post
    I used the command like below,

    Now, Flickering occurred the particular area (0, 0 ,1000, 256).
    Code:
    CRect rect;
    	rect.left = 0;
    	rect.top  = 0;
    	rect.right = ClientWidth; //1000
    	rect.bottom = ClientHeight;//256
    	InvalidateRect(&rect); 
    You missed to add a note that you do this InvalidateRect inside WM_PAINT handler. That is definitely a bad idea, as you make the system never stop with refreshing. Please explain what you tried to achieve with that.

    How can i draw an image without flickering?
    You prepare your bitmap bits first, and only then you invalidate the paint area. The paint must be done in minimum of calculations, a single blit is preferable. The process of refreshing must be driven by some mechanism separate from WM_PAINT handler, thread maybe, or timer routine for example.
    Best regards,
    Igor

  7. #22
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,012

    Re: Draw Image Using 2D Byte Array ?

    Quote Originally Posted by Igor Vartanov View Post
    You missed to add a note that you do this InvalidateRect inside WM_PAINT handler.
    Good catch. Igor!
    I missed it (just thought InvalidateRect is called from within the WM_TIMER handler)
    Victor Nijegorodov

  8. #23
    Join Date
    Feb 2013
    Location
    United States
    Posts
    56

    Lightbulb Re: Draw Image Using 2D Byte Array ?

    You may see flickering when Windows erases the client area, that is, sets all of the pixels in the client area to the window's class's background brush color. To prevent Windows from doing this, you need to capture the WM_ERASEBKGND message so that it does not reach the default window procedure. According to MFC documentation, you do this by overriding the OnEraseBkgnd() method. However, if another window is moved around on top of your window, Windows will still erase the other window with your window's class's background brush color. To prevent this, set your window's class's background brush to NULL_BRUSH when the window's class is created.
    Code:
    		Window.hbrBackground = HBRUSH(GetStockObject(NULL_BRUSH));
    But since you are not creating your window's class from scratch, you may not be able to do this.

    As Igor noted, you should be updating your image and calling the InvalidateRect() function from inside your OnTimer() method.

    Also, the flickering could be caused by your monitor. I have two monitors. The test application, that I wrote and have since added a timer event to scroll the image vertically, flickers a little on one of my monitors but not on the other.
    Last edited by Coder Dave; March 4th, 2013 at 02:15 AM.

  9. #24
    Join Date
    Nov 2011
    Location
    India
    Posts
    128

    Re: Draw Image Using 2D Byte Array ?

    I used the InvalidateRect Command in OnPaint of method on my 18th Post.

    But, Today post, I used the InvalidateRect method inside the OnTimer method only.

    so only I recover my project from Hidden controls problem.

    I call the timer at every 40 millisec for see the real time data like moving.

    I'm getting the real time data in OnTimer method at the same time, inside timer I was used the InvalidateRect command.

    But flickering occurred in the defined rect. If I increase the timer 1000 instead of 40 millisec means it will reduce (Flickering).

    Sorry I was only not define correctly my post.
    Regards,

    SaraswathiSrinath

  10. #25
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,012

    Re: Draw Image Using 2D Byte Array ?

    Well, if you let your image change every 40 millisec then flickering must occur!
    But does your image really change every 40 millisec?
    Victor Nijegorodov

  11. #26
    Join Date
    Nov 2011
    Location
    India
    Posts
    128

    Re: Draw Image Using 2D Byte Array ?

    Mr.Dave, I will see the flickering when Windows erases the client area. I accept this.

    If I set the background color means I recover my project from this problem?

    Mr.Victor, I have the same doubt, Now only I start to test my project that how many times paint method call for set the timer = 40 millisec.

    I will come back soon & reply.
    Regards,

    SaraswathiSrinath

  12. #27
    Join Date
    Feb 2013
    Location
    United States
    Posts
    56

    Re: Draw Image Using 2D Byte Array ?

    I forgot to mention that when you call the InvalidateRect() function, set the bErase parameter to FALSE so that the WM_ERASEBKGND message does not get sent to the window.

    Are you having a "hidden controls" problem? If you have controls or text on the client area and you are redrawing the entire client area with the image using code like the following,
    Code:
    	for (y = 0; y < ClientHeight; y = y + 1)
    	{
    		Index = y * NumberOfBytesPerRow;
    		for (x = 0; x < ClientWidth; x = x + 1)
    		{
    			ImageData[Index] = y;
    			Index = Index + 1;
    		}
    	}
    then you are drawing over the controls and text.

  13. #28
    Join Date
    Nov 2011
    Location
    India
    Posts
    128

    Re: Draw Image Using 2D Byte Array ?

    Quote Originally Posted by Coder Dave View Post
    I forgot to mention that when you call the InvalidateRect() function, set the bErase parameter to FALSE so that the WM_ERASEBKGND message does not get sent to the window.
    This hint really works good. Really very happy Thank to all Guru's.
    Code:
    BOOL CDaveDlg::OnEraseBkgnd(CDC* pDC)
    {	
    	if(refreshflag == false)
    	{
    		CRect rcClient;
    		GetClientRect(&rcClient);
    		 
    		if((HBRUSH)brush == NULL)
    			brush.CreateSolidBrush(MYCOLOR); //0,0,0
    		 
    		pDC->FillRect(&rcClient, &brush);
    		brush.DeleteObject();
    	}
    	else
    	{
    		return false;
    	}
    
    return true;
    } 
    
    HBRUSH CDaveDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
    {
      HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    
    	 pDC->SetBkColor(MYCOLOR);
    	 pDC->SetTextColor(RGB(128,64,0));
    
         if((HBRUSH)brush == NULL)
    	      brush.CreateSolidBrush(RGB(0,0,0));
    		
         return (HBRUSH) brush;
    }
    Using the above code, I recover my project from flickering now. But I can't to display the dialog background now.

    Kindly find the attachment. The code works like that only for dialog background.

    Is possible to set the background for dialog ? But, that code won't affect the image display?

    Pls clear me.
    Attached Images Attached Images  
    Regards,

    SaraswathiSrinath

  14. #29
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,883

    Re: Draw Image Using 2D Byte Array ?

    Quote Originally Posted by saraswathisrinath View Post
    Is possible to set the background for dialog ? But, that code won't affect the image display?
    WM_CTLCOLORDLG returns a brush. This is your dialog's background. The brush may be a solid color brush, some stock object (standard Windows brush), a bitmap based brush, etc. All further painting is done over the background.
    Last edited by Igor Vartanov; March 5th, 2013 at 01:27 AM.
    Best regards,
    Igor

  15. #30
    Join Date
    Feb 2013
    Location
    United States
    Posts
    56

    Re: Draw Image Using 2D Byte Array ?

    Quote Originally Posted by saraswathisrinath View Post
    Using the above code, I recover my project from flickering now. But I can't to display the dialog background now.
    I think I understand your problem now. We do not want the dialog to redraw its background where the image is, since this causes flickering and is inefficient. However, we can not stop the dialog from redrawing the background behind the image without stopping it from redrawing the background all together. The solution is to write your own code to draw the background where the image is not present.

    I have never used the CDialog class, so I do not know how much it is doing behind the scenes. If this was just a regular window that you created from scratch, you would draw the dialog background and the controls that go on top of it in the WM_PAINT event. Of course, you would still use BitBlt() in the WM_PAINT event to display the image.

    Alternatively, you could create your bitmap so that it takes up the whole client area. Then, part of the bitmap would be used to draw your image and the other part would be used to draw your text and other controls. If you draw on the bitmap's compatible device context with the GDI functions, your text and controls will be drawn onto the bitmap. Then all you would need to do in your OnPaint() method is to use BitBlt() on the entire client area. Your OnEraseBkgnd() method should do nothing except return true.

    Now, I see some problems with your code:
    Code:
    BOOL CDaveDlg::OnEraseBkgnd(CDC* pDC)
    {	
    	if(refreshflag == false)
    	{
    		CRect rcClient;
    		GetClientRect(&rcClient);
    		 
    		if((HBRUSH)brush == NULL)
    			brush.CreateSolidBrush(MYCOLOR); //0,0,0
    		 
    		pDC->FillRect(&rcClient, &brush);
    		brush.DeleteObject();
    	}
    	else
    	{
    		return false;
    	}
    
    return true;
    }
    Do not create a brush object in any event the will be called over and over again. Instead, create the brush in the create event and save the handle somewhere so that other events can access it. Delete the brush object in the destroy event. Also, your code above has an error. Since you do not set the brush handle to NULL after you delete it, the next time the code is executed, it will try to fill the rectangle with an invalid brush handle.
    Last edited by Coder Dave; March 6th, 2013 at 11:08 PM.

Page 2 of 3 FirstFirst 123 LastLast

Posting Permissions

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


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center