One way to find all Metro/Windows 8 Modern UI applications in C#

Running this code as an administrator, you can use the following snippet as a method for determining the nature of a process on Windows 8 and whether it would seem that the running process is running in the new Modern UI shell (metro).

static void Main(string[] args)
{            
    var allProcesses = Process.GetProcesses().Where(p =>
    {
        try
        {
            var pid = p.Id;
            var modules = p.Modules.Cast<ProcessModule>()
                .Where(m => m.FileName.Contains("System.Runtime.WindowsRuntime"));
            return modules.Count() > 0;
        }
        catch { return false; }
    }).OrderBy(p => p.MainModule.FileName).ToList();
    
    for (int i = 0; i < allProcesses.Count(); i++)
    {
        var p = allProcesses[i];
        Console.WriteLine(string.Format("{0}. {1}", i, p.MainModule.FileName));
    }
    Console.ReadKey();
}

Modern UI / Metro applications are protected and cannot be easily interrogated by a non-administrative process. While you can get some basics about all processes, a standard user process isn’t allowed to look at the loaded modules for example.

In the code above, all processes are scanned for a particular DLL. In this case, System.Runtime.WindowsRuntime. I’m not 100% confident this is the best choice … there may be a few better options (or multiple that are required). (If you know of them, please leave a comment!). It did find the Modern UI / Metro applications running in my Windows 8 VM.

Once gathered, the code just outputs the basics to the console. (The name of the host, which is WWAHost.exe apparently some times).

Next step is to learn something useful via the process object.

Forcing IE to run as IE9 with embedded web browser

If you embed IE in a windows application, you may notice that it runs in IE7 Emulated mode. This is likely NOT what you want.

I’ve added code like below to solve the problem:

string appName = ""; try { appName = Path.GetFileName(Assembly.GetEntryAssembly().Location);

const string IE_EMULATION = @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION";

using (var fbeKey = Registry.CurrentUser.OpenSubKey(IE_EMULATION, true))

{ 

fbeKey.SetValue(appName, 9000, RegistryValueKind.DWord);

}
}

catch(Exception ex) { MessageBox.Show(appName + "\n" + ex.ToString(), "Unexpected error setting browser mode!"); }

There’s a special registry key that must be set before IE9 loads and is navigated … it must be set to the name of your application. Oddly, not the full path to your application, just the name of your executable.

You may want to delete this registry setting when your application exits.

How to mask an image in HTML/CSS

Until browsers all agree on a technique for masking an image in HTML (like –web-kit-mask-image), I’ve got another option: using SVG.

image

I’m creating a single page application to help sell some electronics and other goodies I’ve collected over the years. Rather than the traditional rectangular display of photos, I wanted to try something different. I wanted the photos to be round. However, I didn’t want to create a bunch of round images.

Enter SVG:

<svg width="220" height="220">
<mask id="m1"><ellipse cx="110" cy="110" rx="98" ry="98" style="fill:white;stroke-width:0;fill-opacity: 1.0"></ellipse></mask>
<g>
<ellipse cx="110" cy="110" rx="100" ry="100" style="stroke-width:10;stroke:#222"></ellipse>
<image href="img/sales/lenovo/IMG_0468.jpg" x="-25%" y="-25%" height="150%" width="150%" style="mask: url(#m1)"></image></g></svg>

The original images aren’t square, so I tweaked the size and position of each so that it would completely fill the ellipse (150% and -25% for size and location).  As a fall back, I’m going to add the CSS property and value “display:none” to a standard HTML img element that will be optionally displayed if the browser can’t do SVG (like IE8 and lower for example). I don’t want to lose a potential sale to images not showing up! I’ll use modernizr for SVG detection.

And although the code above doesn’t demonstrate the technique, you can use CSS to decorate the SVG. Check this demo out that I created:

image

image

image

Announcing Html Grabber v3 (The Spy Who Loved Embedded Internet Explorer)

It’s been a long time since v2 of the Html Grabber.

I updated the Html Grabber earlier this year in response to some requests at work. It was performing poorly with long documents, and occasionally crashing in a few edge cases. I rewrote a few portions of the core code and created a new shell in .NET.

SNAGHTML120a4bae

The core functionality is basically the same. Press and hold the primary mouse button on the image button. Then, with the mouse button still pressed, drag and point at a window/region that you believe is using Internet Explorer. If it is, the cursor changes to include a small green circle. You may then release the mouse button to capture the contained HTML.

SNAGHTML120cc9e2

Once captured, double-click on the capture row and then paste the results into your favorite text editor (ideally, a syntax highlighting editor).

As usual, use at your own risk. It’s designed for debugging, so treat it accordingly. It’s been tested with IE8 and IE9. It requires .NET 4.0. 

Download it here. (Yes, the file name is called v2 … don’t worry, it’s correct). There’s no installer, just run the included EXE.

WinRT/Xaml/AKA Metro DataTemplate selection based on Data Types

You may have noticed that WinRT does not have automatic resolution of a DataTemplate based on the data type of object added to an ItemsControl. While unfortunate as this behavior is quite handy, it’s not too difficult to replicate the functionality using a DataTemplateSelector.

WPF for example, could do something like this:

<DataTemplate DataType="{x:Type local:Task}">
<StackPanel>
<TextBlock Text="{Binding Path=TaskName}" />
<TextBlock Text="{Binding Path=Description}"/>
<TextBlock Text="{Binding Path=Priority}"/>
</StackPanel>
</DataTemplate>

When the Task type as shown above was found in a list, it would have been rendered as a StackPanel with three TextBlocks automatically. That rocked.

WinRT (Metro/Xaml, Windows 8 applications) are missing the DataType property of DataTemplates. Yes, some of you might say it’s not missing as it’s V1, but given the heritage of Windows 8 Xaml applications, I consider it missing.

While an exact duplicate of the functionality isn’t possible, it’s relatively simple to get close.

<GridView
    x:Name="itemGridView"
    ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
    ItemTemplateSelector="{StaticResource typedTemplateSelector}"
    SelectionMode="None"
    IsItemClickEnabled="True">

Take the GridView above for example (using the template project in Visual Studio 2012).

I’ve assigned the ItemTemplateSelector to an instance of the TypedTemplateSelector class I’ve created.

In the Resources for the Page, I added a custom DataTemplate:

image

I’ve added a DataTemplate with a Key called Type : SampleDataItem (without the spaces though – they’re auto converted by my WordPress theme to a squiggle face: Confused smile).

There’s nothing special about the Template, just the name. It must start with Type:.

Here the custom template selector is being constructed in the Resources:

    <local:TypedTemplateSelector x:Key="typedTemplateSelector"
                                 DefaultTemplateKey="Standard250x250ItemTemplate" />
</Page.Resources>

Here’s the class that you’d need below. It has a caching feature (IsCacheEnabled) to prevent the search from occurring more than once for a key. It’s set to True by default. When used, the object searches from the current Item through all Parents trying to match the type of the object (via the VisualTreeHelper). Only the ClassName is used as programmed below (and not the full namespace). You could easily change this behavior by removing the Split and Last calls.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace WiredPrairie.TemplateSelector
{
    public class TypedTemplateSelector : DataTemplateSelector
    {
        private Dictionary<string, DataTemplate> _cachedDataTemplates;

        /// <summary>
        /// Fallback value for DataTemplate
        /// </summary>
        public string DefaultTemplateKey { get; set; }

        /// <summary>
        /// Cache search results for a type (defaults to Enabled)
        /// </summary>
        public bool IsCacheEnabled { get; set; }

        public TypedTemplateSelector()
        {
            IsCacheEnabled = true;
        }

        protected override Windows.UI.Xaml.DataTemplate SelectTemplateCore(object item, Windows.UI.Xaml.DependencyObject container)
        {
            // grab the Type name. Type will be searched as Type:NAME as shown below
            /*
                <DataTemplate x:Key="Type:SampleDataItem">
                    <Grid HorizontalAlignment="Left" Width="250" Height="250">
                        <TextBlock Text="{Binding Title}" />
                    </Grid>
                </DataTemplate>
             */
            string key = item != null ? string.Format("Type:{0}", item.GetType().Name.Split('.').Last()) : DefaultTemplateKey;
            DataTemplate dt = GetCachedDataTemplate(key);
            try
            {
                if (dt != null) { return dt; }

                // look at all parents (visual parents)
                FrameworkElement fe = container as FrameworkElement;
                while (fe != null)
                {
                    dt = FindTemplate(fe, key);
                    if (dt != null) { return dt; }
                    // if you were to just look at logical parents,
                    // you'd find that there isn't a Parent for Items set
                    fe = VisualTreeHelper.GetParent(fe) as FrameworkElement;
                }

                dt = FindTemplate(null, key);
                return dt;
            }
            finally
            {
                if (dt != null)
                {
                    AddCachedDataTemplate(key, dt);
                }
            }
        }

        private DataTemplate GetCachedDataTemplate(string key)
        {
            if (!IsCacheEnabled) { return null; }
            VerifyCachedDataTemplateStorage();
            if (_cachedDataTemplates.ContainsKey(key))
            {
                return _cachedDataTemplates[key];
            }

            return null;
        }

        private void AddCachedDataTemplate(string key, DataTemplate dt)
        {
            if (!IsCacheEnabled) { return; }
            VerifyCachedDataTemplateStorage();
            _cachedDataTemplates[key] = dt;
        }

        /// <summary>
        /// Delay creates storage
        /// </summary>
        private void VerifyCachedDataTemplateStorage()
        {
            if (_cachedDataTemplates == null)
            {
                _cachedDataTemplates = new Dictionary<string, DataTemplate>();
            }

        }

        /// <summary>
        /// Returns a template
        /// </summary>
        /// <param name="source">Pass null to search entire app</param>
        /// <param name="key"></param>
        /// <returns></returns>
        private static DataTemplate FindTemplate(object source, string key)
        {
            var fe = source as FrameworkElement;
            object obj;
            ResourceDictionary rd = fe != null ? fe.Resources : App.Current.Resources;
            if (rd.TryGetValue(key, out obj))
            {
                DataTemplate dt = obj as DataTemplate;
                if (dt != null)
                {
                    return dt;
                }
            }
            return null;

        }
    }
}