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).
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)?
Originally Posted by saraswathisrinath
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.
Originally Posted by saraswathisrinath
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!
Originally Posted by saraswathisrinath
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, ...).
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
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:
Derive your own class from CStatic, let's say it CStaticImage.
In CStaticImage class handle WM_ERASEBKGND and WM_PAINT messages.
In the WM_ERASEBKGND function handler do nothing; just return TRUE to prevent default processing.
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);
}
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.
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.
Re: Draw an image continously using pixel value in vc++
Originally Posted by ProgramArtist
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.
Re: Draw an image continously using pixel value in vc++
Originally Posted by ovidiucucu
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
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:
Derive your own class from CStatic, let's say it CStaticImage.
In CStaticImage class handle WM_ERASEBKGND and WM_PAINT messages.
In the WM_ERASEBKGND function handler do nothing; just return TRUE to prevent default processing.
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);
}
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.
Re: Draw an image continously using pixel value in vc++
Originally Posted by saraswathisrinath
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.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.