// MfcThreadPluginTestDlg.cpp : Implementierungsdatei
//
#include "stdafx.h"
#include "MfcThreadPluginTest.h"
#include "MfcThreadPluginTestDlg.h"
#include "spl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define WM_THREAD_MESSAGE (WM_USER+1)
#define WM_THREAD_ENDS (WM_USER+2)
// CMfcThreadPluginTestDlg Dialogfeld
slcPluginServer pluginServer;
slcPluginInfo pluginInfo;
volatile bool bThreadRun = false;
char szBuf[ MAX_PATH ] = { 0 };
int iThread = 0;
static UINT Thread( LPVOID pParam )
{
CMfcThreadPluginTestDlg* pDlg = reinterpret_cast<CMfcThreadPluginTestDlg*>( pParam );
int iID = iThread;
long lRunPlugin = -1;
CString strTemp;
slcPluginArgs pluginArgs;
if( strlen( (char*) pDlg->m_strInput.operator LPCTSTR() ) == 0 )
{
pDlg->SendMessage( WM_THREAD_ENDS, (WPARAM) iID, (LPARAM) 0 );
iThread--;
return -1;
}
while( bThreadRun )
{
while( pluginServer.TryLock() != 0 )
{
TRACE("EBUSY on thread %d\n", iID );
MSG msg;
while( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
::TranslateMessage( &msg );
::DispatchMessage( &msg );
}
Sleep( 10 );
}
strTemp = (char*) szBuf;
lRunPlugin = 0;
pluginArgs.SetArg( (void*) strTemp.operator LPCTSTR() );
pluginArgs.SetArg( (void*) szBuf );
if( pluginServer.RunPlugin( lRunPlugin, &pluginArgs ) == 1 )
{
TRACE("thread %d: %s\n", iID, (char*) szBuf );
strTemp = szBuf;
pDlg->PostMessage( WM_THREAD_MESSAGE, (WPARAM) MAKELONG( lRunPlugin, iID),
(LPARAM) strTemp.operator LPCTSTR( ) );
}
else
break;
pluginServer.Unlock();
pluginArgs.Clear();
Sleep( rand() % 100 );
}
iThread--;
pDlg->SendMessage( WM_THREAD_ENDS, (WPARAM) iID, (LPARAM) 0 );
return 0;
}
CMfcThreadPluginTestDlg::CMfcThreadPluginTestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMfcThreadPluginTestDlg::IDD, pParent)
, m_strPlugin(_T(""))
, m_strInput(_T(""))
, m_iRunningThreads(0)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMfcThreadPluginTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_OUTPUT, m_ctrlListOutput);
DDX_Text(pDX, IDC_INPUT, m_strInput );
DDX_Text(pDX, IDC_PLUGIN, m_strPlugin );
DDX_Text(pDX, IDC_THREAD_COUNT, m_iRunningThreads );
}
BEGIN_MESSAGE_MAP(CMfcThreadPluginTestDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_START, OnBnClickedStart)
ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel)
ON_MESSAGE(WM_THREAD_MESSAGE, OnThreadMessage)
ON_MESSAGE(WM_THREAD_ENDS, OnThreadEnds)
ON_BN_CLICKED(IDC_STOP, OnBnClickedStop)
ON_BN_CLICKED(IDC_CLEAR, OnBnClickedClear)
END_MESSAGE_MAP()
// CMfcThreadPluginTestDlg Meldungshandler
BOOL CMfcThreadPluginTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Symbol f�r dieses Dialogfeld festlegen. Wird automatisch erledigt
// wenn das Hauptfenster der Anwendung kein Dialogfeld ist
SetIcon(m_hIcon, TRUE); // Gro�es Symbol verwenden
SetIcon(m_hIcon, FALSE); // Kleines Symbol verwenden
pluginServer.LoadPlugin( "..\\plugins\\PLReverseSlow.dll" );
pluginInfo = pluginServer.GetPluginInfo( pluginServer.GetLoadedPlugins() - 1 );
m_strPlugin = pluginInfo.GetName().c_str();
UpdateData( FALSE );
return TRUE; // Geben Sie TRUE zur�ck, au�er ein Steuerelement soll den Fokus erhalten
}
// Wenn Sie dem Dialogfeld eine Schaltfl�che "Minimieren" hinzuf�gen, ben�tigen Sie
// den nachstehenden Code, um das Symbol zu zeichnen. F�r MFC-Anwendungen, die das
// Dokument/Ansicht-Modell verwenden, wird dies automatisch ausgef�hrt.
void CMfcThreadPluginTestDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // Ger�tekontext zum Zeichnen
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Symbol in Clientrechteck zentrieren
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Symbol zeichnen
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
LRESULT CMfcThreadPluginTestDlg::OnThreadMessage( WPARAM wParam, LPARAM lParam )
{
CString strTemp;
pluginServer.Lock();
slcPluginInfo pluginInfo = pluginServer.GetSafedPluginInfo( (long) LOWORD( wParam ) );
strTemp.Format( "Thread %d runs plugin %s:\t%s", (int) HIWORD( wParam),
pluginInfo.GetName().c_str(), (char*) lParam );
m_ctrlListOutput.AddString( strTemp );
m_ctrlListOutput.SetCurSel( m_ctrlListOutput.GetCount() - 1);
pluginServer.Unlock();
return 0;
}
LRESULT CMfcThreadPluginTestDlg::OnThreadEnds( WPARAM wParam, LPARAM lParam )
{
CString strTemp;
strTemp.Format( "Thread %d ends!", (int) wParam);
m_ctrlListOutput.AddString( strTemp );
m_ctrlListOutput.SetCurSel( m_ctrlListOutput.GetCount() - 1);
m_iRunningThreads--;
UpdateData( FALSE );
return 0;
}
// Die System ruft diese Funktion auf, um den Cursor abzufragen, der angezeigt wird, w�hrend der Benutzer
// das minimierte Fenster mit der Maus zieht.
HCURSOR CMfcThreadPluginTestDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CMfcThreadPluginTestDlg::OnBnClickedStart()
{
UpdateData();
strncpy( (char*) szBuf, m_strInput, MAX_PATH );
bThreadRun = true;
if( iThread > 9 )
return;
iThread++;
AfxBeginThread( Thread, this, THREAD_PRIORITY_LOWEST );
m_iRunningThreads = iThread;
UpdateData( FALSE );
Sleep( 500 );
}
void CMfcThreadPluginTestDlg::OnBnClickedCancel()
{
if( bThreadRun )
{
bThreadRun = false;
while( m_iRunningThreads > 0)
{
MSG msg;
Sleep( 10 );
while( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
::TranslateMessage( &msg );
::DispatchMessage( &msg );
}
}
Sleep( 1200 );
}
OnCancel();
}
void CMfcThreadPluginTestDlg::OnBnClickedStop()
{
bThreadRun = false;
while( m_iRunningThreads > 0)
{
MSG msg;
Sleep( 10 );
while( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
::TranslateMessage( &msg );
::DispatchMessage( &msg );
}
}
m_ctrlListOutput.AddString( (char*) szBuf );
}
void CMfcThreadPluginTestDlg::OnBnClickedClear()
{
m_ctrlListOutput.ResetContent();
}