Reputation: 1554
My environment:
C++ Builder XE4 on Windows7 Pro (32bit)
I'm trying to Enable/Disable TButton on Form1 from TThread;
In TThread, I define following and use them
void __fastcall TThreadMain::Form1_enableButtons(bool bfOn)
{
m_setOnOff = bfOn;
Synchronize(Sync_enableButtons);
}
void __fastcall TThreadMain::Sync_enableButtons(void) {
Form1->B_button->Enabled = m_setOnOff;
}
However, this does not disable/enable buttons on Form1.
When I would like to disable/enable Buttons from TThread, what should I do?
I may need to check these through small program to understand the problem.
Now, I have 4 small files, with which I still have the same problem.
#ifndef MainH
#define MainH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ComCtrls.hpp>
#include "ThreadMain.h"
class TFormMain : public TForm
{
__published:
TStatusBar *StatusBar1;
TButton *B_manualPdfMake;
TButton *B_option;
void __fastcall B_optionClick(TObject *Sender);
void __fastcall B_manualPdfMakeClick(TObject *Sender);
private:
TThreadMain *m_thr_main;
public:
void __fastcall EnableButtons(bool bfOn);
__fastcall TFormMain(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TFormMain *FormMain;
//---------------------------------------------------------------------------
#endif
#include <vcl.h>
#pragma hdrstop
#include "Main.h"
#include "option.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFormMain *FormMain;
//---------------------------------------------------------------------------
__fastcall TFormMain::TFormMain(TComponent* Owner)
: TForm(Owner)
{
m_thr_main = new TThreadMain(NULL);
m_thr_main->Resume();
}
void __fastcall TFormMain::B_optionClick(TObject *Sender)
{
Options->ShowModal();
}
void __fastcall TFormMain::B_manualPdfMakeClick(TObject *Sender)
{
m_thr_main->SetManualPdfReq();
}
void __fastcall TFormMain::EnableButtons(bool bfOn)
{
B_manualPdfMake->Enabled = bfOn;
}
//---------------------------------------------------------------------------
#ifndef ThreadMainH
#define ThreadMainH
//---------------------------------------------------------------------------
#include <System.Classes.hpp> // for TMemo
//---------------------------------------------------------------------------
class TThreadMain : public TThread
{
private:
void __fastcall FormMain_enableButtons(bool bfOn);
void __fastcall Sync_enableButtons(void);
bool m_bfManualPdfReq;
bool m_setOnOff; // for Synchronize()
protected:
void __fastcall Execute();
public:
void __fastcall SetManualPdfReq(); // start process
__fastcall TThreadMain(TMemo *pmemo);
};
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "ThreadMain.h"
#include "Main.h"
#include "option.h"
#pragma package(smart_init)
__fastcall TThreadMain::TThreadMain(TMemo *pmemo)
: TThread(/* CreateSuspended=*/ true)
{
// Priority = tpHigher; // TODO: consider priority
m_bfManualPdfReq = false;
FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall TThreadMain::SetManualPdfReq() { m_bfManualPdfReq = true; }
void __fastcall TThreadMain::Execute()
{
while(!Terminated) {
if (m_bfManualPdfReq) {
m_bfManualPdfReq = false;
FormMain_enableButtons(false);
Sleep(3000); // instead of calling some function()
FormMain_enableButtons(true);
ShowMessage(L"Fin");
}
Sleep(100);
}
int nop=1;
}
//---------------------------------------------------------------------------
void __fastcall TThreadMain::FormMain_enableButtons(bool bfOn)
{
m_setOnOff = bfOn;
Synchronize(Sync_enableButtons);
}
void __fastcall TThreadMain::Sync_enableButtons(void) {
Options->Show();
Options->B_cancel->Enabled = m_setOnOff; // works
FormMain->EnableButtons(m_setOnOff); // does not work
}
//---------------------------------------------------------------------------
Something strange is happening.
When the FormMain is the default form opening during the Application boot, the FormMain's TButtons cannot be disabled from Synchronize() of TThread.
On the other hand, if the same FormMain is set to non-defualt Form during Application boot, and after Show() from other Form, FormMain's TButtons can be disabled from Synchronize() of TThread.
Upvotes: 0
Views: 1121
Reputation: 1554
I solved by myself.
In the procject cpp file, somehow I have duplication of CreateForm() of FormMain as follows.
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
//---------------------------------------------------------------------------
USEFORM("Unit2.cpp", Form2);
USEFORM("Main.cpp", FormMain);
//---------------------------------------------------------------------------
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
try
{
Application->Initialize();
Application->MainFormOnTaskBar = true;
Application->CreateForm(__classid(TFormMain), &FormMain);
Application->CreateForm(__classid(TForm2), &Form2);
Application->CreateForm(__classid(TFormMain), &FormMain);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------
When I comment out one of the CreateForm() for FormMain, the problem has gone.
I am not sure why the .cpp file has this strange setting.
Upvotes: 1