Date: | October 11, 2005 / year-entry #300 |
Tags: | code |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20051011-10/?p=33823 |
Comments: | 9 |
Summary: | Last time, we discussed briefly the thread affinity rules that govern window handles. Device contexts (DCs) also have a certain degree of thread affinity. The thread that calls functions such as GetDC must also be the one that calls ReleaseDC, but as with window handles, during the lifetime of the DC, any thread can use... |
Last time, we discussed briefly the thread affinity rules that govern window handles. Device contexts (DCs) also have a certain degree of thread affinity. The thread that calls functions such as The thread affinity of DCs is much more subtle than that of window handles, because if you mess up and release a DC from the wrong thread, things will still seem to be running okay, but the window manager's internal bookkeeping will be messed up and you may get a bad DC from GetDC a little later down the line. Next time, the remaining user interface elements. |
Comments (9)
Comments are closed. |
"the consumers of that device context"
I have done many things with a DC, some even stupid, but I don’t think I’ve ever consumed one. Is there some undocumented GdiEntry4711BonApetit(HDC) added now to do this? :-)
Perhaps… "use" is more descriptive?
"Consumes" implies to me that you have just depleted the supply of something. So I guess you could say that creating a DC "consumes" a device handle. But I can’t see how /using/ that handle would deplete anything, except opaque resources "behind the scenes".
> The thread that calls functions such as
> GetDC must also be the one that calls
> ReleaseDC,
Sorry to multicontext this thread, but I tried to figure out how to figure out whether it’s necessary to call ReleaseDC in the first place, and I couldn’t figure it out.
MSDN page
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_CWnd.3a3a.GetDC.asp
says:
> Unless the device context belongs to a
> window class, the ReleaseDC member function
> must be called to release the context after
> painting.
So some CWnd objects have device contexts that belong to window classes and some CWnd objects have device contexts that don’t belong to window classes? How can I figure out which CWnd objects[*] are really CWnd and which are really CNonWnd?
The same MSDN page answers Mike and TC:
> Since only five common device contexts are
> available at any given time, failure to
> release a device context can prevent other
> applications from accessing a device context.
It makes me wonder though. If I’m using a terminal server and suddenly can’t see my screen, should I whack some of my neighbours until at most four of them remain?
[* Of course this usually involves subclasses of CWnd, i.e. derived and more specialized types.]
So… you have to free the DC from the same thread that allocated it, and also the system sort-of-crashes when you free the DC from the wrong thread.
Now I know this is over-simplistic but is it too much fuzz to add a "creator thread" to the DC and then just plainly refuse to free if it doesn’t match? Or else, at least tell us all the gory details about why it isn’t done ;)
ps. Your earlier article about double ctrl-alt-del already saved a friend of mine who just added a new user to his XP system and lost the admin option, so… thanks!!!
Answering "why it isn’t done" is a topic too large for a comment. It goes to philosophical issues that controlled API design in the 1980’s. More coming later this month.
Wednesday, October 12, 2005 11:18 AM by SJ
> when working with windows created of a class
> with CS_OWNDC you don’t need to call
> ReleaseDC().
OK, and I can tell an object of an MFC class derived from CWnd to tell me what its Windows style is. Thank you.
> I think it’s harmless to call ReleaseDC()
> even on the DC from windows of a CS_OWNDC
> class, so best to always call it (correct me
> if I’m wrong someone).
Even better news. Although it looks like you were guessing, Mr. Chen posted later and he didn’t correct you, so it looks like you’re right. Thank you.
Now if that MSDN page would be revised to say that it’s always safe to call ReleaseDC() even in cases where the MSDN reader doesn’t know how to figure out whether it’s necessary…
"he didn’t correct you, so it looks like you’re right"
Do not assume my silence implies consent. Do you expect me to fact-check every single statement made in a comment? If you do, then I’ll just disable comments.
Thursday, October 13, 2005 1:56 AM by oldnewthing
> Do not assume my silence implies consent.
OK, I understand not to assume.
> Do you expect me to fact-check every single
> statement made in a comment?
"Expect" as in "I think you’re supposed to do it"? No. "Expect" as in "I see you do it frequently"? Well yes…
> If you do, then I’ll just disable comments.
You know how much MSDN benefits from that policy. (Yes I know MSDN is older and no one had the idea of blog-style or wiki-style posting of corrections, and that isn’t MSDN’s fault. Nonetheless you know MSDN’s quality problems and you know how much better it is to allow corrections and discussions.)