【问题标题】:Some trouble with C++ Builder 6C++ Builder 6 的一些问题
【发布时间】:2013-09-25 18:29:54
【问题描述】:

我刚刚尝试在 C++ Builder 6 中编写小程序(不要问我为什么,这只是学院的作业)。 所以,当我调整表单大小时,我的程序必须隐藏 button1。 但是在创建窗口后会引发resize事件,这意味着在我启动程序后button1已经不可见了。

void __fastcall TForm1::FormResize(TObject *Sender)
{
  Button1->Visible = false;
}

我尝试使用不同的调整大小事件,但它也不起作用。 我做错了什么?

PS。对不起我的英语不好。

【问题讨论】:

  • 在您创建表单的工具中,验证按钮的默认值。您可能希望将其设置为禁用。

标签: c++ user-interface vcl c++builder-6


【解决方案1】:

没有错。表单在创建时确实会调整大小,这就是您获得事件的原因。有很多方法可以解决这个问题:

  1. 使用变量忽略第一个OnResize 事件,直到表单准备好:

    private:
        bool fReady;
    

    void __fastcall TForm1::FormResize(TObject *Sender)
    {
        if (!fReady)
            fReady = true;
        else
            Button1->Visible = false;
    }
    
  2. 使用表单的OnShow 事件发布自定义消息以表明表单已准备就绪:

    private:
        bool fReady;
    protected:
        virtual void __fastcall WndProc(TMessage &Message);
    

    const UINT WM_READY = WM_APP + 100;
    
    void __fastcall TForm1::WndProc(TMessage &Message)
    {
        if (Message.Msg == WM_READY)
            fReady = true;
        else
            TForm::WndProc(Message);
    }
    
    void __fastcall TForm1::FormShow(TObject *Sender)
    {
        PostMessage(Handle, WM_READY, 0, 0);
    }
    
    void __fastcall TForm1::FormResize(TObject *Sender)
    {
        if (fReady)
            Button1->Visible = false;
    }
    
  3. 使用短计时器而不是自定义消息:

    private:
        bool fReady;
    

    void __fastcall TForm1::Timer1Timer(TMessage &Message)
    {
        Timer1->Enabled = false;
        fReady = true;
    }
    
    void __fastcall TForm1::FormShow(TObject *Sender)
    {
        Timer1->Enabled = true;
    }
    
    void __fastcall TForm1::FormResize(TObject *Sender)
    {
        if (fReady)
            Button1->Visible = false;
    }
    

仅举几例。

【讨论】:

  • 为什么要推送消息而不是在FormShow 处理程序中设置fReady = true;? (注意fReady需要在构造函数中初始化为false)。
  • OnShow 事件在窗体实际显示在屏幕上之前触发,因此消息发布只是一个额外的延迟,以确保用户在允许按钮隐藏之前看到窗口。并且该变量由 RTL 初始化为 false,因为它是 Form 类的成员,并且所有 TObject 后代(TForm1 是)在调用构造函数之前自动用零填充其分配的内存。
  • 我们在编码时应该依赖零内存行为吗?
  • 这是TObject 类的 Delphi/C++Builder 编译器特有的功能。在执行构造函数之前,所有TObject 派生类都会自动初始化为零。这不是标准的 C++ 行为,但它在 C++Builder 中仅适用于 TObject 派生类。
猜你喜欢
  • 1970-01-01
  • 2015-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多