Question: What data type does one use to pass a JavaScript Error object to a WinRT component?

Answer: None, actually. You cannot directly pass an Error object to native code in a component, as that object type won't be meaningful in C++. You could stringify the Error and pass it as JSON, but that's something of a pain.

What you can do instead is to source an exception in C++ (or C#), where those exceptions have known HRESULTs, because then you'll get the appropriate errors in JavaScript thanks to the projection layer. It does take a little extra time (very small) to marshal this exception across the layer boundaries, but would only matter if you end up throwing millions of exceptions per second. (I hope that's not the case!)

Here's a C++ example to generate an Access Denied (E_ACCESSDENIED) that's usable across the component boundary:

class ErrorHelper
{
    public:
        static void ThrowAccessDenied();
}

ErrorHelper::ThrowAccessDenied()
{
    throw ref new Platform::AccessDeniedException();
}

And clearly you can extend ErrorHelper to include other methods for additional errors you need to use.

Thanks to Rob Paveza for this solution.

 


UPDATE: showing code that actually works.

As a prelude to a series I’m hoping to do on file queries and file information, I just wanted to share a little snippet for making a file read-only. Although you can retrieve the current status through the StorageFile.Attributes property, it just returns an enumeration rather than a property set you can manipulate.

Changing attributes instead has to go through the StorageFile.properties property, which is a StorageItemContentProperties object. Its savePropertiesAsync method is the one you want. For this you need to create a Windows.Foundation.Collections.PropertySet object (see this previous post), populate it with the properties you need, then call savePropertiesAsync.

The specific property you need to set is “System.FileAttributes” with the value FILE_ATTRIBUTE_READONLY, which is just 1 as described for the Win32 SetFileAttributes function. The code looks like this, where I’m just working with a test.jpg in the pictures library to demonstrate:

JavaScript (you can add a completed handler if you need to take other action after savePropertiesAsync):

var key = "System.FileAttributes";
var FILE_ATTRIBUTES_READONLY = 1;
var file;
var pix = Windows.Storage.KnownFolders.picturesLibrary;
pix.getFileAsync("test.jpg").then(function (fileTemp) {
    file = fileTemp;
    return file.properties.retrievePropertiesAsync([key]);
}).done(function (props) {                
    if (props) {                    
        props[key] |= FILE_ATTRIBUTES_READONLY;
    } else {
        props = new Windows.Foundation.Collections.PropertySet();
        props.insert(key, FILE_ATTRIBUTES_READONLY);                    
    }

    file.properties.savePropertiesAsync(props);
});

 

C#:

String key = "System.FileAttributes";
UInt32 FILE_ATTRIBUTES_READONLY = 1;
var pix = Windows.Storage.KnownFolders.PicturesLibrary;

var file = await pix.GetFileAsync("test.jpg");                                
String [] retrieveList = new String [] { key };

var props = await file.Properties.RetrievePropertiesAsync(retrieveList);

if (props != null) {
    var temp = (UInt32)props[key] | FILE_ATTRIBUTES_READONLY;
    props[key] = temp;
} else {
    props = new Windows.Foundation.Collections.PropertySet();                
    props.Add(key, FILE_ATTRIBUTES_READONLY);                    
}

await file.Properties.SavePropertiesAsync(props);

In WinRT, a number of APIs return a Windows.Foundation.Collections.PropertySet object. Two examples are the localSettings and roamingSettings objects within Windows.Storage.ApplicationData.current, whose values propert is a PropertySet.

In JavaScript, doing a simple for…in iteration on a PropertySet will give you not only the properties in that set, but also its methods, which is often unexpected. For example, the following code:

var ls = Windows.Storage.ApplicationData.current.localSettings;
ls.values["property1"] = "value1";
ls.values["property2"] = "value2";
ls.values["property3"] = "value3";

for (var key in ls.values) {
    console.log("values[" + key + "] = " + ls.values[key]);
}

will not only output "values[property1] = value1" for each of the three values, but will also give you stuff like:

values[addEventListener] =
function addEventListener() {
    [native code]
}

This comes as a result of how the PropertySet is projected from WinRT into JavaScript. It sort of works like an array, but not really, so you get this kind of behavior.

Seeing this, one option is to use the iteration methods of the PropertySet, meaning to call its first method to obtain an iterator, then using the iterator's cumbersome current/moveNext semantics. This isn't particularly enjoyable code to write in my mind.

Fortunately, there's an easier way, which Luke Hoban provided based on an old blog post by Douglas Crockford, http://yuiblog.com/blog/2006/09/26/for-in-intrigue/, in which he points out that for…in includes all the keys in an object's prototype and not just those in the object itself. To prevent this, you have to use the hasOwnProperty method to check where the property is coming from. So this modification of the code above will produce the expected output:

for (var key in ls.values) {
    if (ls.values.hasOwnProperty(key)) {
        console.log("values[" + key + "] = " + ls.values[key]);
    }
}

Better still, in Windows Store apps we can rely on the more intelligent behavior of EcmaScript 5's forEach iterator, and just do the following:

Object.keys(ls.values).forEach(function (key) {
    console.log("values[" + key + "] = " + ls.values[key]);
});

This produces the same results with a simpler construct.


Thanks to my associate Tonu Vanatalu for this. He wrote it in response to some brainstorming we did in my larger team about common code patterns in Windows Store apps. It's written in C#, but it just uses WinRT APIs so I trust that JavaScript devs can translate the casing and insert fully-qualified identifiers where needed:

public App()
{
    // Set initial behavior based on connectivity
    SetDataConnectivityOptions();

    // Set up handler for network status change
    NetworkInformation.NetworkStatusChanged += NetworkInformation_NetworkStatusChanged;
}

void NetworkInformation_NetworkStatusChanged(object sender)
{
    // Set behavior based on connectivity status
    SetDataConnectivityOptions();
}

void SetDataConnectivityOptions()
{
    // Get connection profile for currently active connection
    ConnectionProfile profile = NetworkInformation.GetInternetConnectionProfile();

    if (profile != null)
    {
        NetworkConnectivityLevel connectivityLevel = profile.GetNetworkConnectivityLevel();
        if (connectivityLevel == NetworkConnectivityLevel.InternetAccess)
        {
            // Get connection cost associated with the profile
            ConnectionCost cost = profile.GetConnectionCost();

            // Check if there is limit imposed on maximum transfer size
            DataPlanStatus dataplanStatus = profile.GetDataPlanStatus();

            if (dataplanStatus.MaxTransferSizeInMegabytes != null)
            {
                // Maximum transfer size is limited
                // Suspend transfers exceeding the size and warn the user
            }

            switch (cost.NetworkCostType)
            {
                case NetworkCostType.Fixed:
                    // The use of this connection is unrestricted up to a specific limit.
                    if (cost.Roaming == true)
                    {
                        // Even if the cost is fixed up to a limit the user is roaming
                        // Which means the limit might be relatively low and cost per byte expensive
                    }

                    if (cost.ApproachingDataLimit == true)
                    {
                        // The connection is approaching it's unrestricted limit
                    }

                    if (cost.OverDataLimit == true)
                    {
                        // The connection is over the data limit, possibly either connectivity
                        // is severely limited or very costly
                    }

                    break;

                case NetworkCostType.Unknown:
                    // Cost information is not available
                    break;

                case NetworkCostType.Unrestricted:
                   
// The connection is unlimited and has unrestricted usage charges 
                    // and capacity constraints.
                   
break;

                case NetworkCostType.Variable:
                    // The connection is costed on a per-byte basis.
                    if (cost.Roaming == true)
                    {
                        // User is roaming, possibly on a very expensive network
                    }
                    break;
            }
        }
        else
        {
            // Limited network access
            switch (connectivityLevel)
            {
                case NetworkConnectivityLevel.ConstrainedInternetAccess:
                    // This value indicates captive portal connectivity, where local
                    // access to a web portal is provided, but access to the Internet
                    // requires that specific credentials are provided via the portal.
                    break;

                case NetworkConnectivityLevel.LocalAccess:
                    // Local access only
                    break;

                case NetworkConnectivityLevel.None:
                    // No network access
                    break;
            }
        }
    }
    else
    {
        // Currently there are no network connections
        // Suspend pending network operations until network becomes available
    }
}

 


Even though this capability does not exist in WinRT directly, it is possible to determine the processor architecture at runtime through the Win32 API, GetNativeSystemInfo. This API is included in the list of Win32 APIs that can be called from Windows Store apps (see the system page specifically). You can call this directly from a C++ app, of course, and from C# or Visual Basic you can use PInvoke as described on this MSDN forum thread.

To use the API from JavaScript, as with any other Win32 API, you'll need to create a WinRT component wrapper. I show how to do this in Chapter 16 of my book, with the resulting DLL/WinMD being small. The short of it is that within your JavaScript app project, right click the solution in Visual Studio and select Add > New Project… then choose Visual C++ on the left and Windows Runtime Component in the middle. Call it SysInfo for lack of a better name.

In pch.h, add this line:

#include <Windows.h>

In the component's header (.h) file, define a method like this:

namespace SysInfo
{
    public ref class Info sealed
    {
    public:
        Info();
        static Platform::String^ GetProcessorArchitecture();
    };
}

 

Here's the implementation of the class in the .cpp file:

#include "pch.h"
#include "Info.h"

using namespace SysInfo;
using namespace Platform;

Info::Info()
{
}

String^ Info::GetProcessorArchitecture(void)
{
    SYSTEM_INFO sysInfo;
    String^ str;

    GetNativeSystemInfo(&sysInfo);

    switch (sysInfo.wProcessorArchitecture)
    {
        case PROCESSOR_ARCHITECTURE_AMD64:
            str = "x64"; //AMD or Intel
           
break;

        case PROCESSOR_ARCHITECTURE_ARM:
            str = "ARM";
            break;

        case PROCESSOR_ARCHITECTURE_IA64:
            str = "IA64";
            break;

        case PROCESSOR_ARCHITECTURE_INTEL:
            str = "x86";
            break;

        default:
            str = "Unknown";
            break;
    }

return str;
}

 

To use the component from JavaScript, right click the JS project in Visual Studio and select Add Reference…. In that dialog select Solution on the left and the component name in the middle. Then you can use this line and do what you want with the resulting string.

var arch = SysInfo.Info.getProcessorArchitecture();

You could also return numeric codes from the C++ component, of course…your choice.

 


In the Here My Am! app of my book, one problem I didn't get around to solving was scaling of captured images to fit the display area. Typically this isn't a problem when you capture an image large enough for that area, but when you have a low-res camera (or a high-res camera set to a low res output), or when you change view states, the image can become distorted.

As I'm working through the book now for a  second edition, I fixed this particular problem in Chapter 2's version of the app, and fortunately the solution turns out to be pretty simple. The trick is to first wrap the img element in a div where that div contains a 1×1 CSS grid. The img element, as a child, is then centered within that cell. So in default.html I replaced the <img> element line with these:

<div id="photo" class="graphic">
   
<img id="photoImg" src="#" alt="Tap to capture image from camera" role="img" />
</div>

And added these bits to default.css:

#photo {
    display: -ms-grid;
    -ms-grid-columns: 1fr;
    -ms-grid-rows: 1fr;
}

#photoImg {
    -ms-grid-column-align: center;
    -ms-grid-row-align: center;
}

Within photoImg, then, we can style that element to be 100% width or 100% height depending on whether the picture's aspect ration is greater than or smaller than the parent div, photo. The original image size can be easily obtained from StorageFile.properties.getImagePropertiesAsync. So in this added function, imgElement is photoImg, parentDiv is photo, and file is the captured StorageFile object:

function scaleImageToFit(imgElement, parentDiv, file) {
    file.properties.getImagePropertiesAsync().done(function (props) {
        var scaleToWidth = (props.width / props.height > parentDiv.clientWidth / parentDiv.clientHeight);
        imgElement.style.width = scaleToWidth ? "100%" : "";
        imgElement.style.height = scaleToWidth ? "" : "100%";
   
}, function (e) {
        console.log("getImageProperties error: " + e.message);
    });
}

I then call this function from within the completed handler of captureUI.captureFileAsync, after setting the img.src URI. I also have a window.onresize handler to call this again with the most recently captured file, which handles scaling the image again for new view states.

With this approach, specifically centering the image in the parent div's one grid cell, we get automatic letterboxing around the image.

I believe it would also be possible to solve this with a WinJS FlexBox control, which effectively does the same thing. I don't think it would mean any less code, however. The solution here, of course, depends on the WinRT APIs and having a StorageFile object. For use with pure HTML/CSS, you can create a new Image and assign its src, and once loaded that object's width and height properties will be available. When you have those values, you can then use the same calculation as above to scale the image without changing the aspect ratio.

 

 


If you look around within the WinJS source code files, you'll see a curious structure for commenting functions. For example, here's what we see for WinJS.Namespace.define:

function define(name, members) {
    /// <signature helpKeyword="WinJS.Namespace.define">
    /// <summary locid="WinJS.Namespace.define">
   
/// Defines a new namespace with the specified name.
    /// </summary>
    /// <param name="name" type="String" locid="WinJS.Namespace.define_p:name">
    /// The name of the namespace. This could be a dot-separated name for nested namespaces.
    /// </param>
    /// <param name="members" type="Object" locid="WinJS.Namespace.define_p:members">
    /// The members of the new namespace.
    /// </param>
    /// <returns type="Object" locid="WinJS.Namespace.define_returnValue">
   
/// The newly-defined namespace.
   
/// </returns>
   
/// </signature>
   
return defineWithParent(global, name, members);
}

On first glance, you'll wonder why someone wrote comments like this that are somewhat hard to read. But there is a real purpose: they are what provide IntelliSense data to Visual Studio. That is, because IntelliSense provides you with immediate, in-line documentation when you start writing code, there's no need for you to look at the source code for functions that you're consuming to understand how they work. That is, when you type out WinJS.Namespace. and highlight define, you'll see this pop up:

Intellisense comments 1b

When you continue to enter in define, IntelliSense will pop up the details of the function–you can see that all this information is coming straight from those code comments:

Intellisense comments 2b

There is nothing special about WinJS' use of these kinds of comments: you can use them in your own code to provide IntelliSense for your own functions. The documentation for doing this is on JavaScript IntelliSense (the overview) and XML Documentation Comments (the details). Here's a simple example with a function that doesn't actually do anything meaningful:

function myFunction(item, identifier, options) {
    /// <signature helpKeyword="MyNamespace.myFunction">
    /// <summary locid="MyNamespace.myFunction">
    /// Does some nifty stuff with the parameters you provide.
    /// </summary>
    /// <param name="item" type="Object" locid="MyNamespace.myFunction_p:item">
    /// The object to process.
    /// </param>
    /// <param name="identifier" type="String" locid="MyNamespace.myFunction_p:identifier">
    /// Another parameter that I just made up.
    /// </param>
    /// <param name="options" type="Object" locid="MyNamespace.myFunction_p:options">
    /// A fine ubiquitous catch-all parameter.
    /// </param>
    /// <returns type="Object" locid="MyNamespace.myFunction_returnValue">
    /// Whatever it is we emit from this function.
    /// </returns>
    /// </signature>
    item.identifier = identifier;
    item.options = options;
    return item;
}

Now when you start typing out myFunction(, you'll see this:

Intellisense comments 3

As you enter each parameter, the bold highlight in the first line will change and the description at the bottom will update as well.

The other piece to this story is that if you're working in another .js file and referencing functions in another, you'll want to add a reference comment at the top to those other files:

/// <reference path="ScriptFile1.js" />

This is what tells Visual Studio to scan that other file and extract those IntelliSense comments from it. You'll see this at the top of the WinJS file ui.js, in fact:

/// <reference path="ms-appx://Microsoft.WinJS.1.0/js/base.js" />
/// <reference path="ms-appx://Microsoft.WinJS.1.0/js/ui.js" />

 


It occasionally comes up that you need to serially iterate over a synchronous collection, but doing so involves async APIs. For example, you have a vector of StorageFile objects and want to call copyAsync on each of them, one at a time, in the order of the vector.

This can be accomplished with the following code (thanks to Adam Comella for this solution). Assuming that storageItems is the list over which you want to iterate and destination is the folder into which you want to copy those items, you can do this:

var storageItemsPromise = WinJS.Promise.as();
storageItems.forEach(function (item) {
     storageItemsPromise = storageItemsPromise.then(function () {
         return item.CopyAsync(destination);
     });
});
// Call done so that if CopyAsync throws an exception, it'll cause the app to terminate
storageItemsPromise.done();


Apps written in JavaScript occasionally need to obtain a UUID/GUID for one reason or another, so the question comes up: how to generate one?

One method is to just fabricate thestructureof a GUID with random numbers:

'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    var r = Math.random()*16|0, v = c == < 'x' ? r : (r&0×3|0×8);
    return v.toString(16);
});

The problem here is that uniqueness is not guaranteed. If you're just using the identifier for some internal purpose, this method could work, but if you're taking that GUID anywhere outside of your app, you run a possibility of collision with a properly-generated GUID.

The robust method is to use the Win32 CoGreateGuid() API that creates a GUID that is guaranteed to be unique. For this you need to write a small WinRT component as a wrapper, which, as I showed in Chapter 16 of my book, is actually quite easy and the resulting component (DLL/WinMD) is quite small. So while some have considered this a "heavyweight" solution, it's actually not that heavy. Do note that CoCreateGuid, as a COM API, takes a little work to translate its result into a WinRT string (see this thread and this thread).

The same can be done through a C#/VB component with its NewGuid method, where the component would look like this:

public sealed class GuidProvider
{
    public static String GetGuid()
    {

        Guid g = Guid.NewGuid();
        return g.ToString();
    }
}

The caveat with this, as I describe here, is that for even such a simple C# component, you'll be pulling in the .NET runtime into your process, which significantly increases the memory overhead at runtime. So in the end, it's better to use C++ for this purpose.

 


Thanks to my teammate Kyle Marsh for this one:

var freeSpaceProperty = "System.FreeSpace";
var applicationData = Windows.Storage.ApplicationData.current;
var localFolder = applicationData.localFolder;

localFolder.getBasicPropertiesAsync().then(function (basicProperties) {
    // Get extra properties
    return basicProperties.retrievePropertiesAsync([freeSpaceProperty]);
}).done(function (extraProperties) {
    var propValue = extraProperties[freeSpaceProperty];
    if (propValue !== null) {
        outputDiv.innerText = "Free Space: " + propValue;
}
}, function (error) {
    // Handle errors encountered while retrieving properties
});