Article View: borland.public.cppbuilder.nativeapi
Article #4578Re: Animation with TThread in non client area (border form)
From: Remy Lebeau (TeamB)
Date: Thu, 12 Jan 2006 20:14
Date: Thu, 12 Jan 2006 20:14
257 lines
8059 bytes
8059 bytes
"Carlos" <a@a.com> wrote in message news:43c6ac4c@newsgroups.borland.com...
> I donοΏ½t understand.
Like I said earlier, the thread code you showed earlier is not safe, and
using a thread is not necessary to begin with.
> This code works
Only out of luck. The thread code is accessing memory that is not protected
from simultaneous access from multiple threads. You have a good chance of
corrupting memory, since you are performing operations that can alter shared
memory while the main thread is using the same memory for other things.
> How could I draw in DC of Mainform in a safe manner ?
I already told you how - you have to use the thead's Synchronize() method,
ie:
class TAnimationThread : public TThread
{
private:
int FSpeed;
bool FProgressBarEnabled;
HWND FMainFormWnd;
Graphics::TBitmap *FBitmap;
int FIndex;
int FWidth;
protected:
void __fastcall Execute()
void __fastcall ProgressBarEnabledSync();
bool __fastcall IsProgressBarEnabled();
void __fastcall MainFormHandleSync();
HWND __fastcall GetMainFormHandle();
void __fastcall ImageSync();
void __fastcall MainFormWidthSync();
int __fastcall GetMainFormWidth();
public:
__fastcall TAnimationThread(int nSpeed);
};
__fastcall TAnimationThread::TAnimationThread(int nSpeed)
: TThread(true)
{
FreeOnTerminate = true;
FSpeed = nSpeed;
Priority = tpHighest;
Resume();
}
void __fastcall TAnimationThread::ProgressBarEnabledSync()
{
FProgressBarEnabled = FormMain->TimerProgressBar->Enabled;
}
bool __fastcall TAnimationThread::IsProgressBarEnabled()
{
Synchronize(ProgressBarEnabledSync);
return FProgressBarEnabled;
}
void __fastcall TAnimationThread::MainFormHandleSync()
{
FMainFormWnd = FormMain->Handle;
}
HWND __fastcall TAnimationThread::GetMainFormHandle()
{
Synchronize(MainFormHandleSync);
return FMainFormWnd;
}
void __fastcall TAnimationThread::ImageSync()
{
FormMain->ImageListAnimate->GetBitmap(FIndex, FBitmap);
}
void __fastcall TAnimationThread::MainFormWidthSync()
{
FWidth = FormMain->Width;;
}
int __fastcall TAnimationThread::GetMainFormWidth()
{
Synchronize(MainFormWidthSync);
return FWidth;
}
void __fastcall TAnimationThread::Execute()
{
FIndex = 0;
int nDir;
FBitmap = new Graphics::TBitmap;
try
{
TCanvas *pCanvas = new TCanvas;
try
{
while( !Terminated )
{
if( !IsProgressBarEnabled() )
FIndex = 0;
HWND hWnd = GetMainFormHandle();
HDC Dc = GetWindowDC(hWnd);
try
{
pCanvas->Handle = Dc;
try
{
int pMode = SetBkMode(Dc, TRANSPARENT);
try
{
Synchronize(ImageSync);
pCanvas->Draw(GetMainFormWidth() -
FBitmap->Width - 2, 2, FBitmap);
}
__finally {
SetBkMode(Dc, pMode);
}
}
__finally {
pCanvas->Handle = NULL;
}
}
__finally {
ReleaseDC(hWnd, Dc);
}
if( FIndex == 8 )
nDir = -1;
else if( FIndex == 0 )
nDir = 1;
FIndex += nDir;
Sleep(FSpeed);
if ( !IsProgressBarEnabled() )
{
FIndex = 0;
Terminate();
}
}
}
__finally {
delete pCanvas;
}
}
__finally {
delete FBitmap;
}
}
Or else get rid of the thread altogether and use a timer in the main thread
instead since your code is not benefitting from being threaded in the first
place:
class TFormMain : public TForm
{
__published:
TTimer *AnimationTimer;
TImageList *ImageListAnimate;
TProgressBar *TimerProgressBar;
//...
void __fastcall FormPaint(TObject *Sender);
void __fastcall AnimationTimerTimer(TObject *Sender);
//...
private
Graphics::TBitmap *FAnimationBitmap;
int FAnimationIndex;
//...
void __fastcall AnimationBitmapChanged(TObject *Sender);
//...
public:
__fastcall TFormMain(TComponent *Owner);
__fastcall ~TFormMain();
//...
void __fastcall StartAnimation();
void __fastcall StopAnimation();
};
__fastcall TFormMain::TFormMain(TComponent *Owner)
: TForm(Owner)
{
FAnimationBitmap = Graphics::TBitmap;
FAnimationBitmap->OnChange = AnimationBitmapChanged;
}
__fastcall TFormMain::~TFormMain()
{
delete FAnimationBitmap;
}
void __fastcall TFormMain::FormPaint(TObject *Sender)
{
if( !FAnimationBitmap->Empty )
{
// output the caption string
int OldMode = SetBkMode(Canvas->Handle, TRANSPARENT);
try {
Canvas->Draw(Width - FAnimationBitmap->Width - 2, 2,
FAnimationBitmap);
}
__finally {
SetBkMode(Canvas->Handle, OldMode);
}
}
}
void __fastcall TFormMain::AnimationTimerTimer(TObject *Sender)
{
if( !TimerProgressBar->Enabled )
FAnimationIndex = 0;
ImageListAnimate->GetBitmap(FAnimationIndex, FAnimationBitmap);
if( FAnimationIndex == 8 )
--FAnimationIndex;
else if( FAnimationIndex == 0 )
++FAnimationIndex;
if( !TimerProgressBar->Enabled )
FAnimationIndex = 0;
}
void __fastcall TFormMain::AnimationBitmapChanged(TObject *Sender)
{
Invalidate();
}
void __fastcall TFormMain::StartAnimation()
{
AnimationTimer->Interval = 1000; // <-- use whatever interval you
want
AnimationTimer->Enabled = true;
}
void __fastcall TFormMain::StopAnimation()
{
AnimationTimer->Enabled = false;
FAnimationBitmap->Assign(NULL);
}
Gambit
Technical Details
Message-ID:
<43c6b80f$1@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newshub.sdsu.edu!logbridge.uoregon.edu!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mailReferences:
<43c29a01@newsgroups.borland.com> <43c2b613$1@newsgroups.borland.com> <43c6ac4c@newsgroups.borland.com>Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,7abd13b8dc24dd8a X-Google-Attributes: gid10cc67,public X-Google-Language: ENGLISH,ASCII From: "Remy Lebeau \(TeamB\)" <no.spam@no.spam.com> Newsgroups: borland.public.cppbuilder.nativeapi References: <43c29a01@newsgroups.borland.com> <43c2b613$1@newsgroups.borland.com> <43c6ac4c@newsgroups.borland.com> Subject: Re: Animation with TThread in non client area (border form) Date: Thu, 12 Jan 2006 12:14:31 -0800 Lines: 259 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1409 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1409 NNTP-Posting-Host: 68.69.17.41 Message-ID: <43c6b80f$1@newsgroups.borland.com> X-Trace: newsgroups.borland.com 1137096719 68.69.17.41 (12 Jan 2006 12:11:59 -0700) Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newshub.sdsu.edu!logbridge.uoregon.edu!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail