Discussion:
Artifacts when drawing into window device context (Windows 7)
(too old to reply)
Steffen
2010-01-06 09:44:01 UTC
Permalink
I've got a problem drawing GDI-generated graphics into a window device
context; when the corresponding window is moved with the mouse, the output
sometimes is drawn at incorrect locations, causing "smearing" and broken
shapes. It seems as if the origin of the DC is not synchronized with the
(moving) window surface.

This problems occurs under the following circumstances:
1. The drawing occurs in an MDI child window.
2. The operating system is Windows 7. Flavor doesn't matter. Desktop
theme/composition doesn't matter. IAW: The problem also occurs in
the "Basic" theme!
3. The drawing is performed by a separate thread, aka a thread different
from the one which called CreateWindow().

Note that the corresponding code ran fine all the way through from Windows
9x ;-).

The drawing code is pretty simple (and could probably be reduced even
further):

(Pseude Code, runs in separate thread)

hDC = GetDC(...)

for x:=0 to 100
MoveToEx( hDC, x, 50, NULL )
LineTo( hDC, x, 150 )
next

ReleaseDC( ... )

A sample can be easily provided.

I probably should have posted this to a Windows 7-related forum. I couldn't
find one, though.

Does anyone have an idea what might be causing this?

Thanks,
Steffen
Alexander Grigoriev
2010-01-06 15:27:13 UTC
Permalink
3. That's your mistake. Do it in the windows creator thread. You don't gain
anything by doing it in a separate thread.

Windows95 GUI was serialized through 16 bit subsystem. In NT-based systems
it's not so.
Post by Steffen
I've got a problem drawing GDI-generated graphics into a window device
context; when the corresponding window is moved with the mouse, the output
sometimes is drawn at incorrect locations, causing "smearing" and broken
shapes. It seems as if the origin of the DC is not synchronized with the
(moving) window surface.
1. The drawing occurs in an MDI child window.
2. The operating system is Windows 7. Flavor doesn't matter. Desktop
theme/composition doesn't matter. IAW: The problem also occurs in
the "Basic" theme!
3. The drawing is performed by a separate thread, aka a thread different
from the one which called CreateWindow().
Note that the corresponding code ran fine all the way through from Windows
9x ;-).
The drawing code is pretty simple (and could probably be reduced even
(Pseude Code, runs in separate thread)
hDC = GetDC(...)
for x:=0 to 100
MoveToEx( hDC, x, 50, NULL )
LineTo( hDC, x, 150 )
next
ReleaseDC( ... )
A sample can be easily provided.
I probably should have posted this to a Windows 7-related forum. I couldn't
find one, though.
Does anyone have an idea what might be causing this?
Thanks,
Steffen
n***@rtrussell.co.uk
2010-01-06 17:22:17 UTC
Permalink
Post by Alexander Grigoriev
3. That's your mistake. Do it in the windows creator thread. You don't gain
anything by doing it in a separate thread.
The way I deal with this is that all drawing is done in a separate
thread *but* to a memory DC. The memory DC is BitBlt'ed to the
window's DC in the WndProc thread (WM_PAINT). That way I don't get
any anomalies, although it is essential to protect the memory DC with
a Critical Section to prevent concurrent access from the drawing
thread and the WndProc thread.

Maybe the OP can use a similar approach.

Richard.
http://www.rtrussell.co.uk/
To reply by email change 'news' to my forename.
Alexander Grigoriev
2010-01-07 03:15:03 UTC
Permalink
That would work, too.
Post by Alexander Grigoriev
3. That's your mistake. Do it in the windows creator thread. You don't gain
anything by doing it in a separate thread.
The way I deal with this is that all drawing is done in a separate
thread *but* to a memory DC. The memory DC is BitBlt'ed to the
window's DC in the WndProc thread (WM_PAINT). That way I don't get
any anomalies, although it is essential to protect the memory DC with
a Critical Section to prevent concurrent access from the drawing
thread and the WndProc thread.

Maybe the OP can use a similar approach.

Richard.
http://www.rtrussell.co.uk/
To reply by email change 'news' to my forename.
Steffen
2010-01-13 15:44:01 UTC
Permalink
Hi Richard,

Thank you for responding.

What kind of anomalies are you referring to? I'm aware I might need
to synchronize my threads to prevent their respective output from
overwriting each other. However, I'd still expect the OS to properly
align the page origin with the drawing surface (device). Like it did
prior to Windows 7.

Why should this code not be safe?

hdc = GetDC(...)
MoveToEx(hdc, )
LineTo(hdc, )
ReleaseDC( , hdc )

If the coordinates used were the same for all threads, would you
expect problems with this code? If so, why?

Regards,
Steffen
Post by n***@rtrussell.co.uk
Post by Alexander Grigoriev
3. That's your mistake. Do it in the windows creator thread. You don't gain
anything by doing it in a separate thread.
The way I deal with this is that all drawing is done in a separate
thread *but* to a memory DC. The memory DC is BitBlt'ed to the
window's DC in the WndProc thread (WM_PAINT). That way I don't get
any anomalies, although it is essential to protect the memory DC with
a Critical Section to prevent concurrent access from the drawing
thread and the WndProc thread.
Maybe the OP can use a similar approach.
Richard.
http://www.rtrussell.co.uk/
To reply by email change 'news' to my forename.
.
n***@rtrussell.co.uk
2010-01-13 17:23:58 UTC
Permalink
Post by Steffen
However, I'd still expect the OS to properly
align the page origin with the drawing surface (device). Like it did
prior to Windows 7.
Your expectation is reasonable, but if Windows 7 behaves differently
there's probably not a lot you can do about it. Have you tried
setting the CS_OWNDC style when you register your window class? It
may not make a difference, but it's worth a try.

Richard.
http://www.rtrussell.co.uk/
To reply by email change 'news' to my forename.
Steffen
2010-01-11 16:35:01 UTC
Permalink
Hello Alexander,

Thanks for your answer.

However, I'm not sure where I'm going wrong? The docs. state that a DC handle
can be used in another thread as long as the same thread does the
allocation/deallocation of the DC. Therefore, isn't it the responsibility of
the OS
to ensure the DC origin is correctly lined up with the (physical) drawing
surface?

Please note that the corresponding code ran fine on *all* versions of
Windows.
Up to 7.

Cheers,
Steffen.
Post by Alexander Grigoriev
3. That's your mistake. Do it in the windows creator thread. You don't gain
anything by doing it in a separate thread.
Windows95 GUI was serialized through 16 bit subsystem. In NT-based systems
it's not so.
Post by Steffen
I've got a problem drawing GDI-generated graphics into a window device
context; when the corresponding window is moved with the mouse, the output
sometimes is drawn at incorrect locations, causing "smearing" and broken
shapes. It seems as if the origin of the DC is not synchronized with the
(moving) window surface.
1. The drawing occurs in an MDI child window.
2. The operating system is Windows 7. Flavor doesn't matter. Desktop
theme/composition doesn't matter. IAW: The problem also occurs in
the "Basic" theme!
3. The drawing is performed by a separate thread, aka a thread different
from the one which called CreateWindow().
Note that the corresponding code ran fine all the way through from Windows
9x ;-).
The drawing code is pretty simple (and could probably be reduced even
(Pseude Code, runs in separate thread)
hDC = GetDC(...)
for x:=0 to 100
MoveToEx( hDC, x, 50, NULL )
LineTo( hDC, x, 150 )
next
ReleaseDC( ... )
A sample can be easily provided.
I probably should have posted this to a Windows 7-related forum. I couldn't
find one, though.
Does anyone have an idea what might be causing this?
Thanks,
Steffen
.
Michael Hoffmann
2010-01-19 06:18:52 UTC
Permalink
Hello Steffen,

in the remarks section of GetDC you'll find:

--- snip ---

Note that the handle to the DC can only be used by a single thread at any
one time.

--- snap ---

Best regards,

Michael
Post by Steffen
Hello Alexander,
Thanks for your answer.
However, I'm not sure where I'm going wrong? The docs. state that a DC handle
can be used in another thread as long as the same thread does the
allocation/deallocation of the DC. Therefore, isn't it the responsibility of
the OS
to ensure the DC origin is correctly lined up with the (physical) drawing
surface?
Please note that the corresponding code ran fine on *all* versions of
Windows.
Up to 7.
Cheers,
Steffen.
Post by Alexander Grigoriev
3. That's your mistake. Do it in the windows creator thread. You don't gain
anything by doing it in a separate thread.
Windows95 GUI was serialized through 16 bit subsystem. In NT-based systems
it's not so.
Post by Steffen
I've got a problem drawing GDI-generated graphics into a window device
context; when the corresponding window is moved with the mouse, the output
sometimes is drawn at incorrect locations, causing "smearing" and broken
shapes. It seems as if the origin of the DC is not synchronized with the
(moving) window surface.
1. The drawing occurs in an MDI child window.
2. The operating system is Windows 7. Flavor doesn't matter. Desktop
theme/composition doesn't matter. IAW: The problem also occurs in
the "Basic" theme!
3. The drawing is performed by a separate thread, aka a thread different
from the one which called CreateWindow().
Note that the corresponding code ran fine all the way through from Windows
9x ;-).
The drawing code is pretty simple (and could probably be reduced even
(Pseude Code, runs in separate thread)
hDC = GetDC(...)
for x:=0 to 100
MoveToEx( hDC, x, 50, NULL )
LineTo( hDC, x, 150 )
next
ReleaseDC( ... )
A sample can be easily provided.
I probably should have posted this to a Windows 7-related forum. I couldn't
find one, though.
Does anyone have an idea what might be causing this?
Thanks,
Steffen
.
Loading...