Pretty Printers / Format Code / for C# VB.NET

4. March 2008 09:49 by Mrojas in General  //  Tags: , , ,   //   Comments (0)

In my past life I spent a few eons writing Java code. And it wasn't bad. We had nice tools like Jalopy! that allowed us to have
code in a very standard way.

And I missed that. I've been looking around for something similar but I havent found anything like that :(

Until I found a great post from Chris Eargle, he improved the original solution from Kelvinpinch

Well here's the code.

Public Sub FormatSolution()
Dim sol As Solution = DTE.Solution
For i As Integer = 1 To sol.Projects.Count
FormatProject(sol.Projects.Item(i))
Next
End Sub 
Private Sub FormatProject(ByVal proj as Project)
     For i As Integer = 1 To proj.ProjectItems.Count
FormatProjectItem(proj.ProjectItems.Item(i))
Next
End Sub
 
Private Sub FormatProjectItem(ByVal projectItem As ProjectItem)
     If projectItem.Kind = Constants.vsProjectItemKindPhysicalFile Then
          If projectItem.Name.LastIndexOf(".cs") = projectItem.Name.Length - 3 Then
Dim window As Window = projectItem.Open(Constants.vsViewKindCode)
window.Activate()
projectItem.Document.DTE.ExecuteCommand("Edit.FormatDocument")
window.Close(vsSaveChanges.vsSaveChangesYes)
End If
End If
'Be sure to format all of the ProjectItems.
If Not projectItem.ProjectItems Is Nothing Then
For i As Integer = 1 To projectItem.ProjectItems.Count
FormatProjectItem(projectItem.ProjectItems.Item(i))
Next
End If
'Format the SubProject if it exists.
     If Not projectItem.SubProject Is Nothing Then
FormatProject(projectItem.SubProject)
End If
End Sub

To use it perform the following steps:

  •  Go to the VS IDE Tools Option
  • Then Select the Macros option and select Macros IDE...
  • This will open the macros IDE
  • In the Macros IDE navigate to the Module1, and Insert the code

To run the Macro go to Tools\Macros\Macro Explorer

And select FormatAll :)

And last but not least if you want to runit from the command line just do:

devenv /command "Macros.MyMacros.Module1.FormalAll" MyProject.csproj or

devenv /command "Macros.MyMacros.Module1.FormalAll" MySol.sln or


 

ActiveX exceptions when running in .NET

5. February 2008 04:11 by Mrojas in General  //  Tags: , , , ,   //   Comments (0)

During migration to C# or .NET it is easier to keep the same ActiveX.
The VBCompanion does a great work in migrating the ActiveX control using the .NET ActiveX wrappings and fixing all method calls. 
Sadly sometimes those ActiveX do not work properly in .NET.

Well we have good news.
Recently my friend Jose David (who we keep bothering because he is now 
a Project Manager and now he only programs in MS Excel and MS Project, I added the MS by his request :P) fixed a curious bug
we had with an aplication we migrated from VB6 to C#.

The thing is that the aplication had an ActiveX control with a strange runtime behaviour.
We migrated the application keeping the ActiveX control and in most ocasions it worked ok.

But randomly it started throwing exceptions.

During the testing he discovered that if he repeated the steps slowly the bug did not reproduced.

So his idea was that it was due a garbage collection issue. And SURPRINSINLY he was right :P

He added this:

System.GC.Collect();

System.

GC.WaitForPendingFinalizers();

 And the application started to work.

It seems like some of the COM objects needed a little more time for releasing all references :)

 

IsMissing migration in VB.NET or C#

Recently  we added some support for migrating the IsMissing function to VB.NEt or C#

The thing is. In VB6 the IsMissing Function is TRUE only if you have something like:

Public Sub Foo(Optional str)

 

Where you dont specify the variable type, or if you have

 

Public Sub Foo(Optional str as Variant)

 

And is IsMissing is FALSE for any other case. Including Optional variables whose definition type is not Variant.

 

So let's see some examples to illustrate the idea:
 Example 1:

Public Sub Foo(str, a As Integer, b As Integer, Optional c As Integer)
    MsgBox (str & "Foo Is missing a " & IsMissing(a))
    MsgBox (str & "Foo Is missing b " & IsMissing(b))
    MsgBox (str & "Foo Is missing c " & IsMissing(c))
End Sub

 

It occurs that IsMissing is really FALSE in all cases. So it is equivalent to:

 

Public Sub Foo(str, a As Integer, b As Integer, Optional c As Integer)
    MsgBox (str & "Foo Is missing a " & false)
    MsgBox (str & "Foo Is missing b " & false)
    MsgBox (str & "Foo Is missing c " & false)
End Sub

 

 

Example 2:

 

Public Sub Goo(str, a As Integer, b As Integer, Optional c As Object, Optional d As Byte, Optional e)
    MsgBox (str & "Goo Is missing a" & IsMissing(a))
    MsgBox (str & "Goo Is missing b" & IsMissing(b))
    MsgBox (str & "Goo Is missing c" & IsMissing(c))
    MsgBox (str & "Goo Is missing d" & IsMissing(d))
    MsgBox (str & "Goo Is missing e" & IsMissing(e))
End Sub

 

All cases EXCEPT "e" are equivalent to FALSE

 

Public Sub Goo(str, a As Integer, b As Integer, Optional c As Object, Optional d As Byte, Optional e)
    MsgBox (str & "Goo Is missing a" & false)
    MsgBox (str & "Goo Is missing b" & false)
    MsgBox (str & "Goo Is missing c" &false)
    MsgBox (str & "Goo Is missing d" & false)
    MsgBox (str & "Goo Is missing e" & IsMissing(e))
End Sub

 

So if you are migrating your VB6 Code to C# put attention to these little details it can save you a lot of time.And remember that this is just one feature of VBCompanion tool ;)

 

Case Sensitive SQL Server

26. October 2007 06:29 by Mrojas in General  //  Tags: , , , ,   //   Comments (0)
Recently a friend at work had a problem querying a SQL server that indicated that the column name was wrong.

The only thing wrong was the the case. For example he had COLUMN1 instead of Column1. I had never seen that problem in SQLServer.
I had seed that in Sybase but not in SQLServer. He solved that by changing the database collating sequence to something like this:

alter database database1 collate SQL_Latin1_General_CP1_CI_AI

the CI in the collating indicates Case Insensitive

For more information on SQL Server collations check: http://msdn2.microsoft.com/en-us/library/aa258233(SQL.80).aspx

And you determine your current database collation use a code like this:

USE yourdb>
GO

print 'My database [' + db_name() + '] collation is: ' + cast( DATABASEPROPERTYEX ( db_name(), N'Collation' ) as varchar(128) )

print 'My tempdb database collation is: ' + cast( DATABASEPROPERTYEX ( 'tempdb', N'Collation' ) as varchar(128) )

 

Track Changes in VSS (Visual Source Safe)

24. October 2007 06:18 by Mrojas in General  //  Tags: , , , , ,   //   Comments (0)

MS VSS (Visual SourceSafe) is not really my preferred Source Control application, but
sometimes in your company that is what is available and you need to used it to have
at least some versioning of the code.

But haven't you had a situation where last week everything worked and
now everything is broken. And now is up to you to determine what went
wrong? I have it all the time.
 

VSS have some search tools but I really do not enjoy using them.
The Code Project Site provides an excellent tool called VssReporter

Sample Image - VssReporter.jpg

Do take a look at it, it makes it more easy to track changes. :)

 

Get GUIDs/CLSIDs from Exe, dll, ocx, tlb, etc

23. October 2007 10:08 by Mrojas in General  //  Tags: , ,   //   Comments (0)

A simple way of getting the GUID from an exe, dll, ocx, tlb is using the  TLBINF32.dll

This file is in the system path and it must be registered
(Remember to use regsvr32 if you haven't registered).

            TLI.TLIApplicationClass a = new TLI.TLIApplicationClass();
            try
            {

                TLI.TypeLibInfo inf = a.TypeLibInfoFromFile(@"c:\windows\system32\MSHFLXGD.OCX");
                MessageBox.Show(
                "TypeLibrary Name " +  inf.Name + "\r\n" + //name of (Type Library)
                "Tlb ID " +  inf.GUID + "\r\n" + // GUID for Library
                "LCID "  + inf.LCID + "\r\n" + // Language / Country
                "Major Version "+ inf.MajorVersion + "\r\n" + // Major Version
                "Minor Version "+ inf.MinorVersion); // Minor Version
                for (short i = 1; i < inf.TypeInfoCount; i++)
                {

                    TLI.TypeInfo inf2 = inf.TypeInfos[i];
                    MessageBox.Show("CLSID " + inf2.Name + " - " + inf2.GUID,i + " of " +
inf.TypeInfoCount);

                }
            }
            catch (Exception ee)
            {
                MessageBox.Show("No guid");
            }

 

 

MAN for .NET

5. October 2007 03:32 by Mrojas in General  //  Tags: , , , ,   //   Comments (0)
Microsoft recently published the MTPS Content Service

In brief, the MTPS Content Services are a set of
web services for exposing the content in
Microsoft/TechNet Publishing System (MTPS).


And Craig Andera, has develop a swift nice tool
called msdnman that you use from the command line to
get information from the MSDN

Also I recommend you to see this cool video of a Human LCD that Hugo sent me

VB6 Printer Object and PrintForm migration

1. October 2007 10:55 by Mrojas in General  //  Tags: , , ,   //   Comments (0)

If you ever had any problems while migrating from VB6 Printer Object or the PrintForm functionality
we have goods news for you the Microsoft Visual Basic 2005 Power Pack 2.0.
Our version of the Visual Basic Companion already provides and extended migration of the Printer Object,
and we're now updating it to use this new implementation. This Printer Compatibility Library makes it a
breeze to migrate Printer Functionality.

This is the description of the PowerPack:

"The new Line and Shape controls included in this version of the Visual Basic 2005 Power Packs are
a set of three graphical controls that enable you to draw lines, ovals, and rectangles on forms and
containers at design time making it much easier to enhance the look of your user interface.
These new shape controls also provide events such as click and double-click allowing developers
to respond and interact with end users.

The Printer Compatibility Library allows projects that used the Printer and Printers Collection in Visual Basic 6.0
 to be upgraded without having to re-write your printing logic. By simply adding a reference to the library, declaring a
Printer and making a few minor syntax changes, your project will be able to print using the Printers collection
and Printer object as it did in Visual Basic 6.0. This version adds a new Write method to the Printer object which
allows you to print text without a forced carriage return similar to the semicolon syntax used by Print method in Visual Basic 6.0.

The PrintForm component is designed to bring back the ability to easily print a Windows Form.
With this the new PrintForm component you can once again layout the Windows Form exactly as
you want it and allow your users to print the form as a quick report."

You can download the PowerPack from here

NOTE: there's is another link that only includes the Printer Library but MS recommends to download the PowerPack
because minor upgrades and fixes will be done on the PowerPack distribution

 

VB6 API calls to .NET

27. September 2007 10:06 by Mrojas in General  //  Tags: , , , ,   //   Comments (0)
Every SERIOUS VB6 application, ended up requiring
that you import some functionality from the windows API or another DLL.
However if you were looking for a .NET equivalent and
google did not take you to the right page,
there is a document (a little old I might say) called
Microsoft Win32 to Microsoft .NET Framework API Map

I remember a couple of other pages that were even more complete,
but right know I can only remember http://pinvoke.net that gives some info about APIs

Twips and .NET

20. September 2007 04:46 by Mrojas in General  //  Tags: , , ,   //   Comments (0)

In the VB world previous to .NET a concept you probably had to deal with was TWIPS.

What were Twips? Well if you do not remember those happy VB6 times, let me refresh your memory:

Twips are screen-independent units to ensure that the proportion of screen elements are the same on all display systems.
A twip is defined as being 1/1440 of an inch.


A Pixel is a screen-dependent unit, standing for 'picture element'.
A pixel is a dot that represents the smallest graphical measurement on a screen.

In .NET everything is pixels. So if you migrated something from VB6 using the Upgrade Wizard you might found several expressions like:

VB6.TwipsToPixelsX(ctrl.Left)

or VB6.PixelsToTwipsY(ctrl.Height)

There is an X and a Y version of this function, because the conversion factor is not the same for both axis.

Sadly you can even found some expressions like:

VB6.TwipsToPixelsX(VB6.PixelsToTwipsX(ctrl.Left))

In a strict sense there could be minor differences because of the conversion factors. But in it seams that things like that can be removed because all controls Bound properties like Left, Top, Bottom, Right are in pixels. So why will you convert your pixels units to Twips units to then convert them back to Pixels if they where already in Pixels????

Also you can find something like:

VB6.TwipsToPixelsX(ctrl.Left + ctrl.Width + 30) which should be something like:

ctrl.Left + ctrl.Width  + VB6.TwipsToPixelsX(30)

If you have an application migrated with the Upgrade Wizard you can use some regular expressions to improve those expressions. If the conversion is something like:

VB6.TwipsToPixelsY(VB6.PixelsToTwipsX(ctrl.Left)) then be careful because conversion factor might produce a different value, due to the change of axis.

 

 

jeje Or you can uset the VBCompanion, the extensible version of the Upgrade Wizard!!!