« May 2007 | Main | July 2007 »

June 27, 2007

Adobe Illustrator CS3 Installer

"Installation failed -- error 2739, please contact customer service."

Reboot. Maybe because I haven't rebooted after the last security update...?

"Failed. 2739"

Arrgh. How nice. How welcoming.

Start searching Internet as calling customer service is not on my list of things to do tonight....

Solution:

#1445655: Win: Unregistered dlls on Vista can cause installer to fail
------------------------------------------------------------
This is the solution for the 2739 install error on Vista:
1) Launch the Command Prompt from an account with admin privileges
2) Type in the following command and press Return
regsvr32 %windir%\system32\vbscript.dll
3) Type in the following command and press Return
regsvr32 %windir%\system32\jscript.dll
4) Launch Setup

Eh?

Installer starts and works though. Supposedly, this error can happen with the Adobe Creative Suite or Adobe Photoshop as well.

Check out what must be the ugliest icon for a drive ever though:

image

Adobe's packages are usually decent enough and the stuff is usually polished visually -- so, it's even more glaring that this would look so absolutely awful.

 

I like the new Vista application icon for their setup program:

image

Why didn't the artist who worked on that work on some decent drive icons? :)

June 25, 2007

CompositionTarget performance

From Rob, Composition Target.Rendering and minimized Windows.

From: Helpful MS Employee 
The CompositionTarget.Rendering event puts us into a mode where we continuously animate. You should unhook at every opportunity.

The key thing to never forget about using the Rendering event -- it continuously fires, unlike any typical UI development system -- the more you do, the slower it goes. Win32 WM_PAINT messages only fired when a region became invalidated (i.e, it needed to be refreshed). Even WPF doesn't work that way normally -- as it's a retained mode drawing system -- the "OnRender" method only fires when you want it to (controlled by a number of factors of course). 

This event however, fires many times a second -- for example, it could easily fire 60 times a second!

June 13, 2007

Cheap and Easy WPF clr-namespace references.

(inspired by a forum post)

Tired of the Xaml syntax:

xmlns:local="clr-namespace:Blah.Yawn.Zzzzz"

that you add to every Xaml file that you create? Worse yet is that you end up adding multiple as you're referencing a bunch of auxiliary WPF pages, controls, types, etc.... so you have 3, 4, etc. of these. Yuck.

xmlns:local1="clr-namespace:Blah.Yawn"

xmlns:local2="clr-namespace:Blah.Yawn.Zzzzz"

xmlns:local3="clr-namespace:Blah.Yawn.Sleepy"

xmlns:local4="clr-namespace:Blah.Yawn.Snooze"

There's an easier way if you own the assemblies and you don't need to reference types in the main executable assembly!

If you don't (own them or you haven't broken them out into multiple assemblies), then you'll have to stick with the standard syntax, which requires one namespace per xmlns declaration.


Again, note that this only works for referenced assemblies.


Go to the assembly where your controls are located and add this assembly attribute to the AssemblyInfo.cs file:

[assembly: XmlnsDefinition("http://www.wiredprairie.us/WPF", "WiredPrairieUS.Controls")]

The xmlnamespace (first parameter) is up to you and should be unique (often your companies web site address followed by some schema. It doesn't really need to exist, just be unique to your product/component). The second parameter should map to the namespace where your types you want reference from Xaml are located. In this example, I've created some WPF controls and placed them in the WiredPrairieUS.Controls namespace.

You can reuse the same xmlns multiple times with different CLR namespaces if your types are in multiple namespaces. Maybe for example, I have a WiredPrairieUS.Controls.Advanced namespace:

[assembly: XmlnsDefinition("http://www.wiredprairie.us/WPF", "WiredPrairieUS.Controls.Advanced")]


Then, go back to the ordinal Xaml file that is using these types and add to the namespace declarations:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local=
http://www.wiredprairie.us/WPF

That's it. You don't need to declare multiple xml namespaces to reference types in different CLR namespaces as they are automatically imported by the Xaml parser/compiler (it checks the referenced assemblies for the attribute above).

Nice.

If you're developing components for reuse/resale. Please consider adding this to your assemblies and documenting it if you haven't already.

Great WPF hands on lab posted for an Outlook 2007 visual clone

http://www.microsoft.com/switzerland/msdn/de/events/hol/wpf.mspx

Building Line of Business applications with Windows Presentation Foundation

image

Very Blend focused, but goes through a lot of WPF features. Well done.

June 12, 2007

Pack syntax in WPF

If you do much with WPF, at some point you'll be forced to use the pack syntax.

A bit of history:

The pack syntax was created by an evil-alien empire bent on mental destruction of application developers on the planet Earth.

The pack syntax is rooted in conventions established by the Open Packaging Conventions. Sigh. Designed and intended for use by committees.

The syntax is well documented, if you can find it. I came across one of the best resources for learning about the most common options used in WPF here:

Pack URIs in Windows Presentation Foundation

The trouble is actually deciphering it all. The graphic on that referenced page makes great sense -- once you can wrap your head around it. :)

I'll reiterate some of the common scenarios here. I've seen the same ones pop up in the WPF forums time and time again.

The pack syntax for files within your WPF application is easy, usually no more than a forward slash followed by the file name:

"/MyPage.xaml"

If the file is contained within a subfolder within your main application, just include the folder name:

"/Pages/MyPage.xaml"

image

If the content is relative to the current markup file or code, leave off the forward slash at the beginning, which indicates it's in the root of the application. I'll typically leave it in to be more clear where I'm getting the content from.

But, what if you are referencing Pages in another assembly you've referenced in your project?

The syntax is similar:

"/ExternalPages;component/FancyPages1.xaml"

if the file is in the main "root" folder of the referenced assembly. In this case, the referenced assembly was named "ExternalPages". The ;component syntax is required as part of the pack syntax for referenced content in external assemblies.

If the content is in a different folder:

"/ExternalPages;component/AwesomePages/IncrediblePage1.xaml"

image

If you're referring to content in the secondary assembly and loading it via the pack syntax, you'll need to reference the assembly by name, even though the content is located in that assembly. If, for example, in the ExternalPages project I had a class that loaded FancyPages1.xaml, I'd need to use syntax like this in VB.NET:

Dim u as Uri = New Uri("/" + Me.GetType().Assembly.GetName().Name + ";component/FancyPages1.xaml", UriKind.Relative))

or in C#:

Uri u  = new Uri("/" + this.GetType().Assembly.GetName().Name + ";component/FancyPages1.xaml", UriKind.Relative));

Rather than hard code the name of the assembly, I've taken the approach of grabbing it dynamically in the example above.

What's this about "pack" though? It's really how you specify the type of Uri (and where). You need to use the pack syntax when you're specifying an 'absolute' Uri. It hardly changes the common cases though (which is great!).

The pack syntax for example for the hard coded referenced assembly example above would look like this:

"pack://application:,,,/ExternalPages;component/AwesomePages/IncrediblePage1.xaml"

There's one other type of pack that's typically used when you have "loose" Xaml content, and that's the siteoforigin. The huh? Just think of it as a real "absolute" path to the location where your content lives, relative your your application's executable.

If I used this syntax:

pack://siteoforigin:,,,/MyLoosePage.xaml

That would mean that the content would come from a xaml page called MyLoosePage.xaml that was in the same folder as the application as content -- not embedded as a resource. (What's cool about this is that it also works if your application was downloaded via the web as an XBAP -- the site of origin becomes the host application virtual directory (like http://www.wiredprairie.us/myxbap for example could be the host of an Xbap -- that would become the site of origin).

June 6, 2007

How to suck more as an airline or business

My wife are planning a vacation and we wanted to book some flights on Northwest Airlines the other night.

We went through the entire process, clicking, accepting terms and conditions, selecting seats, entering credit card numbers, verifying this and that and was on the final page to purchase the tickets (side story-the last button they want you to click to buy the tickets says "complete transaction" or some jumble like that -- the tooltip says what the button should have though: Purchase tickets).

In any case, I clicked the button. Boof. The web site kicked us clear back to the flight selection screen and said we had to call to purchase tickets. Frustrated by the waste of time, I called the Gold/Platinum service line to complete the transaction. Smoothly completed.

The next day, my wife noticed an extra "$20 service fee" for using the phone service center.

I called within about 15 seconds of hearing that.

Please hold. Holding. Holding.

("We value you as a customer, please continue to do something useful while we keep you on hold and waste your time.")

I was told by the person who answered after a LONG wait that they might not be able to credit me that money as they personally can't -- maybe the helpdesk can. A minute or two passed and she said that "this time, we'll credit your account, but next time we won't. We always charge that fee, EVEN IF THE WEB SITE SAYS YOU HAVE TO CALL." Shocked, I questioned that logic. It was true. I said, next time, I'll choose another airline -- I'm a gold member, and my wife and I have over more than 700,000 miles accumulated between the two of us -- it seems like a terrible way to treat a customer.

"OK. I'll note that," she responded.

"Goodbye NWA."

If you have your own business -- think your rules and regulations through before you slap your customers in the face with rules that may have made sense in a board-room or meeting, but don't connect with reality. Sometimes, the customer may deserve it (as not everyone plays by reasonable rules). Other times, a slap means you're just loosing a customer.

And no, the person I spoke with and booked the tickets originally mentioned no fee for using the service over the phone -- I imagine there was some click-through on the phone that I had agreed to ...

HTC Touch

image

http://www.htctouch.com/

Touch-screen goodness -- running Windows Mobile (which means it would be great for business users). Now, if they could release the software as an add-on to existing Windows Mobile phones (with touch screens of course).... that would be cool. I still like a keyboard like my Treo 750 has -- I wouldn't want to give that up.

Who needs an iPhone now ... (well, no one actually needs one...).

Check out their demo and web site -- all nicely done. It's a very well thought out interface. Big clear buttons. Easy actions.

June 1, 2007

Think you know your .NET string comparison functions?

If you can't easily describe the difference between String.Compare and String.Equals in .NET, then read this.

Help support my web site by searching and buying through Amazon.com (in assocation with Amazon.com).