Brief Full Advanced Search Search Tips
|  |  | To access the contents, click the chapter and section titles. Fast Track Visual C++ 6.0 Programming (Publisher: John Wiley & Sons, Inc.) Author(s): Steve Holzner ISBN: 0471312908 Publication Date: 09/01/98 Search this book:
Previous | Table of Contents | Next
Our program is complete. Run it now, as shown in Figure 9.2, and select the “Find max and min” item in the File menu. This launches the two threads, MaxThread and MinThread. MaxThread finds the maximum of the array and sets the event that MinThread waits for. MinThread then continues and finds the minimum of the array. The result appears in the view, as shown in Figure 9.2. Now we’re coordinating multiple threads, which is an important part of true multitasking. The code for this example, DoubleThreadsView.h and DoubleThreadsView.cpp, appears in Listing 9.2. Listing 9.2 DoubleThreadsView.h and DoubleThreadsView.cpp
    // DoubleThreadsView.h : interface of the CDoubleThreadsView class
    //
    /////////////////////////////////////////////////////////////////////////////

    #if !defined(AFX_DOUBLETHREADSVIEW_H__A880E565_A6EB_11D1_887F_D42B07C10710__INCLUDED_)
    #define AFX_DOUBLETHREADSVIEW_H__A880E565_A6EB_11D1_887F_D42B07C10710__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000

    UINT MaxThreadProcedure(LPVOID pParam);
    UINT MinThreadProcedure(LPVOID pParam);

    struct SData
    {
        int array[5];
        int max;
        int min;
        HANDLE flag;
        HWND NotifyWindow;
    };

    class CDoubleThreadsView : public CView
    {
    protected: // create from serialization only
        CDoubleThreadsView();
        DECLARE_DYNCREATE(CDoubleThreadsView)

    // Attributes
    public:
        CDoubleThreadsDoc* GetDocument();
        SData data;
        CWinThread* MaxThread;
        void OnMaxFound(WPARAM wParam, LPARAM lParam);
        CWinThread* MinThread;
        void OnMinFound(WPARAM wParam, LPARAM lParam);

    // Operations
    public:

    // Overrides

        // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CDoubleThreadsView)
        public:
        virtual void OnDraw(CDC* pDC);  // overridden to draw this view
        virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
        protected:
        virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
        virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
        virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
        //}}AFX_VIRTUAL

    // Implementation
    public:
        virtual ~CDoubleThreadsView();
    #ifdef _DEBUG
        virtual void AssertValid() const;
        virtual void Dump(CDumpContext& dc) const;
    #endif

    protected:

    // Generated message map functions
    protected:
        //{{AFX_MSG(CDoubleThreadsView)
        afx_msg void OnFileFindmaxandmin();
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
    };

    #ifndef _DEBUG  // debug version in DoubleThreadsView.cpp
    inline CDoubleThreadsDoc* CDoubleThreadsView::GetDocument()
       { return (CDoubleThreadsDoc*)m_pDocument; }
    #endif

    /////////////////////////////////////////////////////////////////////////////

    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately
    before the previous line.

    #endif //!defined(AFX_DOUBLETHREADSVIEW_H__A880E565_A6EB_11D1_887F_D42B07C10710__INCLUDED_)

    // DoubleThreadsView.cpp : implementation of the CDoubleThreadsView class
    //

    #include “stdafx.h”
    #include “DoubleThreads.h”

    #include “DoubleThreadsDoc.h”
    #include “DoubleThreadsView.h”

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

    /////////////////////////////////////////////////////////////////////////////
    // CDoubleThreadsView

    IMPLEMENT_DYNCREATE(CDoubleThreadsView, CView)

    BEGIN_MESSAGE_MAP(CDoubleThreadsView, CView)
        //{{AFX_MSG_MAP(CDoubleThreadsView)
        ON_COMMAND(ID_FILE_FINDMAXANDMIN, OnFileFindmaxandmin)
        ON_MESSAGE(WM_MAX, OnMaxFound)
        ON_MESSAGE(WM_MIN, OnMinFound)
        //}}AFX_MSG_MAP
        // Standard printing commands
        ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
        ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
        ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
    END_MESSAGE_MAP()

    /////////////////////////////////////////////////////////////////////////////
    // CDoubleThreadsView construction/destruction

    CDoubleThreadsView::CDoubleThreadsView()
    {
        data.flag = CreateEvent(NULL, FALSE, FALSE, NULL);
    }

    CDoubleThreadsView::~CDoubleThreadsView()
    {
    }

    BOOL CDoubleThreadsView::PreCreateWindow(CREATESTRUCT& cs)
    {
        // TODO: Modify the Window class or styles here by modifying
        //  the CREATESTRUCT cs

        return CView::PreCreateWindow(cs);
    }

    /////////////////////////////////////////////////////////////////////////////
    // CDoubleThreadsView drawing

    void CDoubleThreadsView::OnDraw(CDC* pDC)
    {
        CDoubleThreadsDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);

        pDC->TextOut(0, 0, pDoc->text);
    }

    /////////////////////////////////////////////////////////////////////////////
    // CDoubleThreadsView printing

    BOOL CDoubleThreadsView::OnPreparePrinting(CPrintInfo* pInfo)
    {
        // default preparation
        return DoPreparePrinting(pInfo);
    }

    void CDoubleThreadsView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
        // TODO: add extra initialization before printing

    }

    void CDoubleThreadsView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
        // TODO: add cleanup after printing
    }

    /////////////////////////////////////////////////////////////////////////////
    // CDoubleThreadsView diagnostics

    #ifdef _DEBUG
    void CDoubleThreadsView::AssertValid() const
    {
        CView::AssertValid();
    }

    void CDoubleThreadsView::Dump(CDumpContext& dc) const
    {
        CView::Dump(dc);
    }

    CDoubleThreadsDoc* CDoubleThreadsView::GetDocument() // non-debug version is inline
    {
        ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDoubleThreadsDoc)));
        return (CDoubleThreadsDoc*)m_pDocument;
    }
    #endif //_DEBUG

    /////////////////////////////////////////////////////////////////////////////
    // CDoubleThreadsView message handlers

    void CDoubleThreadsView::OnFileFindmaxandmin()
    {
        // TODO: Add your command handler code here
        data.array[0] = 0;
        data.array[1] = 1;
        data.array[2] = 2;
        data.array[3] = 3;
        data.array[4] = 4;

        data.max = 0;

        data.NotifyWindow = m_hWnd;
        MaxThread = AfxBeginThread(MaxThreadProcedure, &data);
        ResetEvent(data.flag);

        MinThread = AfxBeginThread(MinThreadProcedure, &data);

    }

    UINT MaxThreadProcedure(LPVOID pParam)
    {
        SData* pData = (SData*)pParam;

        for(int loop_index = 0; loop_index <= 4; loop_index++){
            if(pData->array[loop_index] > pData->max)
                pData->max = pData->array[loop_index];
        }

        ::PostMessage(pData->NotifyWindow, WM_MAX, 0, 0);

        SetEvent(pData->flag);
        return 0;
    }

    UINT MinThreadProcedure(LPVOID pParam)
    {
        SData* pData = (SData*)pParam;

        WaitForSingleObject(pData->flag, INFINITE);

        pData->min = pData->max;

        for(int loop_index = 0; loop_index <= 4; loop_index++){
            if(pData->array[loop_index] < pData->min)
                pData->min = pData->array[loop_index];
        }

        ::PostMessage(pData->NotifyWindow, WM_MIN, 0, 0);

        return 0;
    }

    void CDoubleThreadsView::OnMaxFound(WPARAM wParam, LPARAM lParam)
    {
        CDoubleThreadsDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);

        char FormattedString[100];
        wsprintf(FormattedString, “Maximum value in array = %d, ”, data.max);
        pDoc->text = FormattedString;

        TerminateThread(MaxThread, 0);

        Invalidate();
    }

    void CDoubleThreadsView::OnMinFound(WPARAM wParam, LPARAM lParam)
    {
        CDoubleThreadsDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);

        char FormattedString[100];
        wsprintf(FormattedString, “minimum value in array = %d ”, data.min);
        pDoc->text += FormattedString;

        TerminateThread(MinThread, 0);

        Invalidate();
    }
### What’s Ahead In the next chapter, we begin exploring an exceptionally powerful aspect of working with Windows: Dynamic Link Libraries (DLLs). Just about all Windows users have seen DLLs, and in the next chapter, we see how they can be useful to us and how to create them.
Previous | Table of Contents | Next

| Products | Contact Us | About Us | Privacy | Ad Info | Home Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.