newbie question on drawing

B

Ben Taylor

Hi all,
Could somebody please please please take pity on me and
have a look at what I am doing and see where I am going
wrong? This problem has been driving me up the wall for
days.

I am trying to create a windowless ActiveX control which
performs animation using a separate thread. I've got it to
work in windowed mode, I just create a device context in
the thread function using the line:
CClientDC dc(thisctrl)
where thisctrl is the same as 'this' in the OnDraw
function, just passed over in a structure, i.e. a pointer
to the control's main class which is derived from
COleControl.

It NEARLY works in windowless mode, the goal I am
desparately trying to achieve. I change the
GetControlFlags to return COleControl::GetControlFlags |
windowlessActivate, all well and good, and it appears in
test container without its own window.
The problem that then occurs is with using the device
context in the thread. When I use the above, CClientDC dc
(thisctrl) (after packaging 'this' in OnDraw and receiving
it as thisctrl in the thread, as before) it does the
animation, but not where it should! It's outside of its
site, and sometimes even outside of the ActiveX control
test container! So I knew that couldn't be right. So I
changed it to use
CDC * screendc = thisctrl->GetDC(boundary)
where boundary is the rectangle that is the same as
rcBounds, as I put this into the threadparams structure.
However when I try to run this it comes up with Unhandled
Exception in TSTCON32.EXE - 0xC0000005 access violation.
When I click retry on the exception boxIt then goes into
disassembly, and I press Ctrl+F11 to try to step out, and
it says 'this function has no return address' at the
bottom, so I have to stop debugging and am left none the
wiser. So that's obviously wrong aswell, it's obviously
accessing memory it's not supposed to in some way or
accessing an object that's been deleted, but I'm not
expert enough to know where and how to remedy it. Would
somebody mind having a look at my code please and tell me
anything that's glaringly obviously or even minorly wrong?
I've omitted all the irrelevant bits for readability, if I
haven't posted enough information please get back to me.

void CBallAnimationCtrl::OnDraw(CDC * pdc, CRect&
rcBounds,

const CRect &rcInvalid)
{
m_threadcont = 0;//flag to tell the threads to stop
//wait till all threads have stopped:
for(int=1,i<NUMANIMATIONS;i++) m_semaphore.Lock();

m_dccs.Lock()//critical section to protect the screen dc
int oldmapmode = pdc->SetMapMode(MM_TEXt);

//..(select some brushes/pens into pdc
//...and do some drawing, selecting the old
//...one in again afterwards)
m_dccs.Unlock();


for(i=0; i<NUMANIMATIONS; i++)
{
m_threadcont = 1;
THREADSTARTPARAMS * tsp = new THREADSTARTPARAMS;
tsp->thisctrl = this;
tsp->boundary = rcBounds; //set the boundary!
//..THREADSTARTPARAMS contains various other
//specific data but these are only longs
//and CPoints for telling it where to draw,
//these take into account rcBounds.left and .top
//aswell as rcBounds.Width() and rcBounds.Height()
AfxBeginThread(CBallAnimationCtrl::AnimationStart, tsp);
}

m_dccs.Lock();
pdc->SetMapMode(oldmapmode);
m_dccs.Unlock();
m_semaphore.Unlock(NUMANIMATIONS) //this sets the threads
off

}


UINT CBallAnimationCtrl::AnimationStart(LPVOID pParam)
{
//(this function is a static member function of the
//control's main class)

THREADSTARTPARAMS * recd = (THREADSTARTPARAMS *)pParam;
CBallAnimationCtrl * thisctrl =
(CBallAnimationCtrl *)recd->thisctrl;

CRect boundary = recd->boundary;

m_dccs.Lock() //protect the screen dc
CDC * screendc = thisctrl->GetDC(boundary); //retrieve
bndry

int oldmapmode = screendc->SetMapMode(MM_TEXT);

for(;m_threadcont;)
{
{
m_dccs.Lock();
screendc->SelectObject( ...[a brush to erase] ...)
screendc->Ellipse(...[a rectangle within boundary]...)
screendc->SelectObject(...[a brush to draw new pos]...)
screendc->Ellipse(...[a rectangle slightly further
on]...)
m_dccs.Unlock();
}
Sleep(20);
}

m_dccs.Lock();
screendc->SelectObject(...[the old brush]...);
screendc->SetMapMode(oldmapmode);
m_dccs.Unlock();
m_semaphore.Unlock();//let OnDraw continue again
return 0; //thus ending the thread
}
 

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

Similar Threads


Top