3 Replies - 11723 Views - Last Post: 13 January 2010 - 07:25 PM

#1 Yves Vrijhoeven   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 02-January 10

How create custom events

Posted 04 January 2010 - 05:11 PM

I'm writing a forms based application and need to pass some data to and from each form. For now I have two forms:
- Form1: The main form that opens on startup
- Internet: a form shown when the user clicks a button in the main form containing only a webBrowser object

Form1 contains a status bar, when the Internet form is loading a web page, it should state in the status bar of form 1 "Loading web page" and after the web page is loaded "Loading web page completed".

I want to use events to exchange data since my application will need to update a lot of data when the user changes something in a data field (comparable to a complex spreadsheet).

I used to program in Visual C++ some 10 years ago, so it's somewhat a new start :) .
I've never programmed custom events in the past, so this is really new for me. I found some code on the web:
http://www.c-sharpco...M/PassData.aspx
But it is C# and I'm not able to convert this code to C++ but if someone can, it will probably solve my problem.

For now, I tried several things, but end up with lots of errors (as expected :crazy:)
Here are some code snippets:
/****************************************************************
/*		Delegate/Event solution									*
/*		Event Arguments class									*
/***************************************************************/

	public ref class StatusBarEventArgs : public System::EventArgs
	{
		//add local members
	private: System::String^ m_StatusBarText;

		//class constructor
	public: StatusBarEventArgs(System::String^ StatusBarText)
		{
			m_StatusBarText = StatusBarText;
		}

		//properties - viewable by each listener
	public: String^ StatusBarText(System::Void)
		{
			return m_StatusBarText;
		}
	};

// delegate and event in Internetclass that will fire a event if web site is loading/loaded
	
		public ref class Internet : public System::Windows::Forms::Form
	{

/****************************************************************
/*		Define delegate and event of the delegate type					*
/***************************************************************/
	//add a delegate
	public: delegate void StatusBarHandler(System::Object^ sender, StatusBarEventArgs^ e);

	//add an event of the delegate type
	public: event StatusBarHandler^ UpdateStatusBar;

// some other code comes here....

//webBrowser's Navigating and DocumentCompleted events should fire event
	private: System::Void webBrowser1_Navigating(System::Object^  sender, System::Windows::Forms::WebBrowserNavigatingEventArgs^  e) 
			 {
//pass each value to the StatusBarEventArgs (This is really going wrong at compile time)
				 StatusBarEventArgs^ args = gcnew StatusBarEventArgs((System::String^)"Loading web page...");
// raise the event with the updated arguments
				 UpdateStatusBar(this, args);
			 }
	private: System::Void webBrowser1_DocumentCompleted(System::Object^  sender, System::Windows::Forms::WebBrowserDocumentCompletedEventArgs^  e) {
//pass each value to the StatusBarEventArgs (This is really going wrong at compile time)
				 StatusBarEventArgs^ args = gcnew StatusBarEventArgs((System::String^)"Web page loaded");
// raise the event with the updated arguments
				 UpdateStatusBar(this, args);
			 }


Next part is in the listener class Form1:
//Constructor of the main application form
Offerte::Form1::Form1(void) {
			InitializeComponent();
			//
			//Create an instance of the Internet form and hook a event handler
			//
			Website = gcnew Internet(this);
			Website->UpdateStatusBar += gcnew Internet::StatusBarHandler(this, &Form1::UpdateStatusBar);
}

//show Internet form
System::Void Offerte::Form1::OpenWebToolStripButton_Click(System::Object^ sender, System::EventArgs^ e) {
			Website->Visible = true;
}

//and finally the handler
private: System::Void UpdateStatusBar(System::Object^ sender, Internet::StatusBarEventArgs^ e) {
			 StatusText = e->StatusBarText;
};

I will go on checking my own code but it has been some time I programmed in Visual C++.

All help appreciated!
Yves Vrijhoeven
The user can't close the Internet form, clicking the close button ("X") will only hide the form, so I don't need to unhook the event handler I think.

This post has been edited by Yves Vrijhoeven: 05 January 2010 - 11:01 AM


Is This A Good Question/Topic? 0
  • +

Replies To: How create custom events

#2 Yves Vrijhoeven   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 02-January 10

Re: How create custom events

Posted 05 January 2010 - 02:31 PM

Actually sleeping from time to time helps sometimes... :D

actually it was a '}', that I had deleted somehow, resulting in all the compiler errors... :angry:

The rest of the code I mentioned was pretty good working... :D

Except some minor typos...

This post has been edited by Yves Vrijhoeven: 05 January 2010 - 02:32 PM

Was This Post Helpful? 0
  • +
  • -

#3 tommish   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 13-January 10

Re: How create custom events

Posted 13 January 2010 - 10:17 AM

View PostYves Vrijhoeven, on 5 Jan, 2010 - 01:31 PM, said:

Actually sleeping from time to time helps sometimes... :D

actually it was a '}', that I had deleted somehow, resulting in all the compiler errors... :angry:

The rest of the code I mentioned was pretty good working... :D

Except some minor typos...



Hi Yves,

I am having some trouble trying to do the same thing as you have implemented in the code above. My problem is that I do not understand the event architecture and was wondering if you might have a example communicating between two forms using events ?

Many Thanks

Tom Egling
Was This Post Helpful? 0
  • +
  • -

#4 Yves Vrijhoeven   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 02-January 10

Re: How create custom events

Posted 13 January 2010 - 07:25 PM

View Posttommish, on 13 Jan, 2010 - 09:17 AM, said:

Hi Yves,

I am having some trouble trying to do the same thing as you have implemented in the code above. My problem is that I do not understand the event architecture and was wondering if you might have a example communicating between two forms using events ?

Many Thanks

Tom Egling


I tried to set up a simple two form project with Visual Studio 2010 beta 2 and documented the 'delegate/event' stuff. Hope this will help you solve your problem. All code is in managed C++ (C++/CLI).

When you start the program you will see a text box that is read only and a button 'Open Second Form'. Click the button and a second form will open, almost the same form as the first one, except the text box can be edited and the button is named 'Fire Custom Event'.
What the program demonstrates is, when you push the button in the second form, an event is fired. The main form listens to this event and when fired, gets the contents of the text box in the second form and copies it to the text box in the main form (Form1).
Many more things can be done with events (different windows can raise the same event, different windows can listen to the events, you can add more than one function to the event handler (they will be excuted one after the other), and so on) but this should get you started.

The following was done with Visual Studio 2010 Beta 2 (down-loadable from Microsoft)
First start a new 'Windows Form Application' project and name it CustomEvents.
Add a second form to the project and name it Second_Form.
For Form1:
In designer add a textBox control and name it m_textBox, set the Multiline property to True and set the ReadOnly property to True. I sized it to 211;174
add a button control and name it b_OpenSecondForm and set the Text property to 'Open Second Form'. I sized it to 212;25 and placed it under the textBox control. Use the lightning bolt to add an event to the button Click event and name it b_OpenSecondForm_Click (default when you did the above and double click on the 'Click' Action)
The code to be added will follow.
For the 'Second_form:
In designer add a textBox control and name it m_textBox, set the Multiline property to True and set the ReadOnly property to False (default). I sized it also to 211;174
add a button control and name it b_FireCustomEvent and set the text property to 'Fire Custom Event'. I sized it to 212;25 and placed it under the textBox control. Use the lightning bolt to add an event to the button Click event and name it b_FireCustomEvent_Click (default when you did the above and double click on the 'Click' Action)

Finally the code:

Form1.h
#pragma once

//************************************//
// Include header of 'Second Form'	//
//************************************//
#include "Second_Form.h"

namespace CustomEvents {

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

	public ref class Form1 : public System::Windows::Forms::Form
	{
//************************************//
// Create private member of type	  //
// System::Windows::Forms::Form^	  //
// (this is a handle to the object	//
// on the garbage collector heap	  //
//************************************//
	public:
		Form1(void)
		{
			InitializeComponent();

//************************************//
// Initialize an instance of the	  //
// Second Form						  //
//************************************//
			m_SecondForm = gcnew Second_Form();

//******************************************//
// Set UpdateTextControl as the event	   //
// handler. The UpdateTextControl		   //
// function should be of the same		   //
// type as the CustomEventsHandler		  //
// function defined as delegate in		  //
// Second_Form.h:							//
// 1st arg. of type System::Object^		 //
// 2nd arg. of type CustomEvents_EventArgs^ //
//******************************************//
			m_SecondForm->UpdateTextControl += gcnew Second_Form::CustomEventsHandler(this, &Form1::UpdateControl);
		}

	protected:
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::Button^  b_OpenSecondForm;
	private: System::Windows::Forms::TextBox^  m_textBox;
	
//************************************//
// m_SecondForm is a member of the	//
// main form (Form1)				  //
//************************************//
	private: Second_Form^ m_SecondForm;

	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->b_OpenSecondForm = (gcnew System::Windows::Forms::Button());
			this->m_textBox = (gcnew System::Windows::Forms::TextBox());
			this->SuspendLayout();
			// 
			// b_OpenSecondForm
			// 
			this->b_OpenSecondForm->Location = System::Drawing::Point(31, 192);
			this->b_OpenSecondForm->Name = L"b_OpenSecondForm";
			this->b_OpenSecondForm->Size = System::Drawing::Size(212, 25);
			this->b_OpenSecondForm->TabIndex = 0;
			this->b_OpenSecondForm->Text = L" Open Second Form";
			this->b_OpenSecondForm->UseVisualStyleBackColor = true;
			this->b_OpenSecondForm->Click += gcnew System::EventHandler(this, &Form1::b_OpenSecondForm_Click);
			// 
			// m_textBox
			// 
			this->m_textBox->Location = System::Drawing::Point(31, 12);
			this->m_textBox->Multiline = true;
			this->m_textBox->Name = L"m_textBox";
			this->m_textBox->ReadOnly = true;
			this->m_textBox->Size = System::Drawing::Size(211, 174);
			this->m_textBox->TabIndex = 1;
			// 
			// 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->m_textBox);
			this->Controls->Add(this->b_OpenSecondForm);
			this->Name = L"Form1";
			this->Text = L"Form1";
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion

//************************************//
// Event handler created with the	 //
// deigner of visual Studio			  //
//************************************//
	private: System::Void b_OpenSecondForm_Click(System::Object^  sender, System::EventArgs^  e) {

//************************************//
// Show or hide the form, depending   //
// on the current state			   //
//************************************//
				if(m_SecondForm->WindowState == FormWindowState::Minimized)
				{
					m_SecondForm->WindowState = FormWindowState::Normal; // if Second Form was minimized, first resize it
					m_SecondForm->Visible = true;						 // and make shure it's visible
				}
				else
					m_SecondForm->Visible = !(m_SecondForm->Visible);
			 }

//******************************************//
// Finaly the eventhandler.					//
// Notice the following:					//
// 1st arg. of type System::Object^		 //
// 2nd arg. of type CustomEvents_EventArgs^ //
// Conforming the delegate.					//
//******************************************//
	private: System::Void UpdateControl(System::Object^ sender, CustomEvents_EventArgs^ e) {
			m_textBox->Text = e->TextControlText();
			 }
	};
}



Second_Form.h
#pragma once

#ifndef Second_Form_h_
#define Second_Form_h_

namespace CustomEvents {

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

//************************************//
// Need to do a forward declaration   //
// since this class will be used in   //
// class 'Second_Form'. Visual Studio //
// Designer expects the 'Second_Form' //
// class to be the first class		//
// definition.						  //
//************************************//
	ref class CustomEvents_EventArgs;  

	public ref class Second_Form : public System::Windows::Forms::Form
	{

//************************************//
// Define delegate and event of the   //
// delegate type					  //
//*************************************//
	//add a delegate
	public: delegate void CustomEventsHandler(System::Object^ sender, CustomEvents_EventArgs^ e); // this is the reason I needed the forward class declaration

	//add an event of the delegate type
	public: event CustomEventsHandler^ UpdateTextControl;

	public:
		Second_Form(void)
		{
			InitializeComponent();
		}

	protected:
		~Second_Form()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::TextBox^  m_textBox;
	private: System::Windows::Forms::Button^  b_FireCustomEvent;

	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->m_textBox = (gcnew System::Windows::Forms::TextBox());
			this->b_FireCustomEvent = (gcnew System::Windows::Forms::Button());
			this->SuspendLayout();
			// 
			// m_textBox
			// 
			this->m_textBox->Location = System::Drawing::Point(34, 12);
			this->m_textBox->Multiline = true;
			this->m_textBox->Name = L"m_textBox";
			this->m_textBox->Size = System::Drawing::Size(211, 174);
			this->m_textBox->TabIndex = 2;
			// 
			// b_FireCustomEvent
			// 
			this->b_FireCustomEvent->Location = System::Drawing::Point(34, 192);
			this->b_FireCustomEvent->Name = L"b_FireCustomEvent";
			this->b_FireCustomEvent->Size = System::Drawing::Size(211, 26);
			this->b_FireCustomEvent->TabIndex = 3;
			this->b_FireCustomEvent->Text = L"Fire Custom Event";
			this->b_FireCustomEvent->UseVisualStyleBackColor = true;
			this->b_FireCustomEvent->Click += gcnew System::EventHandler(this, &Second_Form::b_FireCustomEvent_Click);
			// 
			// Second_Form
			// 
			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->b_FireCustomEvent);
			this->Controls->Add(this->m_textBox);
			this->Name = L"Second_Form";
			this->Text = L"SecondForm";
			this->FormClosing += gcnew System::Windows::Forms::FormClosingEventHandler(this, &Second_Form::Second_Form_FormClosing);
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
	private: System::Void b_FireCustomEvent_Click(System::Object^  sender, System::EventArgs^  e);

//************************************//
// Added to avoid closing Second Form //
//************************************//
	private: System::Void Second_Form_FormClosing(System::Object^  sender, System::Windows::Forms::FormClosingEventArgs^  e) {
				 this->Hide();
				 e->Cancel = true;
			 }
	};

//************************************//
// This class defines the arguments   //
// that will be send by the event	 //
// (The designer of visual studio	 //
// expects the Form class as the first//
// class in this header, so I put	 //
// a forward declaration in the	   //
// beginning since the class is	   //
// refferenced to in the 'SecondForm' //
// class)							 //
//*************************************//

	public ref class CustomEvents_EventArgs : public System::EventArgs
	{
		//add local members
		private: System::String^ m_TextControlText;

		//class constructor
		public: CustomEvents_EventArgs(System::String^ m_Text)
		{
			m_TextControlText = m_Text;
		}

		//properties - viewable by each listener
		public: String^ TextControlText(System::Void)
		{
			return m_TextControlText;
		}
	};
}

#endif /*Second_Form_h_*/



Second_Form.cpp
#include "StdAfx.h"
#include "Second_Form.h"

using namespace CustomEvents;

//************************************//
// Definition of the function that	//
// will be executed when the 'Fire	//
// Custom Event' button is clicked	//
//************************************//
System::Void Second_Form::b_FireCustomEvent_Click(System::Object^  sender, System::EventArgs^  e) {
				 CustomEvents_EventArgs^ args = gcnew CustomEvents_EventArgs((System::String^)m_textBox->Text); // this will set the private member (in this case the only member) of the EventArgs class
				 UpdateTextControl(this, args); //this is the event that was defined, and it will now be fired
			 }



The rest of the code was generated by Visual Studio.

Hope it will work for you.

Actually I just started programming C++/CLI for two weeks now, I got started with this link http://www.c-sharpco...M/PassData.aspx (It's C#). I've also started reading the book "C++/CLI in action" written by Nishant Sivakumar. Pretty good book I think (I'm on page 61...).

I hope I didn't make any mistakes, let me know if it works.

Yves Vrijhoeven
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1