Click to See Complete Forum and Search --> : Global HDC?


MrDoomMaster
March 4th, 2005, 12:06 PM
Is there a way to be able to write to a client rect from anywhere in my application? I'm guessing create a global memory DC?

How would I create this and write to it? I basically ask because I need a way to display text to the HDC from a different function

Can I get some small example code?

ejmw
March 4th, 2005, 12:36 PM
It sounds like you might be best off looking into a singleton class that can manage the lifetime of the hDC.

Header: class CMyDCHolder
{
public:
static CMyDCHolder& Instance(void) {return(m_Inst);}

void InitializeDC(void);
HDC GetDC(void);
void DestroyDC(void);

protected:
HDC m_hDC;
bool m_bInitialized;

CMyDCHolder();
CMyDCHolder(const CMyDCHolder&){}

static CMyDCHolder m_Inst;
}; implementation: CMyDCHolder CMyDCHolder::m_Inst;

CMyDCHolder::CMyDCHolder()
{
m_bInitialized = false;
m_hDC = NULL;
}

void CMyDCHolder::InitializeDC(void)
{
//initialize m_hDC
//set m_bInitialized to true
}

HDC CMyDCHolder::GetDC(void)
{
ASSERT(m_bInitialized);
return(m_hDC);
}

void CMyDCHolder::DestroyDC(void)
{
//DC cleanup
//set m_bInitialized to false
}Access functions like this: CMyDCHolder::Instance().InitializeDC();
HDC hDC = CMyDCHolder::Instance().GetDC();
CMyDCHolder::Instance().DestroyDC();

MrViggy
March 4th, 2005, 12:38 PM
Well, if you have the handle to the window you want to draw on, just use "HDC GetDC(HWND)".

You need some kind of window handle in order to get a DC, otherwise, where are you going to draw? ;) Actually, I believe if you pass NULL for the HWND param, you get the DC for the desktop (and can draw anywhere you like!).

Viggy

ejmw
March 4th, 2005, 12:41 PM
Well, if you have the handle to the window you want to draw on, just use "HDC GetDC(HWND)".Well, he could also be drawing to a memory DC or enhanced metafile :cool:

MrViggy
March 4th, 2005, 02:28 PM
Well, he could also be drawing to a memory DC or enhanced metafile :cool:
True. In that case, the memory DC needs to be "based" on the window that he intends to draw on.

Otherwise, the memory DC may not be compatible with the DC he bit blits to.

;)

Viggy

NoHero
March 4th, 2005, 02:31 PM
Well, he could also be drawing to a memory DC or enhanced metafile :cool:

Well, of course he can share it: global variable, singleton class there are many ways. Your solution is one (the better) solution.

The only thing you should know is:

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

@Mr Viggy: You are right:

Handle to the window whose DC is to be retrieved.If this value is NULL, GetDC retrieves the DC for the entire screen.

MrViggy
March 4th, 2005, 02:42 PM
I knew there was a reason that storing a DC (handle or CDC) was a bad thing. They are thread dependent (i.e can't access the same handle from two or more threads). Actually, I believe that this goes for any handle, not just DC's (any Windows resource handle).

Viggy

kirants
March 4th, 2005, 02:55 PM
They are thread dependent (i.e can't access the same handle from two or more threads). Actually, I believe that this goes for any handle, not just DC's (any Windows resource handle).


HWNDs aren't thread dependent. I am not sure about HDCs though. Haven't tried it..

NoHero
March 4th, 2005, 02:57 PM
I knew there was a reason that storing a DC (handle or CDC) was a bad thing. They are thread dependent (i.e can't access the same handle from two or more threads). Actually, I believe that this goes for any handle, not just DC's (any Windows resource handle).

Viggy

They are not local to the corresponding thread. This just means that is impossible that two threads open a DC and draw on it simultaneously. One has to "ReleaseDC" on it, otherwise the second one cannot draw it.

MrViggy
March 4th, 2005, 03:12 PM
They are not local to the corresponding thread. This just means that is impossible that two threads open a DC and draw on it simultaneously. One has to "ReleaseDC" on it, otherwise the second one cannot draw it.
Duh, right! I was thinking of MFC objects! :blush:

Viggy

NoHero
March 4th, 2005, 03:22 PM
And by the way: GDI objects are not thread local and not covered by the user address space. So you can easily modify GDI objects of another application from your application. The only problem, without a loop through the GDI object's table (from 0xFFFF to 0x4FFFFF) you won't find them.

MrViggy
March 4th, 2005, 03:35 PM
And by the way: GDI objects are not thread local and not covered by the user address space. So you can easily modify GDI objects of another application from your application. The only problem, without a loop through the GDI object's table (from 0xFFFF to 0x4FFFFF) you won't find them.
Right. There's only one display!

;)

Viggy

NoHero
March 4th, 2005, 03:47 PM
Right. There's only one display!

;)

Viggy

Well, that is incorrect. Sorry I have missed that too: If you are using CreateDesktop() you create a new desktop which has a new set of GDI objects. Only two applications that belongs to the same desktop can modify their GDI objects one another. But multiple displays does not provide that protection.

I shall not be so lazy in writing. :D

MrDoomMaster
March 4th, 2005, 06:22 PM
hmmm... so, how can I write to my DC from a separate thread?

I have 1 thread which simply does nothing but run my message loop, and another does the actual TextOut() on the HDC. I have created a window class, so my window is created with this class and all HDC's (memory and regular) are created/maintained/removed via this class.

It is a requirement of a lab of mine that I must create 40 windows, each with its own thread, and each thread must textout() to that specific window... this means the only possible way I can process messages is by having a 41th thread to run my message loop...

Also I notice my message loop not getting messages when I create windows from a separate thread..................... Multithreading is such a b***h lol