Tags: , , | Posted by admin on 11/21/2008 3:01 AM | Comments (0)

I’ve always wanted to have and play my music from anywhere.  As of today, I’m getting really close.  Two things happened to make it easier.

First, Zune Pass with Free MP3s (if you have MP3s from other sources, skip this section and move on to “Mesh” below)

First, I’m a Zune Pass guy.  For $14 a month, you get unlimited music to listen to on your PCs and Zunes.  Of course, if you end the subscription, you don’t keep the music.  That’s mostly true as of today, with a great exception.  As of now, every month you’re a Zune Pass subscriber, you get to download 10 DRM-free MP3s from the Zune library.  These credits show up as you browse your music, and when you go to buy an MP3, you’ll see ‘NO CHARGE’ as long as you have credits remaining (note: these aren’t rollover credits – you need to use them every month).

image

These MP3s are yours forever, regardless of whether you have a Zune pass, or even Zune hardware or software.  They’re POMP3s (plain-ole MP3s) to do with as you like.

Second, Mesh

Ok, so it’s great that I get free MP3s.  And since I can copy them around, I can take them with me on any device.  However, it’s time-consuming to copy files and make sure everything’s in sync.  It also doesn’t help if you’re at someone else’s computer.  That’s where Live Mesh comes in.  Live Mesh, although much more, includes file-synching capabilities.  Once you install Mesh (www.mesh.com) on the desired computers, you can join them into your own sort of personal network (called a Mesh, of course), simply by using your Live/Msn/Hotmail Logon.  Once they’re in the Mesh, you can add any folder on any computer to be synced, and specify that it should also be synced with any/all of the other computers.  So, Computer A and B sync a folder called ‘ZuneMP3s’.  Any changes on either computer will automatically be synced through the included computers without you doing a thing!  Add some MP3s on computer A and they’ll be on computer B, and vice versa.  Any problems with making sure all your devices have the MP3s is solved.  And you can have nearly unlimited computers in your mesh.

That’s great.  Your PCs all have your MP3s.  But wait, there’s more.  This is where it gets really, really good!  In addition to syncing the folders to your devices, you can sync it to your Mesh “Live Desktop”.  This is your mobile desktop on the web.  As you can see below, I’m syncing my MP3s to my Live Desktop.  (Note: there’s currently a 5gig limit to your Live Desktop while it’s in beta).

image 

Why is this important?  It’s important because your Live Desktop includes a built-in media player by way of the Silverlight plugin.  This means, yes, you can play your MP3s from the browser, from any computer that supports Silverlight (Mac, Windows, Firefox, Safari, etc)!  At a friends house?  Just log on to your Live Desktop and start playing your music!

Bonuses

Bonus #1: Soon you’ll be able to include Mobile devices and Macs in your Mesh.  That means you can have your MP3s sync to your phone for play on the road!

Bonus #2: Mesh includes remote desktop abilities.  That means that you can remotely connect to any machine in your Mesh as if you’re sitting in front of it.

Bonus #3: Mesh is set to be much more than just a file-synching solution.  Silverlight apps can be hosted within it, and developers can write apps that use it to sync whatever types of information is relevant. 

Summary

I can sync and play my MP3s from any PC in my Mesh, and I can play my MP3s anytime, anywhere, from a browser!  How’s that for cool?!?!

Tags: | Posted by Admin on 7/15/2008 4:09 AM | Comments (0)

I'm trying to reuse an animation that I create programmatically.  The why isn't important.  What is important is that the second time I try to run it with animation.Begin(), it bombs.  Well, with some properties it bombs.  With others, it works.  Transform properties cause the error, but standard properties like opacity and canvas location work when you run the animation multiple times.

Below is a sample app.  Button one and two are two instances of the same created animation.  Each of them will run once, but fail the second time.  This shows that it's not the object being animated, but the animation itself that is causing the error.  Button three and four are opacity animations, and show that animations that change opacity never fail when run multiple times.

I'm sure one suggestion will be to recreate the animation each time.  However, in my real-world app, I capture some object properties at the time the animation is created, and need to have these same values used each time the animation runs.  If I were to grab the properties over each time I recreated the animation, the object might be in a different state.  And I don't want to cache the initial values, because 1) it makes my animation library less flexible, and 2) I just want to do it this way, 'cause it's easier :).

I've added my code after the sample app.  If anyone has any idea what I can do to prevent this while still creating the animations programmatically, please add a comment.

 

Here is the xaml (Page.xaml).

<UserControl x:Class="AnimationReuseTest.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
    <Grid x:Name="LayoutRoot" Background="White">
        <Rectangle x:Name="recMain" Height="54" Canvas.Top="225" Stroke="#FF000000" Margin="65,136,76,110" VerticalAlignment="Stretch" d:LayoutOverrides="Height" Fill="#FF941414" RenderTransformOrigin="0.5,0.5" Opacity="0.1" >
            <Rectangle.RenderTransform>
                <TransformGroup>
                    <ScaleTransform ScaleX="0.8" ScaleY="0.8"/>
                    <SkewTransform/>
                    <RotateTransform/>
                    <TranslateTransform/>
                </TransformGroup>
            </Rectangle.RenderTransform>
        </Rectangle>
        <Button Height="40" Margin="24,0,0,70" VerticalAlignment="Bottom" Content="Animate1-scalex" x:Name="btnAnimate1" Click="btnAnimate1_Click" Width="163" HorizontalAlignment="Left"/>
        <Button Height="40" Margin="0,0,37,70" VerticalAlignment="Bottom" Content="Animate2-scalex" x:Name="btnAnimate2" Click="btnAnimate2_Click" Width="163" HorizontalAlignment="Right"/>
        <Button Margin="24,0,0,26" VerticalAlignment="Bottom" Content="Animate3-opacity" x:Name="btnAnimate3" Click="btnAnimate3_Click" HorizontalAlignment="Left" Width="163" Height="40"/>
        <Button Height="40" Margin="0,0,37,26" VerticalAlignment="Bottom" Content="Animate4-opacity" x:Name="btnAnimate4" Click="btnAnimate4_Click" Width="163" HorizontalAlignment="Right"/>
        <TextBlock Height="124" Margin="8,8,8,0" VerticalAlignment="Top" TextWrapping="Wrap" x:Name="lblErrorMsg" FontSize="8" />
    </Grid>
</UserControl>

And here is the code (Page.xaml.vb).

Partial Public Class Page
    Inherits UserControl

    Dim s1 As New Storyboard
    Dim s2 As New Storyboard
    Dim s3 As New Storyboard
    Dim s4 As New Storyboard

    Public Sub New()
        InitializeComponent()

        'add storyboards to resources - not sure why, but I'm following examples I've seen
        LayoutRoot.Resources.Add("S1", s1)
        LayoutRoot.Resources.Add("S2", s2)
        LayoutRoot.Resources.Add("S3", s3)
        LayoutRoot.Resources.Add("S4", s4)
        'initialize the storyboard to animate the rectangle
        CreateAnimation(s1, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)")
        CreateAnimation(s2, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)")
        CreateAnimation(s3, "(UIElement.Opacity)")
        CreateAnimation(s4, "(UIElement.Opacity)")
    End Sub

    Sub CreateAnimation(ByVal s As Storyboard, ByVal Prop As String)
        'create new doubleanimation
        Dim d As New DoubleAnimation
        'set timespan to half a second
        d.Duration = New Duration(TimeSpan.FromSeconds(0.5))
        'reverse animation
        d.AutoReverse = True
        'set target to the rectangle
        Storyboard.SetTarget(d, recMain)
        'we're animating x-axis scale - other props, like (Canvas.X) will work, though
        Storyboard.SetTargetProperty(d, New PropertyPath(Prop))
        'animating from start value of to 1
        d.To = 1
        'add doubleanimation to storyboard
        s.Children.Add(d)
    End Sub

    Private Sub btnAnimate1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        'begin animation when button is clicked - we'll get the error below the second time we click the button.
        'Cannot resolve TargetProperty (UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX) on specified object.
        Try
            s1.Begin()
        Catch ex As Exception
            lblErrorMsg.text = ex.ToString
        End Try
    End Sub

    Private Sub btnAnimate2_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        'begin animation when button is clicked - we'll get the error below the second time we click the button.
        'Cannot resolve TargetProperty (UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX) on specified object.
        Try
            s2.Begin()
        Catch ex As Exception
            lblErrorMsg.text = ex.ToString
        End Try
    End Sub

    Private Sub btnAnimate3_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        'begin animation when button is clicked - we won't get an error on animating
        s3.Begin()
    End Sub

    Private Sub btnAnimate4_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        'begin animation when button is clicked - we won't get an error on animating
        s4.Begin()
    End Sub
End Class

Tags: | Posted by Admin on 5/17/2008 4:08 AM | Comments (0)

    [UPDATE]
    Solved... well, not solved, but explained.  The VB team has valid reasons for not supporting object as an extension parameter type.  The key to take away from the linked article is that, when you specify object, it means "take anything *other* than an object".

    http://blogs.msdn.com/vbteam/archive/2007/01/24/extension-methods-and-late-binding-extension-methods-part-4.aspx
    [/UPDATE]

    I'm trying to create an extension method that takes any object. It's irrelevant what I want it to do. The problem is that I can't get Extension Methods that take objects to work correctly in VB.NET. I don't have any problems with doing this in C#.

    I created a simple console app to show my issues. I have two extension methods. One takes an object, and one takes a string. The code, along with the issues I'm having, are shown in detail below.

    With a string, both methods show up in Intellisense.

    clip_image001

    With an object, the object extension method doesn't appear

    clip_image002

    However, it will compile

    clip_image003

    When running, however, an error occurs on the o.TestObjExt() line

    clip_image004

    Oh, but wait, if I run the same line from the Immediate window, it works!

    clip_image005

    So, I don't know what's happening. It seems to be a compiler issue, but I can't figure it out. Does anybody have any ideas what might be going on?

Tags: | Posted by Admin on 3/4/2008 3:08 AM | Comments (0)

Firefox and Safari seem to be destroying and recreating a Silverlight object when it's inside of a control that has its style set to "display:none".  It doesn't do this when visibility is used instead of display. 

Here's a working example.  I fire an alert in the silverlight object's onload method.  In IE, the alert doesn't pop up when you switch display back to '', but in Firefox and Safari, it does.

image
Example at airportwait.com (my demo site)

I'm sure the next question you're going to ask is why I don't just use visibility... Well, I'm using the ajax tabcontainer control, and it's using display to show/hide tabs.  More importantly, it just doesn't seem right.  It might be ok when your silverlight control is static, but I'm using javascript to initialize a photoviewer I wrote, and don't want it to have to lose the viewer's place.

Anyway, does anyone know why this is?  Is it some kind of standard to destroy objects when their parent is set to display:none?  Is there a workaround?

John

ps.  And dang it all, I thought Silverlight was the end of browser compatibility issues ;).  I could also go into why different browsers fire different silverlight events at different times (onresize, do you hear me?), but I'll leave that alone.

Tags: | Posted by Admin on 2/1/2008 3:08 AM | Comments (0)

I had a problem tonight.  I needed to install the Dotnet 3.5 Runtime onto a server in a DMZ tonight.  I had copied DotNet35FXSetup.exe from a server inside the network earlier in the day, and ran it.  The first thing it tried to do, however, was download additional install files.  Well, this server didn't have access to the internet.  Oops!

This server normally gets updates via WSUS, but my colleague found out that WSUS didn't make 3.5 available.  So...

I wracked my brain for a while before the idea of proxy servers struck me.  I thought, "wow, if I could just set up a proxy server somewhere that this server could get to, then maybe I could make this work".  Two problems: one, no other servers in the DMZ had access to the 'net, either, and two, I didn't know if there was such a thing as client-side software to set up a proxy server, especially a non-intrusive one (I didn't want to hose any machines).  First thing I did was search for proxy client software.  I found a result that did the trick.

CCProxy - Proxy Server Software for Windows
http://www.youngzsoft.net/ccproxy/proxy-server-download.htm

It basically sets up a proxy server on the client.  It's non-intrusive (no drivers, hooks, etc, that I could tell).  It installed in less that 15 seconds!

Here's a screenshot.

image

You can change the ports on which it creates the proxy.  By default, it uses 808, which was not going to work for me.

image

See, my box in the DMZ only had access to two servers, and only single ports on each.  One was a box hosting web services over port 80, and the other was a SQL server.  I installed CCProxy on the box hosting the web services, shut off the web site that was running on it (to free up port 80), and set CCProxy to listen on that port.

Once CCProxy was up and running, I pointed the box in the DMZ to it.

image

Bingo!  Internet access!  I was able to download the update and deploy our application.  This is a great example why developers should take the time to learn about infrastructure.  I can't begin to count the number of times an understanding of networks and servers saved my butt during my development efforts!

Tags: , | Posted by Admin on 12/14/2007 3:07 AM | Comments (0)

Wireless AccessI love the Kindle!  I read my first full-length book over Thanksgiving, and it was a great experience.  At first, you're aware of the device, which is a little distracting, but after a while, you forget about it completely.

The e-ink screen is amazing!  Everyone I show the screen to, whether geek or technophobe, agrees that they could read off of it.  It really does look like gray paper.  Sure, v2 could have some better contrast, or maybe even color, but v1 is perfectly fine.  As with a book, the more surrounding light you have, the better.  You can't really understand how different it is from a laptop until you see it for yourself.

Positives

  • Screen - again, e-ink is awesome!
  • Book availability - Amazon already has tons of books available, with more coming all the time.
  • Wireless - it's so convenient to have wireless built in, with no fees.  Downloading book sample chapters is great, and I subscribe to my local newspaper, so it's just there every morning!  Every once in a while, I also look something up on the web.
  • Form - with it in the included book-like insert, it looks and feels just like a book.

Negatives

  • I'd love for wireless to be controlled with something other than a switch.  It'd be nice to set it to time out, or to only be on when it's plugged in.  If you forget and leave it on, your battery life goes from weeks to a couple of days.
  • The battery cover comes off easily when in the included book-like insert, since the insert uses an indention on the battery cover to keep the device in place.  Annoying.
  • You're not going to write novels with the keyboard.
  • Newspapers and other periodicals don't include images.  To be fair, this is stated on the Amazon web site in the fine print.  Hopefully this will change one day.
  • Bibles, while usable, have limitations.  You get a chapter list as links at the top of every book in the Bible, and once you navigate to the chapter, you can't see what chapter and verse you're at.  The Kindle seems hardwired for page numbers, and that's it.
  • Expensive.  Yes, this is obvious, but it still needs to be in the list.

Bottom line

The negatives are more like nitpicks of any v1.0 device.  This device is great as-is!  If you read a lot, you owe it to yourself to investigate this device!  It is expensive, and you'd have to read a lot of books to get a decent ROI, but the convenience is worth something in and of itself.

Tags: , | Posted by admin on 11/20/2007 3:07 AM | Comments (0)

Wireless Access

Ok.  So I ordered a Kindle.  It will arrive tomorrow - I'm stoked!  I think the days of ebooks have arrived.  The coolest thing about it: it has built-in EVDO!  It doesn't cost anything... it's built into the device price.  It has the following benefits:

  • No need to ever sync to a PC.
  • Browse and buy books, magazines and newspapers direct from the device, and have them delivered in a minute.
  • Email Word docs and pics directly to the device, for only $.10 a piece.
  • Your entire library is backed up at Amazon, so you'll never lose your books, even if something goes wrong with the device.
  • Browse Wikipedia online for free.

There's so much more to this thing.  I'll try to put up a review after using it over Thanksgiving.  For now, take a look at the deets on Amazon.com.

http://www.amazon.com/gp/product/B000FI73MA/ref=sv_kinc_0/102-8150105-3212934

John

PS.  Have a great Thanksgiving!  We are blessed, and have a lot to be thankful for.

Tags: | Posted by Admin on 8/23/2007 4:06 AM | Comments (0)

Everyone knows Silverlight is an object embedded in the browser.  Therefore, it has the same nuances as other plugins like Flash.

What nuances?  Good question.

Nuance #1 - Displaying HTML over Silverlight

I added an autocomplete extender to the airport name text box at www.airportwait.com.  It worked great, except that the dropdown selections don't display over the Silverlight control on the page.  This has always been an issue with plugins, and even with select controls (thankfully, the select control issue is fixed in IE7). 

To fix it, I redesigned the page to hide the Silverlight control during airport name entry.

Nuance #2 - Silverlight object timing issues

I have a javascript method called ProcessResults that calls a method on my Silverlight object, which in turn displays the airport wait times.  I tried this:

createSilverlight();
ProcessResults();

No good. There's a certain amount of time after createSilverlight() is called when the object isn't yet available. 

So, I had to do this:

createSilverlight();
StartResultsDisplay();

function StartResultsDisplay()
{
    setTimeout("ProcessResults()", 500);
}

function ProcessResults()
{
...
}

This way, I wait half a second before beginning to display the data.  Problem solved.

Oops.  As soon as I wrote this, I remembered I could just specify an onLoad event handler for the Silverlight plugin.  I thought about deleting this part, but it's still good info if someone else is dealing with the same thing.

Silverlight.createObjectEx({
...
    },
    events: {onLoad:ProcessResults}
});

UPDATE: I changed this again.  Because the Silverlight control was immediately calling the ProcessResults method after loading, the page didn't render fully until the loading was complete.  This is because it takes a second or two to retrieve data for some airports, and during this time Silverlight "hangs" browser events. 

Now, I still use the Silverlight onload event handler, but I wait a quarter-second to give the browser time to finish rendering.

events: {onLoad:function() {setTimeout("ProcessResults()", 250)}}

Summary

Again, these aren't uncommon issues.  Still, they're the types of things that just continue to remind me that, while I love the deployment model and reach of the web, it will always be inelegant compared to smart client development!

Tags: , | Posted by admin on 8/14/2007 4:06 AM | Comments (0)

I like to think that I'm smarter than the phishers out there on the net.  However, I almost got tricked today.  I have a Roku Soundbridge for sale on Ebay.  I got this question today...

image

It's a real message received through ebay itself.  So, I did what anyone else would do.  I pasted the stores.ebay.com/W4QQZ150147339995Q url into my browser.  I got the ebay logon prompt, which was odd, since I had just logged in.  I took a look at the URL in the browser, and it was site.voila.fr!

image

I was *that* close to entering my logon details!  This random store has javascript to redirect the user to the site in France.  Very simple, yet very effective.  Hopefully, ebay will take notice and prevent javascript on the page in the future!

Tags: | Posted by admin on 8/13/2007 4:05 AM | Comments (0)

I have a separate Microsoft VirtualPC machine for each client.  I have worked with VMWare in the past, and know they do things better (performance, multiple CPUs, USB, etc), but I never thought it justified paying for VMWare Workstation.  Until now, that is... What grand feature could have made me want to switch?  16 terabyte RAM support, 40,000 CPUs, solid-state like access times?  No to all of the above.  What was it then???

VMWare 6 has multiple monitor support!!!

I can't tell you how exciting that is for me!  I'm a huge advocate of multiple monitors.  I've seen studies that show a 10% productivity increase with multiple monitors, and I absolutely believe it.  I have multiple monitors in my home office, and set them up when I have long-term client engagements.  It's always been frustrating having to revert to a single monitor with VPC.  Well, no more.  Now, with a click of a VMWare button, I have my VMWare machine using both monitors.  It really is a beautiful thing.

So far, the only problem I've had with VMWare is that the VMWare Mouse driver isn't working right.  It won't accept mouse button clicks.  Actually, it does weird stuff.  Right-clicking always pulls up the Taskbar menu.  Odd... anyway, I fixed it by going to My Computer | Manage | Device Manager, and deleting the VMWare mouse driver.  A generic one was installed in its place after a reboot, and that one seems to work OK.

One gotcha to converting VPC to VMWare
There's one gotcha when you want to convert a VPC image to VMWare.  You have to run the VMWare Converter software on an OS that is similar to the one being converted.  I run Vista on my workstation, and Server 2003 on most of my VPCs.  It failed every time I tried to run the converter on Vista, something about "Can't find guest operating system".  I just couldn't figure out why.  After finding many posts on the net where people had this problem and couldn't solve it, I finally saw on an obscure post somewhere that you had to use a server OS to convert a server OS.  So, I ran the converter on a Server 2003 VPC to convert another 2003 VPC to VMWare.  Bingo.  Problem solved!

Another tip is that the converter I ran installed VMWare 5 hardware specs on the virtual machine.  You can't use multiple monitors, however, without VMWare 6 hardware specs.  It's any easy fix.  From VMWare Workstation, choose VM | Upgrade or Change Version.  I ran it and had no issues whatsoever.

Multiple monitor software
One additional note.  If you move around to many different environments, and you use different monitor configurations, or, you use multiple monitors and want to do things like move maximized windows from one monitor to another, or set up hotkeys, etc., check out http://www.realtimesoft.com/ultramon/.  For $39.95, it's more than worth it.