Author Archives: admin

DIM x AS NEW SpeechSynthesizer

0
Filed under .NET, VB Feng Shui

Here’s an interesting one for you.

I was playing with the SpeechSynthesis namespace recently when I ran off into a coding ditch. You know, one of those times when things are moving along nicely, and you swerve to avoid some minor nit, only to find yourself stuck upside down with the wheels half sunk in muck, trying to claw yourself out with an ICE and log files…

Anyway, I had this:

Public Class Connect
   Private WithEvents rSynth As New SpeechSynthesizer
   ...

And a little later in the class, I was using it like so…

      If rSynth.State <> SynthesizerState.Speaking Then
         rSynth.SpeakAsync(Speak)
      End If

Simple enough.

But it didn’t work. State was always coming back Ready, not Speaking, so I was getting a rather laughable stuttering intro to tracks as they were playing… “Now…Now…Now…Playing….Playing….Swerve…Playing….Swerve…”

(Sorry, the app in question is a little MP3 player plug in to announce tracks and allow you to navigate through the player using only a remote and no screen.)

I tried several different approaches but none worked. I could never get the proper state of the synthesizer to be reflected.

Then, on a lark, I remove the New from the SpeechSynthesizer declaration line:

Public Class Connect
   Private WithEvents rSynth As SpeechSynthesizer
   ...

And just assigned a new instance to the rSynth var from Sub New.

It worked!? Huh?

What was going on here?

I’m still not 100% sure, and the documentation on the NEW modifier for a DIM statement certainly doesn’t help to clarify things. From what I can tell, it looks like each reference to the regional var rSynth ends up retrieving a new SpeechSynthesizer object. Definitely not the behavior I was expecting. And not behavior I’ve seen before given this use of the New clause.

In reality, I’ve had far too many lessons about Dim x as New from VB6 to normally use it like this anyway. I guess I thought VB was past all that now in .NET, but I’m slowing learning that VB.NET is every bit as quirky as VB6, just differently so.

Ah, progress.

Very Cool VS2008 Add In

0
Filed under .NET, Utilities, VB Feng Shui

I’ve always been a big fan of the MZTools addin for VB6, so it was a little disappointing, if not understandable, that for his .NET foray, he’s wanting to get paid a little something for it.

Not that that’s bad, I just haven’t been able to commit to MZTools for .NET just yet.

In the meantime, I stumbled across a very slick little VS addin called DPack.

It’s actually a small set of different addins. Doesn’t look like you get the source, which is unfortunate, but the features are pretty slick, plus they work in VB, C++ and even C# and Ruby.

The Code Browser alone is worth the download. With one keystroke, you get a window like this:

image

It’s nicely sorted, browsable, and with one other click, takes you directly to the given code element. Even better, you can assign direct keystrokes to filter only methods, classes, properties, etc. By default, ALT-M shows just the methods in the current file, for instance. Reminds me of the old F2 (Function list) key that used to be in older VB’s. I missed that key<sob>.

Also particularly nice is the “Surround Selection With…” feature. You can’t customize the surrounding text but they give you the most common items (surround with TRY CATCH, FOR NEXT, DO WHILE, REGION, etc, etc.), so that’s not too bad.

It seems very quick and stable. And the best part is, it’s completely free!

Compressing Memory Streams

0
Filed under Uncategorized

One thing that has definitely taken some getting used to (for me anyway) in VB.NET is the whole concept of streams.

I like the idea, generally, but I was working through some code to stream debugging info into a resource in an already compiled EXE file when I ran into a problem with decompressing the resource data.

It just wouldn’t decompress properly.

After backtracking and puzzling over it, I discovered that the problem was actually in the compression phase.

   Private Function pCompressStream(ByVal UncompressedStream As MemoryStream) As MemoryStream
      Dim CompressedStream As New System.IO.MemoryStream()
      Using GZip As New System.IO.Compression.GZipStream(CompressedStream, System.IO.Compression.CompressionMode.Compress)
         GZip.Write(UncompressedStream.ToArray, 0, UncompressedStream.Length)
      End Using
      Return CompressedStream
   End Function

Note the Dim GZip line? If you look at the overloads, there’s a possible 3’rd option, LeaveOpen. It defaults to false.

From what I can tell, if you connect a GZipStream up to a FileStream, there’s no need for this parameter. When the GZip closes, the file is closed and on you go.

But, with MemoryStreams, it’s quite unlikely that you’d want to close the resulting output memory stream after zipping data into it.

But that’s exactly what happens if you don’t set LeaveOpen to True.

What’s worse. You need to Close the GZipStream before reading that MemoryStream(either by using a USING block as I have, or by calling Close directly). If you don’t, garbage collection might not happen for some time and the final data in the internal GZip buffers won’t get written to your memory stream, resulting in only partial compressed data, which definitely won’t decompress properly!

All this is likely old hat to grizzled .NET heads, but if you’re like me and coming from an extensive VB6/assembler background, it can certainly causing some headscratching for a bit.

It’ll definitely sting the checkbook!

0
Filed under Hardware

Just stumbled across what has to be the hands-down coolest workstation yet.

It looks like a cross between the swiveling chair in the Millennium Falcon and the long abandoned gunner’s chair from “Alien”. It’s called the Emperor from NovelQuest.

image

That monitor arm thing? It actually electrically lifts those monitors out of the way to allow you in and out. Not sure how practical that is, since it’d require, what, a 20ft ceiling in your office.

No idea how much. It doesn’t go on sale till July ’08. But seriously. Wow.

Slow Vista Copying and Deleting

0
Filed under Uncategorized

image Like a lot of people out there, I’ve been bitten by the Vista “Slow Copy/Delete” bug many many times myself.

I finally decided I’d had enough today and when looking for a solution.

I came across a couple of posts discussing a hotfix available from Microsoft, but it’s apparently not that easy to get a hold of, and its a questionable fix at that.

Then I happened across a short post in a SlashDot discussion that mentioned turning off thumbnails in the Explorer view.

I’ve never heard of that one, so I gave it a quick shot.

First, open the Folder Options:

image

Then, just make sure the first option “Always Show Icons, never thumbnails” is checked:

image

Surprisingly, this does seem to a have a pretty dramatic effect on the copying and deleting processes, as well as noticeably speeding up the time it takes to get from a right-click to actually seeing the right click context menu in Explorer. It’s still not instant like it should be, but it’s better than before.

I’ll keep playing with it and post if I discover any other interesting bits about this seemingly easy workaround.

Line Numbers and VB.NET

3
Filed under .NET, Troubleshooting, VB Feng Shui

Line numbers have been around ever since the dawn of time in BASIC.

Remember this classic:

10 Print “Hello”

20 Goto 10

But what many people may not know is that line numbers still exist in VB.Net!

Yep, that’s right, you can write the above routine, as I show it, in VB.NET.

Well, with one exception. Line numbers in .NET are treated as full on labels, and labels must be followed by a colon. So you’d have this in .NET:

10: Print “Hello”

20: Goto 10

Now, before I start getting hate mail about GOTO’s and such, let me say that I’m only a fan of a GOTO in a few very controlled circumstances.

But GOTO’s are the point here. Way back in the Visual Basic (Pre .NET days), line numbers combined with the ERL function made for a surprisingly effective field debugging tool. If you line numbered your code before compiling, and used ERL appropriately during your error handling, you’d be able to precisely pinpoint the offending line of code very quickly and painlessly.

I’ve used that approach for years, and even wrote an article in VB Programmers journal at one point about a very extensive generic error handling facility.

Recently, I decided to look into updating that facility for VB.NET, and unfortunately have good and bad things to report.

First the good.

  • As I said before, VB.NET still supports line numbers and the ERL statement, as well as all the old favorites ON ERROR RESUME NEXT, ON ERROR GOTO, RESUME, and RESUME NEXT.
  • You can easily compile VB.NET projects from the command line, making it relatively trivial to create a simple batch file to line number your code, compile it, then clean up the line numbered version.
  • VB.NET supports a much more sophisticated StackTrace/StackFrame functionallity that would seem, at first glance to obviate the need for ERL entirely.

but now the bad…

  • The StackTrace/StackFrame functionality works fantastically, as long as you’re willing to ship the program debugging database (PDB files) that are generated when you compile your project.
  • Worse still, you can’t use the old style ON ERROR GOTO, in the same method as the new style TRY CATCH FINALLY exception handling.

image

  • And finally, the ultimate bit of nastiness. While trapping an error with the old style ON ERROR GOTO will generate a standard exception (See the Err.GetException method), trapping an exception with structured exception handling (also known as SEH, or TRY CATCH), does not affect the ERR object at all, specifically, throwing an error in a TRY block will not set the ERL value, even if the code is line numbered.

image

So what’s the end result of all this?

Basically, do not even bother with ON ERROR GOTO style error handling in VB.Net. Even though it would appear to be supported, and even though retrieving the line number of the failing code isn’t possible without shipping your PDB, the fact that line numbers aren’t reported in code using SEH makes them pretty much useless. SEH is quite useful in many situations, so you wouldn’t want to not use it solely because of this.

But that doesn’t address two very real issues.

  1. Line numbers in stack traces are an incredibly useful debugging tool
  2. You don’t want to distribute your PDBs just to get line numbered stack traces if at all possible.

More to ponder…

Internationalizing Applications

0
Filed under Languages, VB Feng Shui

image A recently posted article on CodeProject had this to say about Visual Studio’s support for multi-lingual applications:

Conclusion: Visual Studio .NET does not offer any multilanguage support which is worth thinking about it.
You will only waste your time with Microsoft’s approach!

Check the whole article/project out here.

I can’t verify the author’s credentials that would justify such a claim, but from the sound of it, he did at least start down the MS sanctioned path, and I have to agree with him.

Way back in the dark ages, pre-internet, around 1990 or so, I was managing development of a CRM system (customer relationship management software).

We’d picked up some resellers oversees and needed to get the product internationalized. This was really at the very beginning of Windows even (Win 3.1 and WFW, if you remember those!). Our internationalization efforts had to apply equally well to our DOS app and our Windows version.

Several of the developers and myself went to a conference, the precursor to VBits, (I don’t remember exactly what it was called back then) and I got a chance to talk with one of the MS internationalization engineers directly.

I’d played with the whole “separate resources for each language” technique and found it workable, but so labor intensive, that I couldn’t imagine anyone but the largest shops actually doing it that way.

The MS guy verified that suspicion. He said (and I’m paraphrasing), “The core team finishes up the project, and ships it, and then the whole project base is ‘thrown over the wall’ and each internationalization team then takes over and internationalized the project into their respective languages, re-tests, etc.”

Ouch.

Now, I’m sure times have changed at MS, but if the comment from Elmue in the article on CodeProject is any indication, they haven’t changed that much.

The internationalization functions I helped build way back then was based on 3 simple concepts:

  1. The original english strings had to remain in the code
  2. Those strings has to actually be used by the code
  3. Those strings had to be easily searchable (say, by a GREP or similar utility) for extraction and translation

Why those first two points?

Because if the english strings remain in the code, the code remained relatively easy to debug and maintain for the programmers.

Further, if the strings are actually used by the code, that meant that during dev and alpha/beta testing, we wouldn’t have any disconnect issues with resources not matching what was needed in the code itself. This is akin to the age old concept of eating your own dog food. The idea of socking strings away in resources and just having a comment in the code as to what the string contained just scared the hell out of me.

Also, it also meant that if the translatable resources are lost for whatever reason, the program would still be able to run based on the “compiled in” English strings. Not ideal, but better than simply throwing errors or displaying blanks.

We accomplished all these goals by embedding all translatable strings (including those in dialogs, etc), into a function call. Something like:

MyString$ = TX$(“This is the english version”, stringcode, groupcode)

Where stringcode and groupcode were optional arguments that indicated, basically, the resource ID of the string and an arbitrary group ID of the string.

Originally, when you were writing or working on code, you’d never even bother entering the stringcode or groupcode args, so your call would look like:

MyString$ = TX$(“This is the english version”)

But, because it was trivially easy to scan for TX$(), when our scanner was run on the code, it could

  1. Extract the strings
  2. Give then ID’s
  3. Rewrite the source code with the appropriate string and group codes as necessary.
  4. Generate a “translator’s file” that contained the string, ID’s and potentially developer comments that would indicate the context of the string and intention (for use by translators to assist with the translation).

Nowadays, with OO, extension methods, reflection, and all the other .NET goodies, seems like this whole process could be vastly more efficient than even what we did back then.

But in the end, we translated the product into 8 or more languages in just a few months with this technique, using no additional developers, and a few native speaker volunteer translators. And it didn’t require any code rewrites and was just as efficient to debug as if you’d left the strings in the code and did nothing about translation at all.

Now, granted, there’s a lot more to internationalizing an app that translating text. You have to worry about icons, input method (when applicable), date, time, and number formats, and even subtle things like color choices, but it was a huge timesaver for an otherwise arduous task.

Closing comment: Why TX$() you might ask<g>? Basically, it was because we didn’t want a huge function name taking up tons of space in the code when it would be used as often as it was. That’s all. As I recall, it is about the only two letter function I’ve ever authored in code. I was never a big fan of the BASICA 2 letter name restriction!

Any translation war stories out there? How have you translated applications?

Martian Voyeur

0
Filed under Misc

I’m a space buff so I’ve been following the Phoenix mission for a while now. It finally arrived at Mars and successfully landed 5 days ago (Sunday).

That in and of itself is incredible, considering some of the recent failures NASA has had. This landing went picture perfect, though.

But what’s even more amazing is that the Mars Orbiter, already in orbit around Mars, was able to snap a picture of Phoenix as it was parachuting to the surface!. Just contemplating the enormous number of tasks that had to be done just right to pull that off can make your head spin.

Here’s the photo (from Space.com and NASA):

image

Granted, it’s not a frame from “The Right Stuff” but still, you gotta give the guys at NASA props for pulling this off.

Here’s hoping Phoenix performs even half as well as the other two scamps, Spirit and Opportunity, that have been scurrying around farther south for more than 4 years now.

Being a Good Windows Citizen

0
Filed under Installations, Rants, VB Feng Shui

I’m constantly amazed by some of the goofy things that application installations do to my system without even giving me the option.

Obviously, there’s the whole spyware/adware problem, but that’s just blatant.

There’s an entirely other, more subtle, level to the problem, where applications do little things that are difficult to undo, are annoying and that you aren’t given the option of not “doing” in the first place.

Here’s one example. Now, I like the CodeJock products, and I’m not really picking on them here, it’s just that they give me a good example:

image

This is the “Right Click – New” menu that you get from Explorer when you right click in a folder and select “New”.

Now, I’m a pretty busy developer, and I like a nice shortcut just as much as the next guy, but honestly, I can’t imagine EVER creating so many “Command Bars Designer Documents” that I’d want an entry for it on my New Items menu like this. As you can see, there’s already enough junk on this menu. I wonder how many people out there create a new contact, bitmap image or briefcase so regularly that it belongs on this menu. Hell, I’ve always created new Word docs by opening Word, starting my document and then “File-Save”-ing them wherever, never by the “New Office Word Document” menu, but then, maybe that’s just me.

A few others:

  • Unrequested shortcuts on the QuickLaunch space or the Desktop.
  • Unrequested Tray Icons.
  • Adding Vista Sidebar gadgets without permission.
  • Stealing file extension associations without asking and not restoring them on uninstall.

Any other bits of application rudeness out there anyone has run into?

Choices in Utility Function Implementation

0
Filed under .NET, VB Feng Shui

One thing I’ve begun to notice about VB.NET is that there are a pile of options as to how you might implement a particular piece of functionality. I’m still not convinced that this is necessarily a good thing, but it is hard to argue with having options.

For instance, I recently needed a function to retrieve the number of elements defined in an enumeration. Now, I realize that enumerations can be sparse, and that creating an array to be indexed by the enumeration values will not work with all enumerations, but that’s a topic for another post.

The first option I thought of was to implement it as a plain ol’ function in a module:

Debug.print GetEnumItemCount(GetType(MyEnum))

    Public Function GetEnumItemCount(ByVal typ As Type) As Integer
        If typ.IsEnum Then
            Return System.Enum.GetNames(typ).Length
        Else
            Return 0
        End If
    End Function

Not terribly interesting and it’s perfectly functional, but it just doesn’t seem particularly .NET-ish. Also, I don’t really care for the “double function” approach (ie calling GetType() to retrieve the enum type descriptor object to pass into the function).

So, any way to improve this?

One way is to get rid of the extra GetType function call. Unfortunately, the only way I’ve seen to do this so far is to pass in one of the enumeration values instead of the enumeration itself (or its type).

Debug.print GetEnumSiblingCount(MyEnum.Value1)

    Public Function GetEnumSiblingCount(ByVal e As [Enum]) As Integer
        Return System.Enum.GetNames(e.GetType).Length
    End Function

I’ve renamed the function GetEnumSiblingCount because that’s exactly what this new function does, return the total number of siblings to the passed in enumeration element.

Unfortunately, this approach still seems a little a lot odd.

My next thought was, why not add an extension method to the enumeration itself, so you could do something like:

Debug.print MyEnum.Count

Unfortunately, since MyEnum is a type and not considered an actual object in any sense, you can’t invoke a method on it, or even define one on it for that matter.

You can, however, get close, by defining an extension method on the Type object itself:

Debug.Print GetType(MyEnum).Count

Module EnumExtender
    <extension ()> _
    Public Function Count(ByVal typ As Type) As Integer
        If typ.IsEnum Then
            Return System.Enum.GetNames(typ).Length
        Else
            Return 0
        End If
    End Function
End Module

The downside here is that we’re extending not just enum types but all types, and extending anything other than enums with this function doesn’t make much sense.

Interestingly, there’s yet another option; extend the enum elements themselves.

Debug.print MyEnum.Value1.SiblingCount

Module EnumExtender
    <extension ()> _
    Public Function SiblingCount(ByVal anEnum As [Enum]) As Integer
        Return System.Enum.GetNames(anEnum.GetType).Count
    End Function
End Module

However, this also has the same problem as a previous try in that it just doesn’t feel right to ask an enumeration element for some property of it’s containing type.

Ok, how about just changing up the definition of the enumeration itself:

    Public Enum MyEnum
        Value1 = 0
        Value2 = 1
        Value3 = 2
        Count = 3
    End enum

Short, sweet, no compiler tricks or reflection.

But. It doesn’t work with existing, already defined Enumerations, and since the Count is part of the enumeration, the actual count of the enum is 4, not 3, which would seem to be confusing in the long run.

I’m sure there’s many more possibilities as well, and, hopefully, I’ve missed a better one and someone out there will let me know it!

Long story short, my first inclination, the plain ol’ function-in-a-module GetEnumItemCount(), seems the best solution for this particular piece of functionality.

In reality, the best solution for most of these sorts of generic, application-wide, stateless utility functions seems to be the plain ol’ function-in-a-module.