![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
To access the contents, click the chapter and section titles.
Fast Track Visual C++ 6.0 Programming
Setting Up the New Windows MessageTo 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 dont 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 views 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 threads work. Reporting the Threads ResultsWhen 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 structures 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(); ⇐ }
In the views 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 weve 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; } Weve seen how to work with one thread, but what if we had more than one?
|
![]() |
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. |