Hello,

I'm new to gui programming althou i've done things before in c++ i've always encountered this error and never really tried to fix it.

Lets for say I have a counter label and a button that says "Start" when one clicks start the label changes values from 0 to 999 (does't matter how fast) . SO i have an Event click in my Form1.h (all generated by VS 05) that calls function Count and the functions counts as long as global varaible is set to false .

the only way this global variable will be false is if the persons clicks the event again (or any other button to stop) and the count should stop where it is if the variable goes false and the varaible is turned back on when the start is pressed.

basicly my point being i wrote the program but the gui doesn't take event in the middle of my loop or in other words i want it to run in the background so i can do my other stuff in meanwhile also
like be able to click more buttons that do other stuff..

Here is my .h class files generated by VS ++

#pragma once

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

bool glbl = false;
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;

	/// <summary>
	/// Summary for Form1
	///
	/// WARNING: If you change the name of this class, you will need to change the
	///          'Resource File Name' property for the managed resource compiler tool
	///          associated with all .resx files this class depends on.  Otherwise,
	///          the designers will not be able to interact properly with localized
	///          resources associated with this form.
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//
		}


 void count10(){
	for(int i=0;i<1000;i++){
	if(glbl == true){
			this->lblCount->Text=L"Counting: "+i;
			this->Refresh();
		}else
			break;
	}
}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	public: System::Windows::Forms::Button^  btnStart;
	public: System::Windows::Forms::Label^  lblCount;


	public:
		/// <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->btnStart = (gcnew System::Windows::Forms::Button());
			this->lblCount = (gcnew System::Windows::Forms::Label());
			this->SuspendLayout();
			// 
			// btnStart
			// 
			this->btnStart->Location = System::Drawing::Point(12, 42);
			this->btnStart->Name = L"btnStart";
			this->btnStart->Size = System::Drawing::Size(75, 23);
			this->btnStart->TabIndex = 0;
			this->btnStart->Text = L"Start";
			this->btnStart->UseVisualStyleBackColor = true;
			this->btnStart->Click += gcnew System::EventHandler(this, &Form1::btnStart_Click);
			// 
			// lblCount
			// 
			this->lblCount->AutoSize = true;
			this->lblCount->Location = System::Drawing::Point(29, 9);
			this->lblCount->Name = L"lblCount";
			this->lblCount->Size = System::Drawing::Size(35, 13);
			this->lblCount->TabIndex = 1;
			this->lblCount->Text = L"label1";
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(115, 86);
			this->Controls->Add(this->lblCount);
			this->Controls->Add(this->btnStart);
			this->Name = L"Form1";
			this->Text = L"Form1";
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
	public: System::Void btnStart_Click(System::Object^  sender, System::EventArgs^  e) {
				 if(glbl == false){
					 glbl=true;
					this->btnStart->Text="Stop";
					count10();
					glbl=false;
					this->btnStart->Text="Start";
				 }else{
					this->btnStart->Text="Start";
					glbl=false;
				 }
			 }
	};
}

And here is my .CPP file

// Test.cpp : main project file.

#include "stdafx.h"
#include "Form1.h"

using namespace Test;

[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
	// Enabling Windows XP visual effects before any controls are created
	Application::EnableVisualStyles();
	Application::SetCompatibleTextRenderingDefault(false); 

	Test::Form1 f1;
	f1.ShowDialog();

	// Create the main window and run it
	//Application::Run(gcnew Form1());


	return 0;
}

Thanks for help. I think i'm missing the basic concept of events.
Axar

Recommended Answers

All 6 Replies

basicly my point being i wrote the program but the gui doesn't take event in the middle of my loop or in other words i want it to run in the background so i can do my other stuff in meanwhile also

You need multiple threads to accomplish that. Create a worker thread that does the counting so that the main thread can continue doing whatever needs to be done.

Im not quiet sure how to do do that. Can i get some hints on how to accomplish a worker thread?

one more thing, can I also do lets say 10 things in the background with worker thread?
thanks once again.

So, i created a worker that im guessing suppose to work

Now the problem is that when i'm doing my "WORK" (count function) i'm suppose to change the label values however, the program doesn't do anything there and exists worker when i try to change the value of my label. i checked with break point and all my form values are Error : Cannot obtain value written in them.

thanks once again.

#pragma once

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

bool glbl = false;
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;

	/// <summary>
	/// Summary for Form1
	///
	///          'Resource File Name' property for the managed resource compiler tool
	///          associated with all .resx files this class depends on.  Otherwise,
	///          the designers will not be able to interact properly with localized
	///          resources associated with this form.
	/// </summary>

	public ref class Form1 : public System::Windows::Forms::Form
	{
		
	public:
		Form1(void)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}

	private: System::Windows::Forms::Button^  btnStart;
	private: System::Windows::Forms::Label^  lblCount;
	private: System::ComponentModel::BackgroundWorker^  backgroundWorker1;

	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->backgroundWorker1 = (gcnew System::ComponentModel::BackgroundWorker());
			// Create backgroundWorker1
			// 
			this->backgroundWorker1->DoWork += gcnew DoWorkEventHandler(this, &Form1::Worker);

			this->btnStart = (gcnew System::Windows::Forms::Button());
			this->lblCount = (gcnew System::Windows::Forms::Label());
			this->SuspendLayout();
			// 
			// btnStart
			// 
			this->btnStart->Location = System::Drawing::Point(46, 61);
			this->btnStart->Name = L"btnStart";
			this->btnStart->Size = System::Drawing::Size(75, 23);
			this->btnStart->TabIndex = 0;
			this->btnStart->Text = L"Start";
			this->btnStart->UseVisualStyleBackColor = true;
			this->btnStart->Click += gcnew System::EventHandler(this, &Form1::btnStart_Click);
			// 
			// lblCount
			// 
			this->lblCount->AutoSize = true;
			this->lblCount->Location = System::Drawing::Point(43, 24);
			this->lblCount->Name = L"lblCount";
			this->lblCount->Size = System::Drawing::Size(35, 13);
			this->lblCount->TabIndex = 1;
			this->lblCount->Text = L"label1";
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(177, 118);
			this->Controls->Add(this->lblCount);
			this->Controls->Add(this->btnStart);
			this->Name = L"Form1";
			this->Text = L"Form1";
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
	private: System::Void btnStart_Click(System::Object^  sender, System::EventArgs^  e) {
			//Add Worker Thread Handler
			this->backgroundWorker1->DoWork += gcnew DoWorkEventHandler(this, &Form1::Worker);
			
				 if(glbl == false){
					 glbl=true;
					 this->btnStart->Text="Stop";
					this->backgroundWorker1->RunWorkerAsync();
				 }else{
					 this->btnStart->Text="Start";
					 glbl=false;
				 }
			 }
	public:

	private:
		System::Void Worker(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e)
		{
			count();

		}
		void count(){
				 for(int i=0;i<1000;i++){
				 if(glbl == true){
					   this->lblCount->Text=L"Counting: "+i;
				 }else
					 break;
			 }

			 this->btnStart->Text="Start";
			 glbl=false;
		}
	};
}

bump!

I can't figure out how to change gui from background worker!

bump!

I can't figure out how to change gui from background worker!

No, you won't be able to update a GUI from a worker by calling it directly. You need to use message passing. i.e. call SendMessage() or PostMessage() to send a user defined message to the GUI thread. You'll need to catch the message in your GUI thread and do your GUI stuff.

I was looking at background workers and came across this auricle
http://www.codeproject.com/KB/cpp/BackgroundWorker_Threads.aspx

the Author has two programs
Synchronous Example and Asynchronous
in Synchronous method he does in C#

m_fmProgress.lblDescription.Invoke((MethodInvoker) delegate()
            {
                m_fmProgress.lblDescription.Text =
                "Processing file " + i.ToString() +
                " of " + iCount.ToString();
                m_fmProgress.progressBar1.Value =
                Convert.ToInt32( i * ( 100.0 / iCount ) );
            });

im wondering if there is a way to do this in C++?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.