thanks to all who came out to the denver devdays big event this week.  this was the first time i've traveled in a while since various family ailments and situations.  i had a good few days in denver with some good peeps.  thanks to beth massi for joining our developer crowd in denver.  she was awesome and had a crowd wherever she was.

i attempted to do justice to office development in one of the sessions.  one of the challenges on that topic is that 'office' now encompasses a lot of things...here's my known short list:

    • word, excel, access, outlook, onenote, infopath, powerpoint
    • smart tags
    • sharepoint
    • communicator
    • excel server
    • workflow
    • groove

so when you have an hour for a developer session, which do you pick.  i chose to pick the office client applications and demonstrate how visual studio 2008 enables writing office client applications easier than ever.  i chose this because doing office client development in the past (even with 2005) wasn't really a no-brainer.  there were still a lot of configurations as well as still some things you couldn't do.  with office 2007 and vs2008, it is a no-brainer now.  vs2008 (professional+) now comes with the office tools built-in...no more needing to download a separate client (or pay for a separate tool).

in my session i attempted to cover four key areas (only three of which we got to).  i wanted to demonstrate the UI customization features, outlook form regions, word content controls and task/action pane development.  the slides for my presentation are at the end of this post (PPT 2007 and PDF) and as promised there is an appendix in there with some information we didn't get to.  the two most important links in the slides are the ones to the Office MsoId sheet and the OfficeImageId worksheet (which you need the developer options to be enabled in Excel to see the gallery options).  get these files.  download.  save.  you'll need them.  and when you can't find them you'll need a mt. dew (or scotch or whatever your calming choice is).  don't ask me why the MsoId's are not enabled in the designers of the office components...i've asked and don't know.

the first thing we covered was the office ui customization.  vs2008 provides a new visual designer for the ribbon.  you can still do the RibbonXML if you're insane you want to.  as we demonstrated, almost everything can be accomplished in the ribbon designer.  intercepting commands (such as FileSave) is something you'd need to much with the RibbonXML for and the designer provides an 'export to ribbon xml' feature so you can do most of it visually.  vs2008 provides a great design-time experience as it provides a ribbon as the design-time experience.  most everything after that is choosing which tab (custom or built-in using one of the idMso values from the worksheet), and adding controls.

this capability enables a rapid development timeline of creating customized ui features that are familiar to your users and integrate with your own application.  i demonstrated my flickr add-in which i install on the TabInsert area of office applications:

in outlook development, vs2008 has made this easier now.  we can now extend the default outlook message class UI implementations (i.e., IPM.Contact, IPM.Appointment, etc.) through designers in visual studio.  the tool enables us to choose how we want our customizations to be as well (replacements, adjoining, etc.).  the image below is the adjoining one we created with integrating virtual earth into the contact form to pinpoint in the contact form the address of the selected contact:

when writing outlook form regions (and as we saw in all other areas as well), the development isn't 'office-ish' at all.  once you've decided where/how the form region is going to interact, now you are just writing managed code.  you can integrate with wcf services, use linq, whatever...it is the same .net framework you know and love.  the office api's are now exposed to you to interact with as well.  as an example, anything in the contact item is easily and readily accessible to the developer to use and/or alter.  the same goes for word, excel, etc.

the last area was the task/action panes.  to clarify the terms:

    • task pane: an implementation of a pane that is application-wide -- every document will be able to use the pane
    • actions pane: document-specific panes that are a part of a document/template but not installed as add-in to the global

the distinction between these two is pretty much at that level above.  there are some subtle differences, but for the most part that is the major difference you need to know.  the panes are implemented as user controls for your app/doc add-in now.  so as a developer you now have a user control surface where you can add controls, interact with the document to get values, etc.  to add your custom pane you would write code like this (using excel as an example and a task pane):

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
      CustomTaskPane ctp = this.CustomTaskPanes.Add(new UserControl1(), "Pane Title");
      ctp.Visible = true;
      ctp.Width = 250;
}

the UserControl1 would be whatever your user control representing the task pane you want to display.  remember, that each add-in has that "ThisAddIn" stub generated for you.  there can be multiple task panes for an app/document.  so if you need more you can go nuts.  but i'd be sure you take into account the user experience and ensure that you aren't crowding the main focus of the functionality (the document) for the user.  panes are dockable through the DockPosition property.  if i wanted my pane to be docked on the bottom i could use:

ctp.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionBottom;

but one thing to keep in mind is other properties.  for example, if i added the line above to my initial code and had the width property, i'd get an exception.  i'm trying to set a width when a bottom-docked item fills the user's width -- no can do.  of course i should probably implement better checking and simply handle that scenario.

the action panes are no different (other than how they are added is via a different class instead of CustomTaskPane) and simply are scoped to the document.  both are implemented as user controls and you can put windows controls on there and interact in code however you want.  in fact we demonstrated how we could implement XAML into a task pane.  here's a screen shot of the task pane with a XAML rectangle (which animates, but hey, it's a screenshot) and an embedded media element of a video.  you could think of documents that might be handbooks/trainings and include video with it so as the reader (or form-filler-outer) is looking at the document they might get live help via video:

i didn't get to the word content controls in my session, apologies.  we also didn't talk about sharepoint development, etc.  i think you could spend a whole time on that.  you tell me, what concerns you about sharepoint development?

i mentioned a few developer tips as well that i'll emit here:

    • remember 'Globals'
    • create a stub mail profile (control panel -- Mail) so when writing outlook applications you aren't constantly trying to connect with a real mail system.
    • click the 'office circle' and go to application options, add-ins, manage com add-ins to remove/clean up your developer litter

here are the slide decks: PPT 2007 and PDF

i hope that those who attended learned at least one thing new.  some of my demos weren't cooperating despite me staying up until 3am doing them three times.  such is life.  thanks again to those who came.  be sure to check out beth's post as she used VB XML literals to leverage Office Open XML to write a mail merge in XML code which generate word documents...it was pretty slick.

i hadn't been on a plane in a while and the second i stepped on i realized how much i hate it :-).  but denver was going to be a refreshing stop -- cooler weather and seeing some friends on my team.  so rob and i headed out on wednesday.  i didn't even know we were landing until we hit the ground it was that white outside the windows.  needless to say, despite going to school in constant snow, i'm reminded how much i suck at bad weather driving.  i think i made rob flinch a few times on the way from the airport.

Sam's No 3 Heart attack sam

we made it safely and met up with jd for dinner.  i have to tell this story because it cracked me up.  jd decided he was in the mood for fried chicken.  okay.  good.  all i need.  i've lost 20 pounds since the beginning of december and was dreading this trip for the food (i eat like crap on expense accounts).  jd had picked this place that he said was famous for their fried chicken.  off we went to sam's no. 3 in aurora.  in the snow.  we saved the donut driving until the parking lot though.  we got their fine.  needless to say the fried chicken was not the featured item on the menu.  jd opted for the papa's...whatever...#21 the waitress said.  i asked her if i never came back here again what should i try.  she opted to order me the sourdough meatloaf sandwich with ranch, cheddar, and bbq sauce.  yeah, it sounds nasty but it actually worked.  rob got the fried chicken :-)...he said it wasn't that great.  jd's breakfast burrito was about the size of 2 axe handles.  i'm not sure it is even in the classification of a burrito to be honest.  jd took that down like he was going to lose a contest to kobayashi.  impressive. 

the next day we were all doing an event for microsoft so we hit it early.  well at least went to our rooms early.  i stayed up until about 3am still prepping and triple checking my demos (needless to say 2 still failed).  we had the event and i think it was a great success despite my session.

that night we were beat (and i was beaten up).  we sat in the lobby and watched 2 hours of lost and the season premiere of a show i can't even remember the name of (it wasn't too bad though).  good solid 3 hours of 'team building' -- lost was awesome.

anyhow, good to see the snow.  good to be out of the snow.  stay classy denver.  see you in march.

i've spoken a few times about axosoft.  they are a local ISV that does some great work.  their ceo, hamid, does a great thing every year for his employees (maybe more often) in encouraging and icubating new projects.  they have a core product, but also have incubated some great ideas.  some haven't lasted, but some live strong!  either way it is great to see what kind of ideas their group comes up with.

PureChat is one of those new ideas.  this is an idea that was just released.  it is for asp.net sites and is built using c# and asp.net ajax as well as the ajaxcontroltoolkit.  one of the developers, jonas, writes:

PureChat is written entirely with C# and javascript, against the 2.0 .NET framework. It uses Microsoft's ASP.Net AJAX, as well as selected controls from the AJAX Control Toolkit. Before I go any further, I just want to say that the Atlas (I think I'll always call it Atlas, it's shorter and sounds better) javascript framework really adds a lot of value and productivity for doing any sort of extensive work in javascript. Major kudos go out to that team at Microsoft. (emphasis mine)

very cool.  i just downloaded the free single operator key (this means operator, not incoming chatters) and installed onto my site in < 10 minutes.  i can't get it to play nice with subtext right now, but i'm going to see if the subtext list can help me out (httphandler collision and all).  as an operator i get a complete operator panel that gives me:

    • view of all chats
    • access to transcripts of chats
    • abandoned chats
    • multiple chats

it looks like this:

the end user gets a chat window they communicate with which looks like...well, a chat window.  what's cool is there is nothing for the user to install, and this runs in the browser using asp.net ajax technology.  i was really glad to see jonas' comment about how that framework enabled a lot of things a lot easier for him...that is good to hear.

so if you want to enable web-based chat on your site, you can get a free single operator license or right now they are doing a promotion for $5 for a 5-operator license.  this would be great if you need to provide online customer service in your site/application.  i don't think the intent is to put it on a blog (personal) or anything...at least i don't think that would be a good scenario for me i should say.  the operator has to be logged in.  but for scenarios where you have a product and customers, it would be a good thing to quickly add to your site (or product) and be able to directly communicate with your users.

good work axosoft...i can't wait to hear some behind-the-scenes stories on how it was to leverage the ajax framework for asp.net!  maybe they can add a silverlight UI at some point :-)

while preparing for the code trip, we have several 'on-board' needs.  one of which is a quick method to get our content encoded for consumption by devices and frameworks (i.e., silverlight).  we want a smooth method so that we aren't boggled down with multiple tools opening and changing settings, cutting and pasting, etc.

so, inspired by my colleagues post about using workflow to automate, i set about the task.  we're going to be making several assumptions along our production, one of which is we know we'll have multiple video/audio sources and that there *will* be some post-edit being done.  but once we have that post edit completed, we'll want all videos to feel similar (size, quality, etc.) and encoded for multiple uses.  i've pretty much decided that there really are 3 formats that would suffice the world: WMV, MP4, MP3.  if we get all of these, we can accommodate most.  here's how i justify that:

    • WMV: we'll have standard (4:3) and widescreen (16:9) format for viewing offline as well as online via silverlight (we'll be using the widescreen online most likely).  we'll also have a Zune formatted version for quick updating.
    • MP4: itunes, ipod, mac viewing in both standard and widescreen formats
    • MP3: audio format beloved by all

so the first step is to tackle the how.  if you don't know, expression encoder has a command-line interface.  this is especially helpful for a few things, namely our batch processing (you can also save job files and send in a job to the command-line interface quickly).  so the first thing i did was wrap the input parameters into a windows workflow foundation activity.  luckily michael did a lot of this for me in his webcast :-).  it basically abstracts all the possible input parameters and enables you to optionally send them into the activity:

for the mp4 encoding i'm using a piece of software that also has an command-line interface.  this one isn't as flexible so given my two known encoding types i'm pretty much hard-wiring in some of the settings and only enabling the size parameters for alteration.

mp3 version -- let's get to that later.

now that i have my activities (one for WMV, one for MP4) in an activity library, i'm ready for a client tool.  for our purposes, we don't need a fancy GUI tool, so i settled for a command-line interface.  in my client i added a sequential workflow and then added my activities.  i re-used the WMV activity 3 times to alter the different settings and then use the output of them to feed into my MP4 activity (used twice).  the resulting visual workflow looks like this:

the input to the command line looks for a source WMV file, title, description, author, album.  these input parameters are sent as named parameters to the workflow activity:

var namedArguments = new Dictionary<string, object>();

namedArguments.Add("SourceFilename", args[0]);
namedArguments.Add("Title", args[1]);
namedArguments.Add("Description", args[2]);
namedArguments.Add("Author", args[3]);
namedArguments.Add("Album", args[4]);

which are then mapped to properties of the activities:

the activity libraries also expose a few other properties that i'm passing in to my commands.  for example, i want each video to have a bumper intro and then an icon overlay in the right location.  i'm able to pass in these parameters which then map to expression encoder properties.  i'm also able to tell it to make sure to letterbox content that isn't native 16:9 aspect ratio for the standard format encodings.  the result of these activities is that i have three WMV files appropriate for my use.  expression encoder also generates thumbnail images of a frame in each video.  i've not much use for them, so i added the last workflow code to simply clean up the jpeg images generate (delete them) from the output directory.

one problem i had was that expression encoder exposes a lot of properties but not for metadata individually.  i wanted to embed the appropriate metadata for the WMV files for the title, description, etc.  luckily there is one input parameter for encoder that i can append to my other custom ones, and that is "/Preset" which enables me to provide certain presets that will be passed in and here is where it allows me to make metadata a part of that preset.  the input parameter looks for a literal xml file so i have to create one.  i added the template as a resource in my project:

<?xml version="1.0" encoding="utf-8"?>
<Preset>
  <MediaFiles>
    <Metadata>
          <Item
            Name="Title"
            Value="{0}" />
          <Item
            Name="Author"
            Value="{1}" />
          <Item
            Name="Copyright"
            Value="2008, Microsoft" />
          <Item
            Name="WM/MediaCredits"
            Value="{2}" />
          <Item
            Name="Description"
            Value="{3}" />
          <Item
            Name="WM/AlbumArtist"
            Value="{4}" />
          <Item
            Name="WM/AlbumTitle"
            Value="{4}" />
          <Item
            Name="WM/Genre"
            Value="Podcast" />
          <Item
            Name="WM/Year"
            Value="{5}" />
        </Metadata>
  </MediaFiles>
</Preset>

and then when the user executes the command-line interface, i take their input, merge it with the xml here and output a temporary xml file that is then passed into the named parameter dictionary for the workflow activity.  when no longer needed it is cleaned up (on the workflow completed event handler).  now my WMV file is complete with formats and metadata.

for the MP4 format i chose to use the resulting output of the WMV file and do a single pass there.  the settings for the tool weren't ideal for adding overlays, etc. so using the resulting WMV file and same bitrates i'm just passing in the resulting WMV and creating two MP4 formats.  boom.  done.  the metadata actually *was* parameters i could send into this tool, so it was easy to ensure that metadata was in there.

now, on to the MP3 format.  sigh.  what i need is a tool that will enable me an WMV or MP4 input and extract the audio-only track into an MP3 file.  i found all sorts of tools that will do this, but none that can be automated from a command-line.  this is my last resulting automation problem for now.  if anyone has tips on how to do this, i'll send you a prize :-).

now on to decisions.  while we'll have several formats to offer viewers, we also want to have feeds with enclosures for readers.  that brings us to a decision.  podcast formats for enclosures only enable one enclosure.  so, dear reader, what do we choose?  i figure we offer a WMV, MP4 and MP3 feed uniquely...but then which format do we supply?  is this a lame question?  the widescreen will be the best quality, but will it render okay on all devices/readers?  what do you choose?

anyhow, a fun little project i finished (except for the MP3 -- prize awaiting) and thought i'd share how it is accomplished.  one little command "encodepipe.exe <file> <title> <desc> <author> <album>" and a few short minutes later i have all the formats i need.  the next step is to automate upload to a content delivery network so i don't have to pick and choose uploading!

we just posted the schedule for our trip, so if you want to subscribe to the feed to be notified when we'll start putting out some content, that would be cool.  real-time updates via twitter as well.  see you on the road!

recently i've been getting a few notes/questions about working with web services and asp.net ajax.  my colleague, rob bagby completed a series of great web casts last year covering the topic of the ajax libraries in detail, one of which deals with web services.  there are also two webcasts that deal with calling WCF services using the ajax libraries.  i highly recommend checking them out!