Friday, March 17, 2006

Intel Macs: Developer Dream Machines

Now that Windows XP Boots on Intel Macs and Red Hat is going to get their distro running on Intel Macs it is pretty clear that if you develop for Windows, Mac, or Linux and want to test at native speed competative applications or you develop on multiple platforms, then an Intel Mac is going to be a very enticing option, particularly laptops as roving development labs. MacBooks, the iBook replacement, are surely coming out in just a few weeks time and should over good performance in the $1000-$2000 range. But these is also another option. If you intend on doing any OS X development, you could become an Apple Developer Connection (ADC) Select Member for $500. Click on the link to see all the benefits, but the one thing it give you is a deep discount on one new hardware purchase with your membership. Through the Apple Hardware Purchase Program, you can get the 1.83 GHz MacBook Pro starting at $1599 or the 2.0 GHz MacBook Pro starting at $1999, a discount of $400 and $500 respectively. That's right, if you were going to buy a MacBook Pro, you can get the Select membership and the hardware for the same cost. For me, the additional benefit of the Select membership even if you weren't developing OS X apps is the access to Pre-Release Software. With OS X 10.5 sure to hit public beta this year, you get access to this OS before everyone else. If you are developing for OS X, you also get 2 technical support incidents from Apple with the year membership. If you are going to develop for any OS, why wouldn't you buy a Mac if you wanted to keep your options open with OS support? And if you are going to buy a MacBook Pro, you might as well do it through the ADC Select program and get yourself early access to Leopard. Update: If you are looking for consumer level hardware (iMac, iBook/upcoming MacBook) then the discounts are significantly less. You can check out the prices yourself on the ADC Hardware Purchase Program Store, but here are some example:
  1. iMac Dual Core 17" - Retail starts $1299 - ADC $1170 - $129 difference
  2. iMac Dual Core 20" - Retail starts $1699 - ADC $1529 - $170 difference
You can also get an ADC discount on anything in the ADC store, iPods included, when you buy all the stuff together with your computer purchase. So the more you spend, the more you save. Another benefit to take into account with the Select membership is that you get the final version of the next OS X on DVD. I would imagine you have to be a Select member when the final version of Leopard is released for this to be true, so timing is a factor. I would think that somewhere around the WWDC would be a good time, surely 10.5 is going to be released < 1 year after WWDC.

Thursday, March 16, 2006

Win XP boots on Intel Macs!

As soon as the Intel iBook (soon to be MacBook?) comes out, it may be time to make another purchase. Now that Win XP boots on Intel Macs that is. The solution isn't too bad either. Basically, you make an OEM Windows XP install CD that includes drivers for the Apple hardware, partition your make to make room for XP, then tell OS X to use a file provided with the solution to boot from. The toughest part is making the CD, and of course you have to destroy whatever installation of OS X you have on your Intel Mac. But even that part could be trivialized, using the OS X Setup Assitant you can get your new Intel Mac and just transfer everything off of your old Mac after you have it rigged for dual-boot. I have used the Setup Assistant once before, it worked fantastically. I was a little nervous about it at first because of the terrible experience I had using the Windows XP File and Settings Transfer Wizard. These two technologies are not equivalent, the XP wizard as its reveals only does files and settings, and when I used it a poor job at that. The OS X Setup Assistant migrates all Users, Applications, and OS Settings. It's almost like Symantec Ghost, but its simple to use and smart. For instance if a newer version of an OS X or iLife application is on the target machine, it leaves the new version in place, particularly important for Intel Macs. How can the Setup Assistant make life easier for anyone that has already been using an Intel Mac? You could use a second Mac as temporary staging machine, Setup Assistant everything over to it, rig your Intel Mac for dual-boot, then move it all back over after you have XP and OS X running on the Mactel. You could also use Apple's Backup application, part of the .Mac subscription, to backup your home directory, /Library and /Applications folders to an external drive, then restore when you have the Mactel ready to go.

Tuesday, March 14, 2006

Why is DataGrid.PageCount = 1?

Came across an issue today that was not obvious how to fix, and Googleing revealed no information about it, maybe I just couldn't hit upon the right combination of search terms, but here you go. In ASP.NET, a page that I am working on displays data with a DataGrid. I don't like, nor do any of our users, the built-in paging controls that you get for free with the DataGrid, so we wanted to implement something custom. I found this article on DotNetJunkies.com demonstrating how they did it. They go whole hog and used a stored procedure to implement entirely custom data page management. I have done this before too, but I have a lot of code using DataViews and DataSets already in this page (inherited from someone else) that I don't want to refactor during this phase of development. So I turn off the built-in paging controls with this bit of markup <asp:datagrid id="DataGrid1" AllowPaging="True" PagerStyle-Visible="False"
AllowCustomPaging="True">...</asp:datagrid>
There is just one problem with this, when you have AllowCustomPaging="True", then no matter what you set as DataGrid1.DataSource and do the DataGrid1.DataBind, your DataGrid1.PageCount property will always be 1. I think I copied this out of the DotNetJunkies article because I thought I might replace the way I get data into the DataGrid as well as the paging UI, and forgot about. In MSDN help, the fact that this will always be 1 when AllowCustomPaging is true is not mentioned. In the help for AllowCustomPaging, the only hint there may be a relationship to PageCount is the note that you have to set the VirtualItemCount to the total number of items there could be. When you do, then PageCount is calculated correctly based on the PageSize. The relationship between all these properties is not obvious and if you haven't dealt with this issue in a while, it may take a while to determine why PageCount=1 like it took me. I hope this post saves someone some time.

Friday, March 10, 2006

No easy Vista booting on Intel Mac

No Vista on Mac's horizon | CNET News.com
I felt a great disturbance in the Force, as if millions of voices suddenly cried out in terror and were suddenly silenced.
-Obi-Wan Kenobi, Star Wars As news that Windows Vista won't natively or easily boot on Intel Macs has spread I can only imagine that millions of technology enthusiats like myself that had A New Hope of using one piece of hardware, a Mac, to run both OS X and Windows and in turn their applications have cried out in anger and frustration at this turn of events. Why won't Vista run on Mactels? Simple really. Apple in designing their hardware decided to use the modern pre-OS hardware initilization environment, Intel's Extensible Firmware Interface (EFI), instead of the 20-year old BIOS standard that Windows-based hardware uses. Apple also did not include any backward compatibility junk in their EFI implementation. This is all quite sensible for Apple, new hardware platform, start with the best stuff you can get now, avoid all the old stuff that has caused PC manufacturers and users so much trouble over the years (aka BIOS). It was widely expected that Windows Vista would support booting on 32-bit processors using EFI. Just like replacing PCI with AGP, or Serial ports with USB, replacing BIOS with EFI was long overdue. However, that feature has now been dropped, essentially relegating Windows hardware to continued use of BIOS forever. The Microsoft explanation for not supporting EFI is questionable. You could of course create benign explanations for this (Vista is way late so dropping any features helps, there is no hardware besides Macs to test on, Apple is not a Windows licensee) but the conspiracy theories are flying fast and furious. I am just disappointed. I am disappointed that Apple doesn't realize they could sell a ton of Macs if there was Windows support. I am disappointed in MS that they had the opportunity to drive EFI adoption, even if Apple wasn't i n the picture, and they choose to stay legacy. Dual-booting Windows and OS X was always a last resort option anyway. When I switched from the Win 9x line to NT 4.0 back in the day (96-97), I dual-booting for the occasional game or app that only ran on the 9x codebase, but it was so much hassle I just eventually started choosing games that supported NT. But this "fallback" for Intel Macs has not "officially" been closed. There is always hope that hackers will figure out a way, but its going to be time-consuming and painful, which means I probably won't bother. So what hope is left for easily running Windows application on Mactels? You are pretty much left with emulation or Darwine. Darwine 0.9.9 was released on March 6, 2006. The nearly mythical 1.0 release may just be around the corner, but no word that I can find right now on compatibility or how this release works on Mactels. As for emulation, MacWindows.com has a good summary of the current state of emulators that have Mactel support. All of the emulators are current PPC-based products that have been or are being ported to Intel Macs with a big change in the the code, they will no longer emulate the CPU and have to do CPU instruction set translation. This should be a huge performance boost, how much is yet to be seen. But its not going to be native speed, think of running Windows in VMWare on a Windows machine, its passable depending on the speed of your CPU and how much RAM you have. It may be enough, but it is gong to take more time to get this sorted out. Still no word on if VMWare is going to port to OS X Intel, but it makes to much sense for them not to.

Thursday, March 09, 2006

iPod Mame

I don't have a iPod video or nano, but this looks pretty cool: Mame on the iPod

Tuesday, March 07, 2006

Getting Real Work Done in .NET Windows Forms

I have been working on a Windows Forms (WinForms) applications since Christmas 2005. The application essentially sends files to a web site for business logic processing and receives notifications, via RSS, that the user should be interested in. This is the first WinForms app I have developed entirely on my own. When I was working for Vertigo Software I was the Project Lead/Technical Lead on a number of WinForms apps that were pretty sophisticated. Using IE to do some pretty cool rendering tricks, BITS to download application updates, and good UI. One of those apps was the Windows Server 2003 Guided Tour But this is different because I am doing it all and its eye opening. To get your WinForms app to behave like a first class Windows app, you absolutely are going to step outside the .NET managed libraries and you need to understand how an actual Win32 application is constructed. I am sure this is not news to many, and I knew this is was the case going into this development effort, but it still bears repeating. What am I talking about? Take for instance the behavior of something like MSN Messenger with the close button. Everyone is familiar with this pattern now:
  • Application main window is running and visible to the user
  • Application has a button in the Taskbar and and icon in the tray (i.e. the stuff next to the clock)
  • User clicks the Close button (i.e. the red X). Normally this exits the application, but your app is special
  • Your app should hide its taskbar button but stay running and keep its icon in the tray
How are you going to do this in WinForms? Your first instinct is to register for the Form.Closing event, cancel the event and then hide your form. You also need to show an icon in the tray. Hooking Form.Closing is part of the solution, as is hiding your form (e.g. Form.Visible=False) but this leaves once pretty big whole in the functionality of your application. If your app is running and the user tries to Logoff or Shutdown/Restart the computer, you are implicitely cancelling that event. The user Logging off, Shutting down, or restarting is called ending their session according to Windows. The only way for the user to end their session if your app is cancelling Form.Closing is to kill it with Task Manager! This is obviosuly bad and this is all it takes (in C#):
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
      e.Cancel=true;
}
How do you solve this problem? What you really want to do is cancel the Form.Closing event in cases where the user session isn't ending. You might think that Environment.HasShutdownStarted would be your salvation, and you would be wrong. You might then stumble onto the Microsoft.Win32.SystemEvents.SessionEnding event and hook it. Here is the description from MSDN:
Occurs when the user is trying to log off or shut down the system.
Great I will just hook that and, nada. That's right, There is no guarantee your Form will receive this event before Form.Closing is fired, thus making it useless for your purposes. So what do you do? You Google like mad and hope someone has figured this because you can hear Han Solo saying in your head: "I have a bad feeling about this." Lucky for you, they have and and its actually the poor MS employee writing the documentation for Microsoft.Win32.SystemEvents.SessionEnding because in the explanation of this event, there is sample code to do exactly what you want. How does it work? You have to override the actual message loop processing function, the same one that has existing in Win32 forever, and listen to the WM_QUERYENDSESSION message manually. Then you have to track whether you have received this message manuallly and respond to it in Form.Closing. Ah, now everything behaves right. Why the data about WHY your form is closing isn't in CancelEventArgs boggles the mind. This is far from the only example, but this post is long enough as is. What lesson have I learned from this development effort? Win32 knowledge is going to be relevant for a long time, even with Windows Presentation Foundation (WPF) on the horizon. MS never seems to completely replace the last application development with the new one. Charles Petzold has already confirmed that WPF won't have even all the controls that WinForms has. Maybe this is just me, but is MS ever going to finish one framework before replacing it with another? Win32->MFC->ATL->VB6->WinForms->WPF, when is it going to stabalize? I have been on this ride enough that I don't know if I want to get on the WPF roller coaster. Cocoa is looking better and better...

Monday, March 06, 2006

First Impression: iPod Hi-Fi

Took a look at the iPod Hi-Fi at a local Apple Store this weekend. This is not a comprehensive review, for those, I have read the following: iLoung e Review PC Magazine Review Playlist Review I generally avoid knee-jerk reactions to product announcements now when there is a very good chance I can get my hands on it myself, like with the Apple products. First Impression Man does this sound good. I didn't tweak anything, just walked up to a free iPod Hi-Fi in the Apple Store, put some Alica Keys on, and stepped back. I am no audiophile. I do occasionally compare Apple Lossless to AAC 128 kbps, but I really can't hear a difference. I have some stuff in Lossless (e.g. Batman Begins soundtrack just because I ripped it that way and I don't need the space back yet). The iPod Hi-Fi sounds better to my ears than my Kenwood 5.1 Dolby Digital Home Theatre in a box that I got a number of years ago, at least for music. I have been considering a speaker system just for iPods for a while now, specifically for the kitchen, bedroom, or outdoors. So I am tempted by this. Arguements FOR include portability (D batteries!), can be connected to an Airport Express for wireless streaming, and the sound. Arguements AGAINST include price ($350!), need an iPod video or nano for full features, and I need another Airport Express for wireless streaming. Unless I get this gifted to me, I won't be buying one right now for myself. I like the design, but I think if either $350 included wireless or this was $50 cheaper, it would have been an easy sell, but maybe I am not the target market for this. Bigger Picture One of the complaints about the iPod Hi-Fi you hear is that this doesn't include radio or a CD player. Apple's tagline for this is "Home Stereo. Reinvented" and some people just don't get it. Apple is not trying to replace Sony's existing product lines. Apple's new devices are designed and intended to replace the various old analog based devices and provide the best merger of software and computer-based (i.e. hard drive and CPU based) technologies. Apple doesn't include a CD Player because the iPod replaces the CD player, why would you EVER AGAIN want a CD Player in a Home Stereo? One of the many reasons iPods have become wildly popular was because people were sick of FM Radio, why would you ever include FM Radio in a home stero again? Now whether or not you agree with any, all, or none of these decisions will determine if you buy Apple products or not. I happen to agree with most, certainly the CD Player and FM Radio exclusions. I have FM Radio on my Kenwood HIB, I have never used it.

Thursday, March 02, 2006

Tip: SqlHelper Debugging using IISReset

This is one of those things you always forget because you do it so infrequently. If you use Microsoft's SqlHelper (original not EntLib) to connect to SQL Server and call stored procedures, you should probably be aware that SqlHelper gets a list of your stored procedures parameters from SQL Server ultimately by calling SqlCommandBuilder.DeriveParameters(..). These parameter definitions get cached until your AppDomain is reloaded. The sticky bit here is that if you are changing the number of parameters on a stored procedure where its parameter definitions have already been cached, then you will see exceptions from SqlHelper that the parameter count doensn't the data you are passing in because your business tier code has already been updated to reflect the new parameter count. If you are in ASP.NET, just do an IISReset and save yourself time debugging whether you are connecting to the right database, if you really had updated the sproc, if SQL is finding a different sproc becauase its not qualified by the user that created it (e.g. SomeProc instead of dbo.SomeProc) like I just did. :)