
Today was the MSDN Code Camp here in Charlotte. I got to see some great presentations on things like SOA, Mobile Speech Server, and Reflection. I also presented on Test Driving ASP.NET Development (ppt). I felt like the presentation was quite a success. It ran an hour and 10 minutes, and I had a lot of really good questions from developers.
One of the fascinating parts was the comments I got during and after. About 3/4 had never used NUnit before (I didn’t even ask about NUnitAsp – though a lot of people liked it). Even more interesting was when I asked how many had ever used mock objects to which exactly one developer in the very back raised his hand on.
But all in all I had an awesome time, got to be some great people, and hang out for the day on the Microsoft campus. And with the great feedback I got from the TDD mailing list, the NUnit Mailing list and the NUnitAsp lists, I feel I was able to get some people really thinking about getting their code under unit tests, and just what this whole XP/TDD thing is all about.
For those interested in the presentation:
Presentation
Code
This Saturday (April 30th) I have the pleasure of speaking at the MSDN Code Camp here in Charlotte, NC. I am going to be speaking on Test-Driving ASP.NET Development.
In preparation for that, I’ve put up a copy of my PowerPoint presentation (675k) for comments. What do you all think? Anything that should be added, taken away, made more clear? Email me at Cory.Foy at mobilehwy dot com.
To follow up from my earlier post, I found that Microsoft does indeed offer updates for the Machine.Config file browserCaps section. They call it a Device Update, and by us installing Device Update 4 we were able to fix the issue we were having with Nextel’s new phone header information.
Now that’s how I like to enter the weekend. :)
Config files can be nice. They can help set settings so that you can tweak things on the fly without having to recompile your code. Or so that non-techies can modify things without having to know your code.
Microsoft uses several config files for .NET. The biggie is Machine.Config. And today I had the pleasure of one of our apps breaking because Nextel changed the phone header information, so .NET didn’t recgonize it anymore. First, when I went into the config file, Microsoft provides a link to a company that is supposed to maintain the browserCaps section. But, of course, that company doesn’t. I’m sure they’d be happy to sell it to you, but the free page .NET links to says “Under Construction”. Nice.
So knowing I was going to have to modify it myself, I start looking for the mobile headers section. I found it, but to give you an idea of what not to do in a config file, I’ll post a *small* snippet of it here:
majorVersion = ${browserMajorVersion}
minorVersion = ${browserMinorVersion}
type = “Phone.com %{majorVersion}.x Browser”
preferredImageMime = “image/vnd.wap.wbmp”
requiresUniqueFilePathSuffix = “true”
type = “Phone.com 3.x Browser”
preferredImageMime = “image/bmp”
requiresUrlEncodedPostfieldValues = “true”
requiresUniqueFilePathSuffix = “true”
canRenderInputAndSelectElementsTogether = “false”
version = %{majorVersion}%{minorVersion}
etc, etc. Let me just say that you should not have code and variables and regex strings all slammed together in a XML Config file. Ugh.
Last night CharJUG had the priviledge of having Pragmatic Programmer Andy Hunt speak. Though I was sorely disappointed in the turnout (19 people of 60 some odd who I had talked or had expressed interest in going) I was not in the presentation.
The talk started at 6:45pm and went until nearly 9:45pm. I took lots of notes, and I’m hoping he sends me the powerpoint so I can put it up on the site, but here are some highlights:
– The “Broken Windows” theory. The story is that these researchers put a nice car (Jaguar or similar) in the South Bronx and left it for four days. Nothing happened to the car at all. So they went over and broke one window. Within four hours the car had been stripped, burned and flipped. The moral? Don’t let little things like broken builds pile up – fix them immediately. If you build up too much “technical debt” you may not be able to get back out.
– Processes have to be easy. In 2000 Romaine lettuce consumption went up 162%. Why? Because American’s started eating healthier (“No”, says Andy, “American’s still eat crap”)? Because McDonald’s started selling salads? Nope! Because that was the year they introduced “Salad in a bag” making it a no brainer for people to get some pretty, prewashed lettue and shake it on their plate. Even though it is much more expensive, people want things to be easy.
- Stand up meetings should answer three questions, and three questions only. What have you accomplished? What are you working on? What is in your way? And the answers should be in term of that day. Saying that you are working on getting validation working for your login page is good. Saying you are working on “your app” without specifics is bad.
- Don’t let any of your apps have a Bus number of “1″. Your bus number is not your position in the computer as an ISA card, it is how many people can get hit by a bus before you are in trouble because no one else understands the app.
- The worst words you can hear from a team are “We’ll try.” That means that they know that they are subject to failure, and that they also know they aren’t going to make it, so they are just going to march%2
For anyone in the Charlotte area, Andy Hunt, of the Pragmatic Programmers, is speaking at this month’s CharJUG meeting. We are being sponsored by the ACM Student Chapter of CPCC, The Futures Institute, and best of all, MobileHWY (my employer).
One of the guys from CharLUG put together a really nice graphic for it that we have up on the site. Speaking of CharLUG, they are having an install fest at the end of the month – April 30th. Which happens to be the same day I am speaking at the MSDN Code Camp being held by the Developer’s Guild.
All in all a very busy month for me. Hope to see you soon!
One of my coworkers uses the term MTTMPFS a lot – Mean Time To Major Product Focus Shift. It’s amazing how low that mean time really is.
I’m sure this is all over the web, but bugger if I had a hard time initially finding it. I’ve been working on some custom extensions to NUnitASP and was having trouble building the project. The NUnitASP guys provide an NAnt build script, but when I ran it I was getting the following:
BUILD FAILED[csc] C:\Windows\Microsoft.NET\Framework\v1.0.3705\csc.exe failed to start. The system cannot find the file specified
Which, of course, was driving me crazy because I was specifying in my path to use v1.1. But it was ignoring that, and I couldn’t figure out why.
Turns out, I just need to learn the tools I’m using. Once I spoke with the NUnitASP guys and found out it wasn’t an issue with them, but something with NAnt, I found the following article:
One note: NAnt may be configured out of the box to use a different .NET Framework version than you would like. For example, NAnt 0.84 is configured to use .NET Framework version 1.0 by default. If you only have version 1.1 of the .NET Framework installed on your machine and you try running NANT 0.84 on a task that requires the framework, you will get an error similar to this one:
[csc] C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\csc.exe failed to start.
The system cannot find the file specifiedTo change the default framework version, you need to edit NAnt.exe.config in the
\bin directory. Change the default argument in the platform tag to the .NET Framework version you would like to use as the default. The following example sets the default Framework to use to 1.1:
...
The next Chalotte Linux User’s Group meeting is tomorrow at our new location at Central Piedmont Community College in downtown Charlotte. They’ve got the lowdown up on the CharLUG site.
Recently I needed a way to have an app take a screen shot of itself and save it to a directory. I only wanted the currently focused screen to be captured. I looked around on the web, and found lots of crazy interop scripts to handle doing a screen shots.
But it just didn’t seem right. *I* can screen capture by just hitting Alt->Print Screen, why can’t my app? I knew there would be some interop involved, but certainly it doesn’t have to be that hard, does it?
Turns out, it really doesn’t. By sending some Keyboard events using the Win32 SendInput() via User32.dll, and working with the clipboard data in the normal fashion, it’s fairly easy to get it all working. First, you need the capture and save code:
private void CaptureAndSave(){ uint intReturn = 0; NativeWIN32.INPUT structInput; structInput = new NativeWIN32.INPUT(); structInput.type = (uint)1; structInput.ki.wScan = 0; structInput.ki.time = 0; structInput.ki.dwFlags = 0; structInput.ki.dwExtraInfo = 0;
//Press Alt Key structInput.ki.wVk = (ushort)NativeWIN32.VK.MENU; intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
// Key down the actual key-code structInput.ki.wVk = (ushort)NativeWIN32.VK.SNAPSHOT;//vk; intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
// Key up the actual key-code structInput.ki.dwFlags = NativeWIN32.KEYEVENTF_KEYUP; structInput.ki.wVk = (ushort)NativeWIN32.VK.SNAPSHOT;//vk; intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
//Keyup Alt structInput.ki.dwFlags = NativeWIN32.KEYEVENTF_KEYUP; structInput.ki.wVk = (ushort)NativeWIN32.VK.MENU; intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
IDataObject data = Clipboard.GetDataObject();
if (data.GetDataPresent(DataFormats.Bitmap)) { Image image = (Image)data.GetData(DataFormats.Bitmap,true);
image.Save("image" + ".bmp",System.Drawing.Imaging.ImageFormat.Bmp); image.Save("image" + ".jpg",System.Drawing.Imaging.ImageFormat.Jpeg); image.Save("image" + ".gif",System.Drawing.Imaging.ImageFormat.Gif); } else { Console.WriteLine("The Data In Clipboard is not in an image format"); }}
As you can see, all the heavy lifting appears to be in a class called NativeWIN32. This class is nothing more than an internal wrapper class around the User32.dll functions. I’ve included the full suite of VK enums since I already had it in my code:
public class NativeWIN32{ public const ushort KEYEVENTF_KEYUP = 0x0002;
public enum VK : ushort { SHIFT = 0x10, CONTROL = 0x11, MENU = 0x12, ESCAPE = 0x1B, BACK = 0x08, TAB = 0x09, RETURN = 0x0D, PRIOR = 0x21, NEXT = 0x22, END = 0x23, HOME = 0x24, LEFT = 0x25, UP = 0x26, RIGHT = 0x27, DOWN = 0x28, SELECT = 0x29, PRINT = 0x2A, EXECUTE = 0x2B, SNAPSHOT = 0x2C, INSERT = 0x2D, DELETE = 0x2E, HELP = 0x2F, NUMPAD0 = 0x60, NUMPAD1 = 0x61, NUMPAD2 = 0x62, NUMPAD3 = 0x63, NUMPAD4 = 0x64, NUMPAD5 = 0x65, NUMPAD6 = 0x66, NUMPAD7 = 0x67, NUMPAD8 = 0x68, NUMPAD9 = 0x69, MULTIPLY = 0x6A, ADD = 0x6B, SEPARATOR = 0x6C, SUBTRACT = 0x6D, DECIMAL = 0x6E, DIVIDE = 0x6F, F1 = 0x70, F2 = 0x71, F3 = 0x72, F4 = 0x73, F5 = 0x74, F6 = 0x75, F7 = 0x76, F8 = 0x77, F9 = 0x78, F10 = 0x79, F11 = 0x7A, F12 = 0x7B, OEM_1 = 0xBA, // ',:' for US OEM_PLUS = 0xBB, // '+' any country OEM_COMMA = 0xBC, // ',' any country OEM_MINUS = 0xBD, // '-' any country OEM_PERIOD = 0xBE, // '.' any country OEM_2 = 0xBF, // '/?' for US OEM_3 = 0xC0, // '`~' for US MEDIA_NEXT_TRACK = 0xB0, MEDIA_PREV_TRACK = 0xB1, MEDIA_STOP = 0xB2, MEDIA_PLAY_PAUSE = 0xB3, LWIN =0x5B, RWIN =0x5C }
public struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public long time; public uint dwExtraInfo; };
[StructLayout(LayoutKind.Explicit,Size=28)] public struct INPUT { [FieldOffset(0)] public uint type; [FieldOffset(4)] public KEYBDINPUT ki; };
[DllImport("user32.dll")] public static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);
}
And viola! Quick, easy screen capture code.