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
#### Setting Up the New Windows Message To set up the constant WM_MAX, we define it in the overall header file for the project, Threads.h. This new constant is used as a Windows message, but we don’t want to conflict with other Windows messages that the view object may handle in some other way. Visual C++ defines a constant, WM_USER, as the lowest Windows message available for us to use without conflicting with other Windows messages, so we set up WM_MAX as that value plus 1.
    // Threads.h : main header file for the THREADS application
    //

    #if !defined(AFX_THREADS_H__A880E545_A6EB_11D1_887F_D42B07C10710__INCLUDED_)
    #define AFX_THREADS_H__A880E545_A6EB_11D1_887F_D42B07C10710__INCLUDED_

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

    #ifndef __AFXWIN_H__
        #error include ‘stdafx.h’ before including this file for PCH
    #endif

    #include “resource.h”       // main symbols

    #define WM_MAX (WM_USER + 1)                                    ⇐
        .
        .

        .
Now we connect a function, OnMaxFound(), to WM_MAX so the view can call that function when it gets the WM_MAX message. First, we declare that function. Like all Windows message-handling functions, it is passed two parameters, wParam (a word-length parameter) and lParam (a long parameter, usually a pointer), but because we made both of those 0, we ignore them.
    class CThreadsView : public CView
     {
    protected: // create from serialization only
        CThreadsView();
        DECLARE_DYNCREATE(CThreadsView)

    // Attributes
    public:
        CThreadsDoc* GetDocument();
        SData data;
        CWinThread* Thread;
        void OnMaxFound(WPARAM wParam, LPARAM lParam);                  ⇐
    Next, we connect WM_MAX to OnMaxFound() with a macro in the message map
    section of our view‘s class (which ClassWizard usually maintains):
    /////////////////////////////////////////////////////////////////////////////
    // CThreadsView

    IMPLEMENT_DYNCREATE(CThreadsView, CView)

    BEGIN_MESSAGE_MAP(CThreadsView, CView)
        //{{AFX_MSG_MAP(CThreadsView)
        ON_COMMAND(ID_FILE_FINDMAX, OnFileFindmax)
        ON_MESSAGE(WM_MAX, OnMaxFound)                                  ⇐
        //}}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()
The only thing left to do is to write OnMaxFound() to interpret the results of the thread’s work. #### Reporting the Thread’s Results When OnMaxFound() is called, the new thread has already notified the view that it has completed its task and has sent the WM_MAX message. That means that the maximum value in the array is in the max element in the data structure, and all we need to do is to display that result in the view. Add CThreadsView::OnMaxFound() to the view class now.
    void CThreadsView::OnMaxFound(WPARAM wParam, LPARAM lParam)
     {

    }
The maximum value in the array is in the data structure’s max element, which we reach as data.max. We place that value, along with the message “Max of the array = ”, into a character string named FormattedString.
    void CThreadsView::OnMaxFound(WPARAM wParam, LPARAM lParam)
     {
        char FormattedString[100];                                      ⇐
        wsprintf(FormattedString, “Max of the array = %d”, data.max);      ⇐
          .
          .
          .

    }
We also set up a CString object in the document named text and put the formatted text string into that object.
    void CThreadsView::OnMaxFound(WPARAM wParam, LPARAM lParam)
     {
        CThreadsDoc* pDoc = GetDocument();                              ⇐
        ASSERT_VALID(pDoc);                                             ⇐

        char FormattedString[100];
        wsprintf(FormattedString, “Max of the array = %d”, data.max);
        pDoc->text = FormattedString;                                 ⇐
          .
          .
          .

    }
Finally, we terminate the new thread with TerminateThread(), passing the pointer to the thread object, Thread, and an exit code of 0 as well as invalidating the view to display our result.
    void CThreadsView::OnMaxFound(WPARAM wParam, LPARAM lParam)
     {
        CThreadsDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);

        char FormattedString[100];
        wsprintf(FormattedString, “Max of the array = %d”, data.max);
        pDoc->text = FormattedString;

        TerminateThread(Thread, 0);                                     ⇐

        Invalidate();                                                   ⇐
    }
Figure 9.1 Using the onMouseOut event. In the view’s OnDraw(), we simply display the CString named text that holds our result in the view.
    void CThreadsView::OnDraw(CDC* pDC)
     {
        CThreadsDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);

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

    }
Run the program now and select the Find max item in the File menu. This launches the new thread, which finds the maximum value in the array and sends the Windows message to the view. The result appears in Figure 9.1. Now we’ve created our first multitasking program with Visual C++. The code for this example, ThreadsView.h and ThreadsView.cpp, appears in Listing 9.1. Listing 9.1 ThreadsView.h and ThreadsView.cpp
    // ThreadsView.h : interface of the CThreadsView class
    //
    /////////////////////////////////////////////////////////////////////////////

    #if !defined(AFX_THREADSVIEW_H__A880E54F_A6EB_11D1_887F_D42B07C10710__INCLUDED_)
    #define AFX_THREADSVIEW_H__A880E54F_A6EB_11D1_887F_D42B07C10710__INCLUDED_

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

    UINT ThreadProcedure(LPVOID pParam);

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

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

    // Attributes
    public:
        CThreadsDoc* GetDocument();
        SData data;
        CWinThread* Thread;
        void OnMaxFound(WPARAM wParam, LPARAM lParam);
    // Operations
    public:

    // Overrides
        // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CThreadsView)
        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 ~CThreadsView();
    #ifdef _DEBUG
        virtual void AssertValid() const;
        virtual void Dump(CDumpContext& dc) const;
    #endif

    protected:

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

    #ifndef _DEBUG  // debug version in ThreadsView.cpp
    inline CThreadsDoc* CThreadsView::GetDocument()
       { return (CThreadsDoc*)m_pDocument; }
    #endif

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

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

    #endif // !defined(AFX_THREADSVIEW_H__A880E54F_A6EB_11D1_887F_D42B07C10710__INCLUDED_)

    // ThreadsView.cpp : implementation of the CThreadsView class
    //

    #include “stdafx.h”
    #include “Threads.h”

    #include “ThreadsDoc.h”
    #include “ThreadsView.h”

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

    /////////////////////////////////////////////////////////////////////////////
    // CThreadsView

    IMPLEMENT_DYNCREATE(CThreadsView, CView)

    BEGIN_MESSAGE_MAP(CThreadsView, CView)
        //{{AFX_MSG_MAP(CThreadsView)
        ON_COMMAND(ID_FILE_FINDMAX, OnFileFindmax)
        ON_MESSAGE(WM_MAX, OnMaxFound)
        //}}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()

    /////////////////////////////////////////////////////////////////////////////
    // CThreadsView construction/destruction

    CThreadsView::CThreadsView()
    {
        // TODO: add construction code here

    }

    CThreadsView::~CThreadsView()
    {
    }

    BOOL CThreadsView::PreCreateWindow(CREATESTRUCT& cs)

    {
        // TODO: Modify the Window class or styles here by modifying
        //  the CREATESTRUCT cs

        return CView::PreCreateWindow(cs);
    }

    /////////////////////////////////////////////////////////////////////////////
    // CThreadsView drawing

    void CThreadsView::OnDraw(CDC* pDC)
    {
        CThreadsDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);

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

    /////////////////////////////////////////////////////////////////////////////
    // CThreadsView printing

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

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

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

    /////////////////////////////////////////////////////////////////////////////
    // CThreadsView diagnostics

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

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

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

    /////////////////////////////////////////////////////////////////////////////
    // CThreadsView message handlers

    void CThreadsView::OnFileFindmax()
    {
        // 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;
        Thread = AfxBeginThread(ThreadProcedure, &data);
    }

    UINT ThreadProcedure(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);

        return 0;
    }

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

        char FormattedString[100];
        wsprintf(FormattedString, “Max of the array = %d”, data.max);
        pDoc->text = FormattedString;

        TerminateThread(Thread, 0);

        Invalidate();

        return 0;
    }
We’ve seen how to work with one thread, but what if we had more than one?
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.