developer.com
Search EarthWeb
CodeGuru | Gamelan | Jars | Wireless | Discussions
Navigate developer.com
Architecture & Design  
Database  
Java
Languages & Tools
Microsoft & .NET
Open Source  
Project Management  
Security  
Techniques  
Voice  
Web Services  
Wireless/Mobile
XML  
Technology Jobs  

   Developer.com Webcasts:
  The Impact of Coding Standards and Code Reviews

  Project Management for the Developer

  Defining Your Own Software Development Methodology

  more Webcasts...




See the Winners!


Linked Data Planet Conference & Expo


Developer Jobs

Be a Commerce Partner
Web Design
Promote Your Website
Imprinted Gifts
Compare Prices
Promotional Products
Find Software
Best Price
Memory
KVM Switch over IP
Shop
Computer Hardware
Free Business Cards
Remote Online Backup
Promos and Premiums

 


Download these IBM resources today!
e-Kit: IBM Rational Systems Development Solution
With systems teams under so much pressure to develop products faster, reduce production costs, and react to changing business needs quickly, communication and collaboration seem to get lost. Now, theres a way to improve product quality and communication.

Webcast: Asset Reuse Strategies for Success--Innovate Don't Duplicate!
Searching for, identifying, updating, using and deploying software assets can be a difficult challenge.

eKit: Rational Build Forge Express
Access valuable resources to help you increase staff productivity, compress development cycles and deliver better software, fast.

Download: IBM Data Studio v1.1
Effectively design, develop, deploy and manage your data, databases, and database applications throughout the data management life.

eKit: Rational Asset Manager
Learn how to do more with your reusable assets, learn how Rational Asset Manager tracks and audits your assets in order to utilize them for reuse.
Developer News -
SaaS Tool Offers Custom Database Development    May 9, 2008
Microsoft’s Automated Agent: Can We Talk?    May 7, 2008
Borland Finally Sells CodeGear    May 7, 2008
Red Hat Heads For The JON 2.0    May 7, 2008
Free Tech Newsletter -

Project Management Guide: Developing a Web Site. Best Practices, Tips and Strategies. Download Exclusive eBook Now.

The Book of VB .NET: Migrating to Visual Basic .NET, Part 1
By Matthew MacDonald

Go to page: 1  2  Next  

Excerpted with permission from The Book of VB .NET, by Matthew MacDonald, No Starch Press, Copyright 2002.

A traditional computer book usually discusses migration-the question of how to work with existing data files-early on. In many programs, including office productivity software such as Microsoft Word, working with files from a previous version is just as easy as creating new documents. Unfortunately, Visual Basic .NET doesn't work this way. As you've discovered in the preceding thirteen chapters of The Book of VB .NET, Visual Basic .NET introduces an entirely new programming framework called .NET. To program well in .NET, you have to surrender many time-honored habits and adopt a new, object-oriented style. When it comes to migration, the question is not how you can import your existing applications, but whether you should at all.

This article surveys the major changes between Visual Basic 6 and VB .NET, and in doing so, provides a nice summary of the .NET philosophy. We'll take a look at t he Upgrade Wizard, and see how a sample VB 6 project weathers the transition to .NET. You'll also learn about how to integrate legacy code, which is useful when migration is simply too painful. Specifically, we'll examine how you can access COM components and ActiveX controls-the "old world" of programming-in a .NET project. These techniques allow you to make maximum use of your existing code, while pursuing new development in Visual Basic .NET. Integration and interaction may not always be convenient, but it will be an essential ingredient of .NET programming for the next few years. It will also be the best strategy in many cases where migration is not possible and re-coding is just too time-consuming.

Introducing .NET Migration

Visual Basic .NET compromises backward compatibility in a number of troublesome ways. Hopefully, the advances you've seen over the course of this book will make these complications worthwhile. Once you're in the .NET world, there's really no easy way back.

Visual Basic 6 in the .NET World

Visual Basic 6 is a mature, well-developed programming environment. There's no immediate need to replace a VB 6 program (and there's no shame in maintaining a program in Visual Basic 6). Think of Visual Basic 6 as a well-worn, austere language at the end of its evolution. It still has a nice autumn glow to it, but it will gradually fade into disuse. On the other hand, Visual Basic .NET is a young, dynamic upstart at the beginning of its life cycle. As with any new program, changes will abound in VB .NET over the next few years. However, it's Visual Basic .NET, not Visual Basic 6, that will power the next generation of VB applications.

A key theme in this article is breaking down the barriers between VB 6 and VB .NET. There may not be an easy migration solution for many of your projects. Instead, you may need to start over again in .NET, and make heavy use of the COM compatibility layer that is built into .NET, in order to use your existing VB components.

File Compatibility

There is no file compatibility between Visual Basic .NET and earlier versions. In Chapter 3 of The Book of VB .NET, we explored the new file formats used in VB .NET projects. These files have different extensions (.vb instead of .mod or .frm, and .vbproj instead of .vbp). VB .NET files also use a block structure that allows modules, forms, and classes to be combined in a single file, while Visual Basic 6 used a special syntax for its form files (as explained in Chapter 4 of The Book of VB .NET).

The syntax of the language of itself has been updated, and the alterations range from minor cosmetic changes to entirely new concepts such as namespaces. All these technical details have a single result: There is no way to open a Visual Basic 6 project in VB .NET. Instead, you have to migrate the project.

The Upgrade Wizard

Migration is a special procedure carried out by Visual Studio .NET's built- in Upgrade Wizard. Essentially, the Upgrade Wizard scans through every line of every file in your project. It examines the line, analyzes it for a variety of potential problems, and tries to assign an equivalent VB .NET statement. When dealing with simple programs (for example, utilities that have only one window, or that have the majority of their capabilities concentrated in a few core procedures), it does remarkably well. However, for complex programs that manage a sophisticated user interface and a large amount of data, it works almost embarrassingly badly. In these cases, migration usually isn't a feasible option.

Migrating a Simple Project

Here's a relatively simple VB 6 project using several concepts that are foreign to VB .NET. The full project is available with the samples for this article.

It starts with a simple startup procedure, contained in a module file:

' VB 6 code.
Public Sub Main()
  frmSplash.Show vbModal
  frmMain.Show
End Sub

The first line launches a window modally-a splash screen with a company logo. The window uses a timer that unloads itself automatically after a set amount of time:

' VB 6 code.
Private Sub tmrClose_Timer()
  Unload Me
End Sub

Then the code continues to the second line, launches the main program window nonmodally, and allows the Main subroutine to end. The main window consists of a simple form with an MSFlexGrid control and a single button. When the user clicks on the button, a short routine runs, retrieves information from a database table, and uses that information to fill the grid, as shown in Figure 14-1.

Figure 14-1: A VB 6 program

The code is quite straightforward. The Form_Load event handler configures the grid appropriately, and opens a database connection (using the form-level variable con):

' VB 6 code.
Private con As ADODB.Connection

Private Sub Form_Load()   grid.Cols = 2   grid.Rows = 0   grid.ColWidth(1) = 3000   grid.ColAlignment(0) = 1
  Set con = New ADODB.Connection   con.ConnectionString = "Provider=SQLOLEDB.1;Data Source=localhost;" & _   "Initial Catalog=Northwind;Integrated Security=SSPI"   con.Open End Sub

Of course, opening a database connection in the Form_Load event and closing it in the Form_Unload event is an extremely bad design practice, because it ties up a limited database connection for an undetermined amount of time. The individual using the computer could easily forget, leave the computer running, and go on holiday, tying up the connection indefinitely. However, there's nothing invalid in this code (and probably nothing unusual either).

The button event handler contains the following code:

' VB 6 code.
Private Sub cmdFill_Click()

  Me.MousePointer = vbHourglass   grid.Rows = 0

  Dim rs As ADODB.Recordset   Set rs = con.Execute("SELECT * From Customers")
  Dim i As Integer   Do While rs.EOF <> True     grid.AddItem (rs("CustomerID") & vbTab & rs("ContactName"))     rs.MoveNext   Loop
  Me.MousePointer = vbDefault
End Sub

Don't spend too much time analyzing this code; it uses the ADO library, which is the connection-based predecessor to ADO.NET. ADO works quite a bit differently, using a live connection and a MoveNext method to access all the information in a Recordset (instead of a Rows collection in a DataSet). This technique is similar to the way you use ADO.NET's special DataReader object.

You might also notice that this code uses the MousePointer property to thoughtfully turn the user's mouse pointer into an hourglass, indicating that a database operation is underway and that no other user action can be taken until the operation is finished.

One additional frill is the form's automatic resizing code:

' VB 6 code.
Private Sub Form_Resize()
  grid.Width = Me.Width - 350
  grid.Height = Me.Height - 1200
  cmdFill.Top = Me.Height - 1000
  cmdFill.Left = (Me.Width - cmdFill.Width - 60) \ 2
End Sub

While this code can't stop the form from being made too small, like our VB .NET code can, it still manages to ensure that the button and grid use the appropriate amount of space. The drawback is the introduction of hard-coded values, and generally ugly code, into the Form_Resize event handler. Interestingly, this code is the manual equivalent of two different VB .NET concepts we take for granted. The grid's size changes, but its position does not; this is an example of manual docking. The command button's position changes, but its size is constant, which is an example of anchoring.

Clearly, this is an extremely simple program. However, it does have some aspects that can pose difficulty in the .NET world. They are:

  • The use of ADO, which is a database technology built on COM. (Remember, COM isn't native to .NET.)

  • The use of the MSFlexGrid control, which is an ActiveX control. Like all ActiveX controls, it's also based on COM, and so there is no direct equivalent in the .NET class library.

  • The treatment of forms. In Visual Basic .NET, forms are classes, and you have to create an instance of a form before using it. Clearly, the startup routine in our example doesn't follow these rules. If you'd known that this program was destined for VB .NET migration, you could have programmed accordingly by dynamically creating forms, even in your VB 6 code. However, if you haven't specifically planned for this step, or if you are dealing with an older application, this technique probably hasn't been used.

Design-wise, there are a couple of other potential problems in this example, such as the way the database connection is held open. However, you can create a poorly designed program in VB .NET with the same ease that you could in Visual Basic 6. This example of poor programming should not affect the migration process.

Importing the Project

To import this project into Visual Basic .NET, all you need to do is open the .vbp file. The Upgrade Wizard will automatically appear, as seen in Figure 14- 2.

Figure 14-2: The Upgrade Wizard

At this point, it's just a matter of clicking on Next several times, and the conversion will begin. Along the way, you will be prompted to choose a new directory where the .NET version of our project will be stored (see Figure 14- 3).

Figure 14-3: Creating the new .NET project

Remember, this a complex migration, not a simple File Open operation. The whole process is surprisingly slow, as you'll notice with any real-life application. Even with this simple program, Visual Studio .NET may still take a couple of minutes to complete the migration.

Once the process is completed, the first thing you should do is read the migration report that has been created for you. You can find this as an HTML file (_UpdateReport.htm) in the Solution Explorer. If you double- click on it, you'll see an impressive file-by-file analysis of the project (Figure 14- 4). Each section lists migration problems and warnings, and can be expanded or collapsed individually.

Figure 14-4: The upgrade report

In the case of the simple ADOTest project, no errors are reported, but three warnings are flagged. You can read a full description of these issues by clicking the provided hyperlink, which takes you to a help topic. Usually, though, you'll want to investigate the code yourself. The appropriate area will be marked with a comment and another hyperlink to the help topic:

' UPGRADE_WARNING: Form event frmMain.Unload has a new behavior.
' Click for more: ms-help://MS.MSDNVS/vbcon/html/vbup2065.htm
Private Sub frmMain_Closed(ByVal eventSender As System.Object, _
 ByVal eventArgs As System.EventArgs) Handles MyBase.Closed
  con.Close()
End Sub

In this case, the Wizard has changed the event handler for the Unload event to the corresponding Close event. (The Wizard has also taken care of additional details, such as adding the Handles clause and changing the event handler signature to the .NET standard.)

The second warning is a similar false alarm that alerts us that the Resize event may occur when the form is first initialized. The third warning in the migration report informs us, rather cryptically, that the application will end when the Main subroutine ends. This warning highlights another difference between VB .NET and VB 6: In Visual Basic 6, a program wouldn't end until every window was closed. If you used a startup routine to begin your program, the startup routine could end and leave the other windows running to take care of the rest of the program. In VB .NET, applications work a little differently.

If you use a startup subroutine in Visual Basic .NET, the program will close as soon as the subroutine ends, even if other windows are still open (somewhat like using the End statement).

Module StartupModule
  Public Sub Main()
    frmSplash.DefInstance.ShowDialog()

    ' Program will end immediately after executing the next line.     frmMain.DefInstance.Show()   End Sub End Module

This migration problem could have been avoided if the original program had displayed both windows modally from the Main subroutine. In that case, the subroutine would pause until the frmMain window had closed, rather than ending early. To fix this minor problem, all you need to do is make this modification:

Module StartupModule
  Public Sub Main()
    frmSplash.DefInstance.ShowDialog()
    frmMain.DefInstance.ShowDialog()
  End Sub
End Module

Forms and the Default Instance

You may notice another unusual feature in this portion of the code: the reference to DefInstance. A logical .NET startup routine would look more like this:

Public Sub Main()
  ' Create and show first window.
  Dim Splash As New frmSplash
  Splash.ShowDialog()

  ' Create and show second window.   Dim Main As New frmMain   Main.ShowDialog() End Sub

The .NET Upgrade Wizard doesn't have enough intelligence to make this change. In fact, the problem is potentially a lot more complicated. In traditional VB code, the Wizard really has no way of knowing when you are referring to a form, and when you are trying to create it. In VB 6, a form is loaded automatically the first time it is referred to in code, even if it isn't displayed. This system allows the following kind of logic to work:

' This is VB6 code.
frmMain.TextBox1.Text = "Hi"  ' The form is created and loaded automatically.
frmMain.Show  ' Now the form is displayed.

To emulate this logic, the Upgrade Wizard adds a special block of code to every form under the collapsed Upgrade Support region that works like this:

Private Shared m_vb6FormDefInstance As frmMain
Private Shared m_InitializingDefInstance As Boolean

Public Shared Property DefInstance() As frmMain   Get     If m_vb6FormDefInstance Is Nothing _      OrElse m_vb6FormDefInstance.IsDisposed Then       m_InitializingDefInstance = True       m_vb6FormDefInstance = New frmMain()       m_InitializingDefInstance = False     End If     DefInstance = m_vb6FormDefInstance   End Get
  Set     m_vb6FormDefInstance = Value   End Set End Property

The logic here is quite interesting. It works like this:

  • Every form has a shared property called DefInstance. Because it is shared, it can be accessed even without creating a form instance. (Also, because it is shared, every class uses the same code for this property, and returns the same result.)
  • When you retrieve the DefInstance property in your code, the Property Get procedure checks the form's private m_vb6FormDefInstance shared variable. This variable is designed to hold a reference to the current form (in our example, frmMain). If this variable hasn't yet been initialized, the Property Get procedure creates the form automatically, effectively mimicking the VB 6 form behavior.
  • The end result is that whenever a part of your program uses the DefInstance property, it gets the instance of the form stored in the m_vb6FormDefInstance variable. If necessary, the form is loaded on the spot automatically.

This special block of "upgrade support" code is a trick that allows you to use forms in the VB 6 way, as long as you call the form's default instance instead of just the form's class name. If you have the time, it may make sense to go through your code, remove the default instance logic, and recreate your form properly. However, this isn't strictly necessary.

TIP Incidentally, this code violates an important recommendation of object-oriented programming: namely, that retrieving information from a property procedure should never change the state of the object. In this case, retrieving the property of an uninitialized form causes it to be created.

Go to page: 1  2  Next  

Previous article: The Book of VB .NET: Web Services, Part 2
Next article: The Book of VB .NET: Migrating to Visual Basic .NET, Part 2


Tools:
Add www.developer.com to your favorites
Add www.developer.com to your browser search box
IE 7 | Firefox 2.0 | Firefox 1.5.x
Receive news via our XML/RSS feed


Techniques Archives

Guide to Developing a Web Site. Best Practices, Tips and Strategies. Download Exclusive eBook Now.
Generate Complete .NET Web Apps in Minutes . Download Iron Speed Designer today.
Best Practices for Developing a Web Site. Checklists, Tips & Strategies. Download Exclusive eBook Now.
Learn about expanding business opportunities for the reseller channel. Visit IT Channel Planet.
Flash Demo: Learn how IBM Information Server Blade is easy to manage, highly scalable and efficient.



JupiterOnlineMedia

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info


Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

Solutions
Whitepapers and eBooks
Microsoft Article: Will Hyper-V Make VMware This Decade's Netscape?
Microsoft Article: 7.0, Microsoft's Lucky Version?
Microsoft Article: Hyper-V--The Killer Feature in Windows Server 2008
Avaya Article: How to Feed Data into the Avaya Event Processor
Microsoft Article: Install What You Need with Windows Server 2008
HP eBook: Putting the Green into IT
Whitepaper: HP Integrated Citrix XenServer for HP ProLiant Servers
Intel Go Parallel Portal: Interview with C++ Guru Herb Sutter, Part 1
Intel Go Parallel Portal: Interview with C++ Guru Herb Sutter, Part 2--The Future of Concurrency
Avaya Article: Setting Up a SIP A/S Development Environment
IBM Article: How Cool Is Your Data Center?
Microsoft Article: Managing Virtual Machines with Microsoft System Center
HP eBook: Storage Networking , Part 1
Microsoft Article: Solving Data Center Complexity with Microsoft System Center Configuration Manager 2007
MORE WHITEPAPERS, EBOOKS, AND ARTICLES
Webcasts
Intel Video: Are Multi-core Processors Here to Stay?
On-Demand Webcast: Five Virtualization Trends to Watch
HP Video: Page Cost Calculator
Intel Video: APIs for Parallel Programming
HP Webcast: Storage Is Changing Fast - Be Ready or Be Left Behind
Microsoft Silverlight Video: Creating Fading Controls with Expression Design and Expression Blend 2
MORE WEBCASTS, PODCASTS, AND VIDEOS
Downloads and eKits
Sun Download: Solaris 8 Migration Assistant
Sybase Download: SQL Anywhere Developer Edition
Red Gate Download: SQL Backup Pro and free DBA Best Practices eBook
Red Gate Download: SQL Compare Pro 6
Iron Speed Designer Application Generator
MORE DOWNLOADS, EKITS, AND FREE TRIALS
Tutorials and Demos
How-to-Article: Preparing for Hyper-Threading Technology and Dual Core Technology
eTouch PDF: Conquering the Tyranny of E-Mail and Word Processors
IBM Article: Collaborating in the High-Performance Workplace
HP Demo: StorageWorks EVA4400
Intel Featured Algorhythm: Intel Threading Building Blocks--The Pipeline Class
Microsoft How-to Article: Get Going with Silverlight and Windows Live
MORE TUTORIALS, DEMOS AND STEP-BY-STEP GUIDES