C ++ builder>从TThread禁用Form TButton不起作用

时间:2015-08-03 02:20:07

标签: c++builder

我的环境:

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日) 我添加了一些信息

  • 从Form1
  • 调用TThread(TMainThread)
  • 更改已启用Form1-&gt; B_button通过TThread无法正常工作
  • 更改已启用Form2-&gt; B_close通过TThread确实有效

我可能需要通过小程序来检查这些问题。

现在,我有4个小文件,我仍然遇到同样的问题。

Main.h

#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

Main.cpp的

#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;
}

ThreadMain.h

//---------------------------------------------------------------------------

#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

ThreadMain.cpp

//---------------------------------------------------------------------------

#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。

1 个答案:

答案 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文件有这种奇怪的设置。