Microsoft Visual C++ 2008

My Project contains one Form1 and one Unit (module) Test1.cpp.
There is the button1 on the Form1 which calls the function:

Test1::Change_Button_Text();

There is only one function in unit Test1.cpp

void Test1::Change_Button_Text()
{
	// #1
	Form1::button1->Text = "Hello forum!"; // isn't working :(

	// #2
	Form1 ^fr1 = gcnew Form1(); 
	fr1->button1->Text = "Hello Forum!" // isn't working :(
}

What I want: Run the project, click the button and the button text will be changed to "Hello Forum!".

This is targeted to the following task: to find the way how to control Form properties (and Form component properties) from the other Units (Modules) of the Project (not only from the Form1.h).

I'm going to write a lot of procedures and do not want to place them in Form1.h header.

Thank you!

Rather than instantiating a new fr1 within your class, let the constructor of Test take your form as an argument:

In the declaration in the header:
private: Form1 ^ frm1inclass;
In the cpp file:
Test1::Test1(Form1^ form1)
{
     this->frm1inclass = form1;
}

void Test1::ChangeButtonText()
{
        frm1inclass->button1->Text = "Whatever here";
}

I didn't try compiling it so there may be some missed "punctuation" but you get the idea.

Edited 6 Years Ago by jonsca: n/a

Hi, Thanks for the answer.
I've got the idea but cannot realise :(
The next string is Ok:

private: Form1 ^ frm1inclass;

But something is wrong here:

Test1::Test1(Form1^ form1)
{
     this->frm1inclass = form1;
}

Is it new class? Test1::Test1 is defenitely not working.. :(

Thank you!

This would be the constructor for the same class that contains your Change_Button_Text() -- sorry I missed the underscores when I wrote it out. So when you instantiate Test1 in form1.h you just pass in "this" to the constructor. Make sure you put the new prototype for the constructor in your header as well.

Edited 6 Years Ago by jonsca: n/a

Isn't working yet...
Could you please spend 1 more minutes and put the right strings to the header. :) Below is just the empty header Form.h.
I marked my strings (// My Edition ==):

#pragma once

//private: Form1 ^ frm1inclass;
namespace Test1 {

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

    void Change_Button_Text(); // My Edition =======

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

	protected:
		/// <summary>
		/// ************
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::Button^  button1;
			 Form1 ^ frm1inclass; // My Edition =======

	protected: 

	private: //Form1 ^ frm1inclass;
		/// <summary>
		/// *************
		/// </summary>
		System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
		/// <summary>
		/// **************
		/// </summary>
		void InitializeComponent(void)
		{
			this->button1 = (gcnew System::Windows::Forms::Button());
			this->SuspendLayout();
			// 
			// button1
			// 
			this->button1->Location = System::Drawing::Point(205, 93);
			this->button1->Name = L"button1";
			this->button1->Size = System::Drawing::Size(115, 42);
			this->button1->TabIndex = 0;
			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, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(528, 271);
			this->Controls->Add(this->button1);
			this->Name = L"Form1";
			this->Text = L"Form1";
			this->ResumeLayout(false);

			this->frm1inclass = form1; // My Edition =======

		}
#pragma endregion
//=====================================================================================
	private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
			 {
				 Test1::Change_Button_Text(); // My Edition =======
				 
			 }
//-------------------------------------------------------------------------------------
	};
}

Edited 6 Years Ago by valeriy_zf: n/a

I'm having difficulty with it after I tried it out. I will figure it out. Part of the problem (unrelated to the one that we are having now) is that the button is declared as private within the Form1 class. In order to access it it needs to be public.

EDIT: What you have up there is not correct. You should be instantiating Test1 in the form header, not making a new form1 there. You don't need to start another form in form1 you have one. Test1 ^ mytest1 = gcnew Test1(this); pass in the pointer for the form from the form class.
Then in the click method put mytest1->ChangeButtonText();

Edited 6 Years Ago by jonsca: n/a

Just looking over your code again, I'm realizing that you are trying to make a form within your Test1 class. I would make it separate and have it include your Form1.h as a header and use the namespace from your Form1.h file (and your project overall).

#include "Form1.h"
using namespace FormControlinClass;

Then include your Test1.h file in your form1.h file (there's a way to take care of all of this with stdafx.h but I'm not up on it enough).

Ok, thanks again. Easy task but not the obvious solution.

For me it's strange. I just want to rebuild my project made in C++ Builder 6.
It wasn't any problem with the form controling there.
I have a huge drawing procedures which are splited to the several modules. It would be too much complicated to put them all to the one Form1.h file...

Yeah, I've got to puzzle over it some more. I think we've got it there's just a simple scope issue that I'm running into.

Well, you could break up the drawing procedures again and give the form access to them (might be easier). Anyway, best of luck with it. Apologies that I couldn't help more.

Got it, I think.

See if this is what you need. I left the System:: etc. qualifiers on there just to make sure it wasn't getting the wrong classes. I'm pretty sure everything you need is there, but if need be I can upload the project.

Comments
Good job, Thank you!
Attachments
#include "StdAfx.h"
#include "ClassDataPass.h"

ClassDataPass::ClassDataPass(void)
	{

	}

ClassDataPass::ClassDataPass(System::Windows::Forms::Form^ form1)
	{
		this->frm1 = form1;	
	}

void ClassDataPass::ChangeButtonText()
	{
	System::Windows::Forms::Button^ temp_button = 
		static_cast<System::Windows::Forms::Button^ >(this->frm1->Controls->Find("button1",true)[0]);
	temp_button->Text = "Changed me";
	
	}
#pragma once


public ref class ClassDataPass
	{
	private:
		System::Windows::Forms::Form ^ frm1;
	public:
		ClassDataPass(void);
		ClassDataPass(System::Windows::Forms::Form ^ frm1);
		void ChangeButtonText();
	};
#pragma once
//#include "ClassDataPass.h"

namespace ClassDataPass2 {

	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
			//
			cdp = gcnew ClassDataPass(this);
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::Button^  button1;
			 ClassDataPass^ cdp;
	protected: 

	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->button1 = (gcnew System::Windows::Forms::Button());
		this->SuspendLayout();
		// 
		// button1
		// 
		this->button1->Location = System::Drawing::Point(133, 52);
		this->button1->Name = L"button1";
		this->button1->Size = System::Drawing::Size(75, 23);
		this->button1->TabIndex = 0;
		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, 13);
		this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
		this->ClientSize = System::Drawing::Size(284, 264);
		this->Controls->Add(this->button1);
		this->Name = L"Form1";
		this->Text = L"Form1";
		this->ResumeLayout(false);

			}
#pragma endregion
	private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
				 cdp->ChangeButtonText();
				 }
		};
}
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
#pragma once

// TODO: reference additional headers your program requires here
#include "ClassDataPass.h"
//#include "Form1.h"

Hello jonsca!

Yes, I just finished construction the project you made and posted here.
That's working properly as I want :)
Thank you very much! I'will keep in my mind this forum and you personally.

I also would like to share with you one more solution which I was advised in some russian forum.
Simple this:

Application::OpenForms[0]->Controls["button1"]->Text = "Hello Forum!";

More universal, if you have several forms:

for (int i = 0; i < Application::OpenForms->Count; ++i)
                     if (Application::OpenForms[i]->Name == "Form1")
                         Application::OpenForms[i]->Controls["label1"]->Text = "Hello Forum!";

That's working in any project module.
Thanks again!

Edited 6 Years Ago by valeriy_zf: n/a

This question has already been answered. Start a new discussion instead.