Tuesday, September 30, 2008

Macro for Visual Studio 2005 Keyboard Shortcuts

Most people don't know this, but there are actually over 450 keyboard shortcuts in Visual Studio by default. But there is no easy way to find out all the keyboard shortcuts inside Visual Studio. You can find out what all the default keyboard shortcuts are by writing a simple macro to enumerate all of them. The following is the code for this.



Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Imports System.IO

Public Module Module1

Public Sub ListShortcutsInHTML()

'Declare a StreamWriter
Dim sw As System.IO.StreamWriter
sw = New StreamWriter("c:\\demo\\Shortcuts.html")

'Write the beginning HTML
WriteHTMLStart(sw)

' Add a row for each keyboard shortcut
For Each c As Command In DTE.Commands
If c.Name <> "" Then
Dim bindings As System.Array
bindings = CType(c.Bindings, System.Array)
For i As Integer = 0 To bindings.Length - 1
sw.WriteLine("<tr>")
sw.WriteLine("<td>" + c.Name + "</td>")
sw.WriteLine("<td>" + bindings(i) + "</td>")
sw.WriteLine("</tr>")
Next

End If
Next

'Write the end HTML
WriteHTMLEnd(sw)

'Flush and close the stream
sw.Flush()
sw.Close()
End Sub
Public Sub WriteHTMLStart(ByVal sw As System.IO.StreamWriter)
sw.WriteLine("<html>")
sw.WriteLine("<head>")
sw.WriteLine("<title>")

sw.WriteLine("Visual Studio Keyboard Shortcuts")
sw.WriteLine("</title>")
sw.WriteLine("</head>")

sw.WriteLine("<body>")
sw.WriteLine("<h1>Visual Studio 2005 Keyboard Shortcuts</h1>")
sw.WriteLine("<font size=""2"" face=""Verdana"">")
sw.WriteLine("<table border=""1"">")
sw.WriteLine("<tr BGCOLOR=""#018FFF""><td align=""center""><b>Command</b></td><td align=""center""><b>Shortcut</b></td></tr>")


End Sub

Public Sub WriteHTMLEnd(ByVal sw As System.IO.StreamWriter)
sw.WriteLine("</table>")
sw.WriteLine("</font>")
sw.WriteLine("</body>")
sw.WriteLine("</html>")
End Sub

End Module


To use this macro, go to Tools, select Macros, and then choose Macros IDE. . . to launch the Macros IDE. Expand the MyMacros project, MyMacros namespace and double-click on Module1. Simply copy Listing 1 to the Macros IDE and run the macro. After running the macro, you would have produced a keyboard shortcuts reference for Visual Studio. Open your output at C:\demo\Shortcuts.html.

Sunday, September 21, 2008

How to lock a table in SQL 2005

You would ask yourself why anyone would want to lock a table on purpose. Well… We just had an interesting bug related to table locking. A job in SQL was scheduled to run every night and it took over 10 minutes to complete. During this time it was locking a table exclusively. Of course, in response to this, our middle tier was blowing chunks as it tried to insert records into the locked table. Our insert would result in SQL time out and create an unpredictable behavior then on.
I needed to simulate the table lock situation so I could make the code more resilient. At a minimum I wanted to be able to trap the time out and log it. Also, we wanted to rollback everything up to that point as well.




Here are the steps to Lock and Unlock a table


1- Open a window in Microsoft SQL server Management Studio and open a new SQL window:
2- Use the following code as a template to setup your Lock/Unlock mechanism.


Begin transaction
update top (1) Product WITH (TABLOCK) set Name=’Cheetos’ where ProductID=100
RollBack


3- TO LOCK the table highlight the first two lines (Begin trans + update) and execute them by hitting CTRL+E. At this point table is locked.
4- TO UNLOCK the table highlight the last line (Rollback) and execute it by hitting CTRL+E.


Use the 3 and 4 to repeatedly to lock and unlock the table. Since each time you are rolling back, there will be no change to the content of the table.

After 3 the table Products will be locked. You will not be able to select, insert, update or delete from the table products as long as this transaction is not concluded with a commit or rollback. You may want open a new window in Microsoft SQL server Management Studio and try the following:



select top 1 * from Products


The statement above will hangup and wait for the completion of the transaction we started in step 2.
Similarly, you can run your code and see the same timeout behavior.

Saturday, September 20, 2008

SQL 2005 Table Lock Hint Syntax Change

Syntax for locking tables has been changed in SQL 2005 which makes placing the ‘WITH’ keyword in parentheses illegal.

The following was acceptable in SQL 2000; however, no longer is the case with 2005.
The following is true for SQL 2005:

WRONG
UPDATE Products (WITH NOLOCK) 
SET Name = 'Cheetos'
WHERE ProductCat = 'JunkFood'




CORRECT
UPDATE Products WITH (NOLOCK) 
SET Name = 'Cheetos'
WHERE ProductCat = 'JunkFood'

Thursday, September 18, 2008

Realtime Applications with Flex & Actionscript

Hi everybody. We are developing an SDK for developers out there to easily program realtime applications. (Chat, Multiplayer Games etc)

You can find more info here.

Minimizing an AIR Application to system tray

Adobe AIR applications are windows applications. So they have all the possibilities like any other windows application like using the system tray.

First of all you have to prevent the application to close when clicked on the X close button on the window. To do that you have to trap the "closing" event of the WindowedApplication class.


<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="ApplicationComplete()" closing="MainWindow_OnClosing(event)">

or with actionscript:


this.addEventListener(Event.CLOSING, MainWindow_OnClosing);

When the user clicks on the close button on the corner of the main window MainWindow_OnClosing() function gets called. In this function you have to prevent the default action for the event which is closing the window. The reason why we listen to the "closing" event instead of "close" event is that the window is not closed yet. If you listen to the "close" event you can't prevent the window from getting closed.

So our closing event handler looks like this:


protected function MainWindow_OnClosing(event:Event):void
{
event.preventDefault();
this.visible = false;
}

We didn't close the window but we made it invisible. But how is the user going to interact with our program now? Yes. With the tray icon. So here is the sample code to setup a tray icon:


// A Loader to load the image for the icon png
var icon:Loader = new Loader();

// Not all the operating systems have to support tray icons.
// We just check for it. Windows supports it as you probably know. :)
if (NativeApplication.supportsSystemTrayIcon)
{
// When the user clicks the icon on the tray "TrayIcon_Click" event handler will be called.
NativeApplication.nativeApplication.icon.addEventListener(MouseEvent.CLICK, TrayIcon_Click);

// When the icon gets loaded it will call the iconLoadComplete event handler.
icon.contentLoaderInfo.addEventListener(Event.COMPLETE, iconLoadComplete);

// We actually start loading an icon from the hard drive.
// This could be an icon on the internet as well
icon.load(new URLRequest("images/icons/icon16x16.png"));

// Lets get a handle of the trayIcon to change its tooltip.
var systray:SystemTrayIcon = NativeApplication.nativeApplication.icon as SystemTrayIcon;
systray.tooltip = "Your Application Tooltip";
}

Below you can see the handler for the icon load event.


private function iconLoadComplete(event:Event):void
{
NativeApplication.nativeApplication.icon.bitmaps = [event.target.content.bitmapData];
}

For best performance the icon image should be a 16x16 PNG. (At least in windows this is so).
So what happens when the user clicks the icon in the tray?


protected function TrayIcon_Click(event:Event):void
{
// Do anything here.
}

It is up to your imagination. :) You could do a bunch of things here. You can make the main application visible.

I can hear you guys asking how to add a menu to your tray icon. Ok! Adding a menu to your tray icon is very simple. Below there is the modifed version of the example code at the top:



// A Loader to load the image for the icon png
var icon:Loader = new Loader();

// Not all the operating systems have to support tray icons.
// We just check for it. Windows supports it as you probably know. :)
if (NativeApplication.supportsSystemTrayIcon)
{
// When the user clicks the icon on the tray "TrayIcon_Click" event handler will be called.
NativeApplication.nativeApplication.icon.addEventListener(MouseEvent.CLICK, TrayIcon_Click);

// When the icon gets loaded it will call the iconLoadComplete event handler.
icon.contentLoaderInfo.addEventListener(Event.COMPLETE, iconLoadComplete);

// We actually start loading an icon from the hard drive.
// This could be and icon on the internet as well
icon.load(new URLRequest("images/icons/icon16x16.png"));

// Lets get a handle of the trayIcon to change its tooltip.
var systray:SystemTrayIcon = NativeApplication.nativeApplication.icon as SystemTrayIcon;
systray.tooltip = "Your Application Tooltip";

// Lets add a menu to our tray icon
var iconMenu:NativeMenu = new NativeMenu();
var menuCommand:NativeMenuItem = iconMenu.addItem(new NativeMenuItem("Exit"));
menuCommand.addEventListener(Event.SELECT, Exit_Handler);

// Assign our menu to the icon. Thats it.
systray.menu = iconMenu;
}

Here we have added a menu item which will close the application when clicked on. To close the application we call the exit() function of the native application. Here is the Exit_Handler function:


protected function Exit_Handler(event:Event):void
{
// Actually exiting the application it self removes the items from the tray.
// But just to give an example I clear the icons.
NativeApplication.nativeApplication.icon.bitmaps = [];

NativeApplication.nativeApplication.exit();
}

Here are the example source codes.