Click here to Skip to main content
15,905,785 members
Articles / Programming Languages / Visual Basic
Article

Converting a VB6 gdiplus project to .net

Rate me:
Please Sign up or sign in to vote.
1.08/5 (5 votes)
15 Jan 200713 min read 29.6K   12   2
Designer(c)2006 was an extensive use of GDIPLUS with one of the freeware GDIPLUS type libraries. I was impressed with GDIPLUS capability but my program required large bitmaps, and struggled with that. I could reach 17-20 mgB depending on exact dimensions. The program was aimed at fabric design.

Introduction

I was somewhat apprehensive of converting VB6 graphics project to .NET. Frankly, that was warranted.  This is equivalent to a total rewrite in effort.

GOOD NEWS FOR BASIC PROGRAMMERS

I have written almost every language in existance, even some now wierd ones like PASCAL, Forth etc.  I have always liked the simplicity of BASIC, but of course it has aways had performance issues.  I wrote tons of assembler, and like that feeling of "CLOSENESS" to the processor.  But in todays world you are never close anymore.  There is tons of code between you and the final execution.  Very few operations can be performed without using a framework.  Finally BASIC has no performance issues, it performs the same as C+ or any other language with the .Net framework.  Not sure how C++ or C# performs compared to other generations.  Now everyone shares the same performance issues. But the programmer only writes .1 percent of the code that is executed.  When you call an OpenFileDialog it isnt very significant which language it is called in.  So this has been basically a snob thing for the last 10 years.  It is more important how the framework and OS performs than which code it is written in.

Today the BASIC programmer can feel he is writing just as good of code as anyone.  That was 1000 times by the way, and I'm not sure it isnt 100,000 times of the code executed isnt your's anyway.

CONVERSION WIZARD:

The conversion wizard politely offered to convert the project.  After crunching thru each object it informed me that it had successfully converted the project.  The conversion had ended the build with an error list of 100.  It stayed at 100 after 100's of corrections. I thought I would never END IT. This is the default maximum It also posts numerous warnings within your code with 'comment formats.  Thousands of warnings.  My code lists were solid green.  It would be helpful if there was a way to get rid of them.  There is a compile without warnings, but I dont think there is a conversion option.  It is a question whether the warnings are helpful enough to offset the task of removing them.

'UPGRADE_ISSUE: PictureBox property TheHDC.hDC was not upgraded. Click for more: 'ms-help://MS.VSExpressCC.v80/dv_commoner/local/redirect.htm?keyword="CC4C7EC0-C903-48FC-ACCC-81861D12DA4A"'

'UPGRADE_ISSUE: Form property THEHDC2.hDC was not upgraded. Click for more: 'ms-help://MS.VSExpressCC.v80/dv_commoner/local/redirect.htm?keyword="CC4C7EC0-C903-48FC-ACCC-81861D12DA4A"'

SOME CONFUSIONS?

It is as much effort removing all the comments as it is correcting the code.  Some conversions didnt work.  For example simple string operators like "LEFT" are now in different name spaces such as Microsoft.visualbasic.left, math operations such as ABS are in the Math namespace. Operations in the context as converted to didn't work and still produced compile errors, but this could be solved with an easy "replace" however Left would default to the form namespace as the left position of the form so execution might be faulty.  The same "WORD" behind form and in modules could default to different compiler references depending on the name space in the current context of the code.

UNUSUAL EXECUTION

I had an occasion where a statement such as:

Code Works:
for each item in collection
dim name="XXX"
ITEM.name=whatever
end for

CODE DOSNT WORK:

dim name as string
for each item in "collection"
name="XXX"
ITEM.name=whatever
end for

if I dimmed name inside the loop it worked because I probably was scoped outside the name space. I assume namespace became "collection" inside the loop and there was no name property. AND When I moved the dim outside the loop trying to optimize execution the code failed.  This was somewhat confusing because the code had worked for ages.

Using "NAME" as the name of a variable is a bad choice, but there are so many names in the namespace probably adopting a convention of choosing variables with "MY" or "A" so you have MyName, Mywidth, Mysize or AName, AWidth, ASize guaranteeing no confusion.  The namespace is so extensive that keeping track can be overwhelming.

I'm sure others have better insite than I do ito this situation.

GDIPLUS Typelib

The conversion didnt handle the GDIPLUS typelib correctly, this was not a Microsoft offering so I never pursued trying to add it to the project.  I was shooting for a vannila .Net product anyway.  Using Typelib made me familar with most of GDIPLUS but the format and context of usage wasnt very similar.

OVERLOADS

Overloads was a new experience for me.  The GDIPLUS librabry was set up with dozens of similar calls, if you drew a rectange with a floating point structure you had a call such as RectangleF, if you were long you had a call such as RectangleL.  I originally thought this followed the .net structure and thought it was very cumbersome.  The .Net uses OVERLOADS, that is, the same call accepts different types of arguments.  .NET has a very useful prompt that can step you through each "OVERLOAD" some graphic calls have 30 overloads.  So you have substantially less initial confusion than you have from the GDIPLUS library.  Though the END confusion may be equal.  It is certainly easier to work within the .NET namespace.

NAMESPACE

Anyone still confused about NAMESPACE, this is merely a modern reference similar to type llibrary.  Typing "Application." brings you to the Application namespace, this then will step you through various types, methods and functions available under that "NAMESPACE".  Think of it as a hugh search engine with the format "KEYWORD.KEYWORD.KEYWORD" at the end of the keyword string is a property, or method that you have selected.  If you can determine the first keyword, you can probaby get through the selection.  At Each keyword is listed the next possible selections valid in that space.

Often the issue is more "What does the keyword mean".  Microsoft provides a tool tip for each keyword.  It really is pretty impressive, and mostly pretty useful.  But as usual, whenever you don't really understand you have the option to experiment or research, whichever suits you.

NO INDEXED OBJECTS

I ended up throwing away most of the conversion the Wizard did.  I started new forms and cut and pasted the objects from the old forms (From the conversion).  (I had both projects open at once) This way I wanted to assure myself I didnt keep too much that was not real .NET, and was backward compatibilty.

I found that the very helpful ability in VB6 to "Collect" objects indexed to one set of code like button_click(Index) wasnt supported.  I had extensive use of this.  Wizard converted this to _button_1, _button_2 etc,  with code that didnt work at all.  This required a different approach.  Each button could pass its index to a routine, which requires code for each button.  The point is you have to touch each item with some kind of code.  .Net might have some way to trap events from multiple objects to the same code but I haven't researched it.  I wrote the code in what I considered "Dirty" form and placed some code behind each previously indexed Object.

WARNINGS

VB .NET has added a couple of features to help you keep your code clean.  It will warn you when a dimmed item isnt used, which DOES helps you keep your code clean.  Often when you change code cleaning up is a task, I found this useful.  It also tries to warn you when a item is used without being initialized, it is worried you might end up with NULLS or data exceptions, it is often wrong about this, but I tended to initialze so the compiler would be happy.  It also is concerned in some cases that it can't tell what is going to happen, so this code

ColorWheel.Top = Me.PictureBox1.MousePosition.Y - 100
ColorWheel.Left =
Me.PictureBox1.MousePosition.X - 100

gets this error:

Warning 1 Access of shared member, constant member, enum member or nested type through an instance; qualifying expression will not be evaluated. C:\Documents and Settings\guest1\My Documents\Visual Studio 2005\Projects\designer2007\WindowsApplication2\WindowsApplication2\ColorPick.vb 23 53 Designer2007

This code invariably works so you end up living with these warnings.  I havn't spent the time to figure out if you can "MAKE IT HAPPY".

CODE

Tons of my code was broke because of they GDIPLUS type library, I didn't want to re-impliment that code, but wanted to go to the drawing namespace.  While this was tedius, it was not HARD.  The GDIPLUS Typelb did after all call GDIPLUS a .NET component, and most of the formatting was a straightforward change to the call routine name.  Like I said, once you do it you will prefer the .Net context.

ONE THING  "cannot narrow parameters". 

Often the type casting conversions in .NET are not as aggressive as we have expected in basic in the past.  You might get error messages like "cannot narrow parameters".  Often all you need to do is examine your statement and wherever it seems complex cast the parameter yourself.  This will happen particularily when functions are embeded within a parameter.  I originally didn't glom on to this and kept rewriting code that seemed to be correct.  Eventually, you just "get it" and those problems go away.  I had some of those problems with the type library too, and wrote some wierd code to force parameters to be cast correctly.  That is wierd for a Basic programmer anyway, who often tends to be data type oblivious.

VISUAL STUDIO 2005

There are some issues, it will hangUp on some combinations, which I havnt exactly figured out.  Sometimes when you are in debug mode and editing, it will get confused and hang up.  Most of the time it will time out and return.  All in all I only experienced 1 fatal crash where I lost code, here I actually lost the OS, and went back to a 3 day old restore point before I recovered.  At that time I was running 512MGB and paging a lot, which would probably stress XP in different ways.  I upgraded to 1.5 (and later to 2.5 to see how it effected the size of my bitmaps. ) and havnt experienced any crashes since.  I am distingusihing between crash and exception.  Both in developement and execution unhandled exceptions are handled somewhat gracefully by the .Net engine.  I refer to crash in the OLD sense where you are fatally hung up.

It saves code before each compile, I havnt found options to overide this, which was originally anoying, because I was use to not saving code when I was experimenting and return to previous code.  But most of the time, you can still UNDO back to the original code.  With my overall experience, of never loosing code, I'll accept this approach.

TOOLBOX, is a programmers delight.. what can you say, most everything a Windows programmer wants.  A couple of things, no more shapes.  You can use a label for a box, but that's it.  You'll need to draw during onPaint or do without.  AND group box works differently than Application basic in Access.  There the group was managed, that is if one was on the rest were off, I havnt found this tecnique in .NET... not to say it isnt there. A few lines of code accomplishes the same purpose.  Menus and quickmenues are easy to impliment, although confusding why they follow a different model.  Quickmenues you manage a collection directly, menues have a different "Self Expanding" Interface.

EXECUTABLE

I haven't researched the inner workings of the .NET executable. But it is certainly simplistic when viewed from the external world.  The first time you execute it does a simple install.  After that is seems to check that resources are still available and then loads.  This has a new "Application" model which seems to avoid the overcomplexities of previous models.  I know one of the promissies was to avoid all of the version confusion between .dll's etc.  I dont have a handle on this yet.

SUMMARY

My objectives were to get my program over to the new Framework, be ready for Vista AND I had some issues with the size of bitmaps I was handling, maxing at 15-20 megabytes, and getting random exceptions.  And then I had to carefully manage bitmap size and scaling to achieve that. (some smaller bitmaps with certain scaling and dimensions would fail as well) I was tempted to blame the code around the picture box and the complicated "TWIP" and scaling model in the old windows world.  .NET has a much simpler model.  You size the Picturebox and size the bitmap.  Eveything else goes away.

In fact, my intuition was correct, I can handle up to 80mgb.  On bitmaps larger than that I will still get OUT OF MEMORY exceptions.  I upgraded to 2.5GB and a RADEON graphics card to make sure it wasnt my resources.  I never go over 1.5GB of usage so it is probably still in XP.  I guess they can't manage 2.5GB correctly, or some pointers havn't been expanded to handle these sizes Maybe VISTA will overcome that.  The .NET framework is much more gracefull with errors and in most cases you will recover enough to gracefully exit the program.  I found it totally solid within 60 to 80 MGB graphics files.

NOTE:  Designlab(C)2007 bitmap 11700x3400 there are 17 basic built in shapes and hundreds of additional in the shape library, as well as a tool to compose shapes.  The work buufers have visible pictureboxes bitmap may have 3-4 copies in memory as it transforms, rotates and builds compositions.  Shapes are 2d structured not bitmapped.  Designlab creates designs like that below with one keystroke.  To see more output go to Http://www.usanetinc.com

Sample screenshot

80MGB GRAPHICS YOU ASK

I had read some blog where someone commented to someone else "Why would you need larger bitmaps anyway".  DesignLab is a fablic and fine art designer, I have printed outputs on my EPSON7800 onto fabric as large as 84 inches by 17 inches for table runners as an example. At 200 pixel an inch that is 16,800 x 3400.  Probably almost accurate for a 720 pixel inch printout.  There is a HUGE difference between 100 and 200 per inch.

CONCLUSION

CONVERSION WIZARD = BAD NEWS
TOTAL REWRITE=GOOD NEWS

But since I had to write it over, I fixed all the things I had ideas on how to improved, I structured code so It is closer to a CLASS library and could be recoded as a .DLL graphics engine and overall the design and structure is much clearer and better organized, which will pay off in future developement.

For graphics, you need to make the switch if you have a project you want to keep developing.  But any code that does the job, does the job..just hope MS keeps supporting it.  Corporate America runs code for 30 years, and they NEED to, the cost of development is staggering. To process your checkbook, probably not worth the effort. 

But write all your new code in .NET framework... by all means.

 

 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
Started in IT in 1959 working on Electronic accounting machines.

Worked through wiring panels and card systems.

1963-1965 USArmy
1961-1975 Computer Supervisor Contental Can
1975-1998 Data Force Incorporated - President
1998-2006 IT Director Promotions Unlimited Corp
2007 retired, project DesignLab(C)2007

Design and concept rules, coding is a required evil


Comments and Discussions

 
GeneralMy vote of 1 Pin
Dave Kreskowiak20-Feb-10 10:05
mveDave Kreskowiak20-Feb-10 10:05 
GeneralMy vote of 1 Pin
Juan_Jose_5717-Dec-09 20:30
Juan_Jose_5717-Dec-09 20:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.