M a r k P i t . c o m

"After three days without programming, life becomes meaningless." - The Tao of Programming

Windows Azure

clock June 4, 2009 15:13 by author Mark

I went to an all day session on Windows Azure today at the Engineering Forum at work. It looks really slick and is pretty much a no brainer for .NET developers to use. I can see a lot of ASP.NET sites moving to it from other hosting companies... if the price is right!



Configuration Section Designer

clock October 29, 2008 11:53 by author Mark

I found this really cool Visual Studio add-in today that allows you to visually design a set of classes to handle custom configuration sections in .NET config files. It builds the code and even creates an XSD so you get Intellisense when typing in the config file. It saved me a bunch of time. I always forget the ins and outs of the ConfigurationSection classes and this add-in means I won’t have to go look them up every time I want to do some custom configuration.

Configuration Section Designer - Home



Download SQLPrompt Free Before September 2006

clock July 7, 2006 09:31 by author Mark
If you would like to have Intellisense in Query Analyzer or SQL Server Management Studio, go download SQL Prompt from RedGate Software. It is very slick.



Refactoring menu disappears after installing LINQ May CTP

clock June 16, 2006 08:15 by author Mark

After installing the MAY CTP of LINQ, the refactoring menus in VS2005 stopped working. I use that a lot, so I either had to find a way to fix it or uninstall LINQ! I found a post on the MSDN forums that solves the problem. There is a registry entry you must change along with running a few commands from the command line. I have zipped up two files that will make the process a little easier.

Fix_Refactoring_Menu.zip (.7 KB)

There is a reg file and a cmd file contained in the zip file. You may need to edit the contents if you have installed Visual Studio somewhere besides the default location.



WinFX is now .NET 3.0

clock June 9, 2006 22:42 by author Mark
From S. "Soma" Somasegar's blog:

"The .NET Framework 3.0 is still comprised of the existing .NET Framework 2.0 components, including ASP.NET, WinForms, ADO.NET, additional base class libraries and the CLR, as well as new developer-focused innovative technologies in WPF, WCF, WF and WCS".
...
"We are confident that this change will go a long way towards reducing confusion people may have about our developer platform and the technologies in which they should invest."

Are you kidding me? You really think this will reduce confusion? If the next version of the compilers is not going to be ready when Vista and all the W*Fs ship, then just keep the name WinFX for now. When C# 3.0 is ready, upgrade the whole thing and call it .NET Framework 3.0 if you must. Much less confusing if you ask me.

And as for the question, "WinFX sounds great, but what happens to .NET?" It amazes me that any developer has been asking that. If they can't understand that, their heads are going to explode with all this version mix-matching business.



VS 2005 Doesn't Seem to Work with ActiveSync 3.8

clock November 10, 2005 00:06 by author Mark

I was all excited to try out the new Compact Framework 2.0 stuff with Visual Studio 2005. I wrote a little web browser app and tried to deploy it to my Pocket PC and got a nice error:

The current version of ActiveSync is not supported. Install the latest version from www.microsoft.com.

The latest version of ActiveSync I can find is 3.8, which is what I have installed. Is anyone else seeing this problem? Am I screwed because I had the Beta 2 bits installed on this machine at one time?



Presentation on WSE 2.0

clock April 20, 2005 09:20 by author Mark

I went to a presentation last night at the AZ ASP.NET User Group meeting. It was on Web Services Security with WSE 2.0. WSE is something that I have heard about, maybe even read a little about, but I haven't taken the time to really learn about it so I figured this would be a good way to get into it. The speaker was $g(Michele Leroux Bustamante) and she did an excellent job. I didn't nod off at all :) The timing on this was perfect. I was just writing a web service that I wanted to secure and I started down the road of using Forms Authentication in ASP.NET. That just turns out to be a big pain. WSE looks like it handles the problem quite nicely.

By the way, if anyone didn't know, the guy on her t-shirt is Bob Dobbs from the Church of the Subgenius.
 



Printing the .Net TreeView Control

clock April 2, 2005 00:30 by author Mark

Sample Image - PrintTreeView.gif

Introduction

I looked and looked for�sample code to print TreeView controls in C#. I�couldn't find anything that did exactly what I needed, so I broke down and wrote it myself!�

Background

During my search for a printing sample, I came across this article by Koay Kah Hoe, which presents a solution in C++. It gave me a few ideas and after finding�some information on Usenet about getting an image of a control, I was ready to code.�

Using the code

In order to print�the entire TreeView, the size of the area of all visible nodes has to be calculated and then the tree must be resized to accommodate the contents. This is all handled in the PrepareTreeImage method of the PrintUtility class.

				1:     
				private
				void PrepareTreeImage(TreeView tree){

2: _scrollBarWidth = tree.Width - tree.ClientSize.Width;
3: _scrollBarHeight = tree.Height - tree.ClientSize.Height;
4: tree.Nodes[0].EnsureVisible();
5: int height = tree.Nodes[0].Bounds.Height;
6: this._nodeHeight = height;
7: int width = tree.Nodes[0].Bounds.Right;
8: TreeNode node = tree.Nodes[0].NextVisibleNode;
9: while(node != null){
10: height += node.Bounds.Height;
11: if(node.Bounds.Right > width){
12: width = node.Bounds.Right;
13: }
14: node = node.NextVisibleNode;
15: }
16: //keep track of the original tree settings
17: int tempHeight = tree.Height;
18: int tempWidth = tree.Width;
19: BorderStyle tempBorder = tree.BorderStyle;
20: bool tempScrollable = tree.Scrollable;
21: TreeNode selectedNode = tree.SelectedNode;
22: //setup the tree to take the snapshot
23: tree.SelectedNode = null;
24: DockStyle tempDock = tree.Dock;
25: tree.Height = height + _scrollBarHeight;
26: tree.Width = width + _scrollBarWidth;
27: tree.BorderStyle = BorderStyle.None;
28: tree.Dock = DockStyle.None;
29: //get the image of the tree
30: this._controlImage = GetImage(tree.Handle, tree.Width, tree.Height);
31: //reset the tree to its original settings
32: tree.BorderStyle = tempBorder;
33: tree.Width = tempWidth;
34: tree.Height = tempHeight;
35: tree.Dock = tempDock;
36: tree.Scrollable = tempScrollable;
37: tree.SelectedNode = selectedNode;
38: //give the window time to update
39: Application.DoEvents();
40: }
41:
42:

When it is time to print the resulting image, there is some calculation to do to divide the image up into sections of the proper size to fit on the printed page. This is handled in the printDoc_PrintPage method which handles the PrintPage event of the PrintDocument. This is pretty straightforward. We have to keep track of the direction we are moving in, horizontally or vertically, across the source image.�We also�must keep track of where we left off in the image when the previous page was printed.

		

				1:     
				private
				void printDoc_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) {

2: this._pageNumber++;
3: Graphics g = e.Graphics;
4: Rectangle sourceRect = new Rectangle(_lastPrintPosition, e.MarginBounds.Size);
5: Rectangle destRect = e.MarginBounds;
6: if((sourceRect.Height % this._nodeHeight) > 0){
7: sourceRect.Height -= (sourceRect.Height % this._nodeHeight);
8: }
9: g.DrawImage(this._controlImage, destRect, sourceRect, GraphicsUnit.Pixel);
10: //check to see if we need more pages
11: if((this._controlImage.Height - this._scrollBarHeight) > sourceRect.Bottom
12: || (this._controlImage.Width - this._scrollBarWidth) > sourceRect.Right){
13: //need more pages
14: e.HasMorePages = true;
15: }
16: if(this._currentDir == PrintDirection.Horizontal){
17: if(sourceRect.Right < (this._controlImage.Width - this._scrollBarWidth)){
18: //still need to print horizontally
19: _lastPrintPosition.X += (sourceRect.Width + 1);
20: }
21: else{
22: _lastPrintPosition.X = 0;
23: _lastPrintPosition.Y += (sourceRect.Height + 1);
24: this._currentDir = PrintDirection.Vertical;
25: }
26: }
27: elseif(this._currentDir == PrintDirection.Vertical && sourceRect.Right
28: < (this._controlImage.Width - this._scrollBarWidth)){
29: this._currentDir = PrintDirection.Horizontal;
30: _lastPrintPosition.X += (sourceRect.Width + 1);
31: }
32: else{
33: _lastPrintPosition.Y += (sourceRect.Height + 1);
34: }
35: //print footer
36: Brush brush = new SolidBrush(Color.Black);
37: string footer = this._pageNumber.ToString(System.Globalization.NumberFormatInfo.CurrentInfo);
38: Font f = new Font(FontFamily.GenericSansSerif, 10f);
39: SizeF footerSize = g.MeasureString(footer, f);
40: PointF pageBottomCenter = new PointF(e.PageBounds.Width/2, e.MarginBounds.Bottom +
41: ((e.PageBounds.Bottom - e.MarginBounds.Bottom)/2));
42: PointF footerLocation = new PointF(pageBottomCenter.X - (footerSize.Width/2),
43: pageBottomCenter.Y - (footerSize.Height/2));
44: g.DrawString(footer, f, brush, footerLocation);
45:
46: //print header
47: if(this._pageNumber == 1 && this._title.Length > 0){
48: Font headerFont = new Font(FontFamily.GenericSansSerif, 24f,
49: FontStyle.Bold, GraphicsUnit.Point);
50: SizeF headerSize = g.MeasureString(this._title, headerFont);
51: PointF headerLocation = new PointF(e.MarginBounds.Left,
52: ((e.MarginBounds.Top - e.PageBounds.Top)/2) - (headerSize.Height/2));
53: g.DrawString(this._title, headerFont, brush, headerLocation);
54: }
55: }

The PrintUtility class should be fairly easy to use from just about any�Windows Forms application. Just call either PrintTree or PrintPreviewTree, passing in your TreeView.

When I first decided to tackle the problem of printing the TreeView, I thought it was going to take quite a bit of time and code. I was really surprised once I figured out the algorithm, how simple it really is.



COM and .NET

clock April 2, 2005 00:17 by author Mark

If you are developing an addin for Outlook in C# or another .Net language, automating Outlook or even just using COM from .Net, you should be cleaning up your COM objects (duh!). But, setting them to null is not enough. You must use the System.Runtime.InteropServices.Marshal.ReleaseComObject method to remove all references to that COM object. Here's a little class that you can use so you don't have to retype the code all over the place.

using System;
using System.Runtime.InteropServices;
namespace Utils{
public class ComUtils {
public ComUtils() {

}
/// <summary>
/// Force a release of the COM objects.
/// If you are using Outlook objects, this will allow Outlook to
/// exit cleanly after you are done with it.
/// </summary>
/// <param name="comObjects">Array of COM objects to release,
/// be sure to add the objects to the array in the order you want
/// them destroyed!</param>
public static void Release(params object[] comObjects) {
try {
for(int i = 0; i<comObjects.Length;i++) {
if(comObjects[i] != null) {
try{
// loop until the reference count is zero
while(Marshal.ReleaseComObject(comObjects[i]) > 0);
}
catch(System.InvalidCastException){
// the object was not a COM object
// no big deal, just go on to the next one
}
catch(System.NullReferenceException){
// object was null, still no big deal
// go on to next one
}
finally{
comObjects[i] = null;
}
}
}
}
catch (Exception ex) {
// insert your exception handling here
}
}
}
}

Just pass in a comma separated list of your COM objects (in the order you want them released) to the Release method of this class. For example:

ComUtils.Release(outlookMailItem, outlookNameSpace, outlookApplication);

I haven't tried it, but I assume the same type of stuff applies to automating Excel or Word too.



Windows Debugging

clock October 18, 2004 22:26 by author Mark

I have been lucky enough to be in a Windows debugging class for the last 4 days. The company I work for had an instructor from Microsoft come in to give us two classes. Windows DNA Debugging and .NET Debugging. If you are a Windows developer and you ever have the opportunity to take these classes, do it!

Years ago, I was having troubles with IIS crashing. I remember talking to Microsoft support and they sent me a utility to capture a crash dump when IIS crashed. I sent it off to them and they figured out it was a problem with some Sybase DLLs. At the time, I had no clue how to read the crash dumps. Now that I have taken these classes, I can at least partially understand what is going on. Analyzing crash dumps seems to be something you need to do a LOT before you would become really good at it. There's a lot of assembly code and HEX values involved and it is a little overwhelming at first.

If you can't take the classes, Microsoft has some info here about installing and using the debugging tools. One really cool thing I didn't know about is that Microsoft has a server that the debugger can download debug symbols from when it needs them. It handles getting the right version of each symbol file for you.



About the author

Mark Pitman is a dad, husband and software developer. Not always in that order, but I try!



RecentComments

Comment RSS

Sign in