Click here to Skip to main content
15,884,917 members
Articles / Desktop Programming / MFC

Using Semaphores: Multithreaded Producer/Consumer

Rate me:
Please Sign up or sign in to vote.
4.98/5 (25 votes)
14 Jun 200115 min read 321.1K   3.1K   92  
An introduction to using Semaphores
// ThreadData.cpp : implementation file
//

#include "stdafx.h"
#include "queuetest.h"
#include "ThreadData.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CThreadData

CThreadDataBox::CThreadDataBox()
{
 horizontalExtent = 0;
}

CThreadDataBox::~CThreadDataBox()
{
}


BEGIN_MESSAGE_MAP(CThreadDataBox, CListBox)
	//{{AFX_MSG_MAP(CThreadDataBox)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CThreadDataBox message handlers

/****************************************************************************
*                            CThreadDataBox::isVisible
* Inputs:
*       int n: Position in list
* Result: BOOL
*       TRUE if visible
*	FALSE if hidden
* Notes: 
*       It is assumed that this is working on the last item in the list
*	so we are only concerned about it falling off the bottom
****************************************************************************/

BOOL CThreadDataBox::isVisible(int n, BOOL fully)
    {
     CRect item;
     CRect r;
     GetItemRect(n, &item);
     GetClientRect(&r);

     if(!fully && item.top < r.bottom)
	return TRUE;
     if(fully && item.bottom < r.bottom)
	return TRUE;
     
     return FALSE;
    }

/****************************************************************************
*                            CThreadDataBox::AddString
* Inputs:
*       LPCTSTR s: String to add
* Result: int
*       Place where event was added
* Effect: 
*       If the last item in the box was visible before the add, and is not
*	visible after the add, scroll the box up
****************************************************************************/

int CThreadDataBox::AddString(LPCTSTR event)
    {
     // During shutdown transient, the window may actually be gone
     if(!::IsWindow(m_hWnd))
        { /* gone */
	 return LB_ERR;
	} /* gone */

     // We want to auto-scroll the list box if the last line is showing,
     // even if partially

     int count = GetCount();

     BOOL visible = FALSE;
     CRect r;
     if(count > 0)
        { /* nonempty */
	 visible = isVisible(count - 1, FALSE); // any part showing?
	} /* nonempty */
     else
	visible = TRUE;

     // Add the element to the list box

     int n = CListBox::AddString((LPCTSTR) event);      

     // If the last line had been visible, and the just-added line is
     // not visible, scroll the list box up to make it visible.

     // Note: This depends on the box being LBS_OWNERDRAWFIXED.  The
     // computation for variable is much more complex!
     if(visible)
        { /* was visible */
	 visible = isVisible(n, TRUE); // all of it showing?
	 if(!visible)
	    { /* dropped off */
	     int top = GetTopIndex();
	     if(top + 1 >= GetCount())
	        { /* can't scroll */
		} /* can't scroll */
	     else
	        { /* scroll it */
		 SetTopIndex(top + 1);
		} /* dropped off */
	    } /* dropped off */
	} /* was visible */

     // Get the width and compute the scroll width
     // Optimization: if the current width is less than the current
     // maximum, we don't need to do anything

     CClientDC dc(this);
     CString s;
     GetText(n, s);
     UINT w = dc.GetTextExtent(s, s.GetLength()).cx;
     if(w > horizontalExtent)
	{ /* recompute */
	 horizontalExtent = w;
	 SetHorizontalExtent(horizontalExtent);
	} /* recompute */
     return n;
    }

/****************************************************************************
*                          CThreadDataBox::ResetContent
* Result: void
*       
* Effect: 
*       Resets the listbox content
****************************************************************************/

void CThreadDataBox::ResetContent()
   {
    horizontalExtent = 0; 
    CListBox::ResetContent();
   } // CThreadDataBox::ResetContent

/****************************************************************************
*                    CThreadDataBox::recomputeHorizontalExtent
* Result: void
*       
* Effect: 
*       Recomputes the horizontal extent
****************************************************************************/

void CThreadDataBox::recomputeHorizontalExtent()
    {
     horizontalExtent = 0;
     CClientDC dc(this);
     for(int i = 0; i < CListBox::GetCount(); i++)
	{ /* scan */
	 CString s;
	 GetText(i, s);
	 UINT w = dc.GetTextExtent(s).cx;
	 if(w > horizontalExtent)
	    horizontalExtent = w;
	} /* scan */
     SetHorizontalExtent(horizontalExtent);
    } // CThreadDataBox::recomputeHorizontalExtent

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


Written By
Retired
United States United States
PhD, Computer Science, Carnegie Mellon University, 1975
Certificate in Forensic Science and the Law, Duquesne University, 2008

Co-Author, [i]Win32 Programming[/i]

Comments and Discussions