Click to See Complete Forum and Search --> : CDC lineto is erased


dudu213
January 4th, 2006, 03:18 AM
I have a timer which is called every 5 seconds and as part of it I am drawing lines to the CDC.
If my dialog is hidden the line is erased until the next call to the timer.
I don't want to catch OnEraseBkground or OnPaint to call the drawing.
I want that after the drawing the line will be "part of" the CDC.
I have tried to ValidateRect or Invalidate with but without Success.
How can it be done?

VictorN
January 4th, 2006, 03:30 AM
It doesn't matter whether you "want" or you "don't want to catch OnPaint to call the drawing"
The OnPaint handler is the only correct place to to the drawing!
Move your code to draw the lines and so on from OnTimer to OnPaint and ionly call Invalidate or InvalidateRect from within OnTimer handler.

dudu213
January 4th, 2006, 03:41 AM
After Moving it to the OnPaint - Still when moving another dialog on this window (where I am drawing) - the line I have drawn on this window is erased.

VictorN
January 4th, 2006, 03:45 AM
What do you mean by "moving another dialog on this window"? Which "window"?

dudu213
January 4th, 2006, 03:48 AM
Another dialog for example.

The application is dialog based, on the main dialog I have a rectangle which I am drawing on. Then I open another child dialog from the main dialog (In doModal() mode) - the coordinates where this child dialog is opened are on the rectangle I am drawing the line - and when it is opened it hides the rectangle. When closing the child dialog the line is erased.

Marc G
January 4th, 2006, 04:02 AM
Can you post your OnPaint code?

Marc G
January 4th, 2006, 04:03 AM
[ moved thread ]

dudu213
January 4th, 2006, 04:41 AM
Here you go, thanks...
I haven't add the validate / invalidate to it, cause I don't know where should I do it now.
m_stStatusBar is the window I want to draw on.

static bool bFirstTime = true;
static CRect rect;
static CDC *pDC;
// First intialization of CDC, Rect
if (bFirstTime)
{
m_stStatusBar.ShowWindow(SW_SHOW);
m_stStatusBar.GetClientRect(rect);
pDC = m_stStatusBar.GetDC();
bFirstTime = false;
}

// clear status
pDC->SelectStockObject(LTGRAY_BRUSH);
pDC->Rectangle(0, 0, rect.right, rect.bottom);

float fFreeRatio = (double)m_ulFreeDiskSpace / (double)m_ulDiskSpace;
// draw available
pDC->SelectStockObject(BLACK_BRUSH);
pDC->Rectangle(0, 0, rect.right * fFreeRatio, rect.bottom);

ovidiucucu
January 4th, 2006, 04:58 AM
Passing over other mistakes and the bad approach, I would like to recommend you using a progress bar instead:
This article can help you:
Showing progress bar in a status bar pane (http://www.codeguru.com/cpp/controls/statusbar/article.php/c2991/).

VictorN
January 4th, 2006, 05:00 AM
Here you go, thanks...
I haven't add the validate / invalidate to it, cause I don't know where should I do it now.See the post#2
m_stStatusBar is the window I want to draw on.

static bool bFirstTime = true;
static CRect rect;
static CDC *pDC;
// First intialization of CDC, Rect
if (bFirstTime)
{
m_stStatusBar.ShowWindow(SW_SHOW);
m_stStatusBar.GetClientRect(rect);
pDC = m_stStatusBar.GetDC();
bFirstTime = false;
}

// clear status
pDC->SelectStockObject(LTGRAY_BRUSH);
pDC->Rectangle(0, 0, rect.right, rect.bottom);

float fFreeRatio = (double)m_ulFreeDiskSpace / (double)m_ulDiskSpace;
// draw available
pDC->SelectStockObject(BLACK_BRUSH);
pDC->Rectangle(0, 0, rect.right * fFreeRatio, rect.bottom);
Where does this code come from? :confused: :confused:
There are also several problems in this code snippet:
1. You are using GetDC() but there are not the ReleaseDC() - memory leaks!
2. According to MSDN "... the pointer returned by GetDC() may be temporary and should not be stored for later use".
3. I do NOT see in this code snippet any attempt to draw a line (or you meant a rectangle instead?).
4. As I already wrote you must do drawing within the OnPaint handler of the window you want to draw in. In your case it seems to be a m_stStatusBar window.

dudu213
January 4th, 2006, 05:11 AM
ovidiucucu - I don't want to use progress bar cause I have to use different colors (the code I have pasted is simplified).

VictorN - again this is a simplified code.
1+2)I am using the ReleaseDC ahead.
3)Line / Rectangle - I think this is the same (I am drawing both - the simplified code only rectangle).
4)I am doing it on the OnPaint of the main dialog, where else hold I do it?

Thanks

Marc G
January 4th, 2006, 05:17 AM
See the post#2Where does this code come from? :confused: :confused:
There are also several problems in this code snippet:
1. You are using GetDC() but there are not the ReleaseDC() - memory leaks!
2. According to MSDN "... the pointer returned by GetDC() may be temporary and should not be stored for later use".
3. I do NOT see in this code snippet any attempt to draw a line (or you meant a rectangle instead?).
4. As I already wrote you must do drawing within the OnPaint handler of the window you want to draw in. In your case it seems to be a m_stStatusBar window.
On top of all these problems, you shouldn't call GetDC in a WM_PAINT handler, but you should use BeginPaint and EndPaint.

dudu213
January 4th, 2006, 05:23 AM
Sorry guys I don't get it...

Can someone please post the simpliest code which draws a line to a child window of the main dialog.

Where should the drawing be done? OnPaint of Main Dialog?

Where can I get the DC from? what DC should I use when I am calling CDC::LineTo?

Thnaks,

ovidiucucu
January 4th, 2006, 05:26 AM
(the code I have pasted is simplified).
That is a good method to make your problem confused and delay a good answer for it. Is the original one top secret? ;)

Anyhow, returning to my first proposal: if you don't want a progress control, then make your own one (derived from CWnd) handle its WM_PAINT message and draw there all what your muscles want.

VictorN
January 4th, 2006, 05:28 AM
On top of all these problems, you shouldn't call GetDC in a WM_PAINT handler, but you should use BeginPaint and EndPaint.Agree. And they both are called internally via [B]CPaintDC/B] ctor/dtor used by drawing within any OnPaint handler.

Marc G
January 4th, 2006, 05:30 AM
Something like:
void CMyView::OnPaint()
{
CPaintDC dc(this);

dc.Rectangle(CRect(0, 0, 100, 100));

// Do not call CView::OnPaint() for painting messages
}
or
void CMyView::OnPaint()
{
PAINTSTRUCT ps;
CDC* pDC = BeginPaint(&ps);

pDC->Rectangle(CRect(0, 0, 100, 100));

EndPaint(&ps);

// Do not call CView::OnPaint() for painting messages
}

VictorN
January 4th, 2006, 05:36 AM
Sorry guys I don't get it...

Where should the drawing be done? OnPaint of Main Dialog?As I already wrote (see the post#10) - within the OnPaint handler of the window you want to draw in. You should derive you own class (either from CWnd as ovidiu suggested or from CStatic), add the WM_PAINT message handler and make your drawing within this handler.
Where can I get the DC from? what DC should I use when I am calling CDC::LineTo?From the OnPaint message handler! It is alway the:CPaintDC dc(this);