CDC pointers - will someone know this?

B

Ben Taylor

Hi,
I am writing a program that uses different threads to handle various
painting operations, I wondered if somebody could possible tell me if I
create a new thread using AfxBeginThread(ThreadFunc, &threadparams, ... and
then the various options to create it suspended, and then have it resume.
What I want to know is, can the threadparams structure include a CDC * that
enables the thread to draw to the window, as long as I use a (single)
critical section inside threadparams aswell to make sure that no two threads
draw to the CDC at once??? If not how can I accomplish the same end? If they
can't access the same dc is there any way of making the starting function
for the thread a class member function of the dialog window class, that way
the thread function could create its own DC using the CClientDC dc(this)
statement - I thought threads had to start on global functions but I'm not
so sure if this might be standard practice or not. I understand how new
threads being kicked off works and how critical sections work but I don't
want to go down the line of designing my program on the assumption that
different threads can modify the same CDC * or whether this will assert or
throw an exception when I have carefully designed what I think to be a good
algorithm, or is this the way to go?

Thus, enabling me to produce multiple animations on the window. The thread
that is doing the animation is going to be doing a loop with, say, a
Sleep(20) in it and then some code to erase the moving object from its old
position and redraw it in its new position. BTW the CDC would almost
definitely be a CClientDC rather than a CPaintDC, because CPaintDCs have a
special action in their destructor don't they that needs to be done?
 
S

Scott McPhillips

Ben said:
Hi,
I am writing a program that uses different threads to handle various
painting operations, I wondered if somebody could possible tell me if I
create a new thread using AfxBeginThread(ThreadFunc, &threadparams, ... and
then the various options to create it suspended, and then have it resume.
What I want to know is, can the threadparams structure include a CDC * that
enables the thread to draw to the window, as long as I use a (single)
critical section inside threadparams aswell to make sure that no two threads
draw to the CDC at once??? If not how can I accomplish the same end? If they
can't access the same dc is there any way of making the starting function
for the thread a class member function of the dialog window class, that way
the thread function could create its own DC using the CClientDC dc(this)
statement - I thought threads had to start on global functions but I'm not
so sure if this might be standard practice or not. I understand how new
threads being kicked off works and how critical sections work but I don't
want to go down the line of designing my program on the assumption that
different threads can modify the same CDC * or whether this will assert or
throw an exception when I have carefully designed what I think to be a good
algorithm, or is this the way to go?

Thus, enabling me to produce multiple animations on the window. The thread
that is doing the animation is going to be doing a loop with, say, a
Sleep(20) in it and then some code to erase the moving object from its old
position and redraw it in its new position. BTW the CDC would almost
definitely be a CClientDC rather than a CPaintDC, because CPaintDCs have a
special action in their destructor don't they that needs to be done?

MFC has large restrictions on passing objects to another thread. For
guidance on painting from multiple threads study the MTGDI MFC sample
code. For the most part it bypasses MFC to use the thread-safe Win32
API.

To run a worker thread in a member function pass 'this' as the thread
parameter to a static member function. Then the static member function
can cast the parameter and call a nonstatic member function:

UINT Cxx::StaticThreadFunc(LPVOID pParam)
{ // from C to shining C++
return ((Cxx*)pParam)->NonstaticThreadFunc();
}
 
B

Ben Taylor

Nice! Thanks Scott, just a couple more questions if I may -
With your code such as
UINT Cxx::StaticThreadFunc(LPVOID pParam)
{ // from C to shining C++
return ((Cxx*)pParam)->NonstaticThreadFunc();
}


Would I kick it off by using
AfxBeginThread(StaticThreadFunc, &this, ...)
or
AfxBeginThread(Cxx::StaticThreadFunc, &this, ...)
or
AfxBeginThread(this.StaticThreadFunc, &this, ...)
or something else? I'd rather use AfxBeginThread if
possible as that's what I've got to grips with.

and (presuming 'this' is a pointer to a CFrameWnd)
presumably I would get the DC via something like
CFrameWnd * MyWindowInThread = (CFrameWnd *)pParam
CClientDC ThreadDC(MyWindowInThread)

Also, I may be pushing it here but can I include
the 'this' pointer inside an applicaiton-defined
structure, like
typdef struct tagTHREADPARAMS {
CFrameWnd * pWindow
CCriticalSection * pProtector
long xstartpos ...etc
}
If so, would it know to call the member function of the
class and not expect to be passed a global callback
function?

(and why the 'tag' prefix that is used in books when it
seems to use just the THREADPARAMS name?)

Also what is the difference between a static member
function and a non-static member function?

Thanks very much for the advice
Cheers
Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top