Click to Rate and Give Feedback
Related Articles
Here the author introduces SQL Server Data Services, which exposes its functionality over standard Web service interfaces.

By David Robinson (July 2008)
Here the author answers questions regarding the Entity Framework and provides an understanding of how and why it was developed.

By Elisa Flasko (July 2008)
Here we present techniques for programmatic and declarative data binding and display with Windows Presentation Foundation.

By Josh Smith (July 2008)
Systems that handle failure without losing data are elusive. Learn how to achieve systems that are both scalable and robust.

By Udi Dahan (July 2008)
More ...
Articles by this Author
The Windows Presentation Foundation provides new techniques for UI-based developing applications and makes better use of current hardware and technologies. In this article, Ian Griffiths and Chris Sells explain 10 of the most significant advances that make WPF superior to its Win32 predecessors.

By Ian Griffiths and Chris Sells (January 2006)
The System.Windows.Forms namespace has increased by approximately 134 percent over the .NET Framework 1.1. There are 446 new public types; 113 existing types have been updated with new members and values; 218 types have been carried over from the original namespace. Read about it here.

By Chris Sells and Michael Weinhardt (Visual Studio 2005 Guided Tour 2006)
In this article, the winning Windows Forms duo of Chris Sells and Michael Weinhardt team up again to explore lots of new features and additions to Windows Forms 2.0 that will let you build more flexible, feature-rich controls, get better resource management, more powerful data-binding abilities, and make your development life a whole lot more fun.

By Michael Weinhardt and Chris Sells (May 2005)
The upcoming version of the .NET Framework offers a host of enhancements an order of magnitude over and above existing versions. In particular, developers writing Windows Forms benefit from a variety of new and improved features targeting development, deployment, increased productivity, and auto-generated code. This article covers some of the key new features including designer enhancements, new controls, data binding, and deployment to give you a taste of what's to come.

By Michael Weinhardt and Chris Sells (May 2004)
This is the second of two articles discussing the extremely rich design-time features of the .NET Framework. Part 1 discussed the basics, showing you where to start and how to extend your control implementation through attributes and interfaces, as well as their effects on the property browser, code serialization, and other controls. Part 2 continues the journey by concentrating on design-time functionality that you can implement beyond your components and controls, including TypeConverters, UITypeEditors, and Designers. It would be impossible to cover everything you can do in two short articles, which is a testament to just how all-encompassing and flexible the design-time capability of the .NET Framework is.

By Michael Weinhardt and Chris Sells (May 2003)
Visual Studio .NET provides support for designing rich features into your controls and components, allowing you to set properties, set form placement, inherit from base classes, and much more. So how does Visual Studio .NET do all this? What does the Windows Forms designer do? What's the difference between a control and a component? How does Visual Studio integrate your controls so that they can access features of the .NET Framework?In this article, the authors answer these common questions by building a clock control and taking the reader along for the ride. In building the control, hosts and containers are illustrated, the property browser is explained, debugging is discussed, and a general overview of the design-time infrastructure is presented.

By Michael Weinhardt and Chris Sells (April 2003)
Throughout this issue, you'll read all about the promise of Web Services and how the .NET Framework enables Web Service development. Many people will also be building their Web Services atop C++ code and frameworks like ATL Server, particularly when performance is paramount. In this article, the authors show how fully functional Web Services are built using ATL Server and Visual Studio .NET. Beginning with unmanaged C++ classes, they add ATL attributes that make the code work over HTTP.

By Kirk Fertitta and Chris Sells (December 2002)
Visual Studio .NET has lots of cool features. Obviously, it supports languages that target the common language runtime, like C# and Visual Basic .NET, and it lets you write CLR-managed code. But did you know that there are features of the environment itself, independent of the language features, that earn Visual Studio .NET the cool tool stamp of approval?In this article the authors count down their favorite environment features—the ones they think every developer will applaud. They include support for debugging stored procedures, project reference management, metadata in Class View, a richer immediate window, custom environment programming with macros, and more.

By Jon Flanders and Chris Sells (October 2002)
More ...
Popular Articles
The .NET Compact Framework 3.5 provides a subset of Windows Communication Foundation (WCF) functionality that you can harness to communicate between Windows Mobile devices and desktop PCs. We'll show you how.

By Andrew Arnott (Launch 2008)
Microsoft Robotics Studio is not just for playing with robots. It also allows you to build service-based applications for a wide range of hardware devices.

By Sara Morgan (June 2008)
Here the author introduces SQL Server Data Services, which exposes its functionality over standard Web service interfaces.

By David Robinson (July 2008)
Speech Server 2007 lets you create sophisticated voice-response applications with Microsoft .NET Framework and Visual Studio tool integration. Here’s how.

By Michael Dunn (April 2008)
More ...
Read the Blog
SQL Server Data Services (SSDS) is a robust, scale-free data service that internally uses proven SQL Server technology and exposes its functionality over industry standard Web service interfaces. In the July 2008 issue of MSDN Magazine, David Robinson introduces ...
Read more!
Windows Presentation Foundation (WPF) offers excellent support for managing the display and editing of complex data. In the December 2007 edition of MSDN Magazine, John Papa did a great job of explaining essential WPF data binding concepts. ...
Read more!
The most fundamental form of Web testing is HTTP request/response testing. This involves programmatically sending an HTTP request to the Web application, fetching the HTTP response, and examining the response for an expected value. In the May 2008 issue of MSDN Magazine, Read more!
In the November issue of MSDN Magazine, Jeffrey Richter demonstrates some recent additions to the C# programming language that make working with the APM significantly easier. In the June ...
Read more!
The July 2008 issue of MSDN Magazine is now available online. Here's what's in the issue: Data Services: Develop ...
Read more!
The June 2008 issue features the first installment of a new MSDN Magazine column on software design fundamentals. We’ll discuss design patterns and principles in a manner that isn't bound to a specific tool or lifecycle methodology. In this issue, Jeremy Miller starts the Patterns in Practice column ...
Read more!
More ...
Windows Forms
.NET Framework 1.1 Provides Expanded Namespace, Security, and Language Support for Your Projects
Chris Sells
Code download available at: WindowsForms.exe (135 KB)
Browse the Code Online

This article assumes you're familiar with Windows Forms and C#
Level of Difficulty 1 2 3
SUMMARY
With the much-anticipated release of the .NET Framework 1.1, developers are eager to know what's been added to their programming bag of tricks. In this article, the author focuses on new developments in Windows Forms, such as namespace additions, support for hosting managed controls in unmanaged clients, and designer support for C++ and J#. Integrated access to the Compact Framework and new mobile code security settings also make this release noteworthy. Along with these features, the author reviews the best ways to handle multiple versions of the common language runtime and highlights some potential pitfalls.
Y ou know that the old saying that goes everyone complains about the weather but nobody does anything about it? Well, it can't be applied to programming. Microsoft® is continually working hard to produce the next greatest set of development tools and technologies. In the latest release of the Microsoft .NET Framework, version 1.1, forecasts are very promising. While originally intended only as a bug-fix release (the .NET Framework version 1.0 was released just last February, after all), version 1.1 has both fixed bugs and integrated much needed new features into one of my favorite parts of the .NET Framework—Windows® Forms.
This article is based on the final beta of the .NET Framework 1.1, which ships alongside Visual Studio® .NET 2003. Most features are likely to stay very similar, but some are bound to change by the time it is officially released.

What's New
According to a document that comes with the new .NET Framework SDK entitled "API Changes from v1.0 to v1.1," there are 48 additions, 14 removals, and no breaking changes in the System.Windows.Forms namespace. This news may, at first, cause you to rejoice at the addition of 48 new features and mourn the loss of 14 old features, while hoping that you weren't using anything that was axed. You might also wonder how there can be no breaking changes if 14 things were removed. Since the lack of breaking changes means that all of your existing Windows Forms code should continue to run without any changes, all of the removals have corresponding additions that are really changes, like the change of the declaration of the ProcessDialogKey method on the AxHost class, as shown here:
class AxHost {
  // .NET 1.0 declaration
  protected virtual bool ProcessDialogKey(Keys keyData);

  // .NET 1.1 declaration
  protected override bool ProcessDialogKey(Keys keyData);

  •••
}
This change shows that AxHost no longer provides a new virtual method but overrides an existing one, which means that ProcessDialogKey was declared as virtual further up the inheritance hierarchy. The vast majority of the additions fall into this category, making the changes to the Windows Forms namespace itself seem very boring. There are really only three noteworthy additions to the Windows Forms namespace (and one interesting addition to the System.Drawing namespace):
  • the System.Windows.Forms.FolderBrowserDialog class
  • the System.Windows.Forms.Application.EnableVisualStyles method
  • the System.Windows.Forms.CurrencyManager.MetaDataChanged event
  • the System.Drawing.Printing.PrintDocument.OriginAtMargins property
If that was the whole story, I certainly wouldn't need an entire article to describe what's new. There's much more, including namespace additions, support for hosting managed controls in unmanaged clients, Windows Forms designer support for managed C++ and Visual J#™, integrated access to the Compact Framework, and new mobile code security settings. Before I move on to all that is new, however, I'll discuss how to handle multiple versions of the common language runtime (CLR).

Moving to 1.1
With any new version, I always hope that Microsoft has added the features that I need without ruining any of the ones I depend on. As opposed to Win32® DLLs—where developers pretended that there weren't any versioning issues—and COM, where they pretended that versioning wasn't needed at all—the .NET Framework provides thorough, explicit support for multiple versions of multiple, simultaneously installed versions of components and the runtime itself. In fact, if you're running a version of Windows that's had Windows Update running, you've most likely got CLR version 1.0.3705.288, which is the .NET Framework 1.0 SP2. After installing .NET Framework 1.1, your CLR version will be bumped up to version 1.1.4322.510, which is the .NET Framework 1.1 final beta. However, installing version 1.1 doesn't replace any existing versions installed on your machine. Instead, both versions live in harmony in separate directories.
The version of the CLR that's loaded at run time depends on the version that the EXE assembly was built against. So, if you build a Windows Forms application against .NET Framework 1.0, even on a machine that has .NET Framework 1.1 (or later) installed on it, the 1.0 version of the CLR will be loaded to host your application. However, if a 1.0 application is launched on a machine without version 1.0 installed, will automatically be loaded into CLR version 1.1. This is to prevent every Windows Forms 1.0 application from requiring a .config file that says that it's OK to load a 1.0 application under 1.1. If you'd prefer to turn this behavior off, you can create your own .config file and turn off this auto-upgrade feature:
<!-- support only .NET 1.0 Framework -->
<configuration>
  <startup>
    <requiredRuntime version="v1.0.3705"/>
    <supportedRuntime version="v1.0.3705"/>
  </startup>
</configuration>
In that case, if your version 1.0 application is run on a machine without version 1.0 of the CLR, regardless of whether or not version 1.1 is installed, the user will get the error message indicating that she requires a specific version of the .NET Framework.
Finally, if you'd like to support version 1.0 but prefer version 1.1 if it's available (because it performs better, for example), take a look at the following code:
<!-- prefer .NET Framework 1.1, but support .NET Framework 1.0 -->
<configuration>
  <startup>
    <requiredRuntime version="v1.0.3705"/>
    <!-- order of these keys determines preference -->
    <supportedRuntime version="v1.1.4322"/>
    <supportedRuntime version="v1.0.3705"/>
  </startup>
  •••
</configuration>
Unfortunately, that's not the whole story. Since every assembly comes with a list of required assemblies (including their version numbers), building an application under the .NET Framework version 1.1 is going to require version 1.1 for all of the assemblies. Running a version 1.0 application that's been built under 1.1 on a machine with only 1.0 on it will fail since it won't be able to find the appropriate versions of the referenced assemblies. So, getting your application built under version 1.1 to actually run on an earlier version of the assemblies it references requires entries in the .config file for each assembly, as shown in Figure 1.
These configuration settings specify that when running under version 1.0 of the .NET Framework and loading System.Windows.Forms from any version, version 1.0 of System.Windows.Forms will be loaded, even though the code was built against version 1.1. While this is a handy feature that allows you to use the updated version 1.1 tools, setting up the .config file to make all this happen is a bit of a pain. Luckily, Visual Studio .NET 2003 provides an extra project setting accessible from Project | Properties | Common Properties | General | Supported Runtimes. This setting exposes three runtime options through the .NET Framework Version dialog, namely: Microsoft .NET Framework version 1.1 (default), version 1.0 (advanced), and both.
By default, any application compiled under Visual Studio .NET 2003 will target only the 1.1 version of the CLR. If you'd like to restrict yourself to building just version 1.0 applications, you can check the version 1.0 option. The last option is supporting both versions of the Framework, but preferring 1.1. All three of these options will add an app.config file to your project with the appropriate settings, including an exhaustive list of how to map framework assemblies, saving you the trouble. The resulting app.config file will be copied to the output directory at project build time and renamed projectName.exe.config, as required by the CLR.
If you stop to read the text of the .NET Framework Version dialog, you'll notice that it uses some pretty strong language to dissuade you from choosing to support version 1.0 while using Visual Studio .NET 2003. The problem is that darn middle option that says to only support version 1.0. While Visual Studio .NET 2003 will update the .config file to properly require only version 1.0 of the Framework, neither IntelliSense® nor the compiler will tell you if you make use of a type or a member that's not available under version 1.0. You won't know until run time that the code has run afoul of the 1.0 feature list, and then only if the method that makes use of the missing type or method is actually called. If you decide to use Visual Studio .NET 2003 to build applications targeted at version 1.0, you'll need to do some thorough code coverage testing to make sure that it will actually run under version 1.0.
If you're targeting version 1.0 only and you're desperate to use Visual Studio .NET 2003, but just can't give up the compiler-time checking and accurate IntelliSense, there is a way to eat your cake and have it too. Unfortunately, you'll be without frosting, as you'll have to do more than just flip the bit in the .NET Framework Version dialog. First, you'll have to set Project | Properties | Configuration Properties | Advanced | Do not use Mscorlib to "true" (it defaults to "false") so that you don't pull in the version 1.1 mscorlib.dll when you're compiling. Second, you'll have to remove all of the assembly references that Visual Studio .NET 2003 adds to your project, as it will default to getting them from the version 1.1 Framework directory. Finally, you'll have to add project references from the version 1.0 Framework directory using the browser button in the Add Reference dialog to choose assemblies manually (including mscorlib.dll and system.dll). Since the compiler (and IntelliSense) will be referencing the version 1.0 assemblies, these manual steps let you continue to use Visual Studio .NET 2003, even for version 1.0-only assemblies.
On the other hand, if you're targeting both version 1.0 and version 1.1, it's likely that you'll want to take advantage of the new features of version 1.1. When you do that, you have to be careful to check the version number of the runtime through System.Environment.Version and to only use 1.1 features in methods that will never be called by any version 1.0 code. Even if the 1.1 code won't be called under 1.0, the just-in-time (JIT) compiler will require all types and methods to be present when a method is first called, throwing an exception if something is missing. Figure 2 provides an example of one way to isolate code that requires version 1.1. Notice that this code will only call a method with version 1.1-specific code in it if the version of the runtime supports it.

Namespace Additions
While I'm talking about taking advantage of Windows Forms features available only in version 1.1, recall the CurrencyManager.MetaDataChanged event, the PrintDocument.OriginAtMargins property, the FolderBrowserDialog class, and the Application.EnableVisualStyles method. The MetaDataChanged event is useful if you're employing data binding and you're interested in the underlying metadata changing in addition to new or updated rows and columns. The OriginAtMargins property is useful if you actually want your printed document's margins to align with the edge of the paper instead of the edge of the printable region of the printer (the former is the intuitive location, but the latter was the only option under the .NET Framework 1.0 and is still the default under version 1.1). The FolderBrowserDialog class is a wrapper around the Win32 ShBrowseForFolder function and works the way you'd expect:
void browseButton_Click(object sender, EventArgs e) {
  FolderBrowserDialog dlg = new FolderBrowserDialog();
  dlg.Description = "Please choose a folder:";
  DialogResult res = dlg.ShowDialog();
  if( res == DialogResult.OK ) {
    MessageBox.Show(dlg.SelectedPath, "Selected Path");
  }
}
Of course, the FolderBrowserDialog class is available for drag and drop from the Visual Studio .NET Toolbox, so you can use the Property Browser to set things like the initial folder and whether to show the Make New Folder button.
One other interesting thing about the Browse For Folder dialog box is the use of the cute, rounded, Windows XP-themed buttons. By default, a Windows Forms application will not get the cute, rounded, Windows XP theme—even running under Windows XP and .NET Framework version 1.1. Instead, the classic controls will be used, making your app look old-fashioned when running under Windows XP, especially in comparison to the standard dialogs, which always display in a themed manner.
Under version 1.0, enabling Windows XP themes required a .manifest file to select the themed version of the common controls and dialogs (see References for the manifest required under version 1.0 to enable themes). Enabling themes in version 1.1 no longer requires a manifest. Instead, you need to call the EnableVisualStyles method from the System.Windows.Forms.Application class before showing any UI:
static void Main() {
    Application.EnableVisualStyles();
    Application.Run(new Form1());
}
While EnableVisualStyles sounds comprehensive, you'll also need to set the FlatStyle on each control on your form from the default value of FlatStyle.Standard to FlatStyle.System. Figure 3 shows the difference when running under Windows XP. As a shortcut to setting the FlatStyle property on the subset of controls that support it (buttons, group boxes, and labels), consider the code shown in Figure 4.
Figure 3 FlatStyle 

Managed Controls in Unmanaged Hosts
While I'm on the topic of managed controls, one thing that version 1.0 supported was hosting Windows Forms controls in exactly one unmanaged host: Microsoft Internet Explorer. The syntax was special-purpose and tailored just for hosting Windows Forms controls, as shown here:
  <html> <body>
    <object
      id="iectrl"
      classid="iectrl.dll#iectrl.UserControl1"
      width="100" height="100" >
    </object>
  </body> </html>
While some special interop attributes are required on a Windows Forms control to support events, Internet Explorer didn't require any of the normal COM registry entries to make the control available to it as a COM control. Instead, the classid attribute of the object element takes the name of a Windows Forms control in the following form:
<dllName>#<namespace>.<className>
Internet Explorer simply loads the Windows Forms control itself and treats it as a COM control. However, no other popular COM control hosts, like MFC, Visual Basic® 6.0, or ATL, were supported in version 1.0. While neither Visual Basic 6.0 nor ATL is officially supported in version 1.1 either, the Windows Forms team did a full test cycle on hosting Windows Forms controls as COM controls in MFC 7.1—the version of MFC that comes with Visual Studio .NET 2003—and it is now an officially supported unmanaged host. However, while it is fully supported, it's not fully integrated. You'll need to augment the standard COM control containment infrastructure to support Windows Forms controls.
The core of the MFC support for COM controls lies in COleControlSite, which creates controls on demand given a CLSID. Instead, I'll be creating the Windows Forms control before attempting to host it, so my COleControlSite derivative will ignore the CLSID and create a host around the existing control (see Figure 5).
The COleControlSite CreateControl method is used when the CWnd base class CreateControl method is called to create a COM control. My implementation of CreateControl is mostly a copy of the base class implementation, except that instead of calling the CreateOrLoad method that creates a COM control, it calls my custom WrapWinFormsControl method. My Windows Forms control hosting code depends on the COM interop that the .NET Framework supplies for Windows Forms controls exposing the appropriate COM interfaces.
Also, notice the use of the CWinFormsControlWnd class. Instances of this class hold the HWND that hosts the COM control as well as the IUnknown pointer on the Windows Forms control. The CWinFormsControlSite depends on instances of CWinFormsControlWnd to return the interface pointer on the COM façade around the Windows Forms control on demand via the GetControl method (see Figure 6).
The implementation of GetControl returns a cached COM interface pointer from the Windows Forms control as passed into the Create method. The Create method caches the interface pointer and causes the CWinFormsControlSite class's CreateControl method to be called by calling the base CWnd class's CreateControl method. My custom CWinFormsControlSite class is provided to the CWnd class by overriding the CreateControlSite method of any CWnd-derived class that must host a Windows Forms control, as shown in the following:
BOOL CMfcWinFormsHostDlg::CreateControlSite(...) {
  ASSERT(ppSite);
  *ppSite = new CWinFormsControlSite(this->GetControlContainer());
  return TRUE;
}
As an example of such a class, Figure 7 shows a dialog that hosts the unmanaged and managed MonthCalendar controls side by side on the same MFC dialog.
Figure 7 Hosting a Control in an MFC 7.1 Container 
The dialog in Figure 7 was created using the standard MFC wizard, overriding the CreateControlSite method and creating an instance of the CWinFormsControlWnd class:
class CMfcWinFormsHostDlg : public CDialog {
  •••
virtual BOOL CreateControlSite(...);

private:
  CWinFormsControlWnd m_wndWinFormsCalendar;
};
After hooking into the COM control creation process of MFC, I'm finally able to create instances of Windows Forms controls as the dialog is being created. This can be done from unmanaged code by manually hosting the common language runtime (CLR) and using COM interop to create an instance of any Windows Forms control. However, a far easier solution is to turn on the managed extensions to C++ by setting the Project | Properties | Configuration Properties | General | Use Managed Extensions option to "yes" (it defaults to "no"). This will enable the use of managed types, including Windows Forms controls, from your MFC application without requiring you to make any of your existing unmanaged C++ classes managed (see Figure 8).
While these instructions are a bit cumbersome, the CWinFormsControlWnd and the CWinFormsControlSite helper classes provided in the sample with this article take most of the sting out and require no special support in your Windows Forms controls to host them in MFC 7.1 above and beyond what you already do to support Internet Explorer 5.01 and higher hosting. For more information about the interop story between COM and .NET, see Adam Nathan's book .NET and COM: The Complete Interoperability Guide (Sams, 2002).

Designer Support for C++ and J#
Like hosting Windows Forms controls as COM controls, support for languages other than C# and Visual Basic .NET in Visual Studio .NET 2002 was available, but not completely integrated. You could write a Windows Forms application in managed C++ or J#, but there was no designer support; you had to write all the code by hand. As big a fan as I am of Windows Forms, I wouldn't wish that task on anyone.
Luckily, for programmers who need to stay in C++ or J#, Visual Studio .NET 2003 provides full designer support for managed C++ and J#. When creating a new project, in the Visual C++® and Visual J#™ project types you'll see projects for building a Windows Control Library and a Windows Forms application, just like you're used to for C# and Visual Basic .NET. When creating a Visual C++ Windows Forms app, you'll see a very familiar environment, complete with a toolbox full of controls and components, the designer surface ready for your drag and drop operations, and the Property Browser. In fact, the only thing that's different is the Window tab, which says Form1.h instead of Form1.cs.
When a new C++ Windows Forms application project is created, you'll see a Form1.cpp and an AssemblyInfo.cpp file, as you'd imagine, but you'll also see a .h file for each form class you add to the project using Project | Add New Item. The .h file is where the designer does all of its work and where you're expected to add your own code. The .cpp file is merely a legacy from days gone by and serves only to include the precompiled header and the corresponding .h file. Only the wizard-generated Form1.cpp is at all interesting; it contains the entry point of the app (see Figure 9).
For former C++ programmers who now use C# to build their Windows Forms applications, this syntax should feel either like waking from a dream or falling into a nightmare. Either way, it's pure managed C++, although all of the real action happens in the header file, as shown in Figure 10.
For C# programmers, this code should also be very familiar. The custom Form1 class derives from the Form base class. The form's constructor calls the InitializeComponent class (although without the condescending comment granting permission to add other code to this function). The Dispose function is there to handle integration with nonvisual components, using the __super keyword to call the base class. InitializeComponent is there to set up the initial properties of the form and the controls on the form. Just as in C# or Visual Basic .NET, this function is owned by the designer and should be left alone unless you like playing with fire (and getting burned).
After the wizard generates the initial C++ code, the designer adds member variables as you drag and drop controls onto the form, sets their properties in InitializeComponent as you make changes in the Property Browser, and adds event handlers for you. Honestly, it's all pretty boring until you realize that now you've got all of the convenience of the Windows Forms tools that Visual Basic .NET andC# programmers enjoy, married with the power of both managed and unmanaged C++. For example, one of my favorite features that managed C++ projects allow is adding unmanaged resources, something that neither C# nor Visual Basic .NET support. That's in addition to templates, multiple inheritance, and the mixing of managed and unmanaged code and types, which managed C++ is already known and loved for.

Compact Framework
In Visual Studio .NET 2003, not only can you build desktop applications in C#, Visual Basic .NET, managed C++, and J#, but you now have support for building smart device applications in C# and Visual Basic .NET. This functionality was available in beta form as an add-in for Visual Studio .NET 2002, but it's now built right into the product.
A smart device application runs on a Pocket PC or a machine running Windows CE. When you choose the Smart Device Application project template, you're actually allowed to build an application or a class library. Choosing to build provides you with a familiar environment, except that the common language runtime classes are fewer and smaller. For example, getting 98 percent of an existing Windows Forms game application ported to the .NET Compact Framework was easy, but the rest took some digging. Unlike the .NET Framework, the .NET Compact Framework has, at most, one way to do anything—so some of the shortcuts you're used to taking in Windows Forms are unavailable. For example, when trying to set the background bitmap on the control, I had to draw it during the Paint event. Likewise, reading the bitmap in from a resource wasn't as easy as I'm used to:
// Loading a bitmap from a resource in the .NET 
// Framework
Bitmap logo = new Bitmap(this.GetType(), 
              "sblogo.PNG");

// Loading a bitmap from a resource in the 
// Compact Framework
Assembly assem = Assembly.GetExecutingAssembly();
string file = "PocketWahoo.sblogo.PNG";
Bitmap logo = new Bitmap(assem.GetManifestResourceStream(file));
However, there's nothing like running your Windows Forms application on another device, even if the device is being emulated, as shown in Figure 11.
Figure 11 Windows Forms in Emulator 

Mobile Code Security Settings
One more detail that you may find interesting has nothing to do with code at all, but with the security settings for smart clients and Windows Forms controls downloaded over the Web. In version 1.0, the .NET Framework provided the wonderful ability to host Windows Forms controls on a page in Internet Explorer, just like COM controls. Even better, version 1.0 introduced the idea of smart clients—that is, client applications executed from across the Web. If you haven't done it before, create a virtual directory, plop a Windows Forms application into it, and surf to it from Start | Run using a URL like this: http://localhost/itweb/hr452.exe. This will cause the application to be downloaded to the local machine and run like a standalone client app, but will be constrained by the permissions associated with where the app was launched from (see References in the SDK for more information about smart clients).
Both ways to download and host code from across the Web carry security considerations, of course, since that code could come from either the friendly intranet or the hostile Internet. To make sure that no bad things happen, the .NET Framework Code Access Security (CAS) model provides a partially trusted security sandbox for each assembly based on where it comes from. In version 1.0 SP0, assemblies from both intranet and Internet zones were allowed to run, but the Internet permissions were considerably reduced from intranet permissions. As of version 1.0 SP1, Microsoft changed the settings to disable code from the Internet altogether (although you can turn access back on). Now version 1.1 is a more secure release, and Microsoft has turned execution of code from the Internet back on by default without reducing the Internet permissions themselves. But that's not all. Version 1.1 of the .NET Framework also brings the Authenticode® model back from COM.
With the COM Authenticode model, if the user OK'd code to run, it could do absolutely anything it wanted, subject to the permissions of the user (most of whom run as administrators). If the code did something bad, a team of experts could track it, find the certificate, and bring the bad guys who wrote the code to justice. The .NET CAS model, on the other hand, is preventative in that the user is never asked, but the code only has a limited set of permissions if it's from a location other than the local hard drive. In practice, it turns out that both models have their uses. CAS is great, of course, for keeping bad things from happening. Authenticode, on the other hand, is good at letting the user know that code from outside their machine is about to execute and asking them if that's OK. Whether to ask or not is determined by the same Internet security settings that determine whether or not to ask for a COM control. The default settings for code from the Internet zone as of the final beta of version 1.1 are shown in Figure 12.
Figure 12 Version 1.1 Security Settings 
You'll notice when executing code from the Internet zone that there are no user prompts by default. The same is true of the intranet zone. This is more permission than the default settings for ActiveX®/COM controls, which default to Prompt for signed controls and Disable for unsigned controls. Of course, for COM controls, Authenticode is all the security that's available while in the .NET Framework, there's all of CAS to continue to protect the user.

Where Are We?
Windows Forms in version 1.1 of the .NET Framework provides a number of new and interesting features, ranging from some needed additions to the Windows Forms and Drawing namespaces to entire new subsystems, like the Compact Framework and managed C++ and J# support in the designer. As if that weren't enough, new security settings allow you new choices for your common language runtime-targeted code deployed over the Web. For a city that normally gets a lot of rain, things are definitely rather sunny in Redmond.

For background information see:
.NET Zero Deployment: Security and Versioning Models in the Windows Forms Engine Help You Create and Deploy Smart Clients
Windows Forms: A Modern-Day Programming Model for Writing GUI Applications

Chris Sellsis an independent consultant, speaker, and author specializing in distributed applications in the .NET Framework and COM. More information about Chris and his various projects is available at http://www.sellsbrothers.com.

Page view tracker