vs2010 c++ 窗口程序,在初始化主窗口前开了一个线程,如何在该线程中修改主窗口的控件属性

kingdomhj 2019-01-04 12:55:50
想实现的功能:从串口读取数据,当读到数据后在主窗口的lable1标签中进行显示。
我的思路:在主窗口初始化之前,开了一个线程监听串口并读取数据,读取到数据后修改form1类lable1标签的Text值。我用label1->Text、form1.label1->Text、form1->label1->Text都不行。我已经在form1类中将lable1改成public了,我知道问题应该是在lable1的左边需要明确指出窗口名,但是怎么才能找到这个主窗口的实例名或者是句柄。自动生成的代码中也没有定义form1类实例的地方,就一条Application::Run(gcnew Form1());。还有另一种解决思路,线程收到数据后向form1类发送一个消息,然后form1类去定义消息处理函数来修改lable1,但是这中方法我根本没有找到消息队列的地方,vs生成的代码中就没有看见消息处理的相关代码。这个代码封装到哪里去了。现在的问题是编译通不过,程序中我会加判断代码主窗口知否已经初始化完成了,所以不用担心修改在主窗口初始化之前。
我没搞懂的主要3个方面:
问题1:如何找到主窗口的实例名或者句柄
问题2:这种vs自动生成的form程序,如何自定义消息及处理函数
问题3:在类的初始化函数中是否可以开启一个线程,用于控制该类的相关属性。这个回调函数应该怎么定义,我尝试过定义为类的成员函数线程开始代码编译通不过,定义为static函数又不能直接引用控件。

请大神们帮帮忙


```
//new_form.cpp
#include "stdafx.h"
#include "Form1.h"
#include<iostream>
#include<fstream>
#include <process.h>

using namespace std;
using namespace new_form;

unsigned int _stdcall ListenThread(void* pParam) ;

[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
volatile HANDLE m_hListenThread= INVALID_HANDLE_VALUE;
unsigned int threadId;
m_hListenThread = (HANDLE)_beginthreadex(NULL, 0, ListenThread, NULL, 0, &threadId);//开启监听线程
// 在创建任何控件之前启用 Windows XP 可视化效果
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);

// 创建主窗口并运行它
Application::Run(gcnew Form1());
return 0;
}

unsigned int _stdcall ListenThread(void* pParam)
{
label1->Text="有数据需要显示!";
}
```

头文件
```
//form1.h
#pragma once
#pragma comment(lib,"User32.lib")

#include<windows.h>
#include<iostream>
#include<string>
#include <process.h>

using namespace std;
using namespace System::Runtime::InteropServices;
namespace new_form {

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

/// <summary>
/// Form1 摘要
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
}

protected:
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}

public: System::Windows::Forms::Label^ label1;
private:
/// <summary>
/// 必需的设计器变量。
/// </summary>
System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
void InitializeComponent(void)
{
this->label1 = (gcnew System::Windows::Forms::Label());
this->SuspendLayout();
// label1
//
this->label1->Font = (gcnew System::Drawing::Font(L"宋体", 36, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(134)));
this->label1->Location = System::Drawing::Point(30, 85);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(559, 47);
this->label1->TabIndex = 19;
this->label1->Text = L"默认显示内容:";
this->label1->Click += gcnew System::EventHandler(this, &Form1::label1_Click);
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(623, 340);
this->Controls->Add(this->label1);
this->ForeColor = System::Drawing::Color::CornflowerBlue;
this->Name = L"Form1";
this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
this->Text = L"呼叫器";
this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
};

}
```
...全文
302 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
woshi_hujunjun 2019-01-19
  • 打赏
  • 举报
回复
只想说,版主说的对
kingdomhj 2019-01-06
  • 打赏
  • 举报
回复
引用 4 楼 蒋晟的回复:
等到窗口创建再开你的线程 然后你就可以把窗口句柄传给线程 在线程里你可以给窗口发消息。
而窗口类指针不能定义成Form1*,他只允许定义为Form1 ^,在回调函数的实现中强制转换参数类型会出错。
蒋晟 2019-01-06
  • 打赏
  • 举报
回复
没叫你传窗口,自己声明个结构体。
kingdomhj 2019-01-05
  • 打赏
  • 举报
回复
引用 4 楼 蒋晟的回复:
等到窗口创建再开你的线程 然后你就可以把窗口句柄传给线程 在线程里你可以给窗口发消息。
我试过在窗口构造函数中开起线程,有一个问题是回调函数的参数是void*
蒋晟 2019-01-05
  • 打赏
  • 举报
回复
等到窗口创建再开你的线程 然后你就可以把窗口句柄传给线程 在线程里你可以给窗口发消息。
zgl7903 2019-01-05
  • 打赏
  • 举报
回复
kingdomhj 2019-01-04
  • 打赏
  • 举报
回复
引用 1 楼 zgl7903的回复:
在Form中打开串口及其线程是不是更容易 https://www.cnblogs.com/bacazy/p/3500117.html
你给的例子是点一下按钮再去接收数据,我是需要实时监控串口,一有数据马上处理,所以必须要单独开一个线程循环检测。我串口操作这块是没有问题的,我的问题是在收到数据后处理这块,我需要在子线程中去修改主窗口的控件属性。他这个主窗口是个Form1类,实例还是托管的,我试过在窗口的构造函数中通过this指针传递给全局变量,说托管类不允许这么操作。我把ref去掉错误更多。在Form1类中的成员函数都可以直接改控件属性,但只要开线程就不行,开线程就必须定义成静态函数,只要是静态函数,即便是我通过指针找到这个窗口了,他都不允许我改,说是托管的。把我折腾够了。
zgl7903 2019-01-04
  • 打赏
  • 举报
回复
在Form中打开串口及其线程是不是更容易 https://www.cnblogs.com/bacazy/p/3500117.html

NOIP2011)复赛 提高组 day2 1 页 共 4 页 全国信息学奥林匹克联赛(NOIP2011)复赛 提高组 day2 (请选手务必仔细阅读本页内容) 一.题目概况 文题目名称 计算系数 聪明的质监员 观光公交 英文题目与子目录名 factor qc bus 可执行文件名 factor qc bus 输入文件名 factor.in qc.in bus.in 输出文件名 factor.out qc.out bus.out 每个测试点时限 1 秒 1 秒 1 秒 测试点数目 10 20 20 每个测试点分值 10 5 5 附加样例文件 有 有 有 结果比较方式 全文比较(过滤行末空格及文末回车) 题目类型 传统 传统 传统 二.提交源程序文件名 对于 C++语言 factor.cpp qc.cpp bus.cpp 对于 C 语言 factor.c qc.c bus.c 对于 pascal 语言 factor.pas qc. Pas bus. pas 三.编译命令(不包含任何优化开关) 对于 C++语言 g++ -o factor factor.cpp -lm g++ -o qc qc.cpp –lm g++ -o bus bus.cpp -lm 对于 C 语言 gcc -o factor factor.c -lm gcc -o qc qc.c –lm gcc -o bus bus.c -lm 对于 pascal 语言 fpc factor.pas fpc qc.pas fpc bus.pas 四.运行内存限制 内存上限 128M 128M 128M 注意事项: 1、文件名(程序名和输入输出文件名)必须使用英文小写。 2、C/C++函数 main()的返回值类型必须是 int,程序正常结束时的返回值必须是 0。 3、全国统一评测时采用的机器配置为:CPU P4 3.0GHz,内存 1G,上述时限以此配置为准。 4、特别提醒:评测在 NOI Linux 下进行。 NOIP2011)复赛 提高组 day2 2 页 共 4 页 【问题描述】 1.计算系数 (factor.cpp/c/pas) 给定一个多项式 (ax + by)k ,请求出多项式展开后 x n y m 项的系数。 【输入】 输入文件名为 factor.in。 共一行,包含 5 个整数,分别为 a,b,k,n,m,每两个整数之间用一个空格隔开。 【输出】 输出文件名为 factor.out。 输出共 1 行,包含一个整数,表示所求的系数,这个系数可能很大,输出对 10007 取 模后的结果。 【输入输出样例】 factor.in factor.out 1 1 3 1 2 3 【数据范围】 对于 30%的数据,有 0≤k≤10; 对于 50%的数据,有 a = 1,b = 1; 对于 100%的数据,有 0≤k≤1,000,0≤n, m≤k,且 n + m = k,0≤a,b≤1,000,000。 【问题描述】 2.聪明的质监员 (qc.cpp/c/pas) 小 T 是一名质量监督员,最近负责检验一批矿产的质量。这批矿产共有 n 个矿石,从 1 到 n 逐一编号,每个矿石都有自己的重量 wi 以及价值 vi。检验矿产的流程是: 1、给定 m 个区间[Li,Ri]; 2、选出一个参数 W; 3、对于一个区间[Li,Ri],计算矿石在这个区间上的检验值 Yi : Yi = ∑1* ∑v j , j ∈[Li , Ri ] 且 w j ≥ W ,j 是矿石编号 j j m 这批矿产的检验结果 Y 为各个区间的检验值之和。即:Y = ∑Yi i =1 若这批矿产的检验结果与所给标准值 S 相差太多,就需要再去检验另一批矿产。小 T 不想费时间去检验另一批矿产,所以他想通过调整参数 W 的值,让检验结果尽可能的靠近 标准值 S,即使得 S-Y 的绝对值最小。请你帮忙求出这个最小值。 【输入】 输入文件 qc.in。 NOIP2011)复赛 提高组 day2 3 页 共 4 页 第一行包含三个整数 n,m,S,分别表示矿石的个数、区间的个数和标准值。 接下来的 n 行,每行 2 个整数,间用空格隔开,第 i+1 行表示 i 号矿石的重量 wi 和价 值 vi 。 接下来的 m 行,表示区间,每行 2 个整数,间用空格隔开,第 i+n+1 行表示区间[Li, Ri]的两个端点 Li 和 Ri。注意:不同区间可能重合或相互重叠。 【输出】 输出文件名为 qc.out。 输出只有一行,包含一个整数,表示所求的最小值。 【输入输出样例】 qc.in qc.out 5 3 15 1 5 2 5 3 5 4 5 5 5 1 5 2 4 3 3 10 【输入输出样例说明】 当 W 选 4 的时候,三个区间上检验值分别为 20、5、0,这批矿产的检验结果为 25,此 时与标准值 S 相差最小为 10。 【数据范围】 对于 10%的数据,有 1≤n,m≤10; 对于 30%的数据,有 1≤n,m≤500; 对于 50%的数据,有 1≤n,m≤5,000; 对于 70%的数据,有 1≤n,m≤10,000; 对于 100%的数据,有 1≤n,m≤200,000,0 < wi, vi≤106,0 < S≤1012,1≤Li≤Ri≤n。 【问题描述】 3.观光公交 (bus.cpp/c/pas) 风景迷人的小城 Y 市,拥有 n 个美丽的景点。由于慕名而来的游客越来越多,Y 市特 意安排了一辆观光公交车,为游客提供更便捷的交通服务。观光公交车在第 0 分钟出现在 1 号景点,随后依次前往 2、3、4……n 号景点。从第 i 号景点开到第 i+1 号景点需要 Di 分钟。 任意时刻,公交车只能往前开,或在景点处等待。 设共有 m 个游客,每位游客需要乘车 1 次从一个景点到达另一个景点,第 i 位游客在 Ti 分钟来到景点 Ai,希望乘车前往景点 Bi(Ai一个乘客的旅行时间,等于他到达目的地的时刻减去他来到出发地的时刻。因为只有一 辆观光车,有时候还要停下来等其他乘客,乘客们纷纷抱怨旅行时间太长了。于是聪明的司 机 ZZ 给公交车安装了 k 个氮气加速器,每使用一个加速器,可以使其一个 Di 减 1。对于 同一个 Di 可以重复使用加速器,但是必须保证使用后 Di 大于等于 0。 那么 ZZ 该如何安排使用加速器,才能使所有乘客的旅行时间总和最小? 【输入】 输入文件名为 bus.in。 第 1 行是 3 个整数 n, m, k,每两个整数之间用一个空格隔开。分别表示景点数、乘客数 和氮气加速器个数。 第 2 行是 n-1 个整数,每两个整数之间用一个空格隔开,第 i 个数表示从第 i 个景点开 往第 i+1 个景点所需要的时间,即 Di。 第 3 行至 m+2 行每行 3 个整数 Ti, Ai, Bi,每两个整数之间用一个空格隔开。第 i+2 行表 示第 i 位乘客来到出发景点的时刻,出发的景点编号和到达的景点编号。 【输出】 输出文件名为 bus.out。共一行,包含一个整数,表示最小的总旅行时间。 【输入输出样例】 bus.in bus.out 3 3 2 1 4 0 1 3 1 1 2 5 2 3 10 【输入输出样例说明】 对 D2 使用 2 个加速器,从 2 号景点到 3 号景点时间变为 2 分钟。 公交车在第 1 分钟从 1 号景点出发,第 2 分钟到达 2 号景点,第 5 分钟从 2 号景点出发, 第 7 分钟到达 3 号景点。 第 1 个旅客旅行时间 7-0 = 7 分钟。 第 2 个旅客旅行时间 2-1 = 1 分钟。 第 3 个旅客旅行时间 7-5 = 2 分钟。 总时间 7+1+2 = 10 分钟。 【数据范围】 对于 10%的数据,k=0; 对于 20%的数据,k=1; 对于 40%的数据,2 ≤ n ≤ 50,1 ≤ m ≤ 1,000,0 ≤ k ≤ 20,0 ≤ Di ≤ 10,0 ≤ Ti ≤ 500; 对于 60%的数据,1 ≤ n ≤ 100,1 ≤ m ≤ 1,000,0 ≤ k ≤ 100,0 ≤ Di ≤ 100,0 ≤ Ti ≤ 10,000; 对于 100% 的数据,1 ≤ n ≤ 1,000 ,1 ≤ m ≤ 10,000 ,0 ≤ k ≤ 100,000 ,0 ≤ Di ≤ 100 , 0 ≤ Ti ≤ 100,000。

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧