VC++ .NET UI同步(使用Invoke托管方法),异步线程调用UI

花了好几天才学会,之前的代码都是C#的,无法直接使用.


1.首先定义并声明托管

delegate void testUI1(String ^ptr);	//定义一个UI托管
		delegate void testUI2(String ^ptr);	//定义一个UI托管
		testUI1^ myUI1;
		testUI2^ myUI2;

2.在构造函数中实例化托管对象

myUI1 = gcnew testUI1( this, &test::Form1::UI_Test1);
myUI2 = gcnew testUI2( this, &test::Form1::UI_Test2);

3.托管中调用的函数(主要用于UI操作)

void UI_Test1(String ^ptr)  //这个是被线程调用的函数
{
label1->Text=ptr;
}

void UI_Test2(String ^ptr)  //这个是被线程调用的函数
{
label2->Text=ptr;
}

4.在异步线程中使用托管访问UI

		//线程1
		void TestThread(void)
		{
			DWORD i=0;

			//防止在窗口句柄初始化之前就走到下面的代码
			while (!this->IsHandleCreated)
			{
				Sleep(10);
			}

			//Sleep(1000);	//一定要延时之后再建立线程,否则会出现
			//在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke
			//主要是因为UI界面还没有初始化完成,调用Invoke会出错
			while(1)
			{
				this->Invoke(myUI1, ""+i);
				i ++;
				Sleep(1000);
			}
		}


		//线程2
		void TestThread1(void)
		{
			DWORD i=1000;

			//防止在窗口句柄初始化之前就走到下面的代码
			while (!this->IsHandleCreated)
			{
				Sleep(10);
			}

			//Sleep(2000);	//一定要延时之后再建立线程,否则会出现
			//在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke
			//主要是因为UI界面还没有初始化完成,调用Invoke会出错
			while(1)
			{
				this->Invoke(myUI2, ""+i);
				i ++;
				Sleep(1000);
			}
		}




运行效果




附上所有代码

#pragma once

#include "stdafx.h"
#include "windows.h"


#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "Ws2_32.lib")  
#pragma comment(lib, "User32.lib") 

namespace test {

	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>
	/// Form1 摘要
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{

		System::Threading::Thread  ^Thread1;
		System::Threading::Thread  ^Thread2;

		delegate void testUI1(String ^ptr);	//定义一个UI托管
		delegate void testUI2(String ^ptr);	//定义一个UI托管
		testUI1^ myUI1;
		testUI2^ myUI2;

	public:
		Form1(void)
		{

			InitializeComponent();


			myUI1 = gcnew testUI1( this, &test::Form1::UI_Test1);
			myUI2 = gcnew testUI2( this, &test::Form1::UI_Test2);

			

			this->Thread1 = gcnew Thread (gcnew ThreadStart (this,&test::Form1::TestThread));
			this->Thread1->Start();
			this->Thread1->IsBackground = TRUE;	//将读取线程设置为后台线程,这样在UI线程关闭后可以自动退出
			this->Thread2 = gcnew Thread (gcnew ThreadStart (this,&test::Form1::TestThread1));
			this->Thread2->Start();
			this->Thread2->IsBackground = TRUE;	//将读取线程设置为后台线程,这样在UI线程关闭后可以自动退出
			//
			//TODO: 在此处添加构造函数代码
			//

			this->label1->Text="";
			this->label2->Text="";
		}

		void UI_Test1(String ^ptr)  //这个是被线程调用的函数
		{
			this->label1->Text=ptr;
		}

		void UI_Test2(String ^ptr)  //这个是被线程调用的函数
		{
			this->label2->Text=ptr;
		}

		//线程1
		void TestThread(void)
		{
			DWORD i=0;

			//防止在窗口句柄初始化之前就走到下面的代码
			while (!this->IsHandleCreated)
			{
				Sleep(10);
			}

			//Sleep(1000);	//一定要延时之后再建立线程,否则会出现
			//在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke
			//主要是因为UI界面还没有初始化完成,调用Invoke会出错
			while(1)
			{
				this->Invoke(myUI1, ""+i);
				i ++;
				Sleep(1000);
			}
		}


		//线程2
		void TestThread1(void)
		{
			DWORD i=1000;

			//防止在窗口句柄初始化之前就走到下面的代码
			while (!this->IsHandleCreated)
			{
				Sleep(10);
			}

			//Sleep(2000);	//一定要延时之后再建立线程,否则会出现
			//在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke
			//主要是因为UI界面还没有初始化完成,调用Invoke会出错
			while(1)
			{
				this->Invoke(myUI2, ""+i);
				i ++;
				Sleep(1000);
			}
		}

	protected:
		/// <summary>
		/// 清理所有正在使用的资源。
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::Label^  label1;
	protected: 
	private: System::Windows::Forms::Label^  label2;
	private: System::Windows::Forms::Button^  button1;

	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->label2 = (gcnew System::Windows::Forms::Label());
			this->button1 = (gcnew System::Windows::Forms::Button());
			this->SuspendLayout();
			// 
			// label1
			// 
			this->label1->AutoSize = true;
			this->label1->Font = (gcnew System::Drawing::Font(L"宋体", 20, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(134)));
			this->label1->ForeColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(0)), static_cast<System::Int32>(static_cast<System::Byte>(0)), 
				static_cast<System::Int32>(static_cast<System::Byte>(192)));
			this->label1->Location = System::Drawing::Point(106, 64);
			this->label1->Name = L"label1";
			this->label1->Size = System::Drawing::Size(96, 27);
			this->label1->TabIndex = 0;
			this->label1->Text = L"label1";
			// 
			// label2
			// 
			this->label2->AutoSize = true;
			this->label2->Font = (gcnew System::Drawing::Font(L"宋体", 20, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(134)));
			this->label2->ForeColor = System::Drawing::Color::Red;
			this->label2->Location = System::Drawing::Point(109, 139);
			this->label2->Name = L"label2";
			this->label2->Size = System::Drawing::Size(96, 27);
			this->label2->TabIndex = 1;
			this->label2->Text = L"label2";
			// 
			// button1
			// 
			this->button1->Location = System::Drawing::Point(216, 226);
			this->button1->Name = L"button1";
			this->button1->Size = System::Drawing::Size(75, 23);
			this->button1->TabIndex = 2;
			this->button1->Text = L"button1";
			this->button1->UseVisualStyleBackColor = true;
			this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(503, 288);
			this->Controls->Add(this->button1);
			this->Controls->Add(this->label2);
			this->Controls->Add(this->label1);
			this->Name = L"Form1";
			this->Text = L"Form1";
			this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
	private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
			 }
	private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
				 this->label1->Text = "按下按钮";
				 this->label2->Text = "按下按钮";
			 }
};
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cp1300

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值