Re: trouble with CDC
On Tue, 13 Apr 2010 09:33:55 +0800, "Bill Brehm" <don't want spam> wrote:
Yes, I agree. I put it in as a test and to make some progress until I could
figure out what is going wrong. I dislike timer delays because unless you
guess perfectly, you are either wasting time or still facing the problem
that the delay is supposed to be hiding. That's why I asked if the pointer
that is return cannot be used immediately, how can I tell when it is safe to
use it?
The pointer can be used immediately unless there is some race condition
with code you're not showing. Actually, I don't know how reliable it is to
call GetDC on a window belonging to another process. It can be dicey even
between threads within the same process.
I also don't know what the error is. That's why I'm here looking for the
help of experts with lots of experience. What I know is what I mentioned
about certain pointers or handles being NULL. Running out of GDI resources
might be the cause and I will test for that. But it's seems unlikely to me
that GDI resources would be depleted after fewer calls (not after a shorter
time) with a 1 msec delay than with a 50 msec delay.
Sleep times are at best approximate. It might be more useful to count the
number of calls you're able to make before it fails, and you need to check
for errors so you know immediately when something fails.
The help says typically
that a function returns 0 if error and non zero if success. So 0 only tells
me there was an error but not what the error was. It also doesn't tell me to
call GetLastError so I assume it's not updated in this case.
FWIW, the help is only sometimes helpful. It's usually insufficient to read
only the MFC documentation concerning things that are documented by the SDK
as the primary source.
Okay, thanks. I'll try this. I'd rather not Detach and recreate all the time
if it's not necessary. But many MFC functions that return a pointer say that
the pointer is temporary and should not be saved for future use. So I try
getting a fresh one before I need to use it because I don't know such when a
pointer will become "stale". Could you please shed some light on that? When
do these temporary pointers become invalid? Is it a matter of memory being
swapped out and into a new address? Or control switching out of my thread
then coming back? Is the underlying bitmap or DC (in this example) stable
but only the MFC object might not have a stable connection to it (meaning I
should use the SDK level instead of MFC)?
The temporary MFC objects are deleted during idle-time processing, which is
part of the normal MFC message loop, though IIRC, it doesn't occur while a
dialog box is active. So as a rule of thumb, a temporary MFC object is
usable until the function that obtained it returns, or more correctly (and
dangerously), during the processing of the Windows message under which it
was obtained. The "Create" calls you're making create permanent objects,
which you can reuse to the extent that it makes any sense to reuse them.
The GetDC call may return a temporary object.
To add to what Joe said about the Detach vs. Delete, the CWnd::GetDC
documentation says:
"Unless the device context belongs to a window class, the ReleaseDC member
function must be called to release the context after painting."
That's something else you seem to be forgetting to do. You should call that
function, period. It's at worst unnecessary and harmless. You might want to
go to codeproject.com and look for classes that wrap all this in a more
modern way using the RAII technique. You can probably find one or two to
encapsulate everything you're doing in your function with a single
"SomeMemoryDcClass" variable. Or maybe your function should be a member of
that class named "Update" or something. The initialization and state of
objects of that class will be more complicated since the window you're
interested in belongs to another process and can potentially go away at any
time.
--
Doug Harrison
Visual C++ MVP