我的环境:
C++ Builder XE4 on Windows7 Pro (32bit)
我试图从TThread启用/禁用Form1上的TButton;
在TThread中,我定义了以下内容并使用它们
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;
}
但是,这不会禁用/启用Form1上的按钮。
当我想从TThread禁用/启用按钮时,我该怎么办?
<小时/> (已添加:2015年8月3日) 我添加了一些信息
我可能需要通过小程序来检查这些问题。
现在,我有4个小文件,我仍然遇到同样的问题。
#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
}
//---------------------------------------------------------------------------
<小时/> (补充:2015年8月3日)
发生了一些奇怪的事情。
当FormMain是应用程序启动期间打开的默认表单时,无法从TThread的Synchronize()禁用FormMain的TButtons。
另一方面,如果在应用程序启动期间将相同的FormMain设置为非defualt Form,并且在其他Form的Show()之后,可以从TThread的Synchronize()禁用FormMain的TButtons。
答案 0 :(得分:1)
我自己解决了。
在procject cpp文件中,我以某种方式重复了FormMain的CreateForm(),如下所示。
//---------------------------------------------------------------------------
#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;
}
//---------------------------------------------------------------------------
当我为FormMain注释掉一个CreateForm()时,问题就消失了。
我不确定为什么.cpp文件有这种奇怪的设置。