|
|
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1997-1999 Microsoft Corporation
//
// Module Name:
// WorkThrd.h
//
// Abstract:
// Definition of the CWorkerThread class.
//
// Implementation File:
// WorkThrd.cpp
//
// Author:
// David Potter (davidp) November 17, 1997
//
// Revision History:
//
// Notes:
//
/////////////////////////////////////////////////////////////////////////////
#ifndef __WORKTHRD_H_
#define __WORKTHRD_H_
/////////////////////////////////////////////////////////////////////////////
// Forward Class Declarations
/////////////////////////////////////////////////////////////////////////////
class CWorkerThread;
/////////////////////////////////////////////////////////////////////////////
// External Class Declarations
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Include Files
/////////////////////////////////////////////////////////////////////////////
#ifndef _EXCOPER_H_
#include "ExcOper.h" // for CNTException
#endif
/////////////////////////////////////////////////////////////////////////////
// Type Definitions
/////////////////////////////////////////////////////////////////////////////
// Worker thread function codes.
enum { WTF_EXIT = -1, // Ask the thread to exit.
WTF_NONE = 0, // No function.
WTF_USER = 1000 // User functions start here.
};
/////////////////////////////////////////////////////////////////////////////
//++
//
// class CWorkerThread
//
// Purpose:
// This class provides a means of calling functions in a worker thread
// and allowing a UI application to still respond to Windows messages.
// The user of this class owns the input and output data pointed to
// by this class.
//
// Inheritance:
// CWorkerThread
//
//--
/////////////////////////////////////////////////////////////////////////////
class CWorkerThread { public: //
// Construction and destruction.
//
// Default constructor
CWorkerThread( void ) : m_hThread( NULL ) , m_hMutex( NULL ) , m_hInputEvent( NULL ) , m_hOutputEvent( NULL) , m_idThread( 0 ) , m_bThreadExiting( FALSE ) , m_nFunction( WTF_NONE ) , m_pvParam1( NULL ) , m_pvParam2( NULL ) , m_dwOutputStatus( ERROR_SUCCESS ) , m_nte( ERROR_SUCCESS ) , m_pfnOldWndProc( NULL ) , m_hCurrentCursor( NULL ) { } //*** CWorkerThread()
// Destructor
~CWorkerThread( void ) { ATLASSERT( m_nFunction == WTF_NONE ); ATLASSERT( m_pvParam1 == NULL ); ATLASSERT( m_pvParam2 == NULL );
Cleanup();
ATLASSERT( m_bThreadExiting );
} //*** ~CWorkerThread()
// Create the thread
DWORD CreateThread( void );
// Ask the thread to exit
void QuitThread( IN HWND hwnd = NULL ) { ATLASSERT( ! m_bThreadExiting ); CWaitCursor wc; CallThreadFunction( hwnd, WTF_EXIT, NULL, NULL );
} //*** QuitThread()
// Call a function supported by the thread
DWORD CallThreadFunction( IN HWND hwnd, IN LONG nFunction, IN OUT PVOID pvParam1 = NULL, IN OUT PVOID pvParam2 = NULL );
// Wait for the thread to exit
DWORD WaitForThreadToExit( IN HWND hwnd );
public: //
// Accessor functions.
//
// Get the thread handle
operator HANDLE( void ) const { return m_hThread;
} //*** operator HANDLE()
// Get the thread handle
HANDLE HThreadHandle( void ) const { return m_hThread;
} //*** HThreadHandle()
// Get the thread ID
operator DWORD( void ) const { return m_idThread;
} //*** operator DWORD()
// Get exception information resulting from a thread function call
CNTException & Nte( void ) { return m_nte;
} //*** Nte()
// Get exception information resulting from a thread function call
operator CNTException *( void ) { return &m_nte;
} //*** operator CNTException *()
protected: //
// Synchronization data.
//
HANDLE m_hThread; // Handle for the thread.
HANDLE m_hMutex; // Handle for the mutex used to call a
// function in the thread.
HANDLE m_hInputEvent; // Handle for the event used by the calling
// thread to signal the worker thread that
// there is work to do.
HANDLE m_hOutputEvent; // Handle for the event used by the worker
// thread to signal the calling thread
// that the work has been completed.
UINT m_idThread; // ID for the thread.
BOOL m_bThreadExiting; // Determine if thread is exiting or not.
//
// Data used as input or produced by the thread.
//
LONG m_nFunction; // ID of the function to perform.
PVOID m_pvParam1; // Parameter 1 with function-specific data.
PVOID m_pvParam2; // Parameter 2 with function-specific data.
DWORD m_dwOutputStatus; // Status returned from the function.
CNTException m_nte; // Exception information from the function.
//
// Data and methods for handling WM_SETCURSOR messages.
//
WNDPROC m_pfnOldWndProc; // Old window procedure for the parent window.
HCURSOR m_hCurrentCursor; // Cursor to display while waiting for thread call to complete.
// Window procedure for subclassing the parent window
static LRESULT WINAPI S_ParentWndProc( IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam );
//
// Thread worker functions.
//
// Static thread procedure
static UINT __stdcall S_ThreadProc( IN OUT LPVOID pvThis );
// Thread function handler
virtual DWORD ThreadFunctionHandler( IN LONG nFunction, IN OUT PVOID pvParam1, IN OUT PVOID pvParam2 ) = 0;
//
// Helper functions.
//
// Prepare a window to wait for a thread operation
void PrepareWindowToWait( IN HWND hwnd );
// Cleanup a window after waiting for a thread operation
void CleanupWindowAfterWait( IN HWND hwnd );
// Cleanup objects
virtual void Cleanup( void ) { if ( m_hThread != NULL ) { if ( ! m_bThreadExiting && (m_nFunction != WTF_EXIT) ) { QuitThread(); } // if: thread hasn't exited yet
ATLTRACE( _T("CWorkerThread::Cleanup() - Closing thread handle\n") ); CloseHandle( m_hThread ); m_hThread = NULL; } // if: thread created
if ( m_hMutex != NULL ) { ATLTRACE( _T("CWorkerThread::Cleanup() - Closing mutex handle\n") ); CloseHandle( m_hMutex ); m_hMutex = NULL; } // if: mutex created
if ( m_hInputEvent != NULL ) { ATLTRACE( _T("CWorkerThread::Cleanup() - Closing input event handle\n") ); CloseHandle( m_hInputEvent ); m_hInputEvent = NULL; } // if: input event created
if ( m_hOutputEvent != NULL ) { ATLTRACE( _T("CWorkerThread::Cleanup() - Closing output event handle\n") ); CloseHandle( m_hOutputEvent ); m_hOutputEvent = NULL; } // if: output event created
} //*** Cleanup()
}; // class CWorkerThread
/////////////////////////////////////////////////////////////////////////////
#endif // __WORKTHRD_H_
|