home *** CD-ROM | disk | FTP | other *** search
- // slowcalc.cpp : implementation of the recalc engine, which is reused by
- // both demonstrations of recalculating: single thread,
- // and worker thread.
- //
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
-
- #include "stdafx.h"
- #include "calcthrd.h"
- #include "recaldoc.h"
- #include "slowcalc.h"
- #include "mtrecalc.h"
-
-
- BOOL SlowAdd(int nInt1, int nInt2, int& nResult, CRecalcThreadInfo* pInfo, int nSeconds,
- HWND hwndNotifyProgress)
- {
- CWnd* pWndNotifyProgress = CWnd::FromHandle(hwndNotifyProgress);
-
- BOOL bRestartCalculation = TRUE;
- while (bRestartCalculation)
- {
- bRestartCalculation = FALSE;
- // Do the calculation 5% at a time, allowing for interruption to
- // restart calculation.
- for (int nCount = 1; nCount < 20; nCount++)
- {
- if (pInfo != NULL
- && WaitForSingleObject(pInfo->m_hEventKillRecalcThread, 0) == WAIT_OBJECT_0)
- {
- if (hwndNotifyProgress != NULL)
- {
- // Reset progress indication to 0 (recalculation not begun)
- pWndNotifyProgress->PostMessage(WM_USER_RECALC_IN_PROGRESS);
- }
- return FALSE; // Terminate this recalculation
- }
-
- if (pInfo != NULL
- &&WaitForSingleObject(pInfo->m_hEventStartRecalc, 0) == WAIT_OBJECT_0)
- {
- // Get new source data for the calculation.
- nInt1 = pInfo->m_nInt1;
- nInt2 = pInfo->m_nInt2;
- bRestartCalculation = TRUE;
- continue;
- }
-
- // Notify window about each 5% of progress
- if (hwndNotifyProgress != NULL)
- {
- // If calculating in a single thread, send rather than post the
- // "in progress" message, so that the progress is reflected
- // immediately in the status bar. Otherwise, the posted "in
- // progress" messages won't be handled until after the recalculation
- // has totally completed.
- //
- // If calculating in a separate thread, however, then post rather
- // than send the "in progress" message. Otherwise, in the case where
- // the main thread tries to kill the worker thread, there may be
- // a deadlock where the main thread is doing a WaitForSingleObject
- // on the "kill done" event while the worker thread is waiting for
- // the main thread to handle the sent message.
- if (pInfo == NULL)
- {
- pWndNotifyProgress->SendMessage(WM_USER_RECALC_IN_PROGRESS, nCount*5);
- }
- else
- {
- pWndNotifyProgress->PostMessage(WM_USER_RECALC_IN_PROGRESS, nCount*5);
- }
- }
- // Sleep 1/20th of total recalc time, which is 50 milliseconds
- // per each of total number of seconds (nSeconds) of recalc time.
- Sleep(nSeconds * 50);
-
- }
-
- if (hwndNotifyProgress != NULL)
- {
- // See comment above regarding post versus send message.
- if (pInfo == NULL)
- pWndNotifyProgress->SendMessage(WM_USER_RECALC_IN_PROGRESS, 100);
- else
- pWndNotifyProgress->PostMessage(WM_USER_RECALC_IN_PROGRESS, 100);
-
- }
- }
-
- nResult = nInt1 + nInt2;
- return TRUE;
- }
-