]> git.saurik.com Git - wxWidgets.git/commitdiff
renamed thread sample
authorRon Lee <ron@debian.org>
Tue, 14 Mar 2000 19:35:40 +0000 (19:35 +0000)
committerRon Lee <ron@debian.org>
Tue, 14 Mar 2000 19:35:40 +0000 (19:35 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6714 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

17 files changed:
samples/thread/Makefile.in
samples/thread/makefile.b32
samples/thread/makefile.bcc [new file with mode: 0644]
samples/thread/makefile.dos
samples/thread/makefile.g95
samples/thread/makefile.sc [new file with mode: 0644]
samples/thread/makefile.sl [new file with mode: 0644]
samples/thread/makefile.twn [new file with mode: 0644]
samples/thread/makefile.unx
samples/thread/makefile.vc
samples/thread/makefile.wat
samples/thread/test.cpp [deleted file]
samples/thread/test.def [deleted file]
samples/thread/test.rc [deleted file]
samples/thread/thread.cpp [new file with mode: 0644]
samples/thread/thread.def [new file with mode: 0644]
samples/thread/thread.rc [new file with mode: 0644]

index 4a36eeaa86444d319424795ba89034df301360c6..6df1617e758f7af8b3dd16178ffbeb0abaf90f97 100644 (file)
@@ -1,19 +1,11 @@
-#
-# File:                makefile.unx
-# Author:      Julian Smart
-# Created:     1998
-# Updated:     
-# Copyright:   (c) 1998 Julian Smart
-#
-# "%W% %G%"
-#
-# Makefile for thread example (UNIX).
+# Purpose: makefile for thread example (UNIX).
+# Created: 2000-03-15
 
 top_srcdir = @top_srcdir@/..
 top_builddir = ../..
 program_dir = samples/thread
 
-PROGRAM=test
+PROGRAM=thread
 
 OBJECTS=$(PROGRAM).o
 
index 95ddc80d76f728d37352e263489f8c331912bab8..e088c5c227728196ca66d57677032d1391d8fb03 100644 (file)
@@ -1,15 +1,9 @@
-#
-# File:                makefile.b32
-# Author:      Julian Smart
-# Created:     1999
-# Updated:     
-# Copyright:
-#
-# Makefile : Builds sample for 32-bit BC++
+# Purpose: makefile for thread example (BC++ 32bit)
+# Created: 2000-03-15
 
 WXDIR = $(WXWIN)
 
-TARGET=test
+TARGET=thread
 OBJECTS = $(TARGET).obj
 
 !include $(WXDIR)\src\makeprog.b32
diff --git a/samples/thread/makefile.bcc b/samples/thread/makefile.bcc
new file mode 100644 (file)
index 0000000..4900eac
--- /dev/null
@@ -0,0 +1,14 @@
+# Purpose: makefile for thread example (BC++ 16bit)
+# Created: 2000-03-15
+
+!if "$(WXWIN)" == ""
+!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx
+!endif
+
+WXDIR = $(WXWIN)
+
+TARGET=thread
+OBJECTS=$(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.bcc
+
index 86a90c91f707781acf6d66fdd43e7c4f3c6958fc..3af44652d93c51a348975ce80b4f537deb8fa5c6 100644 (file)
@@ -1,65 +1,10 @@
-#
-# File:                makefile.dos
-# Author:      Julian Smart
-# Created:     1993
-# Updated:     
-# Copyright:   (c) 1993, AIAI, University of Edinburgh
-#
-# "%W% %G%"
-#
-# Makefile : Builds thread example (DOS).
-# Use FINAL=1 argument to nmake to build final version with no debugging
-# info
+# Purpose: makefile for thread example (VC++ 1.5x)
+# Created: 2000-03-15
 
 WXDIR = $(WXWIN)
 
-!include $(WXDIR)\src\makemsc.env
+TARGET=thread
+OBJECTS=$(TARGET).obj
 
-THISDIR = $(WXDIR)\samples\test
+!include $(WXDIR)\src\makeprog.msc
 
-!ifndef FINAL
-FINAL=0
-!endif
-
-HEADERS =
-SOURCES = test.$(SRCSUFF)
-OBJECTS = test.obj
-
-all:    test.exe
-
-wx:
-        cd $(WXDIR)\src\msw
-        nmake -f makefile.dos FINAL=$(FINAL)
-        cd $(THISDIR)
-
-wxclean:
-        cd $(WXDIR)\src\msw
-        nmake -f makefile.dos clean
-        cd $(THISDIR)
-
-test.exe:      $(WXDIR)\src\msw\dummy.obj $(WXLIB) test.obj test.def test.res
-        link $(LINKFLAGS) @<<
-test.obj $(WXDIR)\src\msw\dummy.obj,
-test,
-NUL,
-$(LIBS),
-test.def
-;
-<<
-        rc -K test.res
-
-test.obj:      test.$(SRCSUFF)
-        cl @<<
-$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
-<<
-
-test.res :      test.rc $(WXDIR)\include\wx\msw\wx.rc
-    rc -r /i$(WXDIR)\include test
-
-clean:
-        -erase *.obj
-        -erase *.exe
-        -erase *.res
-        -erase *.map
-        -erase *.sbr
-        -erase *.pdb
index b4a920f047f4d2d08d871efbbb5cc0cf207b6327..bc6829768cb8bb3c5123fe97dd5ccd5bbcef9f8f 100644 (file)
@@ -1,16 +1,10 @@
-#
-# File:         makefile.g95
-# Author:       Julian Smart
-# Created:      1999
-# Updated:
-# Copyright:    (c) Julian Smart, 1999
-#
-# Makefile for wxWindows sample (Cygwin/Mingw32).
+# Purpose: makefile for thread example (Cygwin/Mingw32)
+# Created: #03.01.00
 
 WXDIR = ../..
 
-TARGET=test
+TARGET=thread
 OBJECTS = $(TARGET).o
 
-include $(WXDIR)/src/makeprog.g95
+include $(WXDIR)\src\makeprog.g95
 
diff --git a/samples/thread/makefile.sc b/samples/thread/makefile.sc
new file mode 100644 (file)
index 0000000..5853980
--- /dev/null
@@ -0,0 +1,37 @@
+# Purpose: makefile for thread example (Symantec C++)
+# Created: 2000-03-15
+
+WXDIR = $(WXWIN)
+WXLIB = $(WXDIR)\lib\wx.lib
+INCDIR = $(WXDIR)\include
+INCLUDE=$(INCDIR)
+TARGET=thread
+
+include $(WXDIR)\src\makesc.env
+
+thread.exe: thread.obj $(DEFFILE) thread.res
+       *$(CC) $(LDFLAGS) -o$@ $** $(LIBS)
+    *$(RC) -k thread.res
+
+sc32.def:
+     echo EXETYPE NT > sc32.def
+     echo SUBSYSTEM WINDOWS >> sc32.def
+
+sc16.def:
+     echo NAME $(TARGET) > sc16.def
+     echo EXETYPE WINDOWS >> sc16.def
+     echo STUB         'WINSTUB.EXE' >> sc16.def
+     echo CODE         PRELOAD MOVEABLE DISCARDABLE >> sc16.def
+     echo DATA         PRELOAD MOVEABLE MULTIPLE >> sc16.def
+     echo HEAPSIZE     1024 >> sc16.def
+     echo STACKSIZE    8192 >> sc16.def
+
+clean:
+    -del *.obj
+       -del *.exe
+       -del *.res
+       -del *.map
+       -del *.rws
+    -del sc32.def
+    -del sc16.def
+
diff --git a/samples/thread/makefile.sl b/samples/thread/makefile.sl
new file mode 100644 (file)
index 0000000..0dfd1d8
--- /dev/null
@@ -0,0 +1,14 @@
+# Purpose: makefile for thread example (Salford C++)
+# Created: 2000-03-15
+
+PROGRAM = thread
+OBJECTS = $(PROGRAM).obj
+
+include ..\..\src\makeprog.sl
+
+all:        wx $(TARGET)
+
+wx:
+    cd $(WXDIR)\src\msw ^ mk32 -f makefile.sl all
+    cd $(WXDIR)\samples\thread
+
diff --git a/samples/thread/makefile.twn b/samples/thread/makefile.twn
new file mode 100644 (file)
index 0000000..d2f7abe
--- /dev/null
@@ -0,0 +1,35 @@
+# Purpose: makefile for thread example (TWIN)
+# Created: 2000-03-15
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/maketwin.env
+
+OBJECTS = $(OBJDIR)/thread.$(OBJSUFF) $(OBJDIR)/thread.$(OBJSUFF)
+
+all:    $(OBJDIR) thread$(GUISUFFIX)$(EXESUFF)
+
+wx:
+
+$(OBJDIR):
+       mkdir $(OBJDIR)
+
+thread$(GUISUFFIX)$(EXESUFF):  $(OBJECTS) $(WXLIB)
+       $(CC) $(LDFLAGS) -o thread$(GUISUFFIX)$(EXESUFF) $(OBJECTS) $(LDLIBS)
+
+$(OBJDIR)/thread.$(OBJSUFF):   thread.$(SRCSUFF)
+       $(CC) -c $(CPPFLAGS) -o $@ thread.$(SRCSUFF)
+
+thread.c:  thread.rc
+       $(RESCOMP) $(RCINPUTSWITCH) thread.rc $(RCOUTPUTSWITCH) thread.c $(RESFLAGS)
+
+$(OBJDIR)/thread.$(OBJSUFF):   thread.c
+       $(CC) -c $(CPPFLAGS) -o $@ thread.c
+
+#$(OBJDIR)/thread.o:  thread.rc
+#      $(RESCOMP) $(RCINPUTSWITCH) thread.rc $(RCOUTPUTSWITCH) $(OBJDIR)/thread.o $(RESFLAGS)
+
+clean:
+       rm -f $(OBJECTS) thread$(GUISUFFIX).exe core *.rsc *.res
index 4696faad4f61240f0dec9124231f05b936e4aa90..43224c12649b7c0f6680db5d3db1604dc8e17d74 100644 (file)
@@ -1,17 +1,5 @@
-#
-# File:                Makefile for samples
-# Author:      Robert Roebling
-# Created:     1999
-# Updated:     
-# Copyright:   (c) 1998 Robert Roebling
-#
-# This makefile requires a Unix version of wxWindows
-# to be installed on your system. This is most often
-# done typing "make install" when using the complete
-# sources of wxWindows or by installing the two
-# RPM packages wxGTK.XXX.rpm and wxGTK-devel.XXX.rpm
-# under Linux.
-#
+# Purpose: makefile for thread example (Unix)
+# Created: 2000-03-15
 
 CC = gcc
 
@@ -31,5 +19,5 @@ all:    $(PROGRAM)
 $(PROGRAM):    $(OBJECTS)
        $(CC) -o $(PROGRAM) $(OBJECTS) `wx-config --libs`
 
-clean: 
+clean:
        rm -f *.o $(PROGRAM)
index 4ada748edad53c6917114d10b0dcd373f6ba8648..bd4848853cdc03f772ac337bbef1a0b694fc3c1e 100644 (file)
@@ -1,17 +1,10 @@
-#
-# File:                makefile.vc
-# Author:      Julian Smart
-# Created:     1999
-# Updated:     
-# Copyright:   (c) Julian Smart
-#
-# Makefile : Builds sample (VC++, WIN32)
-# Use FINAL=1 argument to nmake to build final version with no debug info.
+# Purpose: makefile for thread example (VC++ 32bit)
+# Created: 2000-03-15
 
 # Set WXDIR for your system
 WXDIR = $(WXWIN)
 
-PROGRAM=test
+PROGRAM=thread
 OBJECTS = $(PROGRAM).obj
 
 !include $(WXDIR)\src\makeprog.vc
index 81a83e42a9fbbe144c5dfef0f52fae312124c84f..d5741fd111a784cd9d009f2d7804abb74b3fed57 100644 (file)
@@ -1,13 +1,9 @@
-#
-# Makefile for WATCOM
-#
-# Created by Julian Smart, January 1999
-# 
-#
+# Purpose: makefile for thread example (Watcom)
+# Created: 2000-03-15
 
 WXDIR = $(%WXWIN)
 
-PROGRAM = test
+PROGRAM = thread
 OBJECTS = $(PROGRAM).obj
 
 !include $(WXDIR)\src\makeprog.wat
diff --git a/samples/thread/test.cpp b/samples/thread/test.cpp
deleted file mode 100644 (file)
index be40d23..0000000
+++ /dev/null
@@ -1,626 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        test.cpp
-// Purpose:     wxWindows thread sample
-// Author:      Julian Smart(minimal)/Guilhem Lavaux(thread test)
-// Modified by:
-// Created:     06/16/98
-// RCS-ID:      $Id$
-// Copyright:   (c) Julian Smart, Markus Holzem, Guilhem Lavaux
-// Licence:     wxWindows license
-/////////////////////////////////////////////////////////////////////////////
-
-/*
-    TODO: use worker threads to update progress controls instead of writing
-          messages - it will be more visual
- */
-
-#ifdef __GNUG__
-    #pragma implementation "test.cpp"
-    #pragma interface "test.cpp"
-#endif
-
-// For compilers that support precompilation, includes "wx/wx.h".
-#include "wx/wxprec.h"
-
-#ifdef __BORLANDC__
-    #pragma hdrstop
-#endif
-
-#ifndef WX_PRECOMP
-    #include "wx/wx.h"
-#endif
-
-#if !wxUSE_THREADS
-    #error "This sample requires thread support!"
-#endif // wxUSE_THREADS
-
-#include "wx/thread.h"
-#include "wx/dynarray.h"
-#include "wx/time.h"
-
-#include "wx/progdlg.h"
-
-// uncomment this to get some debugging messages from the trace code
-//#define TRACE
-
-class MyThread;
-WX_DEFINE_ARRAY(wxThread *, wxArrayThread);
-
-// Define a new application type
-class MyApp : public wxApp
-{
-public:
-    virtual bool OnInit();
-
-public:
-    // all the threads currently alive - as soon as the thread terminates, it's
-    // removed from the array
-    wxArrayThread m_threads;
-
-    // crit section protects access to all of the arrays below
-    wxCriticalSection m_critsect;
-};
-
-// Create a new application object
-IMPLEMENT_APP(MyApp)
-
-// Define a new frame type
-class MyFrame: public wxFrame
-{
-public:
-    // ctor
-    MyFrame(wxFrame *frame, const wxString& title, int x, int y, int w, int h);
-
-    // operations
-    void WriteText(const wxString& text) { m_txtctrl->WriteText(text); }
-
-    // accessors for MyWorkerThread (called in its context!)
-    bool Cancelled();
-
-    // callbacks
-    void OnQuit(wxCommandEvent& event);
-    void OnAbout(wxCommandEvent& event);
-    void OnClear(wxCommandEvent& event);
-
-    void OnStartThread(wxCommandEvent& event);
-    void OnStartThreads(wxCommandEvent& event);
-    void OnStopThread(wxCommandEvent& event);
-    void OnPauseThread(wxCommandEvent& event);
-    void OnResumeThread(wxCommandEvent& event);
-
-    void OnStartWorker(wxCommandEvent& event);
-    void OnWorkerEvent(wxCommandEvent& event);
-    void OnUpdateWorker(wxUpdateUIEvent& event);
-
-    void OnIdle(wxIdleEvent &event);
-
-private:
-    // helper function - creates a new thread (but doesn't run it)
-    MyThread *CreateThread();
-
-    // just some place to put our messages in
-    wxTextCtrl *m_txtctrl;
-
-    // remember the number of running threads and total number of threads
-    size_t m_nRunning, m_nCount;
-
-    // the progress dialog which we show while worker thread is running
-    wxProgressDialog *m_dlgProgress;
-
-    // was the worker thread cancelled by user?
-    bool m_cancelled;
-
-    // protects m_cancelled
-    wxCriticalSection m_critsectWork;
-
-    DECLARE_EVENT_TABLE()
-};
-
-// ID for the menu commands
-enum
-{
-    TEST_QUIT          = 1,
-    TEST_TEXT          = 101,
-    TEST_ABOUT,
-    TEST_CLEAR,
-    TEST_START_THREAD  = 201,
-    TEST_START_THREADS,
-    TEST_STOP_THREAD,
-    TEST_PAUSE_THREAD,
-    TEST_RESUME_THREAD,
-    TEST_START_WORKER,
-    WORKER_EVENT    // this one gets sent from the worker thread
-};
-
-//--------------------------------------------------
-// GUI thread
-//--------------------------------------------------
-
-class MyThread : public wxThread
-{
-public:
-    MyThread(MyFrame *frame);
-
-    // thread execution starts here
-    virtual void *Entry();
-
-    // called when the thread exits - whether it terminates normally or is
-    // stopped with Delete() (but not when it is Kill()ed!)
-    virtual void OnExit();
-
-    // write something to the text control
-    void WriteText(const wxString& text);
-
-public:
-    size_t   m_count;
-    MyFrame *m_frame;
-};
-
-MyThread::MyThread(MyFrame *frame)
-        : wxThread()
-{
-    m_count = 0;
-    m_frame = frame;
-}
-
-void MyThread::WriteText(const wxString& text)
-{
-    wxString msg;
-
-    // before doing any GUI calls we must ensure that this thread is the only
-    // one doing it!
-
-    wxMutexGuiEnter();
-
-    msg << text;
-    m_frame->WriteText(msg);
-
-    wxMutexGuiLeave();
-}
-
-void MyThread::OnExit()
-{
-    wxCriticalSectionLocker locker(wxGetApp().m_critsect);
-
-    wxGetApp().m_threads.Remove(this);
-}
-
-void *MyThread::Entry()
-{
-    wxString text;
-
-    text.Printf("Thread 0x%x started (priority = %d).\n",
-                GetId(), GetPriority());
-    WriteText(text);
-    // wxLogMessage(text); -- test wxLog thread safeness
-
-    for ( m_count = 0; m_count < 10; m_count++ )
-    {
-        // check if we were asked to exit
-        if ( TestDestroy() )
-            break;
-
-        text.Printf("[%u] Thread 0x%x here.\n", m_count, GetId());
-        WriteText(text);
-
-        // wxSleep() can't be called from non-GUI thread!
-        wxThread::Sleep(1000);
-    }
-
-    text.Printf("Thread 0x%x finished.\n", GetId());
-    WriteText(text);
-    // wxLogMessage(text); -- test wxLog thread safeness
-
-    return NULL;
-}
-
-//--------------------------------------------------
-// worker thread
-//--------------------------------------------------
-
-class MyWorkerThread : public wxThread
-{
-public:
-    MyWorkerThread(MyFrame *frame);
-
-    // thread execution starts here
-    virtual void *Entry();
-
-    // called when the thread exits - whether it terminates normally or is
-    // stopped with Delete() (but not when it is Kill()ed!)
-    virtual void OnExit();
-
-public:
-    MyFrame *m_frame;
-    size_t   m_count;
-};
-
-MyWorkerThread::MyWorkerThread(MyFrame *frame)
-        : wxThread()
-{
-    m_frame = frame;
-    m_count = 0;
-}
-
-void MyWorkerThread::OnExit()
-{
-}
-
-void *MyWorkerThread::Entry()
-{
-    for ( m_count = 0; !m_frame->Cancelled() && (m_count < 100); m_count++ )
-    {
-        // check if we were asked to exit
-        if ( TestDestroy() )
-            break;
-
-        wxString text;
-        text.Printf("[%u] Thread 0x%x here!!", m_count, GetId());
-
-        // create any type of command event here
-        wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, WORKER_EVENT );
-        event.SetInt( m_count );
-        event.SetString( text );
-
-        // send in a thread-safe way
-        wxPostEvent( m_frame, event );
-
-        // same as:
-        // m_frame->AddPendingEvent( event );
-
-        // wxSleep() can't be called from non-main thread!
-        wxThread::Sleep(200);
-    }
-
-    wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, WORKER_EVENT );
-    event.SetInt(-1); // that's all
-    wxPostEvent( m_frame, event );
-
-    return NULL;
-}
-
-//--------------------------------------------------
-// main program
-//--------------------------------------------------
-
-BEGIN_EVENT_TABLE(MyFrame, wxFrame)
-    EVT_MENU(TEST_QUIT, MyFrame::OnQuit)
-    EVT_MENU(TEST_ABOUT, MyFrame::OnAbout)
-    EVT_MENU(TEST_CLEAR, MyFrame::OnClear)
-    EVT_MENU(TEST_START_THREAD, MyFrame::OnStartThread)
-    EVT_MENU(TEST_START_THREADS, MyFrame::OnStartThreads)
-    EVT_MENU(TEST_STOP_THREAD, MyFrame::OnStopThread)
-    EVT_MENU(TEST_PAUSE_THREAD, MyFrame::OnPauseThread)
-    EVT_MENU(TEST_RESUME_THREAD, MyFrame::OnResumeThread)
-
-    EVT_UPDATE_UI(TEST_START_WORKER, MyFrame::OnUpdateWorker)
-    EVT_MENU(TEST_START_WORKER, MyFrame::OnStartWorker)
-    EVT_MENU(WORKER_EVENT, MyFrame::OnWorkerEvent)
-
-    EVT_IDLE(MyFrame::OnIdle)
-END_EVENT_TABLE()
-
-// `Main program' equivalent, creating windows and returning main app frame
-bool MyApp::OnInit()
-{
-#ifdef TRACE
-    wxLog::AddTraceMask("thread");
-#endif
-
-    // Create the main frame window
-    MyFrame *frame = new MyFrame((wxFrame *)NULL, "wxWindows threads sample",
-                                 50, 50, 450, 340);
-
-    // Make a menubar
-    wxMenu *file_menu = new wxMenu;
-
-    file_menu->Append(TEST_CLEAR, "&Clear log\tCtrl-L");
-    file_menu->AppendSeparator();
-    file_menu->Append(TEST_ABOUT, "&About");
-    file_menu->AppendSeparator();
-    file_menu->Append(TEST_QUIT, "E&xit\tAlt-X");
-    wxMenuBar *menu_bar = new wxMenuBar;
-    menu_bar->Append(file_menu, "&File");
-
-    wxMenu *thread_menu = new wxMenu;
-    thread_menu->Append(TEST_START_THREAD, "&Start a new thread\tCtrl-N");
-    thread_menu->Append(TEST_START_THREADS, "Start &many threads at once");
-    thread_menu->Append(TEST_STOP_THREAD, "S&top a running thread\tCtrl-S");
-    thread_menu->AppendSeparator();
-    thread_menu->Append(TEST_PAUSE_THREAD, "&Pause a running thread\tCtrl-P");
-    thread_menu->Append(TEST_RESUME_THREAD, "&Resume suspended thread\tCtrl-R");
-    thread_menu->AppendSeparator();
-    thread_menu->Append(TEST_START_WORKER, "Start &worker thread\tCtrl-W");
-
-    menu_bar->Append(thread_menu, "&Thread");
-    frame->SetMenuBar(menu_bar);
-
-    // Show the frame
-    frame->Show(TRUE);
-
-    SetTopWindow(frame);
-
-    return TRUE;
-}
-
-// My frame constructor
-MyFrame::MyFrame(wxFrame *frame, const wxString& title,
-                 int x, int y, int w, int h)
-       : wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h))
-{
-    m_nRunning = m_nCount = 0;
-
-    m_dlgProgress = (wxProgressDialog *)NULL;
-
-    CreateStatusBar(2);
-
-    m_txtctrl = new wxTextCtrl(this, -1, "", wxPoint(0, 0), wxSize(0, 0),
-                               wxTE_MULTILINE | wxTE_READONLY);
-
-}
-
-MyThread *MyFrame::CreateThread()
-{
-    MyThread *thread = new MyThread(this);
-
-    if ( thread->Create() != wxTHREAD_NO_ERROR )
-    {
-        wxLogError("Can't create thread!");
-    }
-
-    wxCriticalSectionLocker enter(wxGetApp().m_critsect);
-    wxGetApp().m_threads.Add(thread);
-
-    return thread;
-}
-
-void MyFrame::OnStartThreads(wxCommandEvent& WXUNUSED(event) )
-{
-    static long s_num = 10;
-
-    s_num = wxGetNumberFromUser("How many threads to start: ", "",
-                                "wxThread sample", s_num, 1, 10000, this);
-    if ( s_num == -1 )
-    {
-        s_num = 10;
-
-        return;
-    }
-
-    size_t count = (size_t)s_num, n;
-
-    wxArrayThread threads;
-
-    // first create them all...
-    for ( n = 0; n < count; n++ )
-    {
-        wxThread *thr = CreateThread();
-
-        // we want to show the effect of SetPriority(): the first thread will
-        // have the lowest priority, the second - the highest, all the rest
-        // the normal one
-        if ( n == 0 )
-            thr->SetPriority(WXTHREAD_MIN_PRIORITY);
-        else if ( n == 1 )
-            thr->SetPriority(WXTHREAD_MAX_PRIORITY);
-        else
-            thr->SetPriority(WXTHREAD_DEFAULT_PRIORITY);
-
-        threads.Add(thr);
-    }
-
-    wxString msg;
-    msg.Printf("%d new threads created.", count);
-    SetStatusText(msg, 1);
-
-    // ...and then start them
-    for ( n = 0; n < count; n++ )
-    {
-        threads[n]->Run();
-    }
-}
-
-void MyFrame::OnStartThread(wxCommandEvent& WXUNUSED(event) )
-{
-    MyThread *thread = CreateThread();
-
-    if ( thread->Run() != wxTHREAD_NO_ERROR )
-    {
-        wxLogError("Can't start thread!");
-    }
-
-    SetStatusText("New thread started.", 1);
-}
-
-void MyFrame::OnStopThread(wxCommandEvent& WXUNUSED(event) )
-{
-    wxGetApp().m_critsect.Enter();
-
-    // stop the last thread
-    if ( wxGetApp().m_threads.IsEmpty() )
-    {
-        wxLogError("No thread to stop!");
-
-        wxGetApp().m_critsect.Leave();
-    }
-    else
-    {
-        wxThread *thread = wxGetApp().m_threads.Last();
-
-        // it's important to leave critical section before calling Delete()
-        // because delete will (implicitly) call OnExit() which also tries
-        // to enter the same crit section - would dead lock.
-        wxGetApp().m_critsect.Leave();
-
-        thread->Delete();
-
-        SetStatusText("Thread stopped.", 1);
-    }
-}
-
-void MyFrame::OnResumeThread(wxCommandEvent& WXUNUSED(event) )
-{
-    wxCriticalSectionLocker enter(wxGetApp().m_critsect);
-
-    // resume first suspended thread
-    size_t n = 0, count = wxGetApp().m_threads.Count();
-    while ( n < count && !wxGetApp().m_threads[n]->IsPaused() )
-        n++;
-
-    if ( n == count )
-    {
-        wxLogError("No thread to resume!");
-    }
-    else
-    {
-        wxGetApp().m_threads[n]->Resume();
-
-        SetStatusText("Thread resumed.", 1);
-    }
-}
-
-void MyFrame::OnPauseThread(wxCommandEvent& WXUNUSED(event) )
-{
-    wxCriticalSectionLocker enter(wxGetApp().m_critsect);
-
-    // pause last running thread
-    int n = wxGetApp().m_threads.Count() - 1;
-    while ( n >= 0 && !wxGetApp().m_threads[n]->IsRunning() )
-        n--;
-
-    if ( n < 0 )
-    {
-        wxLogError("No thread to pause!");
-    }
-    else
-    {
-        wxGetApp().m_threads[n]->Pause();
-
-        SetStatusText("Thread paused.", 1);
-    }
-}
-
-// set the frame title indicating the current number of threads
-void MyFrame::OnIdle(wxIdleEvent &event)
-{
-    // update the counts of running/total threads
-    size_t nRunning = 0,
-           nCount = wxGetApp().m_threads.Count();
-    for ( size_t n = 0; n < nCount; n++ )
-    {
-        if ( wxGetApp().m_threads[n]->IsRunning() )
-            nRunning++;
-    }
-
-    if ( nCount != m_nCount || nRunning != m_nRunning )
-    {
-        m_nRunning = nRunning;
-        m_nCount = nCount;
-
-        wxLogStatus(this, "%u threads total, %u running.", nCount, nRunning);
-    }
-    //else: avoid flicker - don't print anything
-}
-
-void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
-{
-    size_t count = wxGetApp().m_threads.Count();
-    for ( size_t i = 0; i < count; i++ )
-    {
-        wxGetApp().m_threads[0]->Delete();
-    }
-
-    Close(TRUE);
-}
-
-void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
-{
-    wxMessageDialog dialog(this, "wxWindows multithreaded application sample\n"
-                                 "(c) 1998 Julian Smart, Guilhem Lavaux\n"
-                                 "(c) 1999 Vadim Zeitlin\n"
-                                 "(c) 2000 Robert Roebling",
-                           "About wxThread sample",
-                           wxOK | wxICON_INFORMATION);
-
-    dialog.ShowModal();
-}
-
-void MyFrame::OnClear(wxCommandEvent& WXUNUSED(event))
-{
-#ifdef TRACE
-    // log a separator
-    wxLogTrace("-------- log window cleared --------");
-#endif
-
-    m_txtctrl->Clear();
-}
-
-void MyFrame::OnUpdateWorker(wxUpdateUIEvent& event)
-{
-    event.Enable( m_dlgProgress == NULL );
-}
-
-void MyFrame::OnStartWorker(wxCommandEvent& WXUNUSED(event))
-{
-    MyWorkerThread *thread = new MyWorkerThread(this);
-
-    if ( thread->Create() != wxTHREAD_NO_ERROR )
-    {
-        wxLogError("Can't create thread!");
-    }
-
-    m_dlgProgress = new wxProgressDialog
-                        (
-                         "Progress dialog",
-                         "Wait until the thread terminates or press [Cancel]",
-                         100,
-                         this,
-                         wxPD_CAN_ABORT |
-                         wxPD_APP_MODAL |
-                         wxPD_ELAPSED_TIME |
-                         wxPD_ESTIMATED_TIME |
-                         wxPD_REMAINING_TIME
-                        );
-
-    // thread is not running yet, no need for crit sect
-    m_cancelled = FALSE;
-
-    thread->Run();
-}
-
-void MyFrame::OnWorkerEvent(wxCommandEvent& event)
-{
-#if 0
-    WriteText( "Got message from worker thread: " );
-    WriteText( event.GetString() );
-    WriteText( "\n" );
-#else
-    int n = event.GetInt();
-    if ( n == -1 )
-    {
-        m_dlgProgress->Destroy();
-        m_dlgProgress = (wxProgressDialog *)NULL;
-
-        // the dialog is aborted because the event came from another thread, so
-        // we may need to wake up the main event loop for the dialog to be
-        // really closed
-        wxWakeUpIdle();
-    }
-    else
-    {
-        if ( !m_dlgProgress->Update(n) )
-        {
-            wxCriticalSectionLocker lock(m_critsectWork);
-
-            m_cancelled = TRUE;
-        }
-    }
-#endif
-}
-
-bool MyFrame::Cancelled()
-{
-    wxCriticalSectionLocker lock(m_critsectWork);
-
-    return m_cancelled;
-}
diff --git a/samples/thread/test.def b/samples/thread/test.def
deleted file mode 100644 (file)
index 59f0db7..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-NAME         Minimal
-DESCRIPTION  'Minimal wxWindows application'
-EXETYPE      WINDOWS
-CODE         PRELOAD MOVEABLE DISCARDABLE
-DATA         PRELOAD MOVEABLE MULTIPLE
-HEAPSIZE     4048
-STACKSIZE    16000
diff --git a/samples/thread/test.rc b/samples/thread/test.rc
deleted file mode 100644 (file)
index 82bdf07..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "wx/msw/wx.rc"
-
diff --git a/samples/thread/thread.cpp b/samples/thread/thread.cpp
new file mode 100644 (file)
index 0000000..d53bbca
--- /dev/null
@@ -0,0 +1,626 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        thread.cpp
+// Purpose:     wxWindows thread sample
+// Author:      Julian Smart(minimal)/Guilhem Lavaux(thread test)
+// Modified by:
+// Created:     06/16/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart, Markus Holzem, Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+/*
+    TODO: use worker threads to update progress controls instead of writing
+          messages - it will be more visual
+ */
+
+#ifdef __GNUG__
+    #pragma implementation "thread.cpp"
+    #pragma interface "thread.cpp"
+#endif
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+    #include "wx/wx.h"
+#endif
+
+#if !wxUSE_THREADS
+    #error "This sample requires thread support!"
+#endif // wxUSE_THREADS
+
+#include "wx/thread.h"
+#include "wx/dynarray.h"
+#include "wx/time.h"
+
+#include "wx/progdlg.h"
+
+// uncomment this to get some debugging messages from the trace code
+//#define TRACE
+
+class MyThread;
+WX_DEFINE_ARRAY(wxThread *, wxArrayThread);
+
+// Define a new application type
+class MyApp : public wxApp
+{
+public:
+    virtual bool OnInit();
+
+public:
+    // all the threads currently alive - as soon as the thread terminates, it's
+    // removed from the array
+    wxArrayThread m_threads;
+
+    // crit section protects access to all of the arrays below
+    wxCriticalSection m_critsect;
+};
+
+// Create a new application object
+IMPLEMENT_APP(MyApp)
+
+// Define a new frame type
+class MyFrame: public wxFrame
+{
+public:
+    // ctor
+    MyFrame(wxFrame *frame, const wxString& title, int x, int y, int w, int h);
+
+    // operations
+    void WriteText(const wxString& text) { m_txtctrl->WriteText(text); }
+
+    // accessors for MyWorkerThread (called in its context!)
+    bool Cancelled();
+
+    // callbacks
+    void OnQuit(wxCommandEvent& event);
+    void OnAbout(wxCommandEvent& event);
+    void OnClear(wxCommandEvent& event);
+
+    void OnStartThread(wxCommandEvent& event);
+    void OnStartThreads(wxCommandEvent& event);
+    void OnStopThread(wxCommandEvent& event);
+    void OnPauseThread(wxCommandEvent& event);
+    void OnResumeThread(wxCommandEvent& event);
+
+    void OnStartWorker(wxCommandEvent& event);
+    void OnWorkerEvent(wxCommandEvent& event);
+    void OnUpdateWorker(wxUpdateUIEvent& event);
+
+    void OnIdle(wxIdleEvent &event);
+
+private:
+    // helper function - creates a new thread (but doesn't run it)
+    MyThread *CreateThread();
+
+    // just some place to put our messages in
+    wxTextCtrl *m_txtctrl;
+
+    // remember the number of running threads and total number of threads
+    size_t m_nRunning, m_nCount;
+
+    // the progress dialog which we show while worker thread is running
+    wxProgressDialog *m_dlgProgress;
+
+    // was the worker thread cancelled by user?
+    bool m_cancelled;
+
+    // protects m_cancelled
+    wxCriticalSection m_critsectWork;
+
+    DECLARE_EVENT_TABLE()
+};
+
+// ID for the menu commands
+enum
+{
+    TEST_QUIT          = 1,
+    TEST_TEXT          = 101,
+    TEST_ABOUT,
+    TEST_CLEAR,
+    TEST_START_THREAD  = 201,
+    TEST_START_THREADS,
+    TEST_STOP_THREAD,
+    TEST_PAUSE_THREAD,
+    TEST_RESUME_THREAD,
+    TEST_START_WORKER,
+    WORKER_EVENT    // this one gets sent from the worker thread
+};
+
+//--------------------------------------------------
+// GUI thread
+//--------------------------------------------------
+
+class MyThread : public wxThread
+{
+public:
+    MyThread(MyFrame *frame);
+
+    // thread execution starts here
+    virtual void *Entry();
+
+    // called when the thread exits - whether it terminates normally or is
+    // stopped with Delete() (but not when it is Kill()ed!)
+    virtual void OnExit();
+
+    // write something to the text control
+    void WriteText(const wxString& text);
+
+public:
+    size_t   m_count;
+    MyFrame *m_frame;
+};
+
+MyThread::MyThread(MyFrame *frame)
+        : wxThread()
+{
+    m_count = 0;
+    m_frame = frame;
+}
+
+void MyThread::WriteText(const wxString& text)
+{
+    wxString msg;
+
+    // before doing any GUI calls we must ensure that this thread is the only
+    // one doing it!
+
+    wxMutexGuiEnter();
+
+    msg << text;
+    m_frame->WriteText(msg);
+
+    wxMutexGuiLeave();
+}
+
+void MyThread::OnExit()
+{
+    wxCriticalSectionLocker locker(wxGetApp().m_critsect);
+
+    wxGetApp().m_threads.Remove(this);
+}
+
+void *MyThread::Entry()
+{
+    wxString text;
+
+    text.Printf("Thread 0x%x started (priority = %d).\n",
+                GetId(), GetPriority());
+    WriteText(text);
+    // wxLogMessage(text); -- test wxLog thread safeness
+
+    for ( m_count = 0; m_count < 10; m_count++ )
+    {
+        // check if we were asked to exit
+        if ( TestDestroy() )
+            break;
+
+        text.Printf("[%u] Thread 0x%x here.\n", m_count, GetId());
+        WriteText(text);
+
+        // wxSleep() can't be called from non-GUI thread!
+        wxThread::Sleep(1000);
+    }
+
+    text.Printf("Thread 0x%x finished.\n", GetId());
+    WriteText(text);
+    // wxLogMessage(text); -- test wxLog thread safeness
+
+    return NULL;
+}
+
+//--------------------------------------------------
+// worker thread
+//--------------------------------------------------
+
+class MyWorkerThread : public wxThread
+{
+public:
+    MyWorkerThread(MyFrame *frame);
+
+    // thread execution starts here
+    virtual void *Entry();
+
+    // called when the thread exits - whether it terminates normally or is
+    // stopped with Delete() (but not when it is Kill()ed!)
+    virtual void OnExit();
+
+public:
+    MyFrame *m_frame;
+    size_t   m_count;
+};
+
+MyWorkerThread::MyWorkerThread(MyFrame *frame)
+        : wxThread()
+{
+    m_frame = frame;
+    m_count = 0;
+}
+
+void MyWorkerThread::OnExit()
+{
+}
+
+void *MyWorkerThread::Entry()
+{
+    for ( m_count = 0; !m_frame->Cancelled() && (m_count < 100); m_count++ )
+    {
+        // check if we were asked to exit
+        if ( TestDestroy() )
+            break;
+
+        wxString text;
+        text.Printf("[%u] Thread 0x%x here!!", m_count, GetId());
+
+        // create any type of command event here
+        wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, WORKER_EVENT );
+        event.SetInt( m_count );
+        event.SetString( text );
+
+        // send in a thread-safe way
+        wxPostEvent( m_frame, event );
+
+        // same as:
+        // m_frame->AddPendingEvent( event );
+
+        // wxSleep() can't be called from non-main thread!
+        wxThread::Sleep(200);
+    }
+
+    wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, WORKER_EVENT );
+    event.SetInt(-1); // that's all
+    wxPostEvent( m_frame, event );
+
+    return NULL;
+}
+
+//--------------------------------------------------
+// main program
+//--------------------------------------------------
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+    EVT_MENU(TEST_QUIT, MyFrame::OnQuit)
+    EVT_MENU(TEST_ABOUT, MyFrame::OnAbout)
+    EVT_MENU(TEST_CLEAR, MyFrame::OnClear)
+    EVT_MENU(TEST_START_THREAD, MyFrame::OnStartThread)
+    EVT_MENU(TEST_START_THREADS, MyFrame::OnStartThreads)
+    EVT_MENU(TEST_STOP_THREAD, MyFrame::OnStopThread)
+    EVT_MENU(TEST_PAUSE_THREAD, MyFrame::OnPauseThread)
+    EVT_MENU(TEST_RESUME_THREAD, MyFrame::OnResumeThread)
+
+    EVT_UPDATE_UI(TEST_START_WORKER, MyFrame::OnUpdateWorker)
+    EVT_MENU(TEST_START_WORKER, MyFrame::OnStartWorker)
+    EVT_MENU(WORKER_EVENT, MyFrame::OnWorkerEvent)
+
+    EVT_IDLE(MyFrame::OnIdle)
+END_EVENT_TABLE()
+
+// `Main program' equivalent, creating windows and returning main app frame
+bool MyApp::OnInit()
+{
+#ifdef TRACE
+    wxLog::AddTraceMask("thread");
+#endif
+
+    // Create the main frame window
+    MyFrame *frame = new MyFrame((wxFrame *)NULL, "wxWindows threads sample",
+                                 50, 50, 450, 340);
+
+    // Make a menubar
+    wxMenu *file_menu = new wxMenu;
+
+    file_menu->Append(TEST_CLEAR, "&Clear log\tCtrl-L");
+    file_menu->AppendSeparator();
+    file_menu->Append(TEST_ABOUT, "&About");
+    file_menu->AppendSeparator();
+    file_menu->Append(TEST_QUIT, "E&xit\tAlt-X");
+    wxMenuBar *menu_bar = new wxMenuBar;
+    menu_bar->Append(file_menu, "&File");
+
+    wxMenu *thread_menu = new wxMenu;
+    thread_menu->Append(TEST_START_THREAD, "&Start a new thread\tCtrl-N");
+    thread_menu->Append(TEST_START_THREADS, "Start &many threads at once");
+    thread_menu->Append(TEST_STOP_THREAD, "S&top a running thread\tCtrl-S");
+    thread_menu->AppendSeparator();
+    thread_menu->Append(TEST_PAUSE_THREAD, "&Pause a running thread\tCtrl-P");
+    thread_menu->Append(TEST_RESUME_THREAD, "&Resume suspended thread\tCtrl-R");
+    thread_menu->AppendSeparator();
+    thread_menu->Append(TEST_START_WORKER, "Start &worker thread\tCtrl-W");
+
+    menu_bar->Append(thread_menu, "&Thread");
+    frame->SetMenuBar(menu_bar);
+
+    // Show the frame
+    frame->Show(TRUE);
+
+    SetTopWindow(frame);
+
+    return TRUE;
+}
+
+// My frame constructor
+MyFrame::MyFrame(wxFrame *frame, const wxString& title,
+                 int x, int y, int w, int h)
+       : wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h))
+{
+    m_nRunning = m_nCount = 0;
+
+    m_dlgProgress = (wxProgressDialog *)NULL;
+
+    CreateStatusBar(2);
+
+    m_txtctrl = new wxTextCtrl(this, -1, "", wxPoint(0, 0), wxSize(0, 0),
+                               wxTE_MULTILINE | wxTE_READONLY);
+
+}
+
+MyThread *MyFrame::CreateThread()
+{
+    MyThread *thread = new MyThread(this);
+
+    if ( thread->Create() != wxTHREAD_NO_ERROR )
+    {
+        wxLogError("Can't create thread!");
+    }
+
+    wxCriticalSectionLocker enter(wxGetApp().m_critsect);
+    wxGetApp().m_threads.Add(thread);
+
+    return thread;
+}
+
+void MyFrame::OnStartThreads(wxCommandEvent& WXUNUSED(event) )
+{
+    static long s_num = 10;
+
+    s_num = wxGetNumberFromUser("How many threads to start: ", "",
+                                "wxThread sample", s_num, 1, 10000, this);
+    if ( s_num == -1 )
+    {
+        s_num = 10;
+
+        return;
+    }
+
+    size_t count = (size_t)s_num, n;
+
+    wxArrayThread threads;
+
+    // first create them all...
+    for ( n = 0; n < count; n++ )
+    {
+        wxThread *thr = CreateThread();
+
+        // we want to show the effect of SetPriority(): the first thread will
+        // have the lowest priority, the second - the highest, all the rest
+        // the normal one
+        if ( n == 0 )
+            thr->SetPriority(WXTHREAD_MIN_PRIORITY);
+        else if ( n == 1 )
+            thr->SetPriority(WXTHREAD_MAX_PRIORITY);
+        else
+            thr->SetPriority(WXTHREAD_DEFAULT_PRIORITY);
+
+        threads.Add(thr);
+    }
+
+    wxString msg;
+    msg.Printf("%d new threads created.", count);
+    SetStatusText(msg, 1);
+
+    // ...and then start them
+    for ( n = 0; n < count; n++ )
+    {
+        threads[n]->Run();
+    }
+}
+
+void MyFrame::OnStartThread(wxCommandEvent& WXUNUSED(event) )
+{
+    MyThread *thread = CreateThread();
+
+    if ( thread->Run() != wxTHREAD_NO_ERROR )
+    {
+        wxLogError("Can't start thread!");
+    }
+
+    SetStatusText("New thread started.", 1);
+}
+
+void MyFrame::OnStopThread(wxCommandEvent& WXUNUSED(event) )
+{
+    wxGetApp().m_critsect.Enter();
+
+    // stop the last thread
+    if ( wxGetApp().m_threads.IsEmpty() )
+    {
+        wxLogError("No thread to stop!");
+
+        wxGetApp().m_critsect.Leave();
+    }
+    else
+    {
+        wxThread *thread = wxGetApp().m_threads.Last();
+
+        // it's important to leave critical section before calling Delete()
+        // because delete will (implicitly) call OnExit() which also tries
+        // to enter the same crit section - would dead lock.
+        wxGetApp().m_critsect.Leave();
+
+        thread->Delete();
+
+        SetStatusText("Thread stopped.", 1);
+    }
+}
+
+void MyFrame::OnResumeThread(wxCommandEvent& WXUNUSED(event) )
+{
+    wxCriticalSectionLocker enter(wxGetApp().m_critsect);
+
+    // resume first suspended thread
+    size_t n = 0, count = wxGetApp().m_threads.Count();
+    while ( n < count && !wxGetApp().m_threads[n]->IsPaused() )
+        n++;
+
+    if ( n == count )
+    {
+        wxLogError("No thread to resume!");
+    }
+    else
+    {
+        wxGetApp().m_threads[n]->Resume();
+
+        SetStatusText("Thread resumed.", 1);
+    }
+}
+
+void MyFrame::OnPauseThread(wxCommandEvent& WXUNUSED(event) )
+{
+    wxCriticalSectionLocker enter(wxGetApp().m_critsect);
+
+    // pause last running thread
+    int n = wxGetApp().m_threads.Count() - 1;
+    while ( n >= 0 && !wxGetApp().m_threads[n]->IsRunning() )
+        n--;
+
+    if ( n < 0 )
+    {
+        wxLogError("No thread to pause!");
+    }
+    else
+    {
+        wxGetApp().m_threads[n]->Pause();
+
+        SetStatusText("Thread paused.", 1);
+    }
+}
+
+// set the frame title indicating the current number of threads
+void MyFrame::OnIdle(wxIdleEvent &event)
+{
+    // update the counts of running/total threads
+    size_t nRunning = 0,
+           nCount = wxGetApp().m_threads.Count();
+    for ( size_t n = 0; n < nCount; n++ )
+    {
+        if ( wxGetApp().m_threads[n]->IsRunning() )
+            nRunning++;
+    }
+
+    if ( nCount != m_nCount || nRunning != m_nRunning )
+    {
+        m_nRunning = nRunning;
+        m_nCount = nCount;
+
+        wxLogStatus(this, "%u threads total, %u running.", nCount, nRunning);
+    }
+    //else: avoid flicker - don't print anything
+}
+
+void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
+{
+    size_t count = wxGetApp().m_threads.Count();
+    for ( size_t i = 0; i < count; i++ )
+    {
+        wxGetApp().m_threads[0]->Delete();
+    }
+
+    Close(TRUE);
+}
+
+void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
+{
+    wxMessageDialog dialog(this, "wxWindows multithreaded application sample\n"
+                                 "(c) 1998 Julian Smart, Guilhem Lavaux\n"
+                                 "(c) 1999 Vadim Zeitlin\n"
+                                 "(c) 2000 Robert Roebling",
+                           "About wxThread sample",
+                           wxOK | wxICON_INFORMATION);
+
+    dialog.ShowModal();
+}
+
+void MyFrame::OnClear(wxCommandEvent& WXUNUSED(event))
+{
+#ifdef TRACE
+    // log a separator
+    wxLogTrace("-------- log window cleared --------");
+#endif
+
+    m_txtctrl->Clear();
+}
+
+void MyFrame::OnUpdateWorker(wxUpdateUIEvent& event)
+{
+    event.Enable( m_dlgProgress == NULL );
+}
+
+void MyFrame::OnStartWorker(wxCommandEvent& WXUNUSED(event))
+{
+    MyWorkerThread *thread = new MyWorkerThread(this);
+
+    if ( thread->Create() != wxTHREAD_NO_ERROR )
+    {
+        wxLogError("Can't create thread!");
+    }
+
+    m_dlgProgress = new wxProgressDialog
+                        (
+                         "Progress dialog",
+                         "Wait until the thread terminates or press [Cancel]",
+                         100,
+                         this,
+                         wxPD_CAN_ABORT |
+                         wxPD_APP_MODAL |
+                         wxPD_ELAPSED_TIME |
+                         wxPD_ESTIMATED_TIME |
+                         wxPD_REMAINING_TIME
+                        );
+
+    // thread is not running yet, no need for crit sect
+    m_cancelled = FALSE;
+
+    thread->Run();
+}
+
+void MyFrame::OnWorkerEvent(wxCommandEvent& event)
+{
+#if 0
+    WriteText( "Got message from worker thread: " );
+    WriteText( event.GetString() );
+    WriteText( "\n" );
+#else
+    int n = event.GetInt();
+    if ( n == -1 )
+    {
+        m_dlgProgress->Destroy();
+        m_dlgProgress = (wxProgressDialog *)NULL;
+
+        // the dialog is aborted because the event came from another thread, so
+        // we may need to wake up the main event loop for the dialog to be
+        // really closed
+        wxWakeUpIdle();
+    }
+    else
+    {
+        if ( !m_dlgProgress->Update(n) )
+        {
+            wxCriticalSectionLocker lock(m_critsectWork);
+
+            m_cancelled = TRUE;
+        }
+    }
+#endif
+}
+
+bool MyFrame::Cancelled()
+{
+    wxCriticalSectionLocker lock(m_critsectWork);
+
+    return m_cancelled;
+}
diff --git a/samples/thread/thread.def b/samples/thread/thread.def
new file mode 100644 (file)
index 0000000..ca22c39
--- /dev/null
@@ -0,0 +1,7 @@
+NAME         Thread
+DESCRIPTION  'wxWindows thread sample'
+EXETYPE      WINDOWS
+CODE         PRELOAD MOVEABLE DISCARDABLE
+DATA         PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE     4048
+STACKSIZE    16000
diff --git a/samples/thread/thread.rc b/samples/thread/thread.rc
new file mode 100644 (file)
index 0000000..82bdf07
--- /dev/null
@@ -0,0 +1,2 @@
+#include "wx/msw/wx.rc"
+