Programming for Windows Forms (transfer) using C ++ hosted expansion

xiaoxiao2021-03-06  57

Release Date: 8/9/2004

| Update Date: 8/9/2004

Chris Sells and SAM Gentile

Applicable to:

Microsoft® Visual C ® .NET

Windows Forms

Summary: This article discusses how to use Visual C .NET's hosted extension for Windows Forms, and provide examples of manual programming technology directly accessing Windows Forms, and examples of the Windows Form Designer. In addition, this paper compares the Windows Form and Microsoft Basics (MFC) applications.

This page

Introduction What is a Windows Form? Creating a Windows Form from Schedule Use the Visual Studio .NET Designer to create a Windows Form Schedule Control Data Binding from the MFC Migration Summary

Introduction

For a long time, programmers use C and C to develop Windows GUI applications. For many of us, this history can be traced back to Windows 2.0, then we use C's 16-bit Windows API, even if it is just displaying a window, you also need to write dozens of lines of code. Fortunately, over time, the abstract level is getting higher and higher, better and better. In 1992, Microsoft released Programmer's Workbench, including the Microsoft Basics Library version 1.0. The Microsoft Basics Library version 1.0 contains approximately 60 classes, 16-bit Windows APIs for packaging windowing programming and drawing. Between 2002, the Microsoft Basic Class 7.0 has evolved to have more than 200 classes, and their use has expanded to provide a complete C object model substitute for Microsoft Win32 API.

Although MFC is very powerful, it also has a lot of shortcomings, such as a thin layer of panel outside Win32 API, and for many programmers, it is too complicated, it is difficult to use. Typically, to develop Windows applications, you still need to directly access Win32 API, especially in the case of continuous improvement of the requirements for the basic functions required for Windows applications. Therefore, to develop any functional Windows GUI applications that require a lot of time energy. In order to develop difficulty in developing applications, Microsoft issued a new programming environment for Windows platforms in early 2002. This environment is called .NET framework, which provides developers with a hosted application runtime, and a large library called .NET Framework class library. The .NET framework can manage memory and security, enabling a more reliable application. The .NET Framework class library provides a large, resource rich and unified class library, any .NET language (including the c managed extension and C managed version of the .NET programmer), can be equivalent in the same way Access this class library. As part of the .NET framework, the Windows Form is a set of classes for building a client Windows GUI application.

In this article, we will in-depth understand how to write a Windows form code using C managed extensions, first introduce how to write from beginning, then explain how to use Microsoft Visual Studio .NET 2003 to complete this task. At the same time, we will focus on some common functions of the Windows form, such as automatic layout and data binding. Finally, we will focus on how to compare the Windows Forms and MFC and how to mix using these two sets of tools when further use of managed expansion. Back to top

What is a Windows Form?

The Windows Form is a window toolkit, not just like the MFC is a complete application framework. In fact, the MFC provides more features with respect to the functionality provided by the Windows Form for building a document-based independent application. For example, if you want to generate a text editor, in the MFC, you only need to run a wizard, select the appropriate option and write several lines of code. Just by running the wizard applying a status bar, a toolbar (floating), and implements all the File, Edit, and Help menu items, including the recently used file list and printing and context-related Help, all of this is included in a single document interface (SDI), a multi-SDI or multi-document interface (MDI) application in a full logo. As a document-based application framework, there is no competitor that can match the MFC.

However, programmers now tend to build more HTML-based applications, or applications that can communicate with business objects or database servers, not document-based applications. The .NET framework and Windows form are tailored for this purpose.

This is not to say that the Windows Form cannot be used to build an excellent document-based application. In fact, since the Windows form is only a small portion of the .NET framework, you need is very likely that the Windows form is not provided, but is located in the frame. For example, the Windows form itself does not provide any object serialization support, but the rest of the .NET framework class library provides a variety of serialized object maps.

This is the main difference between the MFC and Windows forms. The MFC is designed to replace the base Win32 API, but this does not prevent Win32 API growth. In fact, just like MFC grows with time, the function of the base OS has a minimum of ten times. However, the Windows form is only a substitute for the Window section of Win32. The rest of the .NET framework class is responsible for replacing the rest of Win32. Of course, the framework will never replace the entire Win32 API, but due to the expected future, most of the new features to add to Windows are added to the frame, replacing the entire Win32 API will be a future goal.

Therefore, although the Windows form does not have the full functionality of the MFC, it is indeed a strong set of features that can greatly facilitate client application developers, including some of the MFCs that do not have. Below, we will introduce how to build an application from scratch, then explain the Work Efficiency Improvement feature provided by Visual Studio .NET 2003 for Windows Form C programmers.

Back to top

Create a Windows Form from the beginning

Typical Windows Forms have at least one form. The form is a window, that is, starting the Microsoft user interface unit we see from Windows 1.0. Typically, a form in the Windows Form Application is a main form, meaning it is the parent or owner of all other forms of other forms that may be displayed within the survival period of the application. The form is a location where the main menu and the toolbar, the taskbar, and the like. At the end of the main form, the application exits. The main form of the application can be a simple message box, a dialog, an SDI window, an MDI window, or more complex control, such as the application of Visual Studio .NET with multiple sub-windows, Tools window And the form of the floating toolbar.

If your application is extremely simple, you can use a simple message box that is flooded in any window system:

#using

#using

#using

Void __stdcall Winmain (Hinstance Hinstance,

Hinstance Hprevinstance,

Long lpcmdline,

INT ncmdshow)

{

System :: Windows :: Forms :: Messagebox :: Show ("Hello, Windows Forms");

}

As a C programmer, you must be very familiar with the WinMain entry point, in the hosted application, the entry point is still required. In our first Windows form application, the only line actual code calls the Windows :: System :: Forms :: MessageBox class static show method, this is actually called included in Window :: Systems :: Forms Name Slimming form of a static method of the Messagebox class in the space. The namespaces are widely used in the .NET Framework class library to separate classes, structures, enumerations, etc. into different logical groups. Because there are thousands of Microsoft employees to work to add .NET framework class libraries, there are hundreds of third-party organizations to expand the library, and millions of programmers are trying to learn it, so this The separation is very necessary. There is no namespace, you need to use a variety of complex agreements to uniquely name various objects (like existing Win32 APIs).

The definition of the type in the namespace is located in the .NET assembly. The assembly is a managed type of a managed type that is packaged as a DLL or EXE. #using instructions are used to apply the types in the program set into your application. For example, Mscorlib and System assemblies provide basic .NET framework types such as INT and String. The System.Windows.Forms assembly contains a Windows Form Type.

Using #using After applying the assembly to the application, you can reference the type, or you can use the standard C Using Namespace statement to omit the job:

#using

#using

Using namespace system :: windows :: forms;

Void __stdcall Winmain (Hinstance Hinstance,

Hinstance Hprevinstance,

Long lpcmdline,

INT ncmdshow)

{

Messagebox :: Show ("Hello, Windows Forms");

}

Therefore, although this simple example is effective in demonstrating the most basic .NET framework and C managed concept, it does not highly demonstrate a typical Windows form program. For real applications, an instance of a FORM class (or class from form) is required, as shown below: Void __stdcall Winmain (Hinstance Hinstance,

Hinstance Hprevinstance,

Long lpcmdline,

INT ncmdshow)

{

Form * form = new form ();

...

}

The FORM variable references an example of the hosted type. The hosting object is processed by the public language runtime library (CLR) of the .NET framework, and their living cycle is controlled by the garbage collector, which cancels the memory at a certain amount of time. Therefore, the C programmer does not need to explicitly delete the managed type, but it is also not possible to destroy the object at any particular moment (such as a closed range).

When you create a form, you need to display it. If you have read the documentation of the Windows Form, you may have noticed the form method show, which means:

Void __stdcall Winmain (Hinstance Hinstance,

Hinstance Hprevinstance,

Long lpcmdline,

INT ncmdshow)

{

Form * form = new form ();

FORM-> show (); // this is not what you want to do.

}

Although the above code can display the form, it is necessary to see the form, because Show displays a form in a modeless manner. This means that after Show displays the new form to the screen, the control will return to the main function, which will exit the process while returning, and closes the form that has just been displayed. To display the form in a mode, the document is recommended to use the showdialog function:

Void __stdcall Winmain (Hinstance Hinstance,

Hinstance Hprevinstance,

Long lpcmdline,

INT ncmdshow)

{

Form * form = new form ();

FORM-> ShowDialog (); // this is not quite what you want to do.

}

Although these codes can actually display an empty form, the control is returned to the main function after the user closes it, but usually you will not write such a code. Instead, you will specify a form as a main form, so that other parts of the application can be accessed as a main form. To do this, the main form can be passed as a parameter to the RUN method of the Application object of the Windows Form:

#using

#using

#using

Using namespace system :: windows :: forms;

Void __stdcall Winmain (Hinstance Hinstance,

Hinstance Hprevinstance,

Long lpcmdline,

INT ncmdshow)

{

Application :: Run (New Form);

}

The static RUN method of the Application class will display the main form and start sending a Windows message until the main form is turned off. After the main form is turned off, RUN will return to let our main function exit to end the process. To actually check this process, you can compile this small Windows Form Application using the following command line: C: / MSDN / MyFIRS ~ 1> CL / CLR myfirstapp.cpp

Now, the compiler has generated myfirstapp.exe, which can be executed. When you turn off the form, myfirstapp.exe will exit and end your first Windows Form application.

To add some fun, you can set an attribute on a new form. Like most objects in the .NET Framework class, the Form object has some properties that can be accessed, and the methods that can be called and events that can be processed. You can set the properties directly on the instance of the Form class, but usually we will not do this. Instead, each custom form is a class derived from the form, and will initialize your properties, as shown below:

__GC Class MyForm: PUBLIC FORM

{

PUBLIC:

MyForm ()

{

TEXT = "Hello, Windows Forms!";

}

}

Void __stdcall Winmain (Hinstance Hinstance,

Hinstance Hprevinstance,

Long lpcmdline,

INT ncmdshow)

{

Application :: Run (New MyForm);

}

In C hosted extensions, custom managed types are represented using the __gc modifier. Note that the MyForm class is derived from Form and then its own properties are initialized in the constructor. This provides a good usage model, as shown in the new main function, the function creates an instance of the MyForm class.

But this form is still very bored. In addition to the feature provided, it does not have any interaction. We can add some interactions by adding a button, as shown below:

MyForm ()

{

TEXT = "Hello, Windows Forms!";

Button * button = new button ();

Button-> text = "Click ME!";

this-> Controls-> Add (Button);

}

Add a button to the form that is created a new Button object, set the properties we need, and add it to the list of controls managed by the form. Although the above code will generate a button on the form, it seems that it seems like being clicked, but does not happen, because you have not processed the Click event of the button. You can handle this event like this:

__GC Class MyForm: PUBLIC FORM

{

PUBLIC:

MyForm ()

{

TEXT = "Hello, Windows Forms!";

Button * button = new button ();

Button-> text = "Click ME!";

Button-> Click = New EventHandler (this, button_click);

this-> Controls-> Add (Button);

}

Void Button_Click (Object * Sender, Eventargs * e)

{

Messagebox :: Show ("Ouch!");

}

The Click event of the processing button involves two work. The first item is to create a handler method with an appropriate signature, we call it Button_Click. Most. Net Framework Signature is a function, which does not return, but get two parameters: an object indicating the sender of the event (this example is button), and a System :: EventArgs object (Or an example of an object from Eventargs class).

The second item required for booking events is to use the = operator in the MyForm constructor. This indication means adding a method to a list of all other methods related to specific events on a particular object. This requires an instance of the EventHandler to delegate the object. The delegation is a class that converts the call to the event to a call for the method of subscribing to the event.

Note that the Click event on the Button class is a reference to the EventHandler, so you need to add your own method to the subscriber list, you also need to create an instance of the delegate of this category. Of course, figure out the entrusted signature of all events you are interested, or by manually write code to add controls to the form, soon it will become a very boring thing. Fortunately, this can also be avoided because Windows Forms for C is integrated in Visual Studio .NET 2003.

Back to top

Create a Windows Form using the Visual Studio .NET designer

Before Visual Studio .NET 2003, only C # and Visual Basic .NET have supported window design. C hosted extension is not. Fortunately, now Visual Studio .NET comes with C managed Windows Form Designer.

Most Windows Forms are starting in the New Project dialog box, you can visit the dialog by clicking File, pointing to New, then click Project, or by pressing Ctrl Shift N to access the dialog.

When you run the Windows Application Wizard, you can choose the project name and location at will, and you can get a blank form in the designer.

In the MFC, only the dialog supports the drag and drop design and user interface layout. Ordinary view must be layout in your code. However, Windows Forms treat all forms in a unified manner, so the same drag and drop designer is suitable for various forms. The type of form (with mode or no mode, dialog, or view) depends on its way of use, not design.

The next major difference between the Windows Forms and MFC in the designer is that the designer saves controls and layout information in the code rather than separate resource files. This is very different from the MFC, and the MFC saves the dialog box layout information in the Win32 dialog resource in the .rc file. Both of these programs have advantages and disadvantages, but the MFC programmer will soon notice the differences. It needs a process to adapt to it.

Another thing you should pay attention to is the C Hosting Extension Project Wizard will generate the code to the .h file instead of .cpp file. This may be because the C designer must adapt to the existing designer architecture rather than Visual Studio .NET 2002, the latter only supports languages ​​such as C # and Visual Basic .NET, these languages ​​are not split declared and defined. The generated header file (you can click the design graph and then select View Code or by pressing F7) as follows:

Namespace mysecondapp {

Using Namespace System;

Using Namespace System :: ComponentModel;

Using Namespace System :: Collectes;

Using namespace system :: windows :: forms;

Using namespace system :: data;

Using namespace system :: drawing;

///

/// summary for Form1

PUBLIC __GC CLASS FORM1: PUBLIC System :: Windows :: Forms :: Form

{

PUBLIC:

Form1 (void)

{

InitializationComponent ();

}

Private:

///

/// Required Designer Variable.

///

System :: ComponentModel :: Container * Components;

///

/// Required Method for Designer Support - Do Not Modify

/// The contents of this method with the code editor.

///

Void InitializeComponent (Void)

{

This-> Components = New System :: ComponentModel :: Container ();

This-> size = system :: drawing :: size (300, 300);

This-> text = "form1";

}

}

}

Most of the code above should be known for everyone, including a custom form that is derived from the FORM base class. The only place in which you implement is different from your implementation is called InitializationComponent to set the properties of the form, not in the constructor itself. The reason why this is done, in order to place the Windows Form Designer to place the control and the code on the form itself on the form.

Windows Form Application Project Template generates a .cpp file:

Int apientry _twinmain (Hinstance Hinstance,

Hinstance Hprevinstance,

LPTSTR LPCMDLINE,

INT ncmdshow)

{

System :: Thieading :: thread :: currentthread-> ApartmentState =

System :: Thieading :: ApartmentState :: sta;

Application :: Run (New Form1 ());

Return 0;

}

The above code is equally familiar. The main function provides an application's entry point and an instance of the Application :: Run to incorporate the main form class. Setting the ApartmentState variable to a single line unit (STA), is for the appropriate inert initialization of COM to be used in a user-friendly manner in the drag and drop operation, and the host COM control.

Return to the InitializationComponent implementation, you can see that the form designer is placed there. For example, the design graph that drags the button from the toolbox to the form will change the INITIALIZECMOMPONENT to the code as follows:

Void InitializeComponent (Void)

{

This-> Button1 = new system :: windows :: forms :: button (); t-> suspendlayout ();

//

// Button1

//

This-> Button1-> location = system :: Drawing :: Point (0, 0);

This-> Button1-> Name = "Button1";

this-> Button1-> TabINDEX = 0;

This-> Button1-> text = "button1";

//

// Form1

//

this-> AutoScaleBasesize = System :: Drawing :: Size (5, 13);

This-> Clientsize = System :: Drawing :: Size (288, 253);

This-> Controls-> Add (this-> Button1);

THIS-> Name = "Form1";

This-> text = "form1";

this-> ResumeLayout (false);

}

Please note that the above code is similar to the code you previously generated, but they are created by the designer. Unfortunately, to make this process can run reliably, the designer needs to fully control the initializecomponent method. In fact, you can see the InitializationComponent code package generated by the wizard in a region (by default, the code will be hidden), and mark the descriptive comment:

/// Required Method for Designer Support - Do Not Modify

/// The contents of this method with the code editor.

This may look like your preferred programming language, but InitializeComponent is actually a sequence formation of the designer for managing the design graphic. Although you can make some subtle changes to these code, if you change the text properties of the new button, the major changes may be ignored, or even deleted. We recommend that you initialize custom Forms After the built-in built-in function, you will ensure that your designer does not destroy your code.

Of course, the benefits of the designer offset its violation of the code. For example, you do not need to set the multi-line code to set the form or the properties of the control it contain, just right-click the desired object and select Properties (or press F4) to adjust the properties browser for the selected object. .

All non-default properties (indicated as a crude display) will write to the InitializationComponent method for you, you do not need to write these code. Similar to this, the event to select a control of the form or form for processing, you can click on the Events flash icon at the top of the property browser window.

In the Properties Browser window, the event can be processed in a variety of ways. One way is to find out the events to be processed by clicking and typing the name of the function to be called when the function to be called, such as Button_Click. After entering the name of the event handler, press ENTER to bring you to the body with the event handler with the name and the correct signature, you can immediately start:

Private: System :: void button_click (Object * Sender, Eventargs * e)

{

}

If you are like a general case, you want to process each of the objects, or you don't care about the name of the handler, just double-click the name of the event in the property browser, you will be based on the name of the control and event. You generate an event handler name. For example, if you double-click on the Load event of the Form 1 form, the event handler name will be form1_load. Also, if you want to handle the default event of the object, you can do it by double-clicking on the object itself - this will generate an event handler name like the event name in the list of property browser events. The default event of the object refers to an intuitive-specific type of most frequently processed event. For example, the default event of the button is click, and the default event for the form is LOAD. Unfortunately, both the designer and attribute browser do not prompt to a particular type of default event, but it usually does not usually won't have much exception.

Back to top

Control

The designer is the advantage where you can arrange the layout of the control in the form to ensure that all elements are arranged neatly (as shown in Figure 1), and is not like the size adjusted (as shown in Figure 2).

Figure 1 Forms that are ideal and neat layout

Figure 2 The form size of neat layout is adjusted

User adjustment form size is not to have more gray space, they are to have more space to use data input controls. To achieve this, you need to re-adjust the size of the control to occupy the new available space. This can be manually completed by processing the resize event of the form and writing code. Alternatively, it can be achieved by positioning.

Positioning is a way to provide automatic layout control for the controls included in the form and forms. By default, all controls are positioned to the top left, so that all controls will maintain their positions with respect to the upper left corner of the form to adjust the size of the form. However, in this example, it is best to widen or narrow the text box control at the adjustment form size. This can be implemented by setting the anchor attribute of each text box. Displays the property browser of the control and select the Anchor property, the editor shown in Figure 3 will be displayed.

Figure 3 Set an ANCHOR attribute

To change the text box to the right edge and the upper edge and left edge, you only need to click the positioning box on the right and then change the Anchor property to Top, Left, and Right. This will cause the size of the text box to change along the size of the form, as shown in Figure 4.

Figure 4 Position the text box to top, left and right and position the button to the bottom and right side

Although the default positioning is top left, these edges do not need to be part of the positioning settings. For example, you can see that in Figure 4, the OK and Cancel buttons are positioned in the lower right corner, which is the same as the habit of the Windows dialog.

If you don't want to generate a form of a dialog style, but to generate a window style form, the location will not be the best choice. For example, if you want to build an Explorer style application, the application has a menu bar and a toolbar at the top, with a status bar, a tree view and a list view occupy the remaining space, and use the control between controls The splitter determines the space occupied by the control, and it will not be used. At this point, you need to stop.

By default, the control's Dock property is set to NONE. You can change the Dock property in the Properties Browser, and the method is to select an edge to be docked or choose to occupy the remaining space.

For example, the Dock property of the status bar, the tree view, and the list view may be displayed by a splitter control. All of this has been arranged, you do not need to write any code.

Positioning, docking, and splitting are not only a method of arranging controls on the form. The Windows Form also supports packet controls and handling custom layouts in special circumstances. In addition, Windows Forms supports windows in the parent, which is often referred to as multi-document interface (MDI). Back to top

Data binding

Data binding refers to a capability: binding one or more controls to a data source, making it updated when one party is updated, and the other is updated. Data Binding is not only good support in the Windows form, it is completely integrated into the Visual Studio .Net itself.

Drag and drop a table from the Server Explorer to the design map, which will create two components, one connection to the database and a adapter that transmits data between the two sides. Right-click the adapter in the designer and select Generate Dataset, create a new dataset, which is a class derived from the DataSet, generating this class dedicated to saving the table dragged out of the table from the Server Explorer. The default General DataSet option also creates an instance of the new dataset for associated with the control.

After obtaining the source of the data, you can bind the data to one or more controls. Windows Forms provide multiple database binding controls, including Listbox and ComboBox, etc., where DataGrid flexibility is the highest.

After the data set on the form, you want to bind the data grid to it and use it as a data source, simply set the DataSource and DataMember properties of the data grid in the property browser, and populate the form when loading the form data set:

Void InitializeComponent (Void)

{

...

This-> DataGrid1-> DataMember = "Customers";

THIS-> DATAGRID1-> Datasource = this-> DataSet11;

...

}

Private: System :: Void Form1_load (System :: Object * Sender, System :: EventArgs * e)

{

SqlDataAdapter1-> Fill (DataSet11);

}

The above is just the general purpose of data binding, as well as a specific purpose of the data grid. For links to more data binding resources, see the Reference section later.

Back to top

Migration from MFC

As a MFC programmer, you spend the time and energy of the existing code basis must be very much. Migrate the MFC code to the .NET framework requires a careful plan. Here are some precautions:

• If you can withstand the maintenanceability code base, it will be able to get the best-maintainable code base, but the longest time consumption. • If you most of your MFC code in the COM control (or can migrate to COM controls), you can use the Windows Form as the host of these controls and write new managed code for the frame. • If you need to upgrade the MFC application itself, you can use the functionality provided by MFC 7.1, and the Windows Form Control Host is a COM control, and the MFC code is still a non-hosting. See the "Reference" section for links to the details of the above scheme. • If you want to use managed code in a Windows Form application, you want to avoid overhead of COM INTEROP, you can cancel the option of the "Use Managed Extensions" of the MFC project so that you can mix the use of managers and non-use in the same code. Managed type. See the "Reference" section on the link to the details of the above scheme.

Suitable for your options depending on the specific situation, but generally, we recommend that you use yourself to write most of the new code of the .NET framework, although this means that some of the Windows Forms you generated were originally It is aware of the MFC and like it. Back to top

summary

This article describes some of the most striking new Windows form functions, but the Windows Form has more features, such as fully automated deployment, dialog data exchange, and verification, MDI applications, drawing, and printing (including print preview), users Controls, custom components, and design support, lists, and type resources, non-compile resource localization and application settings.

For the comparison of the MFC and Windows forms, you need to keep in mind that they are constructed in a very different era to solve a large different problem. The MFC is a document-based application framework. The Windows Form is a window library for N-layer applications. There is a difference between the two. Some of them, such as positioning and docking, making Windows forms more advantageous. Other differences, such as object serialization, existing in other parts of the .NET framework class library. Some features do not exist at all, which is the interesting thing for document-based applications development.

However, there are two things very well: Microsoft is in a big step, while the advantage of the hosted code is very striking. The .NET framework provides automatic processing of both memory and security, enabling more reliable applications and enhances the work efficiency of developers. The .NET framework class library provides a large, resource rich and unified class library. With such a combination, we will be able to build a Windows application more quickly.

reference

Visual Studio .NET: Managed Extensions Bring .NET CLR Support To C , the author is Chris Sells, MSDN Magazine, July 2001.

Windows Forms: a Modern-Day Programming Model for Writing GUI Applications, the author is Jeff Prosise, MSDN Magazine, 2002.

.NET DELEGATES: A C # BedTime Story, Chris Sells.

Cutting Edge: Data Binding Between Controls in Windows Forms, the author is Dino Esposito, MSDN Magazine 2002

Pragmatic ADO.NET: DATA Access for the Internet World, the author is Shawn Wildermuth, Addison-Wesley, published in 2002.

Windows Forms Programming In C #, the author is Chris Sells, Addison-Wesley, published in 2003.

Windows Forms: .NET Framework 1.1 Provides Expanded Namespace, Security, And Language Support for your projects, the author is Chris Sells, Msdn Magazine March 2003.

Introduction to Managed C . The author is O'Reilly OnDotNet SAM Gentile, published in January 2003.

Go to the original English page

转载请注明原文地址:https://www.9cbs.com/read-115093.html

New Post(0)