It was 2009 when I started my first open source project and announced it with this unspectacular blog post. Back then it was developed with Visual Studio 2008 targeting Silverlight and hosted on CodePlex.
Many things have changed and tech comes and goes but during the last 10 years I always adapted, extended it, added bug fixes and reviewed/merged Pull Requests. Even after all the years WriteableBitmapEx is still quite popular, especially with Windows desktop WPF developers.
Version 1.6.2 of WriteableBitmapEx finally adds dedicated libs for UWP and an UWP sample. For WPF it now supports .NET Core, both the .NET Framework and .NET Core libs are part of the NuGet pack.
If you are using the source code and the VS solution directly, you can choose the .NET Framework 4.5 or .NET Core 3 as the target in the VS drop-down.
WriteableBitmapEx supports a variety of Windows platforms and versions.
WPF and Windows 10 Universal Windows Platform (UWP) are actively maintained.
Silverlight, Windows 8/8.1 WinRT, Windows Phone WinRT and Silverlight 7/8/8.1 are not maintained anymore but the latest stable libs are still part of the NuGet package.
You can download the latest via the updated NuGet package. The packages contain the WriteableBitmapEx binaries. All samples and the source code can be found in the GitHub repository.
A huge shout out and thank you to all the contributors, bug issuers and users of the library. ❤
Showing posts with label Win8. Show all posts
Showing posts with label Win8. Show all posts
Wednesday, January 23, 2019
Friday, May 5, 2017
Long time no hear - WriteableBitmapEx 1.5.1 is out
Even after all the years WriteableBitmapEx is still quite popular, especially with WPF developers and I always incorporate bug fixes and also accept Pull Requests if I get some time.
Many contributions were integrated and lots of bugs fixed. Among those are some nice additions like a clipped line drawing or a dotted line renderer.
WriteableBitmapEx supports a variety of Windows platforms and versions: WPF, Silverlight, Windows 10 Universal Windows Platform (UWP), Windows 8/8.1, Windows Phone WinRT and Silverlight 7/8/8.1.
You can download the latest via the updated NuGet package. The packages contain the WriteableBitmapEx binaries. All samples and the source code can be found in the GitHub repository.
A big thank you to all the contributors, bug reporters and users of the library who help with feedback.
Many contributions were integrated and lots of bugs fixed. Among those are some nice additions like a clipped line drawing or a dotted line renderer.
WriteableBitmapEx supports a variety of Windows platforms and versions: WPF, Silverlight, Windows 10 Universal Windows Platform (UWP), Windows 8/8.1, Windows Phone WinRT and Silverlight 7/8/8.1.
You can download the latest via the updated NuGet package. The packages contain the WriteableBitmapEx binaries. All samples and the source code can be found in the GitHub repository.
A big thank you to all the contributors, bug reporters and users of the library who help with feedback.
Labels:
.Net,
C#,
Computer graphics,
metro,
Silverlight,
uap,
Win8,
windows 10,
windows 8,
Windows Phone,
windows store,
WinRT,
Wp7Dev,
wp8dev,
wpdev,
wpf,
WriteableBitmap,
WriteableBitmapEx,
xaml
Wednesday, September 23, 2015
We've Come a Long Way Baby - WriteableBitmapEx now on GitHub
The WriteableBitmapEx project is now 6 years old and times have changed since all began. It all started with Silverlight and more XAML flavors were added over time until all XAML flavors were supported including Windows Phone, WPF, WinRT Windows Store XAML, (Windows 10) UWP and still Silverlight.
The version control system and open source services landscape has changed as well and the CodePlex infrastructure has not been too reliable recently. That's why I finally took the time to move the WriteableBitmapEx source code from CodePlex' SVN bridge to Git and make it available on GitHub: https://github.com/teichgraf/WriteableBitmapEx
Additionally was the open source license changed from Ms-PL to MIT which should simplify the usage as well. See the Codeplex Issue Tracker for a list of features that will be added in the future. Please use the GitHub Issues functionality to add new issues which are not already reported. Of course the latest binaries will continue to be distributed via NuGet.
Labels:
.Net,
C#,
Computer graphics,
Open Source,
Silverlight,
Store apps,
uwp,
Win8,
windows 10,
Windows Phone,
wp7,
WriteableBitmap,
WriteableBitmapEx,
xaml
Tuesday, March 31, 2015
Staying Alive! - WriteableBitmapEx 1.5 is out
After a couple of minor updates on top of version 1.0 which lead to 1.0.14, I'm happy to announce that WriteableBitmapEx 1.5 is now available.
Many contributions were integrated and lots of bugs fixed. Among those are some nice new color modifications and also long awaited DrawLine with variable thickness, pen support, better anti-aliased lines, Cohen-Sutherland line clipping, even-odd polygon filling and alpha-blended shape filling... Read the details at the end of this post or the release notes.
WriteableBitmapEx supports a variety of Windows platforms and versions: WPF, Silverlight, Windows 10 Universal App Platform (UAP), Windows 8/8.1, Windows Phone WinRT and Silverlight 7/8/8.1.
You can download the binaries here or via the NuGet package. The packages contain the WriteableBitmapEx binaries. All samples and the source code can be found in the repository.
A big thank you to all the contributors, bug reporters and users of the library who helped to shape this. You rock!
Changes
Many contributions were integrated and lots of bugs fixed. Among those are some nice new color modifications and also long awaited DrawLine with variable thickness, pen support, better anti-aliased lines, Cohen-Sutherland line clipping, even-odd polygon filling and alpha-blended shape filling... Read the details at the end of this post or the release notes.
WriteableBitmapEx supports a variety of Windows platforms and versions: WPF, Silverlight, Windows 10 Universal App Platform (UAP), Windows 8/8.1, Windows Phone WinRT and Silverlight 7/8/8.1.
You can download the binaries here or via the NuGet package. The packages contain the WriteableBitmapEx binaries. All samples and the source code can be found in the repository.
A big thank you to all the contributors, bug reporters and users of the library who helped to shape this. You rock!
Changes
- Added lots of contributions including DrawLine with variable thickness, penning, improved anti-aliasing and Wu's anti-aliasing algorithm
- Added usage of CohenSutherland line clipping for DrawLineAa and DrawLine, etc.
- Added support for alpha blended filled shapes and adapted the FillSample for WPF
- Added FillPolygonsEvenOdd() which uses the even-odd algorithm to fill complex polygons with more than one closed outline like for the letter O
- Added AdjustBrightness(), AdjustContrast() and AdjustGamma() methods
- Added Gray() method which returns the gray scaled version the bitmap
- Fixed regression issue with alpha blending for Blit for non-WinRT
- Fixed bug in Blit Alpha code for WPF when source format is not pre-multiplied alpha
- Fixed bug #21778 where FromStream for WPF needs to be called inside Init scope
- Fixed issue with IndexOutOfRangeEx in DrawLine method
- Fixed Invalidate for Silverlight BitmapContext.Dispose
- Fixed many more reported issues
- ...
Labels:
.Net,
C#,
Computer graphics,
metro,
Silverlight,
uap,
Win8,
windows 10,
windows 8,
Windows Phone,
windows store,
WinRT,
Wp7Dev,
wp8dev,
wpdev,
wpf,
WriteableBitmap,
WriteableBitmapEx,
xaml
Friday, January 31, 2014
No Biggie - How to Query the Available Storage Size in WinRT
![]() |
| Tape drive photo by P. Hollenback |
Unfortunately there's no built-in way to check for the available free storage size / free disk space at those locations, although there are scenarios where that information can be essential, especially when dealing with removable devices. But no worries, the good old Win32 has it covered with the GetFreeDiskSpaceEx function and it can be used with Windows 8 and Windows Phone 8. In order to use it from managed code it just has to be called through P/Invoke or wrapped in a WinRT component which I prefer nowadays, therefore this post provides a short WinRT C++/Cx snippet.
I assume you know how to create a custom C++/Cx WinRT component with Visual Studio, if not go back to my previous blog post which shows just that.
How it works
- Open the generated precompiled header file pch.h of your WinRT component's Visual Studio project and add an include for windows.h:
// pch.h - Header for standard system include files. #pragma once #include <windows.h>
- Open the header file of your component and add the method declaration of GetAvailableBytes to your WinRT component which will internally use the GetFreeDiskSpaceEx, but only takes a path as string parameter and returns a WinRT uint64 (unsigned long) type with the available free space in bytes.
namespace MyNativeStuff { public ref class MyStorageExtensions sealed { public: uint64 GetAvailableBytes(Platform::String^ path); }; }
- Add the method implementation in the source file of the component (.cpp).
The GetDiskFreeSpaceEx function takes a pointer to an ULARGE_INTEGER which is an union from ancient times when compilers didn't support 64 bit types. Our method then returns the filled unsigned long QuadPart of it.
#include "pch.h" #include "MyNativeStuff.h" using namespace MyNativeStuff; using namespace Platform; uint64 MyStorageExtensions::GetAvailableBytes(Platform::String^ path) { ULARGE_INTEGER availableBytesToCaller; availableBytesToCaller.QuadPart = 0; GetDiskFreeSpaceEx(path->Data(), &availableBytesToCaller, NULL, NULL); return availableBytesToCaller.QuadPart; }
- You are now ready to use the component in your managed C# code.
var myNativeComponent = new MyNativeStuff.MyStorageExtensions(); // Create a folder in temp folder of the app and check the available free space var myTempFolder = await ApplicationData.Current.TemporaryFolder.CreateFolderAsync("test", CreationCollisionOption.OpenIfExists); var availableSpaceTempFolder = myNativeComponent.GetAvailableBytes(myTempFolder.Path); // Create a folder in videos lib and check the available free space var myVideoFolder = await KnownFolders.VideosLibrary.CreateFolderAsync("test", CreationCollisionOption.OpenIfExists); var availableSpaceVideoLib = myNativeComponent.GetAvailableBytes(myVideoFolder.Path);
Note, the GetFreeDiskSpaceEx works with any directory path the calling code is allowed to access.
Labels:
C++. Cx,
c++11,
Win8,
win81,
windev,
windows 8,
windows 8.1,
Windows Phone,
windows store,
winprt,
WinRT,
wp8,
wpdev
Friday, December 20, 2013
What are you Awaiting for - How to Turn a C/C++ Callback into a C++/Cx WinRT IAsyncAction
Windows and Windows Phone 8 and its WinRT / WinPRT component model provide a nice way to leverage good ol' native C/C++ libraries in all WinMD language projections by wrapping them in a WinRT C++/Cx component. Such a native WinRT component only exposes WinRT types and can therefore be consumed through the WinMD projections also in C# or WinJS.
Often those good ol' native libraries provide events or callback functions for asynchronous calls. This means one would also have to provide a WinRT wrapper for those events and callbacks as well, although the WinRT has the nice IAsyncAction and IAsyncOperation constructs together with the Parallel Patterns Library (PPL) which make the WinRT component way better to use.
This post describes how to plug both worlds together to turn your good ol' C++ code into rose colored C++/Cx consumable through WinMD.
We won't go too deep into C++/Cx in general here. There's a good intro at the MSDN and also a nice Quick Reference which provides a table how Standard C++ types and constructs compare to C++/Cx. I also don't cover how the PPL and WinRT async works here, but there's a great MSDN page: Creating Asynchronous Operations in C++ for Windows Store Apps.
Assuming you have a good ol' native interface like this with a defined callback template:
It could be used like this using a C++11 lambda as callback function:
It's worth mentioning this will also work with C function pointers and you can use a C++ 11 lambda for it as long as the lambda does not capture any variable. Stateless lambdas will just degrade to function pointers.
This is how your C++/Cx WinRT component's method which wraps the above C++ template could look like:
You could then use your WinRT component in C# like this:
And similar in WinJS using a JS Promise:
Way better API for the custom WinRT component if you ask me!
The trick to achieve that is the usage of the PPL's create_async, create_task and especially the task_completion_event which provides a nice way to make that callback-based model work with the proper WinRT modern async Task-based way.
Often those good ol' native libraries provide events or callback functions for asynchronous calls. This means one would also have to provide a WinRT wrapper for those events and callbacks as well, although the WinRT has the nice IAsyncAction and IAsyncOperation
This post describes how to plug both worlds together to turn your good ol' C++ code into rose colored C++/Cx consumable through WinMD.
We won't go too deep into C++/Cx in general here. There's a good intro at the MSDN and also a nice Quick Reference which provides a table how Standard C++ types and constructs compare to C++/Cx. I also don't cover how the PPL and WinRT async works here, but there's a great MSDN page: Creating Asynchronous Operations in C++ for Windows Store Apps.
Assuming you have a good ol' native interface like this with a defined callback template:
template <typename TCallback>
HRESULT StartAsyncOperation(const TCallback &callback)
{
...
}
It could be used like this using a C++11 lambda as callback function:
StartAsyncOperation([this](HRESULT error) -> HRESULT
{
// Do whatever here after the async is done...
// Notify the calling code through an event or another callback
// that the async operation has finished.
return S_OK;
});
It's worth mentioning this will also work with C function pointers and you can use a C++ 11 lambda for it as long as the lambda does not capture any variable. Stateless lambdas will just degrade to function pointers.
// Definition of fucntion pointer and a function expecting it as parameter
typedef void (*SomeOtherCallback)(int param1);
FunctionExpectingSomeOtherCallback(SomeOtherCallback cb);
// Example call using a stateless lambda
FunctionExpectingSomeOtherCallback([](int param1)
{
// Perform some operation with param1
});
This is how your C++/Cx WinRT component's method which wraps the above C++ template could look like:
Windows::Foundation::IAsyncAction^ MyWinRtComponent::RunAsync()
{
// Setup the Task Completion Event and the async Task
Concurrency::task_completion_event<void> tce;
auto tsk = Concurrency::create_task(tce);
Windows::Foundation::IAsyncAction^ asyncOp = Concurrency::create_async( [tsk]()
-> Concurrency::task<void>
{
return tsk;
});
// Run good ol' native code wih callback defined as C++ lambda
StartAsyncOperation([this, tce](HRESULT error) -> HRESULT
{
try
{
// Check for error and wrap in platfrom exception
if (FAILED(error))
{
throw Platform::Exception::CreateException(error);
}
}
catch(...)
{
// Pass exception on to calling code using the
// Task Completion Event's dedicated method
tce.set_exception(std::current_exception());
return error;
}
// Set the Task Completion Event's Result to mark the Task as complete
// If a IAsyncOperation is used the result value is passed
tce.set();
return S_OK;
});
return asyncOp;
}
You could then use your WinRT component in C# like this:
var component = new MyWinRtComponent(); await component.RunAsync();
And similar in WinJS using a JS Promise:
this._component.runAsync().then(function () {
WinJS.log("My component finished the async call! :-)", null, "status");
});
Way better API for the custom WinRT component if you ask me!
The trick to achieve that is the usage of the PPL's create_async, create_task and especially the task_completion_event which provides a nice way to make that callback-based model work with the proper WinRT modern async Task-based way.
How to Encode and Save a WriteableBitmap with Windows WinRT
Here's a code snippet how this can be achieved:
private static async TaskSaveWriteableBitmapAsJpeg(WriteableBitmap bmp, string fileName) { // Create file in Pictures library and write jpeg to it var outputFile = await KnownFolders.PicturesLibrary.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting); using (var writeStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite)) { await EncodeWriteableBitmap(bmp, writeStream, BitmapEncoder.JpegEncoderId); } return outputFile; } private static async Task EncodeWriteableBitmap(WriteableBitmap bmp, IRandomAccessStream writeStream, Guid encoderId) { // Copy buffer to pixels byte[] pixels; using (var stream = bmp.PixelBuffer.AsStream()) { pixels = new byte[(uint) stream.Length]; await stream.ReadAsync(pixels, 0, pixels.Length); } // Encode pixels into stream var encoder = await BitmapEncoder.CreateAsync(encoderId, writeStream); encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, (uint) bmp.PixelWidth, (uint) bmp.PixelHeight, 96, 96, pixels); await encoder.FlushAsync(); }
It's all pretty straightforward actually: The SaveWriteableBitmapAsJpeg creates a file in the user's pictures library and passes the file's stream and an BitmapEncoder ID on to the EncodeWriteableBitmap method which is doing the actual work. EncodeWriteableBitmap first copies the WriteableBitmap pixel buffer into a byte array, then creates the BitmapEncoder based on the file's stream and the desired BitmapEncoder ID, then sets the pixels and flushes all into the stream.
The BitmapEncoder class supports a couple of BitmapEncoder IDs out of the box like JPEG, PNG and more.
Labels:
.Net,
C#,
metro,
Store apps,
Win8,
win81,
windows 8,
windows 8.1,
WinRT,
WriteableBitmap,
xaml
Monday, December 2, 2013
Easy Render! - WriteableBitmapEx now with Better Support for Win 8.1 RenderTargetBitmap

The lack of WriteableBitmap.Render in Windows WinRT 8.0 was quite an issue for many apps, but fortunately did WinRT 8.1 (re-)introduce the RenderTargetBitmap class which provides the functionality of rendering the visual tree of the UI to a bitmap. The new update of WriteableBitmapEx makes it even easier to use with a WriteableBitmap by introducing the FromPixelBuffer method.
WriteableBitmapEx is available for 4 platforms: Windows Phone 8 and 7, WPF, Silverlight and Windows Store WinRT .NET XAML 8 and 8.1.
You can download the binaries here or via the NuGet package. The packages contain the WriteableBitmapEx binaries. As usual all samples and the source code can be found in the repository.
How to use
The below code snippet shows how a part of the UI can be rendered into a WriteableBitmap via RenderTargetBitmap, how it can be modified and then finally presented back into the UI by using an Image control.
// Render some UI to a RenderTargetBitmap
var renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(Panel);
// Get the pixel buffer and copy it into a WriteableBitmap
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
var width = renderTargetBitmap.PixelWidth;
var height = renderTargetBitmap.PixelHeight;
var wbmp = await new WriteableBitmap(1, 1).FromPixelBuffer(pixelBuffer, width, height);
// Modify the WriteableBitmap
wbmp.FillEllipse(10, 10, 256, 256, Colors.Salmon);
// ... More drawing including writeableBitmap.Blit(...) might go here
// Assign WriteableBitmap to an Image control to present it
ImgMirror.Source = wbmp;
Labels:
.Net,
C#,
Computer graphics,
metro,
Silverlight,
Win8,
windows 8,
Windows Phone,
windows store,
WinRT,
Wp7Dev,
wp8dev,
wpdev,
wpf,
WriteableBitmap,
WriteableBitmapEx,
xaml
Tuesday, October 30, 2012
Faster! - WriteableBitmapEx for Windows Phone 8 and WinRT Updated
The Windows Phone 8 SDK is now available and with that WriteableBitmapEx was updated too. The performance of the WinRT XAML version was also improved dramatically and an update is highly recommended.WriteableBitmapEx is available for 4 platforms: Windows Phone 8 and 7, WPF, Silverlight and Windows Store WinRT .NET XAML.
You can download the binaries here or via the NuGet package. The packages contain the WriteableBitmapEx binaries. As usual all samples and the source code can be found in the repository.
Labels:
.Net,
C#,
Computer graphics,
metro,
Silverlight,
Win8,
windows 8,
Windows Phone,
windows store,
WinRT,
Wp7Dev,
wp8dev,
wpdev,
wpf,
WriteableBitmap,
WriteableBitmapEx,
xaml
Sunday, October 28, 2012
Know Your Users - Windows 8 Store App System Info
This is just a quick a post to provide a little class for Windows 8 Store app development. The SystemInformation class gathers some useful information about the current system and can dump those as a string. I usually have such a class for all the platforms I work on and it's very helpful for logging and error analysis, but it also serves as a list of all available system information which are scattered in different APIs. The info can also be used to dynamically adapt the app, etc.
Here's the code I have so far, you can also download the complete class here.
On my system it provides the following info (anonymized):
If you know more system information Windows 8 APIs that listing is missing, please add a comment.
Here's the code I have so far, you can also download the complete class here.
public static async TaskDump(bool shouldDumpCompleteDeviceInfos = false) { var builder = new StringBuilder(); var packageId = Windows.ApplicationModel.Package.Current.Id; var clientDeviceInformation = new EasClientDeviceInformation(); // Get hardware Id var token = HardwareIdentification.GetPackageSpecificToken(null); var stream = token.Id.AsStream(); string hardwareId; using (var reader = new BinaryReader(stream)) { var bytes = reader.ReadBytes((int)stream.Length); hardwareId = BitConverter.ToString(bytes); } builder.AppendLine("***** System Infos *****"); builder.AppendLine(); #if DEBUG builder.AppendLine("DEBUG"); builder.AppendLine(); #endif builder.AppendFormat("Time: {0}", DateTime.Now.ToUniversalTime().ToString("r")); builder.AppendLine(); builder.AppendFormat("App Name: {0}", packageId.Name); builder.AppendLine(); builder.AppendFormat("App Version: {0}.{1}.{2}.{3}", packageId.Version.Major, packageId.Version.Minor, packageId.Version.Build, packageId.Version.Revision); builder.AppendLine(); builder.AppendFormat("App Publisher: {0}", packageId.Publisher); builder.AppendLine(); builder.AppendFormat("Supported Package Architecture: {0}", packageId.Architecture); builder.AppendLine(); builder.AppendFormat("Installed Location: {0}", Windows.ApplicationModel.Package.Current.InstalledLocation.Path); builder.AppendLine(); builder.AppendFormat("Store App Id: {0}", CurrentApp.AppId); builder.AppendLine(); if (CurrentApp.LicenseInformation.IsActive) { var listingInformation = await CurrentApp.LoadListingInformationAsync(); builder.AppendFormat("Store Current Market: {0}", listingInformation.CurrentMarket); builder.AppendLine(); } builder.AppendFormat("Culture: {0}", CultureInfo.CurrentCulture); builder.AppendLine(); builder.AppendFormat("OS: {0}", clientDeviceInformation.OperatingSystem); builder.AppendLine(); builder.AppendFormat("System Manufacturer: {0}", clientDeviceInformation.SystemManufacturer); builder.AppendLine(); builder.AppendFormat("System Product Name: {0}", clientDeviceInformation.SystemProductName); builder.AppendLine(); builder.AppendFormat("System Sku: {0}", clientDeviceInformation.SystemSku); builder.AppendLine(); builder.AppendFormat("System Name: {0}", clientDeviceInformation.FriendlyName); builder.AppendLine(); builder.AppendFormat("System ID: {0}", clientDeviceInformation.Id); builder.AppendLine(); builder.AppendFormat("Hardware ID: {0}", hardwareId); builder.AppendLine(); builder.AppendFormat("User Display Name: {0}", await UserInformation.GetDisplayNameAsync()); builder.AppendLine(); builder.AppendFormat("Window Bounds w x h: {0} x {1}", Window.Current.Bounds.Width, Window.Current.Bounds.Height); builder.AppendLine(); builder.AppendFormat("Current Orientation: {0}", DisplayProperties.CurrentOrientation); builder.AppendLine(); builder.AppendFormat("Native Orientation: {0}", DisplayProperties.NativeOrientation); builder.AppendLine(); builder.AppendFormat("Logical DPI: {0}", DisplayProperties.LogicalDpi); builder.AppendLine(); builder.AppendFormat("Resolution Scale: {0}", DisplayProperties.ResolutionScale); builder.AppendLine(); builder.AppendFormat("Is Stereo Enabled: {0}", DisplayProperties.StereoEnabled); builder.AppendLine(); builder.AppendFormat("Supports Keyboard: {0}", IsKeyboardPresent()); builder.AppendLine(); builder.AppendFormat("Supports Mouse: {0}", IsMousePresent()); builder.AppendLine(); builder.AppendFormat("Supports Touch (contacts): {0} ({1})", IsTouchPresent(), new TouchCapabilities().Contacts); builder.AppendLine(); builder.AppendFormat("Is Network Available: {0}", NetworkInterface.GetIsNetworkAvailable()); builder.AppendLine(); builder.AppendFormat("Is Internet Connection Available: {0}", NetworkInformation.GetInternetConnectionProfile() != null); builder.AppendLine(); builder.AppendFormat("Network Host Names: "); foreach (var hostName in NetworkInformation.GetHostNames()) { builder.AppendFormat("{0} ({1}), ", hostName.DisplayName, hostName.Type); } builder.AppendLine(); builder.AppendFormat("Current Memory Usage: {0:f3} MB", GC.GetTotalMemory(false) / 1024f / 1024f); builder.AppendLine(); builder.AppendFormat("App Temp Folder: {0}", ApplicationData.Current.TemporaryFolder.Path); builder.AppendLine(); builder.AppendFormat("App Local Folder: {0}", ApplicationData.Current.LocalFolder.Path); builder.AppendLine(); builder.AppendFormat("App Roam Folder: {0}", ApplicationData.Current.RoamingFolder.Path); builder.AppendLine(); builder.AppendLine(); if (shouldDumpCompleteDeviceInfos) { var devInfos = await DeviceInformation.FindAllAsync(); builder.AppendLine(); builder.AppendLine("Complete Device Infos:"); foreach (var devInfo in devInfos) { builder.AppendFormat("Name: {0} Id: {1} - Properties: ", devInfo.Name, devInfo.Id); foreach (var pair in devInfo.Properties) { builder.AppendFormat("{0} = {1}, ", pair.Key, pair.Value); } builder.AppendLine(); } } return builder.ToString(); } public static bool IsTouchPresent() { return new TouchCapabilities().TouchPresent == 1; } public static bool IsMousePresent() { return new MouseCapabilities().MousePresent == 1; } public static bool IsKeyboardPresent() { return new KeyboardCapabilities().KeyboardPresent == 1; }
On my system it provides the following info (anonymized):
***** System Infos ***** DEBUG Time: Sun, 28 Oct 2012 07:51:11 GMT App Name: MyApp App Version: 1.0.0.5 App Publisher: CN=A8E2F0B1-4749-48AE-AE18-C7FFB5B30272 Supported Package Architecture: Neutral Installed Location: D:\Development\MyApp\bin\Debug\AppX Store App Id: 00000000-0000-0000-0000-000000000000 Culture: en-US OS: WINDOWS System Manufacturer: Dell Inc. System Product Name: Precision M6600 System Sku: System Name: MYLAPTOP System ID: 18a2e8c6-cc7d-8546-1e9e-56a12ffb32fd Hardware ID: 03-00-D2-41-03-00-AA-72-08-00-EF-AD-05-AA-B6-4F-06-00-01-01-04-00-31-1B-04-00-0C-48-04-00-D2-55-04-00-D3-66-01-00-0E-D6-02-00-E4-7F-09-00-56-47 User Display Name: Rene Schulte Window Bounds w x h: 1920 x 1080 Current Orientation: Landscape Native Orientation: Landscape Logical DPI: 96 Resolution Scale: Scale100Percent Is Stereo Enabled: False Supports Keyboard: True Supports Mouse: True Supports Touch (contacts): False (0) Is Network Available: True Is Internet Connection Available: True Network Host Names: mylaptop (DomainName), mylaptop.local (DomainName), 169.254.85.85 (Ipv4), 192.168.2.148 (Ipv4), Current Memory Usage: 0.451 MB App Temp Folder: C:\Users\Rene\AppData\Local\Packages\MyApp\TempState App Local Folder: C:\Users\Rene\AppData\Local\Packages\MyApp\LocalState App Roam Folder: C:\Users\Rene\AppData\Local\Packages\MyApp\RoamingState
If you know more system information Windows 8 APIs that listing is missing, please add a comment.
Wednesday, August 29, 2012
Update WriteableBitmapEx for WinRT RTM, WPF, Windows Phone and Silverlight
The RTM version of Windows 8 is now available and with that WriteableBitmapEx was updated too. WriteableBitmapEx is now available for 4 platforms: WPF, Silverlight, Silverlight for Windows Phone and Windows Store Style WinRT .NET.
You can download the binaries here or via the NuGet package. The packages contain the WriteableBitmapEx binaries. As usual all samples and the source code can be found in the repository.
Since the last WinRT release preview version, a couple of bugs were fixed and a new FromStrean method was added which loads an image stream into a WriteableBitmap. The project was also updated for the Windows 8 RTM version. Please read this blog post for more details about the WinRT version.
Labels:
.Net,
C#,
Computer graphics,
metro,
Silverlight,
Win8,
windows 8,
Windows Phone,
windows store,
WinRT,
Wp7Dev,
wpdev,
wpf,
WriteableBitmap,
WriteableBitmapEx,
xaml
Thursday, June 14, 2012
It's Alive! - WriteableBitmapEx 1.0 for WinRT Metro Style, WPF, Windows Phone and Silverlight
After a few preview versions, I'm happy to announce that the final version of WriteableBitmapEx 1.0 is now available.
A couple of weeks ago we added official WPF support and WinRT Metro Style support. With that WriteableBitmapEx is now available for 4 platforms: WPF, Silverlight, Silverlight for Windows Phone and Metro Style WinRT .NET.
You can download the binaries here or via the NuGet package. The packages contain the WriteableBitmapEx binaries. All samples and the source code can be found in the repository.
Since the last WinRT preview version, a new WinRT sample was added, a couple of bugs were fixed and a new FromStrean method was added which loads an image stream into a WriteableBitmap. The project was also updated for the Windows 8 Release Preview. Please read this blog post for more details (about the WinRT version).
A couple of weeks ago we added official WPF support and WinRT Metro Style support. With that WriteableBitmapEx is now available for 4 platforms: WPF, Silverlight, Silverlight for Windows Phone and Metro Style WinRT .NET.
You can download the binaries here or via the NuGet package. The packages contain the WriteableBitmapEx binaries. All samples and the source code can be found in the repository.
Since the last WinRT preview version, a new WinRT sample was added, a couple of bugs were fixed and a new FromStrean method was added which loads an image stream into a WriteableBitmap. The project was also updated for the Windows 8 Release Preview. Please read this blog post for more details (about the WinRT version).
Labels:
.Net,
C#,
Computer graphics,
metro,
Silverlight,
Win8,
windows 8,
Windows Phone,
WinRT,
Wp7Dev,
wpdev,
wpf,
WriteableBitmap,
WriteableBitmapEx,
xaml
Monday, May 7, 2012
One Bitmap to Rule Them All - WriteableBitmapEx for WinRT Metro Style
A couple of weeks ago we added official WPF support to
WriteableBitmapEx. Today I'm happy to announce that WriteableBitmapEx now also officially supports Windows 8 Metro Stlye WinRT .NET XAML. With that WriteableBitmapEx is now available for 4 platforms: WPF, Silverlight, Silverlight for Windows Phone and Metro Style WinRT .NET.
Although Direct2D is the best solution for fast 2D graphics with Windows 8 Metro Style, I think there are scenarios where the WriteableBitmapEx could be helpful, esp. when using C# with XAML. I also know that some devs were waiting for this to port their Windows Phone apps to Windows 8 Metro Style.
WinRT Differences
Unlike the Silverlight WriteableBitmap, the Metro Style WriteableBitmap doesn't provide the pixel data directly. Its IBuffer PixelBuffer property doesn't have an interface to get the color information. Fortunately there are a few C# extension methods available which provide the pixel data as byte array or stream in the BGRA pixel format. Yes, BGRA and not like all the other platforms supported by WriteableBitmapEx as ARGB. The BGRA format is mainly used by Direct2D, which might be the reason for this hidden, but important difference of the Metro Style WriteableBitmap.
The WriteableBitmapEx algorithms are written for the ARGB pixel format. Fortunately I was able to keep the details away from the library user by leveraging the BitmapContext concept we introduced with the WPF support. This approach makes it possible to share almost the same code for all 4 platforms without being cluttered with #if directives all over place. Actually the most significant WinRT adaptation inside the WriteableBitmapEx methods was done in the FromContent method, which loads an image from the app content and provides it as WriteableBitmap. See this StackOverflow question I answered if you're interested in the details.
Nothing comes for free, but if the BitmapContext is used the right way, the performance hit won't be that much thanks to an internal reference counting WriteableBitmapEx' BitmapContext uses. No worries, you don't have to change all your WriteableBitmapEx calls, just wrap your calls in a simple using(writeableBmp.GetBitmapContext()) and you will only have one buffer conversion instead of one for each draw call.
It's really simple to use:
All samples were tested with the new version, but due to the refactoring more testing is needed. Please test this version with your projects and report the bugs you encounter. You can download the binaries here. Note that this package only contains the WriteableBitmapEx binaries for Silverlight, Windows Phone, WinRT Metro Style .NET and WPF. All the samples can be found in the source code repository in the branch "WBX_1.0_BitmapContext". If all goes well, this branch will become the trunk and the 1.0 RTM in a few weeks.
WinMD / Windows Runtime Component
There's also a WinMD version available which makes it possible to consume the WriteableBitmapEx library from all the WinRT Metro Style projections, although only C# and C++ XAML make actually sense.
I had to move some parts and leave some functionality like the ForEach out, but it contains 99% of the library's features. Unfortunately the C++ sample I created crashes when the WriteableBitmapExWinMD library is loaded. So for now this WinMD version can be found in a separate branch "WBX_1.0_WinMD" in the source code repository and it won't be part of the trunk and release until it works with the sample. I'm a bit running out of time and don't know where to look for, since it seems all is wired up correctly and compiles fine. If you are a WinMD wizard and have a few minutes, I'd appreciate if you could look into the WinMD version.
Although Direct2D is the best solution for fast 2D graphics with Windows 8 Metro Style, I think there are scenarios where the WriteableBitmapEx could be helpful, esp. when using C# with XAML. I also know that some devs were waiting for this to port their Windows Phone apps to Windows 8 Metro Style.
WinRT Differences
Unlike the Silverlight WriteableBitmap, the Metro Style WriteableBitmap doesn't provide the pixel data directly. Its IBuffer PixelBuffer property doesn't have an interface to get the color information. Fortunately there are a few C# extension methods available which provide the pixel data as byte array or stream in the BGRA pixel format. Yes, BGRA and not like all the other platforms supported by WriteableBitmapEx as ARGB. The BGRA format is mainly used by Direct2D, which might be the reason for this hidden, but important difference of the Metro Style WriteableBitmap.
The WriteableBitmapEx algorithms are written for the ARGB pixel format. Fortunately I was able to keep the details away from the library user by leveraging the BitmapContext concept we introduced with the WPF support. This approach makes it possible to share almost the same code for all 4 platforms without being cluttered with #if directives all over place. Actually the most significant WinRT adaptation inside the WriteableBitmapEx methods was done in the FromContent method, which loads an image from the app content and provides it as WriteableBitmap. See this StackOverflow question I answered if you're interested in the details.
Nothing comes for free, but if the BitmapContext is used the right way, the performance hit won't be that much thanks to an internal reference counting WriteableBitmapEx' BitmapContext uses. No worries, you don't have to change all your WriteableBitmapEx calls, just wrap your calls in a simple using(writeableBmp.GetBitmapContext()) and you will only have one buffer conversion instead of one for each draw call.
It's really simple to use:
private void Draw()
{
// Wrap updates in a GetContext call, to prevent invalidation overhead
using (writeableBmp.GetBitmapContext())
{
writeableBmp.Clear();
DrawPoints();
DrawBeziers();
} // Invalidates on exit of using block
}
private void DrawPoints()
{
foreach (var p in points)
{
DrawPoint(p, Colors.Green, PointVisualSizeHalf);
}
}
private void DrawPoint(ControlPoint p, Color color, int halfSizeOfPoint)
{
var x1 = p.X - halfSizeOfPoint;
var y1 = p.Y - halfSizeOfPoint;
var x2 = p.X + halfSizeOfPoint;
var y2 = p.Y + halfSizeOfPoint;
writeableBmp.DrawRectangle(x1, y1, x2, y2, color);
}
private void DrawBeziers()
{
if (points.Count > 3)
{
writeableBmp.DrawBeziers(GetPointArray(), Colors.Yellow);
}
}
| Screenshot WinRT Metro Style sample running in the simulator |
All samples were tested with the new version, but due to the refactoring more testing is needed. Please test this version with your projects and report the bugs you encounter. You can download the binaries here. Note that this package only contains the WriteableBitmapEx binaries for Silverlight, Windows Phone, WinRT Metro Style .NET and WPF. All the samples can be found in the source code repository in the branch "WBX_1.0_BitmapContext". If all goes well, this branch will become the trunk and the 1.0 RTM in a few weeks.
WinMD / Windows Runtime Component
There's also a WinMD version available which makes it possible to consume the WriteableBitmapEx library from all the WinRT Metro Style projections, although only C# and C++ XAML make actually sense.
I had to move some parts and leave some functionality like the ForEach out, but it contains 99% of the library's features. Unfortunately the C++ sample I created crashes when the WriteableBitmapExWinMD library is loaded. So for now this WinMD version can be found in a separate branch "WBX_1.0_WinMD" in the source code repository and it won't be part of the trunk and release until it works with the sample. I'm a bit running out of time and don't know where to look for, since it seems all is wired up correctly and compiles fine. If you are a WinMD wizard and have a few minutes, I'd appreciate if you could look into the WinMD version.
Labels:
.Net,
C#,
Computer graphics,
metro,
Silverlight,
Win8,
windows 8,
Windows Phone,
WinRT,
Wp7Dev,
wpdev,
wpf,
WriteableBitmap,
WriteableBitmapEx,
xaml
Saturday, September 17, 2011
Welcome to Zombieland, the Metro Style Land of WinRT and the Undead
Silverlight is dead! WPF is dead! .NET is dead! Hey, they didn't talk about SharePoint or SQL Server at the BUILD conference, those must be dead too. Welcome our new Metro-id overlords!
We read such FUD everywhere these days. Actually none of these technologies are dead for the next several years! And you'll probably agree if you know the facts and not the FUD. So here are my thoughts based only on the facts I got from watching BUILD sessions, reading posts that stick to the facts and not listening to people who obviously didn't inform themselves, but nevertheless spread FUD around.
What happened
Microsoft announced the new version of Windows at the BUILD conference and the new Windows 8 runtime called WinRT, which is used to develop Metro style Apps. Metro style Apps are primarily focused on consumers, designed touch first and therefore perfect for modern multi-touch devices like tablets.
The good ol' desktop is still there and the usual Windows applications are now called Desktop Apps.
There's a lot confusion out there at the moment and many think only Metro style Apps are the future. Actually both models can exist side-by-side and I'm sure the mainly used UI will be the classic desktop for the usual business client. Metro is for tablets, maybe later for the phone. Desktop Apps will still work better for the classic business PC scenario in an office.
After trying Windows 8 I don't see myself using Metro style Apps a lot on my PC when I work at the desk. However, I will love to use it when I'm hanging out on my couch with a tablet. The good news is, both models are supported by Windows 8 and therefore can run on one device, including ARM hardware. Awesome!
WinRT
First and foremost, .NET plays a significant role in both development models and is not only used for Desktop Apps. I guess the FUD comes from the architectural picture above, where .NET and Silverlight are only represented by a small box in the lower right corner. Of course Microsoft wants to push the new Metro style Apps, the WinRT model and wants to get web developers into the boat, so they adjusted the graphic and marketing message accordingly.
WinRT is actually a new native COM library, plus some extra infrastructure. Therefore an app developer has not to deal with the COM stuff directly, instead you get a thin / fast projection layer (binding) for each of the supported programming languages. This projection layer is automatically built using WinMD metadata and provides projections for JavaScript, .NET (C# / VB) or C / C++. The UI can be designed with XAML or HTML / CSS in case of JavaScript.
The rendering is completely done using DirectX 11.1 (Direct2D) which results in great performance. In Windows 8 the rendering job is finally fully executed by the right processor. This architecture makes it also possible to implement the complete UI just with DirectX, which will usually be done by games. At the moment it's not possible in the Windows 8 Developer Preview to mix a XAML app with DirectX, which doesn't make much sense since the XAML rendering is done by DirectX. Fortunately all hints that it'll be possible in a later version of Windows 8, maybe in the beta.
The below picture by Doug Seven is a way more accurate picture of the Windows 8 platform architecture.
There are a few good, unbiased posts about WinRT out there, which stick to the facts:
WinRT: An Object Orientated Replacement for Win32
WinRT, the C++ Component Extensions
WinRT demystified
A bad picture is worth a thousand long discussions.
WinRT reference with all namespaces at the unbiased MSDN, where JaveScript is just another language one can use for Metro style Apps.
WinRT and .NET
From what I have seen so far, coding Metro style Apps using C# / .NET seems pretty straightforward if you've done Silverlight, WPF or esp. Windows Phone development before. The BCL used by .NET WinRT is not the full Desktop version of .NET 4.5, it's a reduced set similar to the Silverlight types.
The design of the native WinRT COM library was heavily influenced by .NET. You see it everywhere. Type names, Properties, Events... Even WinMD is the .NET assembly metadata format.
WinRT types map to .NET types and copying of data structures at the boundaries is avoided by the projection layer to get the best performance. Only two types need to be converted using built-in extension methods. The System.IO.Stream can't be mapped to the WinRT stream, so there's an extension method. A Byte[] to WinRT IBuffer conversion is the other extension method.
You can even write your own, custom WinRT components in C# without decorating the classes with ugly COM attributes. Those components are then automatically exposed to the other languages using the generic WinMD metadata. So you can write a component in C++ or in C# and use it from a JavaScript WinRT project. Pretty cool concept if you ask me.
Many WinRT classes look like their origin is .NET / Silverlight and the WinRT WriteableBitmap is also very similar to Silverlight's implementation. So expect a WinRT version of my open source WriteableBitmapEx library in a few weeks when I'm done with the Mango updates for all my Windows Phone apps. After that I will probably port / rewrite some of my WP7 apps for WinRT.
The lifecycle of a WinRT app should be quite familiar for a WP7 developer, since it's similar to the WP 7.5 Mango Fast App Switching. The lifecycle states are: Running > Suspended in RAM > Terminated. Apps get an event for suspending, not for terminate, so the state has to be saved during suspending. Of course an app should only be resurrected from the tombstone state if the app was launched, not when resumed. Apps get 5s for suspending and need to launch within 15s. Unfortunately we don't know the reference machine where those values are measured. Probably the low end configuration.
By the way, the Windows Store will be the better version of the WP7 Marketplace. It will include In-App offers, time limited trials and a very nice dashboard with a lot of analytic capabilities and insights.
In general should a WP7 developer feel most familiar with WinRT. Many concepts made it into WinRT and were improved and actually cleaned up.
My Silverlight MVP friend Morten Nielsen started a blog post series about how to port Silverlight / WPF apps to WinRT.
You should also read this post: WinRT and .NET and watch the ton of great BUILD sessions.
We read such FUD everywhere these days. Actually none of these technologies are dead for the next several years! And you'll probably agree if you know the facts and not the FUD. So here are my thoughts based only on the facts I got from watching BUILD sessions, reading posts that stick to the facts and not listening to people who obviously didn't inform themselves, but nevertheless spread FUD around.
What happened
Microsoft announced the new version of Windows at the BUILD conference and the new Windows 8 runtime called WinRT, which is used to develop Metro style Apps. Metro style Apps are primarily focused on consumers, designed touch first and therefore perfect for modern multi-touch devices like tablets.
The good ol' desktop is still there and the usual Windows applications are now called Desktop Apps.
There's a lot confusion out there at the moment and many think only Metro style Apps are the future. Actually both models can exist side-by-side and I'm sure the mainly used UI will be the classic desktop for the usual business client. Metro is for tablets, maybe later for the phone. Desktop Apps will still work better for the classic business PC scenario in an office.
After trying Windows 8 I don't see myself using Metro style Apps a lot on my PC when I work at the desk. However, I will love to use it when I'm hanging out on my couch with a tablet. The good news is, both models are supported by Windows 8 and therefore can run on one device, including ARM hardware. Awesome!
WinRT
First and foremost, .NET plays a significant role in both development models and is not only used for Desktop Apps. I guess the FUD comes from the architectural picture above, where .NET and Silverlight are only represented by a small box in the lower right corner. Of course Microsoft wants to push the new Metro style Apps, the WinRT model and wants to get web developers into the boat, so they adjusted the graphic and marketing message accordingly.
WinRT is actually a new native COM library, plus some extra infrastructure. Therefore an app developer has not to deal with the COM stuff directly, instead you get a thin / fast projection layer (binding) for each of the supported programming languages. This projection layer is automatically built using WinMD metadata and provides projections for JavaScript, .NET (C# / VB) or C / C++. The UI can be designed with XAML or HTML / CSS in case of JavaScript.
The rendering is completely done using DirectX 11.1 (Direct2D) which results in great performance. In Windows 8 the rendering job is finally fully executed by the right processor. This architecture makes it also possible to implement the complete UI just with DirectX, which will usually be done by games. At the moment it's not possible in the Windows 8 Developer Preview to mix a XAML app with DirectX, which doesn't make much sense since the XAML rendering is done by DirectX. Fortunately all hints that it'll be possible in a later version of Windows 8, maybe in the beta.
The below picture by Doug Seven is a way more accurate picture of the Windows 8 platform architecture.
There are a few good, unbiased posts about WinRT out there, which stick to the facts:
WinRT: An Object Orientated Replacement for Win32
WinRT, the C++ Component Extensions
WinRT demystified
A bad picture is worth a thousand long discussions.
WinRT reference with all namespaces at the unbiased MSDN, where JaveScript is just another language one can use for Metro style Apps.
WinRT and .NET
From what I have seen so far, coding Metro style Apps using C# / .NET seems pretty straightforward if you've done Silverlight, WPF or esp. Windows Phone development before. The BCL used by .NET WinRT is not the full Desktop version of .NET 4.5, it's a reduced set similar to the Silverlight types.
The design of the native WinRT COM library was heavily influenced by .NET. You see it everywhere. Type names, Properties, Events... Even WinMD is the .NET assembly metadata format.
WinRT types map to .NET types and copying of data structures at the boundaries is avoided by the projection layer to get the best performance. Only two types need to be converted using built-in extension methods. The System.IO.Stream can't be mapped to the WinRT stream, so there's an extension method. A Byte[] to WinRT IBuffer conversion is the other extension method.
You can even write your own, custom WinRT components in C# without decorating the classes with ugly COM attributes. Those components are then automatically exposed to the other languages using the generic WinMD metadata. So you can write a component in C++ or in C# and use it from a JavaScript WinRT project. Pretty cool concept if you ask me.
Many WinRT classes look like their origin is .NET / Silverlight and the WinRT WriteableBitmap is also very similar to Silverlight's implementation. So expect a WinRT version of my open source WriteableBitmapEx library in a few weeks when I'm done with the Mango updates for all my Windows Phone apps. After that I will probably port / rewrite some of my WP7 apps for WinRT.
The lifecycle of a WinRT app should be quite familiar for a WP7 developer, since it's similar to the WP 7.5 Mango Fast App Switching. The lifecycle states are: Running > Suspended in RAM > Terminated. Apps get an event for suspending, not for terminate, so the state has to be saved during suspending. Of course an app should only be resurrected from the tombstone state if the app was launched, not when resumed. Apps get 5s for suspending and need to launch within 15s. Unfortunately we don't know the reference machine where those values are measured. Probably the low end configuration.
By the way, the Windows Store will be the better version of the WP7 Marketplace. It will include In-App offers, time limited trials and a very nice dashboard with a lot of analytic capabilities and insights.
In general should a WP7 developer feel most familiar with WinRT. Many concepts made it into WinRT and were improved and actually cleaned up.
My Silverlight MVP friend Morten Nielsen started a blog post series about how to port Silverlight / WPF apps to WinRT.
You should also read this post: WinRT and .NET and watch the ton of great BUILD sessions.
Conclusion
I welcome the new possibilities and great performance we get in Windows 8 with the WinRT. I'm sure Windows 8 will be an awesome tablet OS.
XAML has become a first class citizen and .NET is now installed with Windows 8. Microsoft is also working on a next version of .NET. Version 4.5 of .NET will bring better performance for WPF's ItemsControl for example. Seems not very dead to me. In fact, a Silverlight / WPF / WP7 developer's knowledge of XAML and the Silverlight runtime is more valuable than ever before with WinRT.
Silverlight 5 is still in development and wasn't even released. We don't know if it will be the last version or if Silverlight 6 will see the light of the day. For now I'm quite happy with all the features of Silverlight 5 and we can develop a ton of applications for our customers for the next several years.
XAML has become a first class citizen and .NET is now installed with Windows 8. Microsoft is also working on a next version of .NET. Version 4.5 of .NET will bring better performance for WPF's ItemsControl for example. Seems not very dead to me. In fact, a Silverlight / WPF / WP7 developer's knowledge of XAML and the Silverlight runtime is more valuable than ever before with WinRT.
Silverlight 5 is still in development and wasn't even released. We don't know if it will be the last version or if Silverlight 6 will see the light of the day. For now I'm quite happy with all the features of Silverlight 5 and we can develop a ton of applications for our customers for the next several years.
One should also not forget how long it will take until Windows 8 is finally out and reached a critical mass. A lot of machines out there still run Windows XP. Windows 7 is way better and I guess the transition to Windows 8 will take even longer. Windows 8 will probably mainly pushed by non-PC multi-touch consumer devices in the near future.
This flowchart by the Telerik guys sums it up pretty nicely.
So get yourself informed and start coding away. Don't give FUD a chance!
So get yourself informed and start coding away. Don't give FUD a chance!
Labels:
.Net,
C#,
Microsoft,
Silverlight,
Win8,
WinRT,
wp7,
WriteableBitmapEx
Subscribe to:
Posts (Atom)








