smithvoice.com
 Y'herd thisun? 

“Remote to linux or mac machine from windows... or from linux or mac with SSH and SCP!”
-Smith


from this page

Your own image control and App part 4

TaggedCoding, Imaging

Originally published December 2002 on DoItIn.net using VB7.0/2002. Updated for VB7.1 February 2005

Links for compiled demo versions, all required resources and source code are included at the end of this article.

Plus, get the complete eBook in Adobe Acrobat 7 format ... all here.


 

4) Custom Exceptions

Just like most everything else in the runtime, Net's baked-in Exceptions are objects. As such they inherit from Object way up in their hierarchy, and closer to the bone they all inherit from System.Exception. While you can completely code your own exceptions from scratch with all your own syntax, it's most helpful for your user-devs if you make your custom exceptions do what the CLR ones do - inherit from System.Exception and expose the elements of the base interface that will primarily be used.

In the beginning days of .Net we were all urged to make our exceptions inherit from System.ApplicationException which in turn inherits from System.Exception. While many MS code samples show that being done, it didn't turn out to be of any use at all so now the general advice is to inherit from System.Exception directly. See this from CLR Lead Program Manager Brad Adams, and also the bulletpoints on this page (I'm really sick & tired of seeing so many "I just started my blog with the one page and have not intention of ever adding anything to it" blogs out there, but at least this one pager has something useful <g>).

Here's a custom exception that we'll use when a file load hits the base OutofMemoryException:

 

Public Class svImageInvalidImageFileException
Inherits System.Exception
  
Private Const EXCEPTION_MESSAGE_IMAGE_FILE As String = _
"The specified file is corrupt or does not contain a valid image"
  
Public Sub New()
MyBase.new(EXCEPTION_MESSAGE_IMAGE_FILE)
  
End Sub
  
Public Sub New(ByVal message As String)
MyBase.New(message)
  
End Sub
  
Public Sub New(ByVal message As String, ByVal innerException As System.Exception)
MyBase.New(message, innerException)
  
End Sub
  
'I add this overload version that uses the message constant by default and
'just makes it simple to pass in the original CLR exception
Public Sub New(ByVal innerException As System.Exception)
MyBase.New(EXCEPTION_MESSAGE_IMAGE_FILE, innerException)
  
End Sub
  
End Class

You might wonder why we're not just inheriting from OutOfMemoryException and the reason is that at this point in our testing we can't be sure if OutOfMemory will be the only CLR exception that fits our "The specified file is corrupt or does not contain a valid image" message. If later in testing we find that the runtime tosses us another exception that fits this bill we can pass it into the innerException argument too. (fyi: It has been said over the years that "Out Of Memory" may not truly be the base problem in some cases, and that Microsoft uses OutOfMemoryException generically to just give us something trappable when it can't figure out anything more fitting.)

As you see, coding a custom exception is pretty easy, the only geek part is deciding what files to put the code in.

Custom exceptions are classes so they can be put in all the places that any other classes can go; One class per file as was required in VB4/5/6, with related classes in a single *.vb file and all the file's classes top-level or defined within an existing class. The choice is yours, go with whatever style you think will make your code maintenance easier, but keep in mind that your dev-user might have to make adjustments to their Imports or the number of dots they use in their code.

We're going to go with a separate file from the UC file and define our custom exceptions within a surrounding class definition - this is not the same as creating an Exception inheritance hierarchy, it's more of a trick to isolate the custom exceptions in a way that our dev-users can find them easily. We've found it annoying that the .Net exception classes are intermingled with all of the other classes in the Framework because MS decided to make the rule that exception names have to end with the word "Exception" rather than start with "Exception". Had they stuck with just a bit of Hungarian Notation and made the rule that they had to start with "Exception" then they'd all be grouped together in the alphabetical popup list, but the die has been cast. By putting our exceptions in a nicely named surrounding class we can make searching for our exceptions easier and not have to go so far as breaking the naming convention by putting the word up front "Exception" where it would really be most useful.

Create a new class file in the UC project (Right click on the svImageEdit project node and click on Add >> Class), name the file "svImageExceptions.vb" and press "Ok". Click your mouse between the default "Public Class svImageExceptions" and "End Class" and paste in the above exception class definition.

Rebuild and save the solution.

Now go back over to the svImageEdit UC codeview and import the new class file:

Option Strict On
Imports Smithvoice.svImageExceptions
  
Public Class svImageEditor ...

And set an exception handler:

 

Public Function LoadImage(ByVal fileName As String) As Boolean
If File.Exists(fileName) Then
Try
 Return LoadImage(Image.FromFile(fileName))
Catch ex As OutOfMemoryException
 Throw New svImageInvalidImageFileException(ex)
Catch ex As Exception
 'todo:  test to figure errors
 '       and remove catch-all
 Throw ex
End Try
Else
Throw New FileNotFoundException
End If
End Function

Now open the codeview of testHarness's Form1 and in the load button add the new catch:

 

...
Try
SvImageEditor1.LoadImage(.FileName)
  
Catch ex As svImageExceptions.svImageInvalidImageFileException
MsgBox(ex.Message & vbCrLf & ex.InnerException.tostring)
  
Catch ex As Exception
MsgBox(ex.Message)
  
...

Give that a test with an obviously invalid file and see what you get.

If your dev-user is in a rush they can just toss up the Message to the end user, and if they have resources during their development time they can get at the original exception to try to figure out if they can do better before their call to your method.

Next: Fax images and multipage Tiffs

Robert Smith
Kirkland, WA

 

added to smithvoice march 2005


jump to:

  • 1) The spec
  • 2) Setting up the workspace 
  • 3) Feature 1: Loading an image
  • 4) Custom Exceptions
  • 5) "Fax images" and Multipage TIFFs
  • 6) Custom events
  • 7) Selecting specific fax pages
  • 8) Feature 2: Rotating image displays
  • 9) The most useful tool in GDI+: DrawImage
  • 10) Feature 3: Zooming
  • 11) Handling the unhandleable exception
  • 12) Fixing the squish
  • 13) Zooming to fit the control
  • 14) You're already beating the Pros
  • 15) Feature 4: Cropping
  • 16) Bonus Feature: StickyMouse
  • 17a) Final Cleanup
  • 17b) Passing the current display image
  • 18) Making the application
  • 19) Source and result viewports
  • 20) A better toolbar
  • 21) Hooking the toolbar to the project
  • 22) Adding ImageEditors
  • 23) The toolbar ZoomCombo
  • 24) The final solution
  • 25) Saving to image files
  • 26) An integer-only textbox
  • 27) Passing save options between forms
  • 28) Dealing with that last exception
  • 29) Offer more options with menus
  • 30 The downloads and ebook


  • home     who is smith    contact smith     rss feed π
    Since 1997 a place for my stuff, and it if helps you too then all the better smithvoice.com