Winforms C++;表单启动时无响应 我正在做我的第一个C++项目,它需要一个表单,而我似乎已经超越了我的头脑。在很大程度上,我认为我的问题与我的表单没有多线程有关,但我不确定正确的实现。我希望有人能指出我到底去了哪里,让我看起来像个木偶。(对于内心的假象,我使用全局变量快速创建概念证明,一旦一切正常运行,我将返回并正确保护一切)

Winforms C++;表单启动时无响应 我正在做我的第一个C++项目,它需要一个表单,而我似乎已经超越了我的头脑。在很大程度上,我认为我的问题与我的表单没有多线程有关,但我不确定正确的实现。我希望有人能指出我到底去了哪里,让我看起来像个木偶。(对于内心的假象,我使用全局变量快速创建概念证明,一旦一切正常运行,我将返回并正确保护一切),winforms,visual-c++,c++-cli,Winforms,Visual C++,C++ Cli,*编辑:我想澄清一下,问题似乎是我在主线程中执行所有操作,可以为整个表单创建一个新线程,还是需要为表单上的每个控件创建一个新线程 Winmain.cpp 初始化表单并更新表单上的信息/刷新表单的主函数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { using namespace Interface; cooldowns ^ CDwi

*编辑:我想澄清一下,问题似乎是我在主线程中执行所有操作,可以为整个表单创建一个新线程,还是需要为表单上的每个控件创建一个新线程

Winmain.cpp

初始化表单并更新表单上的信息/刷新表单的主函数

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    using namespace Interface;
    cooldowns ^ CDwin = gcnew cooldowns;
    CDwin->Show();
    CDwin->Location = Point(0,0);

    while (true)
    {
        CDwin->timer1->Text = timer1Duration.ToString();
        CDwin->timer1Progress->Value = timer1Value;
        CDwin->timer1->Refresh();
        CDwin->timer1Progress->Refresh();

        //collect info to populate CDwin values for next cycle
        //something tells me this sleep could be part of the problem?

        Sleep(50);
    }
}
表格h

#pragma once

namespace Interface {

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    using namespace System::Threading;

    /// <summary>
    /// Summary for cooldowns
    /// </summary>
    public ref class cooldowns : public System::Windows::Forms::Form
    {
    public:
        cooldowns(void)
        {
            InitializeComponent();
            //
            //TODO: Add the constructor code here
            //
        }

    protected:
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        ~cooldowns()
        {
            if (components)
            {
                delete components;
            }
        }
    public: System::Windows::Forms::ProgressBar^  timer1Progress;

    protected: 

    public: System::Windows::Forms::Label^  timer1;

    private:
        /// <summary>
        /// Required designer variable.
        /// </summary>
        System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        void InitializeComponent(void)
        {
            this->timer1Progress = (gcnew System::Windows::Forms::ProgressBar());
            this->timer1 = (gcnew System::Windows::Forms::Label());
            this->SuspendLayout();
            // 
            // timer1Progress
            // 
            this->timer1Progress->ForeColor = System::Drawing::Color::Fuchsia;
            this->timer1Progress->Location = System::Drawing::Point(3, 12);
            this->timer1Progress->Maximum = 30000;
            this->timer1Progress->Name = L"timer1Progress";
            this->timer1Progress->Size = System::Drawing::Size(244, 18);
            this->timer1Progress->Style = System::Windows::Forms::ProgressBarStyle::Continuous;
            this->timer1Progress->TabIndex = 0;
            this->timer1Progress->Value = 10000;
            //
            //timer1
            //
            this->timer1->AutoSize = true;
            this->timer1->ForeColor = System::Drawing::Color::White;
            this->timer1->Location = System::Drawing::Point(253, 108);
            this->timer1->Name = L"Timer1";
            this->timer1->Size = System::Drawing::Size(34, 13);
            this->timer1->TabIndex = 9;
            this->timer1->Text = L"00.00";
            // 
            // cooldowns
            // 
            this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(64)), static_cast<System::Int32>(static_cast<System::Byte>(64)), 
                static_cast<System::Int32>(static_cast<System::Byte>(64)));
            this->ClientSize = System::Drawing::Size(294, 138);
            this->Controls->Add(this->Timer1);;
            this->Controls->Add(this->timer1Progress);
            this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::None;
            this->Name = L"cooldowns";
            this->StartPosition = System::Windows::Forms::FormStartPosition::Manual;
            this->Text = L"cooldowns";
            this->TopMost = true;
            this->Load += gcnew System::EventHandler(this, &cooldowns::cooldowns_Load);
            this->ResumeLayout(false);
            this->PerformLayout();

        }
#pragma endregion

private: System::Void cooldowns_Load(System::Object^  sender, System::EventArgs^  e) {

         }
};
}
#pragma一次
名称空间接口{
使用名称空间系统;
使用名称空间System::ComponentModel;
使用名称空间系统::集合;
使用命名空间System::Windows::Forms;
使用名称空间System::Data;
使用名称空间系统::绘图;
使用名称空间系统::线程;
/// 
///冷却总结
/// 
public ref类冷却:public System::Windows::Forms::Form
{
公众:
冷却(无效)
{
初始化组件();
//
//TODO:在此处添加构造函数代码
//
}
受保护的:
/// 
///清理所有正在使用的资源。
/// 
~cooldowns()
{
if(组件)
{
删除组件;
}
}
public:System::Windows::Forms::ProgressBar^timer1进度;
受保护的:
public:System::Windows::Forms::Label^timer1;
私人:
/// 
///必需的设计器变量。
/// 
系统::组件模型::容器^组件;
#pragma区域Windows窗体设计器生成的代码
/// 
///设计器支持所需的方法-不修改
///此方法的内容与代码编辑器一起使用。
/// 
void初始化组件(void)
{
这->Timer1进度=(gcnew System::Windows::Forms::ProgressBar());
这->timer1=(gcnewsystem::Windows::Forms::Label());
此->SuspendLayout();
// 
//计时器1进度
// 
这->Timer1进度->前景色=System::Drawing::Color::Fuchsia;
这->时间进度->位置=系统::图纸::点(3,12);
此->时间1进度->最大值=30000;
此->Timer1进度->名称=L“Timer1进度”;
这->Timer1进度->尺寸=系统::图纸::尺寸(244,18);
这->Timer1进度->样式=系统::窗口::窗体::进度条样式::连续;
此->Timer1进度->TabIndex=0;
此->Timer1进度->值=10000;
//
//定时器1
//
此->定时器1->自动调整大小=真;
这->定时器1->前景色=系统::绘图::颜色::白色;
这个->定时器->位置=系统::绘图::点(253108);
此->计时器1->名称=L“计时器1”;
这->计时器->尺寸=系统::图纸::尺寸(34,13);
此->计时器1->选项卡索引=9;
此->定时器1->文本=L“00.00”;
// 
//冷却
// 
这->自动缩放尺寸=系统::图纸::尺寸(6,13);
这->AutoScaleMode=System::Windows::Forms::AutoScaleMode::Font;
这->BackColor=System::Drawing::Color::FromArgb(static_cast(64)),static_cast(64)),static_cast(64)),
静态施法(静态施法(64));
这->ClientSize=System::Drawing::Size(294138);
此->控制->添加(此->计时器1);;
此->控制->添加(此->计时器进度);
此->FormBorderStyle=System::Windows::Forms::FormBorderStyle::None;
此->名称=L“冷却”;
这->StartPosition=System::Windows::Forms::FormStartPosition::Manual;
此->文本=L“冷却”;
这->最上面的=真;
this->Load+=gcnew System::EventHandler(this,&cooldowns::cooldowns\u Load);
此->恢复布局(错误);
此->执行布局();
}
#布拉格端区
私有:系统::无效冷却\u加载(系统::对象^sender,系统::事件参数^e){
}
};
}

经过大量的尝试和错误之后,编辑问题似乎围绕着CDwin->Show();。如果我将其切换到ShowDialog();它不再是无响应的,不幸的是,进度条的值也没有更新,我相信这就是多线程发挥作用的地方。

我认为您应该使用
ShowDialog
这样您的表单就有一个消息循环,并将“每50毫秒”放在在事件处理程序中填充侦听计时器的
Tick
事件的内容。

作为第一个表单,您应该始终使用
System::Windows::Forms::Application::Run(CDwin)
,当您已经运行表单时,您只能使用
Show()
ShowDialog()
方法

如果使用
Run()
,您将遇到一些问题。此函数仅在窗体关闭后返回某些内容,这意味着
Run()
代码在窗体关闭之前不会运行

所以您必须忘记在main函数中使用表单。我建议您创建两个表单,例如“Form1”和“Form2”(使用线程是另一种方法,但这一种更容易)

使用“Form1”作为隐藏的基本表单,它用于通过刷新计时器更新应用程序

使用向用户显示的“表格2”。为此,应使用
Show()
ShowDialog在“Form1”中运行“Form2”
// This is Form1 or base.
#include "Form2.h"
Form2 ^openForm2 = gcnew Form2();
openForm2->Show();
// while(true) Refresh the other form and other codes...