Managed C++ and .NET Development: Visual Studio .NET 2003 Edition

Remember back in Chapter 4 when I discussed delegates and events and you thought to yourself, "That would be a great way to handle an event-driven GUI application!" You know what? You were right. This is exactly how the Win Form handles its user- and system-generated events.

Win Forms uses the .NET Framework's event model to handle all the events that take place within the form. What this requires is a delegate, an event source class, and an event receiver class. (You might want to revisit Chapter 4 if this means nothing to you.) Fortunately, all the delegates and event source classes you need to worry about are already part of the .NET Framework class library. You need to define the event receiver class.

For the following example, you'll use the MouseDown event that's defined in the event source class System::Windows::Forms::Control.

__event MouseEventHandler *MouseDown;

This event uses the MouseEventHandler delegate, which is defined in the System::Windows::Forms namespace.

public __gc __delegate void MouseEventHandler ( System::Object* sender, System::Windows::Forms::MouseEventArgs* e );

For those of you who are curious, the class MouseEventArgs provides five properties that you can use to figure out information about the MouseDown event:

The first step in creating an event receiver class is to create the event handler that will handle the event generated by the event source class. So, in the case of MouseDown, you need to create a method with the same signature as MouseEventHandler. Notice also that you make the handler private. You don't want any outside method calling this event by accident, as it's only intended to be called within the event receiver class.

private: void Mouse_Clicked(System::Object * sender, System::Windows::Forms::MouseEventArgs * e) { }

Once you have the handler, all you need to do is delegate it onto the MouseDown event. As you may recall from Chapter 4, Managed C++ uses multicast delegates; therefore you can chain as many handler methods as you need to complete the MouseDown event.

MouseDown += new MouseEventHandler(this, Mouse_Clicked);

If at a later time you no longer want this handler to handle the MouseDown event, all you need to do is remove the delegated method.

MouseDown -= new MouseEventHandler(this, Mouse_Clicked);

After describing all this, I'll now tell you that you can create and delegate event handlers automatically using the design tool and you don't have to worry about syntax or coding errors for the declarations. All you have to code is the functionality that handles the event. To add event handlers to a control or (in this case) a form, follow these steps:

  1. In the Properties window, click the icon that looks like a lightning bolt. This will change the view from properties to events (see Figure 9-5).

    Figure 9-5: Properties view of event handlers

  2. Double-click the event you want to add to the control or form. This will create all the appropriate code in the form using the default name.

    or

    Enter the name of the new method in the text box next to the event handler you are creating.

    or

    If you have already written the method, select the method from the drop-down list next to the event that you want it to handle.

Listing 9-4 is a fun little program that jumps your Win Form around the screen depending on where your mouse pointer is and which mouse button you press within the client area of the form. As you can see, event handling is hardly challenging. Most of the logic of this program is just to determine where to place the form on a MouseDown event.

Listing 9-4: Mouse Jump: Press a Mouse Button and See the Form Jump

namespace MouseJump { 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 __gc class Form1 : public System::Windows::Forms::Form { public: Form1(void) //... protected: void Dispose(Boolean disposing) //... private: System::ComponentModel::Container * components; void InitializeComponent(void) { this->ClientSize = System::Drawing::Size(450, 300); this->Name = S"Form1"; this->Text = S"Mouse Jump"; this->MouseDown += new System::Windows::Forms::MouseEventHandler(this, Form1_MouseDown); } private: System::Void Form1_MouseDown(System::Object * sender, System::Windows::Forms::MouseEventArgs * e) { // Get mouse x and y coordinates Int32 x = e->X; Int32 y = e->Y; // Get Forms upper left location Point loc = DesktopLocation; // Handle left button mouse click if (e->Button == MouseButtons::Left) { Text = String::Format(S"Mouse Jump - Left Button at {0},{1}", __box(x), __box(y)); DesktopLocation = Drawing::Point(loc.X + x, loc.Y +y); } // Handle right button mouse click else if (e->Button == MouseButtons::Right) { Text = String::Format(S"Mouse Jump - Right Button at {0},{1}", __box(x), __box(y)); DesktopLocation = Point((loc.X+1) - (ClientSize.Width - x), (loc.Y+1) - (ClientSize.Height - y)); } // Handle middle button mouse click else { Text = String::Format(S"Mouse Jump - Middle Button at {0},{1}", __box(x), __box(y)); DesktopLocation = Point((loc.X+1) - ((ClientSize.Width/2) - x), (loc.Y+1) - ((ClientSize.Height/2) - y)); } } }; }

The MouseJump.exe application shown in Figure 9-6 is hardly exciting, because you can't see the jumping of the form in a still image. You might want to notice that the coordinates at which the mouse was last clicked are displayed in the title bar.

Figure 9-6: The form after a mouse jump

Категории