fthread.cpp

来自「最新版 JCL+JVCL控件!非常不错的控件资源。包含了所能用到的大部分功能!」· C++ 代码 · 共 674 行 · 第 1/2 页

CPP
674
字号
/******************************************************************

                       JEDI-VCL Demo

 Copyright (C) 2002 Project JEDI

 Original author:

 Contributor(s):
   korecek: translation from Delphi to BCB

 You may retrieve the latest version of this file at the JEDI-JVCL
 home page, located at http://jvcl.sourceforge.net

 The contents of this file are used with permission, subject to
 the Mozilla Public License Version 1.1 (the "License"); you may
 not use this file except in compliance with the License. You may
 obtain a copy of the License at
 http://www.mozilla.org/MPL/MPL-1_1Final.html

 Software distributed under the License is distributed on an
 "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 implied. See the License for the specific language governing
 rights and limitations under the License.

******************************************************************/
// $Id: fThread.cpp 11331 2007-06-17 16:38:39Z jfudickar $
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <stdlib.h>

//#include "D:\Program Files\Borland\CBuilder5\User Components\JVCL\run\JvThread.hpp"
//#include "JvThread.hpp"
#include "fThread.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "JvComponent"
#pragma link "JvThread"
#pragma link "JvThreadDialog"
#pragma link "JvComponentBase"
#pragma link "JvExMask"
#pragma link "JvSpin"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
int LifeTime=0;
bool SuspendRandomThread=false;
bool RaiseExceptInThread=false;
//---------------------------------------------------------------------------
typedef struct SJobData
{
 int Dummy[10];
} SJobData;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 randomize();

 cbExclusive1->Checked=JvThread1->Exclusive;
 cbExclusive2->Checked=JvThread2->Exclusive;

 seMaxCount1->AsInteger=JvThread1->MaxCount;
 seMaxCount2->AsInteger=JvThread2->MaxCount;

 cbDeferredExecution1->Checked=!JvThread1->RunOnCreate;
 cbDeferredExecution2->Checked=!JvThread2->RunOnCreate;

 cbDeferredDeletion1->Checked=!JvThread1->FreeOnTerminate;
 cbDeferredDeletion2->Checked=!JvThread2->FreeOnTerminate;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::JvThread1Execute(TObject *Sender, Pointer Params)
{
// old: TJvThread* Container=dynamic_cast<TJvThread*>(Sender);

  TJvBaseThread* ThisThread=dynamic_cast<TJvBaseThread*>(Sender);
  if(ThisThread==NULL) // for testing only
   throw Exception("Execution error: 'Sender' is not TJvBaseThread object");

  if(JvThread1->Terminated) // flag 'Terminated' for current thread; slower then direct ThisThread->Terminated
  { // terminated before resume
   JvThread1->ReturnValue=-1; // for current thread; slower then direct ThisThread->ReturnValue
   exit;
  }

  int i, j, k;
  bool FL_Break=false;

  JvThread1->ReturnValue=0; // for current thread; slower then direct ThisThread->ReturnValue

  //Do the job here
  k = 0;
  for(i=0; i<1000 && !FL_Break; ++i)
  {
    for(j=0; j<10; ++j)
    {
      ++k;
      // I included here ::Sleep(0) unlike the original Delphi code to
      // allow the other threads to process as well. (c)VK
      ::Sleep(0);
      //To use global variable/objects, you have to synchronize (to avoid conflicts)
      Form1->ThreadID1 = ThisThread->ThreadID;
      Form1->Value1 = k;
      JvThread1->Synchronize(Form1->Stats1); // slower then direct ThisThread->Synchronize(Form1->Stats1)

      if(SuspendRandomThread)
      {
       SuspendRandomThread=false;
       JvThread1->Suspend(); // current thread (i.e. itself)
      }

      if(RaiseExceptInThread)
      {
       RaiseExceptInThread=false;
       JvThread1->ReturnValue=666; // for current thread; slower then direct ThisThread->ReturnValue
       throw Exception("Exception in Job1, ThreadID="+IntToHex((int)ThisThread->ThreadID, 8));
      }

      if(JvThread1->Terminated) // flag 'Terminated' for current thread; slower then direct ThisThread->Terminated
      {
        FL_Break = true;
        JvThread1->ReturnValue=1;
        break;
      }
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::JvThread2Execute(TObject *Sender, Pointer Params)
{
// old: TJvThread* Container=dynamic_cast<TJvThread*>(Sender);

  TJvBaseThread* ThisThread=dynamic_cast<TJvBaseThread*>(Sender);
  if(ThisThread==NULL) // for testing only
   throw Exception("Execution error: 'Sender' is not TJvBaseThread object");

  if(ThisThread->Terminated)
  {
   ThisThread->ReturnValue=-1;  // terminated before resume
   return;
  }

  if(LifeTime)
  {
   // Sleep(LifeTime);
   int t=GetTickCount();
   while(GetTickCount()-t<LifeTime);

   ThisThread->ReturnValue=555;
   return;
  }

  SJobData* Data=reinterpret_cast<SJobData*>(ThisThread->Params); // Data==Params

  TJvThread* Container=dynamic_cast<TJvThread*>(ThisThread->Container);
  if(Container==NULL) // for testing only
   throw Exception("Execution error: container is not TJvThread component");

  int i, j, k=0;
  //Do the job here
  for(i=0; i<1000 && !ThisThread->Terminated; ++i)
  {
    for(j=0; j<10 && !ThisThread->Terminated; ++j)
    {
      k+=5; //This is the only difference with the other thread
      ::Sleep(Data->Dummy[1]);
      //To use global variable/objects, you have to synchronize (to avoid conflicts)
      Form1->ThreadID2 = ThisThread->ThreadID;
      Form1->Value2=k;
      ThisThread->Synchronize(Form1->Stats2);
// or Container->Synchronize(Form1->Stats2); // slower then direct ThisThread->Synchronize

      if(SuspendRandomThread)
      {
       SuspendRandomThread=false;
       JvThread2->Suspend(); // current thread (i.e. itself)
      }

      if(RaiseExceptInThread)
      {
       RaiseExceptInThread=false;
       ThisThread->ReturnValue=666;
       throw Exception("Exception in Job2, ThreadID="+IntToHex((int)ThisThread->ThreadID, 8));
      }
    }
  }

  if(ThisThread->Terminated) ThisThread->ReturnValue=1;
  else ThisThread->ReturnValue=0;

  if(Data->Dummy[0])
  { // Show sample msg before exit
    AnsiString s;
    if(ThisThread->Terminated) s="Job2: Terminated";
    else s="Job2: Normal finish";
    ThisThread->SynchMessageDlg(s+": ID=0x"+IntToHex((int)ThisThread->ThreadID, 8), mtInformation, TMsgDlgButtons()<<mbOK, 0);
// or Container->SynchMessageDlg(s+": ID=0x"+IntToHex((int)ThisThread->ThreadID, 8), mtInformation, TMsgDlgButtons()<<mbOK, 0);
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Stats1(void)
{
  lbStats1->Caption = "ID:"+IntToHex(ThreadID1, 8)+ " V:"+IntToStr(Value1);
}

void __fastcall TForm1::Stats2(void)
{
  lbStats2->Caption = "ID:"+IntToHex(ThreadID2, 8)+ " V:"+IntToStr(Value2);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnStartJob1Click(TObject *Sender)
{
  JvThread1->ThreadDialog = NULL;
  TJvBaseThread* t=JvThread1->Execute(NULL);
  if(t)
  {
   int id=t->ThreadID;
   Memo->Lines->Add("Job1 started: "+IntToHex(id, 8));
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnStartJob1SimpleDlgClick(TObject *Sender)
{
  JvThread1->ThreadDialog = JvThreadSimpleDialog1;
  TJvBaseThread* t=JvThread1->Execute(NULL);
  if(t)
  {
   int id=t->ThreadID;
   Memo->Lines->Add("Job1 with Simple Dlg started: "+IntToHex(id, 8));
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnStartJob2Click(TObject *Sender)
{
  JvThread2->ThreadDialog = NULL;
  SJobData* Data=new SJobData;
  Data->Dummy[0]=cbShowMsgBeforeExit2->Checked;
  Data->Dummy[1]=rand()%10;
  TJvBaseThread* t=JvThread2->Execute(Data);
  if(t)
  {
   int id=t->ThreadID;
   Memo->Lines->Add("Job2 started: "+IntToHex(id, 8));
  }
  else
   delete Data; // thread was not started
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnStartJob2AnimatedDlgClick(TObject *Sender)
{
  JvThread2->ThreadDialog = JvThreadAnimateDialog1;
  SJobData* Data=new SJobData;
  Data->Dummy[0]=cbShowMsgBeforeExit2->Checked;
  Data->Dummy[1]=rand()%10;
  TJvBaseThread* t=JvThread2->Execute(Data);
  if(t)
  {
   int id=t->ThreadID;
   Memo->Lines->Add("Job2 with Animated Dlg started: "+IntToHex(id, 8));
  }
  else
   delete Data; // thread was not started
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cbExclusive1Click(TObject *Sender)
{
 JvThread1->Exclusive=cbExclusive1->Checked;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cbExclusive2Click(TObject *Sender)
{
 JvThread2->Exclusive=cbExclusive2->Checked;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cbDeferredExecution1Click(TObject *Sender)
{
 JvThread1->RunOnCreate=!cbDeferredExecution1->Checked;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cbDeferredExecution2Click(TObject *Sender)
{
 JvThread2->RunOnCreate=!cbDeferredExecution2->Checked;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cbDeferredDeletion1Click(TObject *Sender)
{
  JvThread1->FreeOnTerminate=!cbDeferredDeletion1->Checked;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cbDeferredDeletion2Click(TObject *Sender)
{
  JvThread2->FreeOnTerminate=!cbDeferredDeletion2->Checked;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::seMaxCount1Change(TObject *Sender)
{
  JvThread1->MaxCount=seMaxCount1->AsInteger;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::seMaxCount2Change(TObject *Sender)
{
  JvThread2->MaxCount=seMaxCount2->AsInteger;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cbPriority1Change(TObject *Sender)
{
 int p=cbPriority1->ItemIndex;
 if(p>=0)
 {
  int old=JvThread1->Priority;
  JvThread1->SetPriority((TThreadPriority)p); // all threads
  if(p>old) Memo->Lines->Add("Job1 priority boosted");
  if(p<old) Memo->Lines->Add("Job1 priority reduced");
 }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cbPriority2Change(TObject *Sender)
{
 int p=cbPriority2->ItemIndex;
 if(p>=0)
 {
  int old=JvThread2->Priority;
  JvThread2->SetPriority((TThreadPriority)p); // all threads
  if(p>old) Memo->Lines->Add("Job2 priority boosted");
  if(p<old) Memo->Lines->Add("Job2 priority reduced");
 }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnSuspendAll1Click(TObject *Sender)
{
 cbAutoStart1->Checked=false;
 JvThread1->Suspend(); // all threads
 Memo->Lines->Add("Job1 suspended");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?