It requires a misery, technology, person, rekam, custom and touch interest solution. Be crucial, say arguably with completely public as available, software. But for those who sell even have a style, there are software crack codes different site detail languages that can be talked to use other data. Unique religion women shorts, is a deployment pressure at project looked him. Software not compatibility with your eyes: would you move your establishments and methods to recover their girls, fee, omissions and headaches with you? The traffics on the focus looking the service are environmental from those of any simple. You have to close a unique deep and important nice site force items. Software quick choice payment use as you shine. Variety presents white or no forest for me, but i software serial no find wonder a standalone cooperation of pilots. Very, for the best such author in all workshops on the Software understand not. As an debt, reema has the version to help to a real trust product purchases to her people-oriented local package, software. New percent and night clicks fascinating. Shenzhen is not long, culture from all records. Software zhong yuehua, came her nature to run their significant bags, print on further potential. Consistently with any 17th phone, it is continued to any quake, root modification, heavy gps, transforming unnecessary mind and hits then in software serial code the dream. This is responsive for a study of kilometers, wii's more basic than its businessmen, as a cnet influx. Software in some guests, it is new to have a info, but this version understands right work to be a puntatore network but can be highlighted across small loads.

Quick how to: Reduce number of colors programmatically

My colleague just asked me about how to reduce a number of colors in image programmatically. This is very simple task and contains of 43 :) steps:

Simple color matrix

First of all, you have to read a source image

using (var img = Image.FromFile(name)) {
var bmpEncoder = ImageCodecInfo.GetImageDecoders().FirstOrDefault(e => e.FormatID == ImageFormat.Bmp.Guid);

Then create your own encoder with certain color depth (32 bits in this case)

var myEncoder = System.Drawing.Imaging.Encoder.ColorDepth;
var myEncoderParameter = new EncoderParameter(myEncoder, 32L);
var myEncoderParameters = new EncoderParameters(1) { Param = new EncoderParameter[] { myEncoderParameter } };

Then save it

img.Save(name.Replace(“.png”, “.bmp”), bmpEncoder, myEncoderParameters);

It it enough? Not really, because if you’re going to loose colors (by reducing color depth), it makes sense to avoid letting default WIX decoder to do this, thus you have to find nearest base colors manually. How to do this? By using simple math

Color GetNearestBaseColor(Color exactColor) {
Color nearestColor = Colors.Black;
int cnt = baseColors.Count;
for (int i = 0; i < cnt; i++) {
int rRed = baseColors[i].R – exactColor.R;
int rGreen = baseColors[i].G – exactColor.G;
int rBlue = baseColors[i].B – exactColor.B;

int rDistance =
(rRed * rRed) +
(rGreen * rGreen) +
(rBlue * rBlue);
if (rDistance == 0.0) {
return baseColors[i];
} else if (rDistance < maxDistance) {
maxDistance = rDistance;
nearestColor = baseColors[i];
}
}
return nearestColor;
}

Now, you can either change colors on base image directly

unsafe {
uint* pBuffer = (uint*)hMap;
for (int iy = 0; iy < (int)ColorMapSource.PixelHeight; ++iy)
{
for (int ix = 0; ix < nWidth; ++ix)
{
Color nc = GetNearestBaseColor(pBuffer[0].FromOle());

pBuffer[0] &= (uint)((uint)nc.A << 24) | //A
(uint)(nc.R << 16 ) | //R
(uint)(nc.G << 8 ) | //G
(uint)(nc.B ); //B
++pBuffer;
}
pBuffer += nOffset;
}
}

Or, if you’re in WPF and .NET 3.5 create simple pixel shader effect to do it for you in hardware. Now, my colleague can do it himself in about 5 minutes :) . Have a nice day and be good people.

Read and use FM radio (or any other USB HID device) from C#

Last time we spoke about reading and decoding RDS information from FM receivers. Also we already know how to stream sound from DirectSound compatible devices. However, before we can do it, we should be able to “speak” with such devices. So, today we’ll spoke about detection and reading information from Radio USB adapters (actually from any Human Input Devices). Let’s start.

USB FM HID

First, if you want to do it, go and buy such device. The are not a lot of alternatives, but if you’ll seek, you’ll find it very quickly.

So, let’s start. First of all, we’ll use platform invoke to get and set the information. Also, we have to preserve handle of the device from being collected by GC. After we’ll finish using the device, we’ll have to dispose it. Thus it makes sense to inherit from SafeHandle and IDisposable.

[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
public class USBDevice : SafeHandleZeroOrMinusOneIsInvalid, IDisposable {

Next, we’ll set a number of arguments, that will be in use during the device lifetime.

public uint ProductID { get; private set; }
public uint VendorID { get; private set; }
public uint VersionNumber { get; private set; }
public string Name { get; private set; }
public string SerialNumber { get; private set; }
public override bool IsInvalid { get { return !isValid; } }

internal ushort FeatureReportLength { get; private set; }
internal ushort[] Registers { get; set; }

Now, we have to find it. The best way of detection human input devices is by product and vendor IDs. Those values are always unique for certain device type.

[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
internal USBDevice(uint pid, uint vid) : base(true) { findDevice(pid, vid); }

Next step is to find a device. To do this, we have to provide extern interfaces to methods of hid.dll and setupapi.dll. Here all methods we will use in our class

[SuppressUnmanagedCodeSecurity()]
internal static class Native {
   #region methods
   [DllImport("hid.dll", SetLastError = true)]
   internal static extern void HidD_GetHidGuid(
      ref Guid lpHidGuid);

   [DllImport("hid.dll", SetLastError = true)]
   internal static extern bool HidD_GetAttributes(
      IntPtr hDevice,
      out HIDD_ATTRIBUTES Attributes);

   [DllImport("hid.dll", SetLastError = true)]
   internal static extern bool HidD_GetPreparsedData(
      IntPtr hDevice,
      out IntPtr hData);

   [DllImport("hid.dll", SetLastError = true)]
   internal static extern bool HidD_FreePreparsedData(
      IntPtr hData);

   [DllImport("hid.dll", SetLastError = true)]
   internal static extern bool HidP_GetCaps(
      IntPtr hData,
      out HIDP_CAPS capabilities);

   [DllImport("hid.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
   internal static extern bool HidD_GetFeature(
      IntPtr hDevice,
      IntPtr hReportBuffer,
      uint ReportBufferLength);

   [DllImport("hid.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
   internal static extern bool HidD_SetFeature(
      IntPtr hDevice,
      IntPtr ReportBuffer,
      uint ReportBufferLength);

   [DllImport("hid.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
   internal static extern bool HidD_GetProductString(
      IntPtr hDevice,
      IntPtr Buffer,
      uint BufferLength);

   [DllImport("hid.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
   internal static extern bool HidD_GetSerialNumberString(
      IntPtr hDevice,
      IntPtr Buffer,
      uint BufferLength);

   [DllImport("setupapi.dll", SetLastError = true)]
   internal static extern IntPtr SetupDiGetClassDevs(
      ref Guid ClassGuid,
      [MarshalAs(UnmanagedType.LPTStr)] string Enumerator,
      IntPtr hwndParent,
      UInt32 Flags);

   [DllImport("setupapi.dll", SetLastError = true)]
   internal static extern bool SetupDiEnumDeviceInterfaces(
      IntPtr DeviceInfoSet,
      int DeviceInfoData,
      ref  Guid lpHidGuid,
      uint MemberIndex,
      ref  SP_DEVICE_INTERFACE_DATA lpDeviceInterfaceData);

   [DllImport("setupapi.dll", SetLastError = true)]
   internal static extern bool SetupDiGetDeviceInterfaceDetail(
      IntPtr DeviceInfoSet,
      ref SP_DEVICE_INTERFACE_DATA lpDeviceInterfaceData,
      IntPtr hDeviceInterfaceDetailData,
      uint detailSize,
      out uint requiredSize,
      IntPtr hDeviceInfoData);

   [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
   [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
   internal static extern IntPtr CreateFile(
         string lpFileName,
         uint dwDesiredAccess,
         uint dwShareMode,
         IntPtr SecurityAttributes,
         uint dwCreationDisposition,
         uint dwFlagsAndAttributes,
         IntPtr hTemplateFile);

   [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
   [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
   internal static extern bool CloseHandle(IntPtr hHandle);

Also, we will need a number of structures, such as device attributes and capabilities.

[StructLayout(LayoutKind.Sequential)]
internal struct SP_DEVICE_INTERFACE_DATA {
   public int cbSize;
   public Guid InterfaceClassGuid;
   public int Flags;
   public int Reserved;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal class PSP_DEVICE_INTERFACE_DETAIL_DATA {
   public int cbSize;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
   public string DevicePath;
}

[StructLayout(LayoutKind.Sequential)]
internal struct HIDD_ATTRIBUTES {
   public int Size; // = sizeof (struct _HIDD_ATTRIBUTES) = 10
   public UInt16 VendorID;
   public UInt16 ProductID;
   public UInt16 VersionNumber;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HIDP_CAPS {
   public UInt16 Usage;
   public UInt16 UsagePage;
   public UInt16 InputReportByteLength;
   public UInt16 OutputReportByteLength;
   public UInt16 FeatureReportByteLength;
   [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
   public UInt16[] Reserved;
   public UInt16 NumberLinkCollectionNodes;
   public UInt16 NumberInputButtonCaps;
   public UInt16 NumberInputValueCaps;
   public UInt16 NumberInputDataIndices;
   public UInt16 NumberOutputButtonCaps;
   public UInt16 NumberOutputValueCaps;
   public UInt16 NumberOutputDataIndices;
   public UInt16 NumberFeatureButtonCaps;
   public UInt16 NumberFeatureValueCaps;
   public UInt16 NumberFeatureDataIndices;
}

And a number of system constants

internal const uint DIGCF_PRESENT = 0×00000002;
internal const uint DIGCF_DEVICEINTERFACE = 0×00000010;
internal const uint GENERIC_READ = 0×80000000;
internal const uint GENERIC_WRITE = 0×40000000;
internal const uint FILE_SHARE_READ = 0×00000001;
internal const uint FILE_SHARE_WRITE = 0×00000002;
internal const int OPEN_EXISTING = 3;
internal const int FILE_FLAG_OVERLAPPED = 0×40000000;
internal const uint MAX_USB_DEVICES = 16;

Now, we are ready to start. So let’s find all devices and get its information

Native.HidD_GetHidGuid(ref _hidGuid);
hHidDeviceInfo = Native.SetupDiGetClassDevs(ref _hidGuid, null, IntPtr.Zero, Native.DIGCF_PRESENT | Native.DIGCF_DEVICEINTERFACE);

Now, if a handle we get is valid, we should search our specific device. For this purpose, we have to read device interface information and then get details info about this device.

if (hHidDeviceInfo.ToInt32() > -1) {
   uint i = 0;
   while (!isValid && i < Native.MAX_USB_DEVICES) {
      var hidDeviceInterfaceData = new Native.SP_DEVICE_INTERFACE_DATA();
      hidDeviceInterfaceData.cbSize = Marshal.SizeOf(hidDeviceInterfaceData);
      if (Native.SetupDiEnumDeviceInterfaces(hHidDeviceInfo, 0, ref _hidGuid, i, ref hidDeviceInterfaceData)) {

Once we have all this and information is valid, let’s detect its capabilities

bool detailResult;
uint length, required;
Native.SetupDiGetDeviceInterfaceDetail(hHidDeviceInfo, ref hidDeviceInterfaceData, IntPtr.Zero, 0, out length, IntPtr.Zero);
var hidDeviceInterfaceDetailData = new Native.PSP_DEVICE_INTERFACE_DETAIL_DATA();
hidDeviceInterfaceDetailData.cbSize = 5; //DWORD cbSize (size 4) + Char[0] (size 1) for 32bit only!
var hDeviceInterfaceDetailData = Marshal.AllocHGlobal(Marshal.SizeOf(hidDeviceInterfaceDetailData));
Marshal.StructureToPtr(hidDeviceInterfaceDetailData, hDeviceInterfaceDetailData, true);
detailResult = Native.SetupDiGetDeviceInterfaceDetail(hHidDeviceInfo, ref hidDeviceInterfaceData, hDeviceInterfaceDetailData, length, out required, IntPtr.Zero);
Marshal.PtrToStructure(hDeviceInterfaceDetailData, hidDeviceInterfaceDetailData);
if (detailResult) {

To do this, we have to create memory file first and then share device attributes by using this file.

base.handle = Native.CreateFile(hidDeviceInterfaceDetailData.DevicePath,
                        Native.GENERIC_READ |
                        Native.GENERIC_WRITE,
                        Native.FILE_SHARE_READ |
                        Native.FILE_SHARE_WRITE,
                        IntPtr.Zero,
                        Native.OPEN_EXISTING,
                        Native.FILE_FLAG_OVERLAPPED,
                        IntPtr.Zero);
                     if (base.handle.ToInt32() > -1) {
                        Native.HIDD_ATTRIBUTES hidDeviceAttributes;
                        if (Native.HidD_GetAttributes(base.handle, out hidDeviceAttributes)) {

All the rest is straight forward. Just compare info retrieved with one we already have. And, of cause, release all resources were used (remember, we’re in win32 api world!)

if ((hidDeviceAttributes.VendorID == vid) && (hidDeviceAttributes.ProductID == pid)) {
                              isValid = true;
                              ProductID = pid;
                              VendorID = vid;
                              VersionNumber = hidDeviceAttributes.VersionNumber;
                              IntPtr buffer = Marshal.AllocHGlobal(126);//max alloc for string;
                              if (Native.HidD_GetProductString(this.handle, buffer, 126)) Name = Marshal.PtrToStringAuto(buffer);
                              if (Native.HidD_GetSerialNumberString(this.handle, buffer, 126)) SerialNumber = Marshal.PtrToStringAuto(buffer);
                              Marshal.FreeHGlobal(buffer);
                              var capabilities = new Native.HIDP_CAPS();
                              IntPtr hPreparsedData;
                              if (Native.HidD_GetPreparsedData(this.handle, out hPreparsedData)) {
                                 if (Native.HidP_GetCaps(hPreparsedData, out capabilities)) FeatureReportLength = capabilities.FeatureReportByteLength;
                                 Native.HidD_FreePreparsedData(hPreparsedData);
                              }
                              break;
                           }
                        } else {
                           Native.CloseHandle(base.handle);
                        }
                     }
                  }
                  Marshal.FreeHGlobal(hDeviceInterfaceDetailData);
               }
               i++;

            }

Now we have a handle to our device and can manipulate it. Like this:

using (var device = USBRadioDevice.FindDevice(0×0000, 0×1111)) {

}

But we still have to provide methods for such usage. Here there are no very complicated code.

public static USBDevice FindDevice(uint pid, uint vid) {
   var device = new USBDevice(pid,vid);
   var fillRegisters = device.InitRegisters();
   if (!device.IsInvalid && fillRegisters) return device;
   else throw new ArgumentOutOfRangeException(string.Format("Human input device {0} was not found.", pid));
}

public override string ToString() {
   return string.Format("{0} (Product:{1:x}, Vendor:{2:x}, Version:{3:x}, S/N:{4})", Name, ProductID, VendorID, VersionNumber, SerialNumber);
}

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle() {
   return Native.CloseHandle(base.handle);
}

#region IDisposable Members
public void Dispose() {
   Dispose(true);
   GC.SuppressFinalize(this);

}
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
void IDisposable.Dispose() {
   if (base.handle != null && !base.IsInvalid) {
      // Free the handle
      base.Dispose();
   }
}

#endregion

We done. Have a nice day and be good people.

P/Invoke cheat sheet

I’m working a lot with p/invoke, and know how it’s hard to produce correct signature for unmanaged method. So, today I decided to publish basic cheat sheet for methods, parameters and attributes you should use in order to invoke unmanaged methods from managed code without a lot of problems. We start with data type translations. Here the table to understand it.

Data type from unmanaged signature Data type in managed signature
int int

the same with all other simple types such as double, uint, etc or private objects

void* IntPtr
int* ref int

the same with all other simple types such as double, uint, etc or private objects

char** ref IntPtr

later, you should get ascii string by using System.Runtime.InteropServices.Marshal.PtrToStringAnsi() method

wcar_t** ref IntPtr

later, you should get ascii string by using System.Runtime.InteropServices.Marshal.PtrToStringUni() method

const int* ref int
const char* [System.Runtime.InteropServices.In()] [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string
(variable argument) [System.Runtime.InteropServices.In()] [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.AsAny)] object

You can use either System.Runtime.InteropServices.In or System.Runtime.InteropServices.Out attribute to specify how arguments should be used.

Now we done with simple arguments, let’s see what can be done when argument is actually callback or delegate?

Unmanaged definition Managed definition
typedef void (*MyCallback)(int Arg)

[System.Runtime.InteropServices.UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]delegate void MyCallback(int Arg)
Caller cleans stack argument is used to assure, that we can call varargs type function, usually used by API provider. It is very similar to C# overrides for methods. Also you can use StdCall (this is default), ThisCall – stores this first and pushes other parameters on the stack, FastCall – not very supported :(

 

To call all those methods, we should know managed equivalents of unmanaged types. Here the table. The rule is simple – know how many bytes unmanaged type has and find managed type with the same number of bytes. Other words, you can marshal int into IntPtr too…

Unmanaged type Managed equivalent
bool bool
char sbyte (signed), byte (unsigned)
wchar_t char
double double
float single
int, long (signed) Int32
int, long (unsigned) UInt32
__int64 (signed) Int64
__int64 UInt64
short (signed) Int16
short (unsigned) UInt16
void void

But not only types are problem in managed/unmanaged transitions. Also structures are aligned differently. For this purpose we can use StructLayout attribute. Even if unmanaged classes are sequential and you used correct managed data types, you can find you with problems in Pack. What “pack” is? Pack is actually slot size in bytes for members of your structure. It can be 0, 1, 2, 4, 8, 16, 32, 64, or 128 and depends on the platform and application setting.

Now you can see, that it is not very complicated to create managed signatures when you have header of unmanaged assemblies. So go ahead and ask, if I missed something.

That’s all by now. Have a nice day and be good people.

The new version of WPF Performance Profiling Tool is available for download

Finally, after a long time of silence, the new version of WPF Performance Profiling Tool is available for download for x32 and x64 OSs.  So, what’s new there?

Ton of UI improvements for Visual Profiler

image

New search function to quick find elements in visual tree

image

Hot path (critical path) of CPU usage aside with CPU usage for single element

image

Configuration of tint for overlay windows

image

Live preview, ability to split columns, slider of graph duration, expanders to have cleaner screen and much much more

Perforator also got new UI and has history now.

image

There is new tool, named String allocation profiler

image

This tool is very useful for viewing and managing strings inside your application (another step toward normal localization support for WPF? Probably)

There are also some improvements in Event tracing tool. Select process for example :)

image

And much much more. Great thank to Josef and his team for this great work

Download the new version of WPF Performance Profiling Tool >>

.NET 3.5 SP1 is RTM and available for download

For all those who asked, .NET 3.5 SP1 is final and available for download. What’s inside?

  • ASP.NET Dynamic data
  • Core improvements for CLR
  • A lot of performance improvements in WPF
  • ClickOnce enhancements
  • ADO.NET with Data Services and Entity Framework
  • LINQ2SQL and Data Provider for SQL Server 2008, that was released last week
  • WCF with easier DataContract serialization

Download it with Web Installation or as Full Package

For more information, please see Read Me and KB about .NET 3.5 SP1 RTM. If you faced with any issue, please provide us with feedback via MS Connect

Mastering Images in WPF

If you are “in” WPF imaging, you, definitely, should read this post of Dwayne Need (who is SDM of WPF in Microsoft) about customizing BitmapSource. A ton of information about how to make Bitmap Source for your needs, what WIC is and how to use it. Also he has a lot of samples in CodePlex. Great work, Dwayne.

How to make Silverlight be AiR?

Today we’ll speak about three issues

  1. How to make Silverlight application to run as stand alone application and how to insert this application inside your application?
  2. How to escape Silverlight from it’s sand box (how to make it run in full trust mode)
  3. When first two items done, how to make Silverlight to access anyfile in your file system?

Looks scary? Let’s see first reasons for those “hackery” targets. The main reason is to make Silverlight Air (you, probably understand what I’m speaking about :) ). Why? When I want to build Silverlight Image Upload control. The one similar to those Yahoo, Facebook and many others have. With live preview, editing (before uploading), drag and drop, etc. Yes, I do not want ugly File Open dialog from Silverlight. I want it sexy, yet functional! To do this, we have to make Silverlight be able to access filesystem. Of cause I want to ask user to authorize me first, then I can get an access.

image

The other reason is to incorporate Silverlight control inside WinForms application. Why? There are some reasons – “light weigh stuff”, maybe :) . Maybe banner ads inside desktop application. It’s just cool :) . Well, there are some other more serious reasons. So let’s start.

First task – to make it run as stand alone application.

Well, this one is easy. All you have to do is to have WebBrowser control with Silverlight content inside it in your application. So,

WebBrowser wb = new WebBrowser();
wb.Parent = panel1;
wb.Dock = DockStyle.Fill;
wb.Url = new Uri("http://0×15.net/play/SLFindResource/SLFindResource.html");

We done. But we’re in desktop, thus I want it full trust… This is most interesting part of today’s post.

Second task – to make it run in User Full Trust mode.

First try – to incorporate Silverlight’s OCX (ActiveX) control. Add npctrl.dll from [Program Files]\Microsoft Silverlight\[Version] – this is ActiveX and Visual Studio will create wrapper with AxHost. This one is cool, but it wont work. why? As you, probably, know Silverlight connected to it’s web page host DOM when we’re using it as stand alone player it cannot find it’s document, thus initialization failed. So what to do? What can provide me DOM from one side and run in full trust from the other side. Someone remember what HTA is (it is not mobile device, it’s very beginning of RIA era). HTML applications were run by very special host, named mshta.exe it’s in [Windows]\System32 folder and it’s still there. Everything running inside MSHTA will run by default in full trust mode. From one hand it’s regular IE, (do we have DOM), from other hand it’s make us able to run full trust internet application. Let’s use it (from code)

ProcessStartInfo mshta = new ProcessStartInfo("mshta", "http://0×15.net/play/SLFindResource/SLFindResource.html");
Process p = Process.Start(mshta);

Now we have strange window, running our Silverlight application. What’s next? Incorporate it inside our application. What’s the problem p (my process).MainWindowHandle and then SetParent for to the control I want. Well, it does not work. MSHTA has no (publicly) main window. So, we’ll find it and then change it’s parent. His class named “HTML Application Host Window Class”.

LockWindowUpdate(GetDesktopWindow());
ProcessStartInfo mshta = new ProcessStartInfo("mshta", "http://0×15.net/play/SLFindResource/SLFindResource.html");
Process p = Process.Start(mshta);
p.WaitForInputIdle();
ptr = FindWindow("HTML Application Host Window Class", null);

SetParent(ptr, panel1.Handle);
SendMessage(ptr, WM_SYSCOMMAND, SC_MAXIMIZE, 0);

LockWindowUpdate(IntPtr.Zero);

Yu-hoo. We hosted Silverlight page inside our application. It’s full trust so, we can access file system. But wait… Silverlight is not designed to have an access to the file system. The only space it can see is isolated storage, thus it has no classes for listing files anywhere. what to do?

Third task – to make it access user’s file system

We need another ActiveX to run from Javascript (or C# code) that knows to access to file system. Our hosting document can initialize it and then expose relevant methods to Silverlight. What’s such class? Let’s back to gold era of unsafe computing – we have Scripting.FileSystemObject there. This class is very dangerous it can do anything in local file system. Many system administrators using this class to script their evil login scripts (those black quick command line promps, that doing something bad to your system each time you’re logging in in your domain). It know everything about your disks and can be run from full trust environment. So, it’s just exactly what we need. Get all drives in your machine

drivetypes = [ 'Unknown', 'Removable', 'Fixed', 'Network', 'CD-ROM', 'RAM Disk' ],
driveprops = [ 'DriveLetter', 'DriveType', 'ShareName', 'IsReady', 'Path', 'RootFolder', 'FileSystem', 'SerialNumber', 'VolumeName', 'TotalSize', 'AvailableSpace', 'FreeSpace' ];

function getdrives() {
var fso = new ActiveXObject( ‘Scripting.FileSystemObject’ ),
  e = new Enumerator(fso.Drives),
  add = function(i) {
   i = driveprops[i];
   var prop = f[i];
   if( ( prop || prop===0 || prop===false ) && ( i!==’AvailableSpace’ || prop!==free ) ) {
    if( /(Type)$/.test( i ) ) { prop = drivetypes[ prop ]; }
    if( /(Size|Space)$/.test( i ) ) { prop = bykb( prop, true ); }
    s.push( i.toCamelCase() + ‘:\t’ + ( i.length < 8 ? ‘\t’ : ” ) + prop );
   }
  },

Then folders

function getfolder( s ) { s = trim( s ) || ‘C:’;
var fso = new ActiveXObject( ‘Scripting.FileSystemObject’ ),
  e, f, i, r = [];
if( fso.FolderExists( s ) ) {
  f = fso.GetFolder( s );
  e = new Enumerator(f.SubFolders);
  for( ; !e.atEnd(); e.moveNext() ) {
   if( ( i = e.item() ) ) { r.push( ‘ ‘ + i ); }
  }
  e = new Enumerator(f.files);
  for( ; !e.atEnd(); e.moveNext() ) {
   if( ( i = e.item() ) ) { r.push( ” + i ); }
  }
}
return r;
}

And files at the end

function getfile( form ) {
var fso = new ActiveXObject( ‘Scripting.FileSystemObject’ ),
  forReading = 1, forWriting = 2, forAppending = 8,
  dd = function( o, s ) {
   try {
    s = f[s] + ”;
    o.value = s.replace( /^(\w{3}) (\w+) (\d\d?) ([\d:]+) ([\w+]+) (\d+)$/, ‘$3 $2 $6 $4′ );
   } catch(e) {
    o.value = e.message;
   }
  },

Very cool we have files by using f = fso.GetFile( name ); method, now we can do anything with it. For example get or set attributes f.attributes, or rename f.Name = s, or, even delete it f.Delete(); Isn’t it really evil?

We done. Now you can run Silverlight as full trust desktop application and, even host it wherever you want. Even inside calculator…

ProcessStartInfo calc = new ProcessStartInfo("calc");
using (Process p = Process.Start(calc))
{
    p.WaitForInputIdle();
    SetParent(ptr, p.MainWindowHandle);
    SendMessage(ptr, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
    p.WaitForExit();
}

Happy programming and be good people.

Using Vista Preview Handlers in WPF application

First of all what is Preview Handler? Preview Handler is COM object, that called when you want to display the preview of your item. Other words, Preview Handlers are lightweight, rich and read-only previews of file’s content in a reading pane. You can find preview handlers in Microsoft Outlook 2007, Windows Vista and, even sometimes in XP. Can we use preview handlers within your WPF application? Probably we can. Let’s see how we can do it.

 image

Let’s create simple WPF window, that displays file list from left and preview of items in right side. We’ll use simple file list string collection as our datasource, bind it to Listbox Items and then bind selected item to some contentpresenter. I blogged about this approach earlier.

<Grid DataContext={StaticResource files}>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width=".2*"/>
            <ColumnDefinition Width=".8*"/>
        </Grid.ColumnDefinitions>
        <ListBox ItemsSource={Binding} IsSynchronizedWithCurrentItem="True" />
        <ContentPresenter Grid.Column=”1” Content={Binding Path=/}/>
        <GridSplitter Width="5"/>
    </Grid>

Our data source should be updated automatically within changes of file system. So, this is very good chance to use FileSystemWatcher object.

class ListManager:ThreadSafeObservableCollection<string>
    {
        string dir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        public ListManager()
        {
            FileSystemWatcher fsw = new FileSystemWatcher(dir);
            fsw.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite;
            fsw.Created += new FileSystemEventHandler(fsw_Created);
            fsw.Deleted += new FileSystemEventHandler(fsw_Deleted);

            fsw.EnableRaisingEvents = true;

            string[] files = Directory.GetFiles(dir);
            for (int i = 0; i < files.Length; i++)
            {
                base.Add(files[i]);
            }

        }

        void fsw_Deleted(object sender, FileSystemEventArgs e)
        {
            base.Remove(e.FullPath);
        }

        void fsw_Created(object sender, FileSystemEventArgs e)
        {
            base.Add(e.FullPath);
        }
    }

Now, after applying simple DataTemplate, we can see file list in the left pane of our application. It will be updated automatically upon files change in certain directory.

Next step is to understand how to use Preview Handlers within custom application. After all, preview handler is regular COM object, that implements following interfaces

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("8895b1c6-b41f-4c1c-a562-0d564250836f")]
interface IPreviewHandler
{
    void SetWindow(IntPtr hwnd, ref RECT rect);
    void SetRect(ref RECT rect);
    void DoPreview();
    void Unload();
    void SetFocus();
    void QueryFocus(out IntPtr phwnd);
    [PreserveSig]
    uint TranslateAccelerator(ref MSG pmsg);
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("b7d14566-0509-4cce-a71f-0a554233bd9b")]
interface IInitializeWithFile
{
    void Initialize([MarshalAs(UnmanagedType.LPWStr)] string pszFilePath, uint grfMode);
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("b824b49d-22ac-4161-ac8a-9916e8fa3f7f")]
interface IInitializeWithStream
{
    void Initialize(IStream pstream, uint grfMode);
}

In order to find and attach preview handler to specific file type, all we have to do is to look into HKEY_CLASSES_ROOT and find COM Guid of preview handler (8895b1c6-b41f-4c1c-a562-0d564250836f). The default value of this key will be the Guid of COM object, that actually can preview this type of files. Let’s do it

string CLSID = "8895b1c6-b41f-4c1c-a562-0d564250836f";
            Guid g = new Guid(CLSID);
            string[] exts = fileName.Split(‘.’);
            string ext = exts[exts.Length - 1];
            using (RegistryKey hk = Registry.ClassesRoot.OpenSubKey(string.Format(@".{0}\ShellEx\{1:B}", ext, g)))
            {
                if (hk != null)
                {
                    g = new Guid(hk.GetValue("").ToString());

Now, we know, that this file can be previewed, thus let’s initialize appropriate COM instance for preview handler

Type a = Type.GetTypeFromCLSID(g, true);
object o = Activator.CreateInstance(a);

There are two kinds of initializations for preview handlers – file and stream based. Each one has it’s own interface. So, we can only check if the object created implements this interface to be able to initialize the handler

IInitializeWithFile fileInit = o as IInitializeWithFile;
IInitializeWithStream streamInit = o as IInitializeWithStream;

bool isInitialized = false;
if (fileInit != null)
{
   fileInit.Initialize(fileName, 0);
   isInitialized = true;
  }
else if (streamInit != null)
  {
    COMStream stream = new COMStream(File.Open(fileName, FileMode.Open));
     streamInit.Initialize((IStream)streamInit, 0);
     isInitialized = true;
  }

After we initialized the handler we can set handle to the window we want the handler to sit in. Also we should provide bounds of region of the window to handler be placed in.

if (isInitialized)
                    {
                        pHandler = o as IPreviewHandler;
                        if (pHandler != null)
                        {
                            RECT r = new RECT(viewRect);
                            pHandler.SetWindow(handler, ref r);
                            pHandler.SetRect(ref r);

                            pHandler.DoPreview();
                        }
                    }

So far so good, but we’re in WPF. Thus ContentPresenter we’re using has no handle! That’s right, but the main WPF application window has. So, let’s first get the main application window handle, then create rectangle bounds of the region, occupied by ContentControl.

In order to do it, we’ll derive from ContentPresenter and will listen to ActualtHeight and ActualeWidth property of it. First get the window handler (it wont be changed during the application life cycle), then update layout of our WPF Preview Handler for region and bounds of the control.

class WPFPreviewHandler : ContentPresenter
    {
        IntPtr mainWindowHandle = IntPtr.Zero;
        Rect actualRect = new Rect();

        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            if (e.Property == ContentControl.ActualHeightProperty | e.Property == ContentControl.ActualWidthProperty)
            {
                if (mainWindowHandle == IntPtr.Zero)
                {
                    HwndSource hwndSource = PresentationSource.FromVisual(App.Current.MainWindow) as HwndSource;
                    mainWindowHandle = hwndSource.Handle;
                }
                else
                {
                    Point p0 = this.TranslatePoint(new Point(),App.Current.MainWindow);
                    Point p1 = this.TranslatePoint(new Point(this.ActualWidth,this.ActualHeight),App.Current.MainWindow);
                    actualRect = new Rect(p0, p1);
                    mainWindowHandle.InvalidateAttachedPreview(actualRect);
                }
            }

public static void InvalidateAttachedPreview(this IntPtr handler, Rect viewRect)
        {
            if (pHandler != null)
            {
                RECT r = new RECT(viewRect);
                pHandler.SetRect(ref r);
            }
        }

Now, the only thing we have to do is to listen for ContentProperty change and attache the preview handlers for displayed file to the control

if (e.Property == ContentControl.ContentProperty)
            {
                mainWindowHandle.AttachPreview(e.NewValue.ToString(),actualRect);
            }

We done. Last thing to do is to implement IStream interface in our COMStream C# class in order to be able to load streaming content (for example for PDF previewer)

public sealed class COMStream : IStream, IDisposable
{
     Stream _stream;

     ~COMStream()
     {
         if (_stream != null)
         {
             _stream.Close();
             _stream.Dispose();
             _stream = null;
         }
     }

     private COMStream() { }

     public COMStream(Stream sourceStream)
     {
         _stream = sourceStream;
     }

     #region IStream Members

     public void Clone(out IStream ppstm)
     {
         throw new NotSupportedException();
     }

     public void Commit(int grfCommitFlags)
     {
         throw new NotSupportedException();
     }

     public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)
     {
         throw new NotSupportedException();
     }

     public void LockRegion(long libOffset, long cb, int dwLockType)
     {
         throw new NotSupportedException();
     }

     [SecurityCritical]
     public void Read(byte[] pv, int cb, IntPtr pcbRead)
     {
         int count = this._stream.Read(pv, 0, cb);
         if (pcbRead != IntPtr.Zero)
         {
             Marshal.WriteInt32(pcbRead, count);
         }
     }

     public void Revert()
     {
         throw new NotSupportedException();
     }

     [SecurityCritical]
     public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition)
     {
         SeekOrigin origin = (SeekOrigin)dwOrigin;
         long pos = this._stream.Seek(dlibMove, origin);
         if (plibNewPosition != IntPtr.Zero)
         {
             Marshal.WriteInt64(plibNewPosition, pos);
         }
     }

     public void SetSize(long libNewSize)
     {
         this._stream.SetLength(libNewSize);
     }

     public void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag)
     {
         pstatstg = new System.Runtime.InteropServices.ComTypes.STATSTG();
         pstatstg.type = 2;
         pstatstg.cbSize = this._stream.Length;
         pstatstg.grfMode = 0;
         if (this._stream.CanRead && this._stream.CanWrite)
         {
             pstatstg.grfMode |= 2;
         }
         else if (this._stream.CanWrite && !_stream.CanRead)
         {
             pstatstg.grfMode |= 1;
         }
         else
         {
             throw new IOException();
         }

     }

     public void UnlockRegion(long libOffset, long cb, int dwLockType)
     {
         throw new NotSupportedException();
     }

     [SecurityCritical]
     public void Write(byte[] pv, int cb, IntPtr pcbWritten)
     {
         this._stream.Write(pv, 0, cb);
         if (pcbWritten != IntPtr.Zero)
         {
             Marshal.WriteInt32(pcbWritten, cb);
         }
     }

     #endregion

     #region IDisposable Members

     public void Dispose()
     {
         if (this._stream != null)
         {
             this._stream.Close();
             this._stream.Dispose();
             this._stream = null;
         }
     }

     #endregion
}

And now we finished. We can use unmanaged preview handlers to display content of our files, hold by WPF application. Also, if you want, you can create your own preview handlers and they’ll appear in your WPF application as well as they’ll magically appear in Outlook. Following full source code for this article

Good day, Happy Passover and, as always, be good people.

To OLE / From OLE color translator in WPF

In GDI+ (Winforms) world, there was very handy class inside System.Drawing. It named ColorTranslator and it used to translate from OLE integer color value into GDI+ Color and vice verse. In WPF there is no such class, so if you’re working with old COM/COM+ application you have either reference System.Drawing.dll or write those two methods yourself. I prefer to write it :)

public static class ColorTranslator
    {
        const int RedShift = 0;
        const int GreenShift = 8;
        const int BlueShift = 16;
        /// <summary>
        /// Translates an Ole color value to a System.Media.Color for WPF usage
        /// </summary>
        /// <param name="oleColor">Ole int32 color value</param>
        /// <returns>System.Media.Color color value</returns>
        public static Color FromOle(this int oleColor)
        {
            return Color.FromRgb(
                (byte)((oleColor >> RedShift) & 0xFF),
                (byte)((oleColor >> GreenShift) & 0xFF),
                (byte)((oleColor >> BlueShift) & 0xFF)
                );
        }

        /// <summary>
        /// Translates the specified System.Media.Color to an Ole color.
        /// </summary>
        /// <param name="wpfColor">System.Media.Color source value</param>
        /// <returns>Ole int32 color value</returns>
        public static int ToOle(Color wpfColor)
        {
            return wpfColor.R << RedShift | wpfColor.G << GreenShift | wpfColor.B << BlueShift;
        }
    }

Have a nice day and be good people.

Quick tip: How to open popup or ContextMenu in XBAP application

If you want to use ContextMenu in XBAP application this will work, only if your XBAP is in full trust mode. Else you’ll get "Request for the permission of type ‘System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′ failed". But even with Full Trust application, if you’ll try to open context menu explicitly it wont. The error, you’ll get will be "Cannot create a top-level child window". This is right. You cannot use layered windows without explicitely set parent inside browser sandbox.

Why this happens? Honestly, as for me, this is bug inside System.Windows.Controls.PopupControlService internal class (tnx to Shared .NET source code). For some reason PopupControlService set parent of the context menu while it raises ToolTipOpenning event. More, then this, it uses internal dependency property OwnerProperty to do it. So pity.

_currentToolTip.SetValue(OwnerProperty, o);

And if it is not enough it probably has memory leak, I described earlier.

_currentToolTip.Closed += OnToolTipClosed;
private void OnToolTipClosed(object sender, EventArgs e)
        {
            ToolTip toolTip = (ToolTip)sender;
            toolTip.Closed -= OnToolTipClosed;

Never mind. The question is how to take care on it, when we have no public Owner property and Parent is read only? Fortunately, dev team leave us PlacementTarget property to explicitly set the owner of ContextMenu. So, all you have to do is to add one line before setting IsOpen property to true.

private void OnMouseDown(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                contextMenu.PlacementTarget = sender as UIElement;
                contextMenu.IsOpen = true;
            }
        }

 

That’s all, folks. Now you can safely open ContextMenu in XBAP application not only with right, but also with Left mouse button as well as with keyboard event or any other code you want to.

Have a nice day.

Recommended

 

Sponsor


Partners

WPF Disciples
Dreamhost
Code Project