<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tamir Khason - Just code &#187; WPF crossbow</title>
	<atom:link href="http://khason.net/tag/wpf-crossbow/feed/" rel="self" type="application/rss+xml" />
	<link>http://khason.net</link>
	<description>Take care of the sense, and the sounds will take care of themselves.</description>
	<lastBuildDate>Mon, 02 Apr 2012 08:58:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Quick how to: Reduce number of colors programmatically</title>
		<link>http://khason.net/dev/quick-how-to-reduce-number-of-colors-programmatically/</link>
		<comments>http://khason.net/dev/quick-how-to-reduce-number-of-colors-programmatically/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 18:46:50 +0000</pubDate>
		<dc:creator>Tamir</dc:creator>
				<category><![CDATA[DEV]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[DirectX]]></category>
		<category><![CDATA[Interop]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[Work process]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[WPF crossbow]]></category>

		<guid isPermaLink="false">http://khason.net/dev/quick-how-to-reduce-number-of-colors-programmatically/</guid>
		<description><![CDATA[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: First of all, you have to read a source image using (var img = Image.FromFile(name)) { var bmpEncoder = ImageCodecInfo.GetImageDecoders().FirstOrDefault(e =&#62; e.FormatID == ImageFormat.Bmp.Guid); Then create your own encoder [...]
Related posts:<ol>
<li><a href='http://khason.net/dev/rsa-private-key-import-from-pem-format-in-c/' rel='bookmark' title='RSA private key import from PEM format in C#'>RSA private key import from PEM format in C#</a></li>
<li><a href='http://khason.net/dev/video-encoder-and-metadata-reading-by-using-windows-media-foundation/' rel='bookmark' title='Video encoder and metadata reading by using Windows Media Foundation'>Video encoder and metadata reading by using Windows Media Foundation</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>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 <img src='http://khason.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  steps:</p>
<p><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="Simple color matrix" src="http://khason.net/images/2009/02/image2.png" border="0" alt="Simple color matrix" width="383" height="366" /></p>
<p>First of all, you have to read a source image</p>
<blockquote><p>using (var img = Image.FromFile(name)) {<br />
var bmpEncoder = ImageCodecInfo.GetImageDecoders().FirstOrDefault(e =&gt; e.FormatID == ImageFormat.Bmp.Guid);</p></blockquote>
<p>Then create your own encoder with certain color depth (32 bits in this case)</p>
<blockquote><p>var myEncoder = System.Drawing.Imaging.Encoder.ColorDepth;<br />
var myEncoderParameter = new EncoderParameter(myEncoder, 32L);<br />
var myEncoderParameters = new EncoderParameters(1) { Param = new EncoderParameter[] { myEncoderParameter } };</p></blockquote>
<p>Then save it</p>
<blockquote><p>img.Save(name.Replace(&#8220;.png&#8221;, &#8220;.bmp&#8221;), bmpEncoder, myEncoderParameters);</p></blockquote>
<p>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</p>
<blockquote><p>Color GetNearestBaseColor(Color exactColor) {<br />
Color nearestColor = Colors.Black;<br />
int cnt = baseColors.Count;<br />
for (int i = 0; i &lt; cnt; i++) {<br />
int rRed = baseColors[i].R &#8211; exactColor.R;<br />
int rGreen = baseColors[i].G &#8211; exactColor.G;<br />
int rBlue = baseColors[i].B &#8211; exactColor.B;</p>
<p>int rDistance =<br />
(rRed * rRed) +<br />
(rGreen * rGreen) +<br />
(rBlue * rBlue);<br />
if (rDistance == 0.0) {<br />
return baseColors[i];<br />
} else if (rDistance &lt; maxDistance) {<br />
maxDistance = rDistance;<br />
nearestColor = baseColors[i];<br />
}<br />
}<br />
return nearestColor;<br />
}</p></blockquote>
<p>Now, you can either change colors on base image directly</p>
<blockquote><p>unsafe {<br />
uint* pBuffer = (uint*)hMap;<br />
for (int iy = 0; iy &lt; (int)ColorMapSource.PixelHeight; ++iy)<br />
{<br />
for (int ix = 0; ix &lt; nWidth; ++ix)<br />
{<br />
Color nc = GetNearestBaseColor(pBuffer[0].FromOle());</p>
<p>pBuffer[0] &amp;= (uint)((uint)nc.A &lt;&lt; 24) | //A<br />
(uint)(nc.R &lt;&lt; 16 ) | //R<br />
(uint)(nc.G &lt;&lt; 8 ) | //G<br />
(uint)(nc.B ); //B<br />
++pBuffer;<br />
}<br />
pBuffer += nOffset;<br />
}<br />
}</p></blockquote>
<p>Or, if you’re in WPF and .NET 3.5 <a title="HLSL (Pixel shader) effects tutorial" href="http://khason.net/blog/hlsl-pixel-shader-effects-tutorial/" target="_blank">create simple pixel shader effect</a> to do it for you in hardware. Now, my colleague can do it himself in about 5 minutes <img src='http://khason.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  . Have a nice day and be good people.</p>
<p>Related posts:<ol>
<li><a href='http://khason.net/dev/rsa-private-key-import-from-pem-format-in-c/' rel='bookmark' title='RSA private key import from PEM format in C#'>RSA private key import from PEM format in C#</a></li>
<li><a href='http://khason.net/dev/video-encoder-and-metadata-reading-by-using-windows-media-foundation/' rel='bookmark' title='Video encoder and metadata reading by using Windows Media Foundation'>Video encoder and metadata reading by using Windows Media Foundation</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://khason.net/dev/quick-how-to-reduce-number-of-colors-programmatically/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Read and use FM radio (or any other USB HID device) from C#</title>
		<link>http://khason.net/blog/read-and-use-fm-radio-or-any-other-usb-hid-device-from-c/</link>
		<comments>http://khason.net/blog/read-and-use-fm-radio-or-any-other-usb-hid-device-from-c/#comments</comments>
		<pubDate>Tue, 30 Dec 2008 20:42:18 +0000</pubDate>
		<dc:creator>Tamir</dc:creator>
				<category><![CDATA[BLOG]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[DEV]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Interop]]></category>
		<category><![CDATA[source]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[Vista]]></category>
		<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[Work process]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[WPF crossbow]]></category>

		<guid isPermaLink="false">http://khason.net/blog/read-and-use-fm-radio-or-any-other-usb-hid-device-from-c/</guid>
		<description><![CDATA[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 [...]
Related posts:<ol>
<li><a href='http://khason.net/dev/video-encoder-and-metadata-reading-by-using-windows-media-foundation/' rel='bookmark' title='Video encoder and metadata reading by using Windows Media Foundation'>Video encoder and metadata reading by using Windows Media Foundation</a></li>
<li><a href='http://khason.net/dev/rsa-private-key-import-from-pem-format-in-c/' rel='bookmark' title='RSA private key import from PEM format in C#'>RSA private key import from PEM format in C#</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Last time <a href="http://khason.net/blog/reading-and-decoding-rds-radio-data-system-in-c/">we spoke about reading and decoding RDS information from FM receivers</a>. Also <a href="http://khason.net/blog/capturing-and-streaming-sound-by-using-directsound-with-c/">we already know how to stream sound from DirectSound compatible devices</a>. 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.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="USB FM HID" border="0" alt="USB FM HID" src="http://khason.net/images/2008/12/image-460dcf0b.png" width="240" height="211" /> </p>
<p>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.</p>
<p>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.</p>
<blockquote><p>[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]     <br />[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]      <br />public class USBDevice : SafeHandleZeroOrMinusOneIsInvalid, IDisposable {</p>
</blockquote>
<p>Next, we’ll set a number of arguments, that will be in use during the device lifetime.</p>
<blockquote><p>public uint ProductID { get; private set; }     <br />public uint VendorID { get; private set; }      <br />public uint VersionNumber { get; private set; }      <br />public string Name { get; private set; }      <br />public string SerialNumber { get; private set; }      <br />public override bool IsInvalid { get { return !isValid; } } </p>
<p>internal ushort FeatureReportLength { get; private set; }     <br />internal ushort[] Registers { get; set; }</p>
</blockquote>
<p>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.</p>
<blockquote><p>[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]     <br />internal USBDevice(uint pid, uint vid) : base(true) { findDevice(pid, vid); }</p>
</blockquote>
<p>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</p>
<blockquote><p>[SuppressUnmanagedCodeSecurity()]     <br />internal static class Native {      <br />&#160;&#160; #region methods      <br />&#160;&#160; [DllImport(&quot;hid.dll&quot;, SetLastError = true)]      <br />&#160;&#160; internal static extern void HidD_GetHidGuid(      <br />&#160;&#160;&#160;&#160;&#160; ref Guid lpHidGuid); </p>
<p>&#160;&#160; [DllImport(&quot;hid.dll&quot;, SetLastError = true)]     <br />&#160;&#160; internal static extern bool HidD_GetAttributes(      <br />&#160;&#160;&#160;&#160;&#160; IntPtr hDevice,      <br />&#160;&#160;&#160;&#160;&#160; out HIDD_ATTRIBUTES Attributes); </p>
<p>&#160;&#160; [DllImport(&quot;hid.dll&quot;, SetLastError = true)]     <br />&#160;&#160; internal static extern bool HidD_GetPreparsedData(      <br />&#160;&#160;&#160;&#160;&#160; IntPtr hDevice,      <br />&#160;&#160;&#160;&#160;&#160; out IntPtr hData); </p>
<p>&#160;&#160; [DllImport(&quot;hid.dll&quot;, SetLastError = true)]     <br />&#160;&#160; internal static extern bool HidD_FreePreparsedData(      <br />&#160;&#160;&#160;&#160;&#160; IntPtr hData); </p>
<p>&#160;&#160; [DllImport(&quot;hid.dll&quot;, SetLastError = true)]     <br />&#160;&#160; internal static extern bool HidP_GetCaps(      <br />&#160;&#160;&#160;&#160;&#160; IntPtr hData,      <br />&#160;&#160;&#160;&#160;&#160; out HIDP_CAPS capabilities); </p>
<p>&#160;&#160; [DllImport(&quot;hid.dll&quot;, SetLastError = true, CallingConvention = CallingConvention.StdCall)]     <br />&#160;&#160; internal static extern bool HidD_GetFeature(      <br />&#160;&#160;&#160;&#160;&#160; IntPtr hDevice,      <br />&#160;&#160;&#160;&#160;&#160; IntPtr hReportBuffer,      <br />&#160;&#160;&#160;&#160;&#160; uint ReportBufferLength); </p>
<p>&#160;&#160; [DllImport(&quot;hid.dll&quot;, SetLastError = true, CallingConvention = CallingConvention.StdCall)]     <br />&#160;&#160; internal static extern bool HidD_SetFeature(      <br />&#160;&#160;&#160;&#160;&#160; IntPtr hDevice,      <br />&#160;&#160;&#160;&#160;&#160; IntPtr ReportBuffer,      <br />&#160;&#160;&#160;&#160;&#160; uint ReportBufferLength); </p>
<p>&#160;&#160; [DllImport(&quot;hid.dll&quot;, SetLastError = true, CallingConvention = CallingConvention.StdCall)]     <br />&#160;&#160; internal static extern bool HidD_GetProductString(      <br />&#160;&#160;&#160;&#160;&#160; IntPtr hDevice,       <br />&#160;&#160;&#160;&#160;&#160; IntPtr Buffer,       <br />&#160;&#160;&#160;&#160;&#160; uint BufferLength); </p>
<p>&#160;&#160; [DllImport(&quot;hid.dll&quot;, SetLastError = true, CallingConvention = CallingConvention.StdCall)]     <br />&#160;&#160; internal static extern bool HidD_GetSerialNumberString(      <br />&#160;&#160;&#160;&#160;&#160; IntPtr hDevice,      <br />&#160;&#160;&#160;&#160;&#160; IntPtr Buffer,      <br />&#160;&#160;&#160;&#160;&#160; uint BufferLength); </p>
<p>&#160;&#160; [DllImport(&quot;setupapi.dll&quot;, SetLastError = true)]     <br />&#160;&#160; internal static extern IntPtr SetupDiGetClassDevs(      <br />&#160;&#160;&#160;&#160;&#160; ref Guid ClassGuid,      <br />&#160;&#160;&#160;&#160;&#160; [MarshalAs(UnmanagedType.LPTStr)] string Enumerator,      <br />&#160;&#160;&#160;&#160;&#160; IntPtr hwndParent,      <br />&#160;&#160;&#160;&#160;&#160; UInt32 Flags); </p>
<p>&#160;&#160; [DllImport(&quot;setupapi.dll&quot;, SetLastError = true)]     <br />&#160;&#160; internal static extern bool SetupDiEnumDeviceInterfaces(      <br />&#160;&#160;&#160;&#160;&#160; IntPtr DeviceInfoSet,      <br />&#160;&#160;&#160;&#160;&#160; int DeviceInfoData,      <br />&#160;&#160;&#160;&#160;&#160; ref&#160; Guid lpHidGuid,      <br />&#160;&#160;&#160;&#160;&#160; uint MemberIndex,      <br />&#160;&#160;&#160;&#160;&#160; ref&#160; SP_DEVICE_INTERFACE_DATA lpDeviceInterfaceData); </p>
<p>&#160;&#160; [DllImport(&quot;setupapi.dll&quot;, SetLastError = true)]     <br />&#160;&#160; internal static extern bool SetupDiGetDeviceInterfaceDetail(      <br />&#160;&#160;&#160;&#160;&#160; IntPtr DeviceInfoSet,      <br />&#160;&#160;&#160;&#160;&#160; ref SP_DEVICE_INTERFACE_DATA lpDeviceInterfaceData,      <br />&#160;&#160;&#160;&#160;&#160; IntPtr hDeviceInterfaceDetailData,      <br />&#160;&#160;&#160;&#160;&#160; uint detailSize,      <br />&#160;&#160;&#160;&#160;&#160; out uint requiredSize,      <br />&#160;&#160;&#160;&#160;&#160; IntPtr hDeviceInfoData); </p>
<p>&#160;&#160; [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]     <br />&#160;&#160; [DllImport(&quot;kernel32.dll&quot;, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]      <br />&#160;&#160; internal static extern IntPtr CreateFile(      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; string lpFileName,      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; uint dwDesiredAccess,      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; uint dwShareMode,      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IntPtr SecurityAttributes,      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; uint dwCreationDisposition,      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; uint dwFlagsAndAttributes,      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IntPtr hTemplateFile); </p>
<p>&#160;&#160; [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]     <br />&#160;&#160; [DllImport(&quot;kernel32.dll&quot;, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]      <br />&#160;&#160; internal static extern bool CloseHandle(IntPtr hHandle);</p>
</blockquote>
<p>Also, we will need a number of structures, such as device attributes and capabilities.</p>
<blockquote><p>[StructLayout(LayoutKind.Sequential)]     <br />internal struct SP_DEVICE_INTERFACE_DATA {      <br />&#160;&#160; public int cbSize;      <br />&#160;&#160; public Guid InterfaceClassGuid;      <br />&#160;&#160; public int Flags;      <br />&#160;&#160; public int Reserved;      <br />} </p>
<p>[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]     <br />internal class PSP_DEVICE_INTERFACE_DETAIL_DATA {      <br />&#160;&#160; public int cbSize;      <br />&#160;&#160; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]      <br />&#160;&#160; public string DevicePath;      <br />} </p>
<p>[StructLayout(LayoutKind.Sequential)]     <br />internal struct HIDD_ATTRIBUTES {      <br />&#160;&#160; public int Size; // = sizeof (struct _HIDD_ATTRIBUTES) = 10      <br />&#160;&#160; public UInt16 VendorID;      <br />&#160;&#160; public UInt16 ProductID;      <br />&#160;&#160; public UInt16 VersionNumber;      <br />}      <br />[StructLayout(LayoutKind.Sequential)]      <br />internal struct HIDP_CAPS {      <br />&#160;&#160; public UInt16 Usage;      <br />&#160;&#160; public UInt16 UsagePage;      <br />&#160;&#160; public UInt16 InputReportByteLength;      <br />&#160;&#160; public UInt16 OutputReportByteLength;      <br />&#160;&#160; public UInt16 FeatureReportByteLength;      <br />&#160;&#160; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]      <br />&#160;&#160; public UInt16[] Reserved;      <br />&#160;&#160; public UInt16 NumberLinkCollectionNodes;      <br />&#160;&#160; public UInt16 NumberInputButtonCaps;      <br />&#160;&#160; public UInt16 NumberInputValueCaps;      <br />&#160;&#160; public UInt16 NumberInputDataIndices;      <br />&#160;&#160; public UInt16 NumberOutputButtonCaps;      <br />&#160;&#160; public UInt16 NumberOutputValueCaps;      <br />&#160;&#160; public UInt16 NumberOutputDataIndices;      <br />&#160;&#160; public UInt16 NumberFeatureButtonCaps;      <br />&#160;&#160; public UInt16 NumberFeatureValueCaps;      <br />&#160;&#160; public UInt16 NumberFeatureDataIndices;      <br />}</p>
</blockquote>
<p>And a number of system constants</p>
<blockquote><p>internal const uint DIGCF_PRESENT = 0&#215;00000002;     <br />internal const uint DIGCF_DEVICEINTERFACE = 0&#215;00000010;      <br />internal const uint GENERIC_READ = 0&#215;80000000;      <br />internal const uint GENERIC_WRITE = 0&#215;40000000;      <br />internal const uint FILE_SHARE_READ = 0&#215;00000001;      <br />internal const uint FILE_SHARE_WRITE = 0&#215;00000002;      <br />internal const int OPEN_EXISTING = 3;      <br />internal const int FILE_FLAG_OVERLAPPED = 0&#215;40000000;      <br />internal const uint MAX_USB_DEVICES = 16;</p>
</blockquote>
<p>Now, we are ready to start. So let’s find all devices and get its information</p>
<blockquote><p>Native.HidD_GetHidGuid(ref _hidGuid);     <br />hHidDeviceInfo = Native.SetupDiGetClassDevs(ref _hidGuid, null, IntPtr.Zero, Native.DIGCF_PRESENT | Native.DIGCF_DEVICEINTERFACE);</p>
</blockquote>
<p>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.</p>
<blockquote><p>if (hHidDeviceInfo.ToInt32() &gt; -1) {     <br />&#160;&#160; uint i = 0;      <br />&#160;&#160; while (!isValid &amp;&amp; i &lt; Native.MAX_USB_DEVICES) {      <br />&#160;&#160;&#160;&#160;&#160; var hidDeviceInterfaceData = new Native.SP_DEVICE_INTERFACE_DATA();      <br />&#160;&#160;&#160;&#160;&#160; hidDeviceInterfaceData.cbSize = Marshal.SizeOf(hidDeviceInterfaceData);      <br />&#160;&#160;&#160;&#160;&#160; if (Native.SetupDiEnumDeviceInterfaces(hHidDeviceInfo, 0, ref _hidGuid, i, ref hidDeviceInterfaceData)) {</p>
</blockquote>
<p>Once we have all this and information is valid, let’s detect its capabilities</p>
<blockquote><p>bool detailResult;     <br />uint length, required;      <br />Native.SetupDiGetDeviceInterfaceDetail(hHidDeviceInfo, ref hidDeviceInterfaceData, IntPtr.Zero, 0, out length, IntPtr.Zero);      <br />var hidDeviceInterfaceDetailData = new Native.PSP_DEVICE_INTERFACE_DETAIL_DATA();      <br />hidDeviceInterfaceDetailData.cbSize = 5; //DWORD cbSize (size 4) + Char[0] (size 1) for 32bit only!      <br />var hDeviceInterfaceDetailData = Marshal.AllocHGlobal(Marshal.SizeOf(hidDeviceInterfaceDetailData));      <br />Marshal.StructureToPtr(hidDeviceInterfaceDetailData, hDeviceInterfaceDetailData, true);      <br />detailResult = Native.SetupDiGetDeviceInterfaceDetail(hHidDeviceInfo, ref hidDeviceInterfaceData, hDeviceInterfaceDetailData, length, out required, IntPtr.Zero);      <br />Marshal.PtrToStructure(hDeviceInterfaceDetailData, hidDeviceInterfaceDetailData);      <br />if (detailResult) {</p>
</blockquote>
<p>To do this, we have to create memory file first and then share device attributes by using this file.</p>
<blockquote><p>base.handle = Native.CreateFile(hidDeviceInterfaceDetailData.DevicePath,      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Native.GENERIC_READ |      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Native.GENERIC_WRITE,      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Native.FILE_SHARE_READ |      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Native.FILE_SHARE_WRITE,       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IntPtr.Zero,      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Native.OPEN_EXISTING,      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Native.FILE_FLAG_OVERLAPPED,       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IntPtr.Zero);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (base.handle.ToInt32() &gt; -1) {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Native.HIDD_ATTRIBUTES hidDeviceAttributes;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (Native.HidD_GetAttributes(base.handle, out hidDeviceAttributes)) {</p>
</blockquote>
<p>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!)</p>
<blockquote><p>if ((hidDeviceAttributes.VendorID == vid) &amp;&amp; (hidDeviceAttributes.ProductID == pid)) {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; isValid = true;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ProductID = pid;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; VendorID = vid;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; VersionNumber = hidDeviceAttributes.VersionNumber;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IntPtr buffer = Marshal.AllocHGlobal(126);//max alloc for string;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (Native.HidD_GetProductString(this.handle, buffer, 126)) Name = Marshal.PtrToStringAuto(buffer);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (Native.HidD_GetSerialNumberString(this.handle, buffer, 126)) SerialNumber = Marshal.PtrToStringAuto(buffer);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Marshal.FreeHGlobal(buffer);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var capabilities = new Native.HIDP_CAPS();      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IntPtr hPreparsedData;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (Native.HidD_GetPreparsedData(this.handle, out hPreparsedData)) {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (Native.HidP_GetCaps(hPreparsedData, out capabilities)) FeatureReportLength = capabilities.FeatureReportByteLength;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Native.HidD_FreePreparsedData(hPreparsedData);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } else {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Native.CloseHandle(base.handle);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Marshal.FreeHGlobal(hDeviceInterfaceDetailData);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; i++; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
</blockquote>
<p>Now we have a handle to our device and can manipulate it. Like this:</p>
<blockquote><p>using (var device = USBRadioDevice.FindDevice(0&#215;0000, 0&#215;1111)) {     <br />…      <br />}</p>
</blockquote>
<p>But we still have to provide methods for such usage. Here there are no very complicated code.</p>
<blockquote><p>public static USBDevice FindDevice(uint pid, uint vid) {     <br />&#160;&#160; var device = new USBDevice(pid,vid);      <br />&#160;&#160; var fillRegisters = device.InitRegisters();      <br />&#160;&#160; if (!device.IsInvalid &amp;&amp; fillRegisters) return device;      <br />&#160;&#160; else throw new ArgumentOutOfRangeException(string.Format(&quot;Human input device {0} was not found.&quot;, pid));      <br />} </p>
<p>public override string ToString() {     <br />&#160;&#160; return string.Format(&quot;{0} (Product:{1:x}, Vendor:{2:x}, Version:{3:x}, S/N:{4})&quot;, Name, ProductID, VendorID, VersionNumber, SerialNumber);      <br />} </p>
<p>[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]     <br />protected override bool ReleaseHandle() {      <br />&#160;&#160; return Native.CloseHandle(base.handle);      <br />} </p>
<p>#region IDisposable Members     <br />public void Dispose() {      <br />&#160;&#160; Dispose(true);      <br />&#160;&#160; GC.SuppressFinalize(this); </p>
<p>}     <br />[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]      <br />void IDisposable.Dispose() {      <br />&#160;&#160; if (base.handle != null &amp;&amp; !base.IsInvalid) {      <br />&#160;&#160;&#160;&#160;&#160; // Free the handle      <br />&#160;&#160;&#160;&#160;&#160; base.Dispose();      <br />&#160;&#160; }      <br />} </p>
<p>#endregion</p>
</blockquote>
<p>We done. Have a nice day and be good people.</p>
<p>Related posts:<ol>
<li><a href='http://khason.net/dev/video-encoder-and-metadata-reading-by-using-windows-media-foundation/' rel='bookmark' title='Video encoder and metadata reading by using Windows Media Foundation'>Video encoder and metadata reading by using Windows Media Foundation</a></li>
<li><a href='http://khason.net/dev/rsa-private-key-import-from-pem-format-in-c/' rel='bookmark' title='RSA private key import from PEM format in C#'>RSA private key import from PEM format in C#</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://khason.net/blog/read-and-use-fm-radio-or-any-other-usb-hid-device-from-c/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>P/Invoke cheat sheet</title>
		<link>http://khason.net/blog/pinvoke-cheat-sheet/</link>
		<comments>http://khason.net/blog/pinvoke-cheat-sheet/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 16:02:40 +0000</pubDate>
		<dc:creator>Tamir</dc:creator>
				<category><![CDATA[BLOG]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[DEV]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[Work process]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[WPF crossbow]]></category>
		<category><![CDATA[x64]]></category>

		<guid isPermaLink="false">http://khason.net/blog/pinvoke-cheat-sheet/</guid>
		<description><![CDATA[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. [...]<p/>]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<table cellspacing="0" cellpadding="2" width="600" border="0">
<tbody>
<tr>
<td valign="top" width="300">Data type from unmanaged signature</td>
<td valign="top" width="300">Data type in managed signature</td>
</tr>
<tr>
<td valign="top" width="300">int</td>
<td valign="top" width="300">int         </p>
<p><em>the same with all other simple types such as double, uint, etc or private objects</em></td>
</tr>
<tr>
<td valign="top" width="300">void*</td>
<td valign="top" width="300">IntPtr</td>
</tr>
<tr>
<td valign="top" width="300">int*</td>
<td valign="top" width="300">ref int         </p>
<p><em>the same with all other simple types such as double, uint, etc </em><em>or private objects</em> </td>
</tr>
<tr>
<td valign="top" width="300">char**</td>
<td valign="top" width="300">ref IntPtr         </p>
<p><em>later, you should get ascii string by using System.Runtime.InteropServices.Marshal.PtrToStringAnsi() method</em></td>
</tr>
<tr>
<td valign="top" width="300">wcar_t**</td>
<td valign="top" width="300">ref IntPtr         </p>
<p><em>later, you should get ascii string by using System.Runtime.InteropServices.Marshal.PtrToStringUni() method</em></td>
</tr>
<tr>
<td valign="top" width="300">const int*</td>
<td valign="top" width="300">ref int</td>
</tr>
<tr>
<td valign="top" width="300">const char*</td>
<td valign="top" width="300">[System.Runtime.InteropServices.In()] [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string</td>
</tr>
<tr>
<td valign="top" width="300">… <em>(variable argument)</em></td>
<td valign="top" width="300">[System.Runtime.InteropServices.In()] [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.AsAny)] object</td>
</tr>
</tbody>
</table>
<p><em>You can use either System.Runtime.InteropServices.In or System.Runtime.InteropServices.Out attribute to specify how arguments should be used.</em></p>
<p>Now we done with simple arguments, let’s see what can be done when argument is actually callback or delegate?</p>
<table cellspacing="0" cellpadding="2" width="600" border="0">
<tbody>
<tr>
<td valign="top" width="300">Unmanaged definition</td>
<td valign="top" width="300">Managed definition</td>
</tr>
<tr>
<td valign="top" width="300">typedef void (*MyCallback)(int Arg)</td>
<td valign="top" width="300">
<p>[System.Runtime.InteropServices.UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]delegate void MyCallback(int Arg)           <br /><em>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 <img src='http://khason.net/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </em></p>
</td>
</tr>
</tbody>
</table>
<p>&#160;</p>
<p>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…</p>
<table cellspacing="0" cellpadding="2" width="600" border="0">
<tbody>
<tr>
<td valign="top" width="300">Unmanaged type</td>
<td valign="top" width="300">Managed equivalent</td>
</tr>
<tr>
<td valign="top" width="300">bool</td>
<td valign="top" width="300">bool</td>
</tr>
<tr>
<td valign="top" width="300">char</td>
<td valign="top" width="300">sbyte (signed), byte (unsigned)</td>
</tr>
<tr>
<td valign="top" width="300">wchar_t</td>
<td valign="top" width="300">char</td>
</tr>
<tr>
<td valign="top" width="300">double</td>
<td valign="top" width="300">double</td>
</tr>
<tr>
<td valign="top" width="300">float</td>
<td valign="top" width="300">single</td>
</tr>
<tr>
<td valign="top" width="300">int, long (signed)</td>
<td valign="top" width="300">Int32</td>
</tr>
<tr>
<td valign="top" width="300">int, long (unsigned)</td>
<td valign="top" width="300">UInt32</td>
</tr>
<tr>
<td valign="top" width="300">__int64 (signed)</td>
<td valign="top" width="300">Int64</td>
</tr>
<tr>
<td valign="top" width="300">__int64</td>
<td valign="top" width="300">UInt64</td>
</tr>
<tr>
<td valign="top" width="300">short (signed)</td>
<td valign="top" width="300">Int16</td>
</tr>
<tr>
<td valign="top" width="300">short (unsigned)</td>
<td valign="top" width="300">UInt16</td>
</tr>
<tr>
<td valign="top" width="300">void</td>
<td valign="top" width="300">void</td>
</tr>
</tbody>
</table>
<p>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.</p>
<p>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.</p>
<p>That’s all by now. Have a nice day and be good people.</p>
<p/>]]></content:encoded>
			<wfw:commentRss>http://khason.net/blog/pinvoke-cheat-sheet/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>The new version of WPF Performance Profiling Tool is available for download</title>
		<link>http://khason.net/blog/the-new-version-of-wpf-performance-profiling-tool-is-available-for-download/</link>
		<comments>http://khason.net/blog/the-new-version-of-wpf-performance-profiling-tool-is-available-for-download/#comments</comments>
		<pubDate>Fri, 26 Sep 2008 15:07:34 +0000</pubDate>
		<dc:creator>Tamir</dc:creator>
				<category><![CDATA[BLOG]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[DEV]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[My tools]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[promo]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[WPF crossbow]]></category>

		<guid isPermaLink="false">http://khason.net/blog/the-new-version-of-wpf-performance-profiling-tool-is-available-for-download/</guid>
		<description><![CDATA[Finally, after a long time of silence, the new version of WPF Performance Profiling Tool is available for download for x32 and x64 OSs.&#160; So, what’s new there? Ton of UI improvements for Visual Profiler New search function to quick find elements in visual tree Hot path (critical path) of CPU usage aside with CPU [...]<p/>]]></description>
			<content:encoded><![CDATA[<p>Finally, after a long time of silence, the new version of WPF Performance Profiling Tool is available for download for x32 and x64 OSs.&#160; So, what’s new there?</p>
<p>Ton of UI improvements for Visual Profiler</p>
<p><img title="image" style="display: inline" height="314" alt="image" src="http://khason.net/images/2008/12/image-7600c96c.png" width="377" border="0" /> </p>
<p>New search function to quick find elements in visual tree</p>
<p><img title="image" style="display: inline" height="195" alt="image" src="http://khason.net/images/2008/12/image-5c1c6d70.png" width="377" border="0" /> </p>
<p>Hot path (critical path) of CPU usage aside with CPU usage for single element</p>
<p><img title="image" style="display: inline" height="249" alt="image" src="http://khason.net/images/2008/12/image-07bd11a0.png" width="377" border="0" /> </p>
<p>Configuration of tint for overlay windows</p>
<p><img title="image" style="display: inline" height="293" alt="image" src="http://khason.net/images/2008/12/image-1a61e58a.png" width="377" border="0" /> </p>
<p>Live preview, ability to split columns, slider of graph duration, expanders to have cleaner screen and much much more</p>
<p>Perforator also got new UI and has history now.</p>
<p><img title="image" style="display: inline" height="288" alt="image" src="http://khason.net/images/2008/12/image-3b453264.png" width="377" border="0" /> </p>
<p>There is new tool, named String allocation profiler</p>
<p><img title="image" style="display: inline" height="318" alt="image" src="http://khason.net/images/2008/12/image-26631417.png" width="351" border="0" /> </p>
<p>This tool is very useful for viewing and managing strings inside your application (another step toward normal localization support for WPF? Probably)</p>
<p>There are also some improvements in Event tracing tool. Select process for example <img src='http://khason.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><img title="image" style="display: inline" height="271" alt="image" src="http://khason.net/images/2008/12/image-60ae642b.png" width="377" border="0" /> </p>
<p>And much much more. Great thank to <a href="http://blogs.msdn.com/jgoldb/archive/2008/09/25/updated-wpfperf-performance-profiling-tools-for-wpf.aspx">Josef and his team</a> for this great work </p>
<p><a href="http://windowsclient.net/wpf/perf/wpf-perf-tool.aspx"><strong>Download the new version of WPF Performance Profiling Tool &gt;&gt;</strong></a></p>
<p/>]]></content:encoded>
			<wfw:commentRss>http://khason.net/blog/the-new-version-of-wpf-performance-profiling-tool-is-available-for-download/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>.NET 3.5 SP1 is RTM and available for download</title>
		<link>http://khason.net/blog/net-35-sp1-is-rtm-and-available-for-download/</link>
		<comments>http://khason.net/blog/net-35-sp1-is-rtm-and-available-for-download/#comments</comments>
		<pubDate>Mon, 11 Aug 2008 11:12:48 +0000</pubDate>
		<dc:creator>Tamir</dc:creator>
				<category><![CDATA[BLOG]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[My tools]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[promo]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[WPF crossbow]]></category>

		<guid isPermaLink="false">http://khason.net/blog/net-35-sp1-is-rtm-and-available-for-download/</guid>
		<description><![CDATA[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 [...]<p/>]]></description>
			<content:encoded><![CDATA[</p>
<p>For all those who asked, .NET 3.5 SP1 is final and available for download. What’s inside?</p>
<ul>
<li>ASP.NET Dynamic data</li>
<li>Core improvements for CLR</li>
<li>A lot of performance improvements in WPF</li>
<li>ClickOnce enhancements</li>
<li>ADO.NET with Data Services and Entity Framework</li>
<li>LINQ2SQL and Data Provider for SQL Server 2008, that was released last week</li>
<li>WCF with easier DataContract serialization</li>
</ul>
<p>Download it with <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=ab99342f-5d1a-413d-8319-81da479ab0d7&amp;DisplayLang=en">Web Installation</a> or as <a href="http://download.microsoft.com/download/2/0/e/20e90413-712f-438c-988e-fdaa79a8ac3d/dotnetfx35.exe">Full Package</a></p>
<p>For more information, please see <a href="http://www.microsoft.com/downloads/info.aspx?na=40&amp;p=1&amp;SrcDisplayLang=en&amp;SrcCategoryId=&amp;SrcFamilyId=ab99342f-5d1a-413d-8319-81da479ab0d7&amp;u=http%3a%2f%2fgo.microsoft.com%2ffwlink%2f%3fLinkId%3d122089">Read Me</a> and <a href="http://www.microsoft.com/downloads/info.aspx?na=40&amp;p=2&amp;SrcDisplayLang=en&amp;SrcCategoryId=&amp;SrcFamilyId=ab99342f-5d1a-413d-8319-81da479ab0d7&amp;u=http%3a%2f%2fsupport.microsoft.com%2fkb%2f951847">KB</a> about .NET 3.5 SP1 RTM. If you faced with any issue, please provide us with feedback <a href="https://connect.microsoft.com/VisualStudio">via MS Connect</a></p>
<p/>]]></content:encoded>
			<wfw:commentRss>http://khason.net/blog/net-35-sp1-is-rtm-and-available-for-download/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Mastering Images in WPF</title>
		<link>http://khason.net/blog/mastering-images-in-wpf/</link>
		<comments>http://khason.net/blog/mastering-images-in-wpf/#comments</comments>
		<pubDate>Sun, 22 Jun 2008 09:53:00 +0000</pubDate>
		<dc:creator>Tamir</dc:creator>
				<category><![CDATA[BLOG]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[promo]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[WPF crossbow]]></category>

		<guid isPermaLink="false">http://khason.net/blog/mastering-images-in-wpf/</guid>
		<description><![CDATA[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. [...]<p/>]]></description>
			<content:encoded><![CDATA[<p>If you are “in” WPF imaging, you, definitely, should <a href="http://blogs.msdn.com/dwayneneed/archive/2008/06/20/implementing-a-custom-bitmapsource.aspx" mce_href="http://blogs.msdn.com/dwayneneed/archive/2008/06/20/implementing-a-custom-bitmapsource.aspx">read this post</a> 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 <a href="http://www.codeplex.com/MicrosoftDwayneNeed" mce_href="http://www.codeplex.com/MicrosoftDwayneNeed">lot of samples in CodePlex</a>. Great work, Dwayne.</p>
<p/>]]></content:encoded>
			<wfw:commentRss>http://khason.net/blog/mastering-images-in-wpf/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How to make Silverlight be AiR?</title>
		<link>http://khason.net/blog/how-to-make-silverlight-be-air/</link>
		<comments>http://khason.net/blog/how-to-make-silverlight-be-air/#comments</comments>
		<pubDate>Sun, 27 Apr 2008 20:29:02 +0000</pubDate>
		<dc:creator>Tamir</dc:creator>
				<category><![CDATA[BLOG]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[SVG]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[Vista]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[WPF crossbow]]></category>

		<guid isPermaLink="false">http://khason.net/blog/how-to-make-silverlight-be-air/</guid>
		<description><![CDATA[Today we’ll speak about three issues How to make Silverlight application to run as stand alone application and how to insert this application inside your application? How to escape Silverlight from it’s sand box (how to make it run in full trust mode) When first two items done, how to make Silverlight to access anyfile [...]<p/>]]></description>
			<content:encoded><![CDATA[<p>Today we’ll speak about three issues</p>
<ol>
<li>How to make Silverlight application to run as stand alone application and how to insert this application inside your application?</li>
<li>How to escape Silverlight from it’s sand box (how to make it run in full trust mode)</li>
<li>When first two items done, how to make Silverlight to access anyfile in your file system?</li>
</ol>
<p>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 <img src='http://khason.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). 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.</p>
<p><img title="image" border="0" alt="image" src="http://khason.net/images/2008/12/image-b54b4803-58bc-41a7-9dd2-a7012758734f.png" width="561" height="407" /> </p>
<p>The other reason is to incorporate Silverlight control inside WinForms application. Why? There are some reasons &#8211; “light weigh stuff”, maybe <img src='http://khason.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Maybe banner ads inside desktop application. It’s just cool <img src='http://khason.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Well, there are some other more serious reasons. So let’s start. </p>
<h3>First task – to make it run as stand alone application.</h3>
<p>Well, this one is easy. All you have to do is to have WebBrowser control with Silverlight content inside it in your application. So, </p>
<blockquote><p>WebBrowser wb = new WebBrowser();     <br />wb.Parent = panel1;      <br />wb.Dock = DockStyle.Fill;      <br />wb.Url = new Uri(&quot;http://0&#215;15.net/play/SLFindResource/SLFindResource.html&quot;);</p>
</blockquote>
<p>We done. But we’re in desktop, thus I want it full trust… This is most interesting part of today’s post.</p>
<h3>Second task – to make it run in User Full Trust mode.</h3>
<p>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 <a href="http://en.wikipedia.org/wiki/HTML_Application" target="_blank">very beginning of RIA era</a>). HTML applications were run by very special host, named <strong>mshta.exe</strong> 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)</p>
<blockquote><p>ProcessStartInfo mshta = new ProcessStartInfo(&quot;mshta&quot;, &quot;<a href="http://0x15.net/play/SLFindResource/SLFindResource.html");">http://0&#215;15.net/play/SLFindResource/SLFindResource.html&quot;);</a>      <br />Process p = Process.Start(mshta);</p>
</blockquote>
<p>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”.</p>
<blockquote><p>LockWindowUpdate(GetDesktopWindow());     <br />ProcessStartInfo mshta = new ProcessStartInfo(&quot;mshta&quot;, &quot;<a href="http://0x15.net/play/SLFindResource/SLFindResource.html");">http://0&#215;15.net/play/SLFindResource/SLFindResource.html&quot;);</a>      <br />Process p = Process.Start(mshta);      <br />p.WaitForInputIdle();      <br />ptr = FindWindow(&quot;HTML Application Host Window Class&quot;, null); </p>
<p>SetParent(ptr, panel1.Handle);     <br />SendMessage(ptr, WM_SYSCOMMAND, SC_MAXIMIZE, 0); </p>
<p>LockWindowUpdate(IntPtr.Zero);</p>
</blockquote>
<p>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?</p>
<h3>Third task – to make it access user’s file system</h3>
<p>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 <a href="http://msdn2.microsoft.com/en-us/library/z9ty6h50.aspx" target="_blank">Scripting.FileSystemObject</a> 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</p>
<blockquote><p>drivetypes = [ 'Unknown', 'Removable', 'Fixed', 'Network', 'CD-ROM', 'RAM Disk' ],     <br />driveprops = [ 'DriveLetter', 'DriveType', 'ShareName', 'IsReady', 'Path', 'RootFolder', 'FileSystem', 'SerialNumber', 'VolumeName', 'TotalSize', 'AvailableSpace', 'FreeSpace' ]; </p>
<p>function getdrives() {     <br /> var fso = new ActiveXObject( &#8216;Scripting.FileSystemObject&#8217; ),      <br />&#160; e = new Enumerator(fso.Drives),      <br />&#160; add = function(i) {      <br />&#160;&#160; i = driveprops[i];      <br />&#160;&#160; var prop = f[i];      <br />&#160;&#160; if( ( prop || prop===0 || prop===false ) &amp;&amp; ( i!==&#8217;AvailableSpace&#8217; || prop!==free ) ) {      <br />&#160;&#160;&#160; if( /(Type)$/.test( i ) ) { prop = drivetypes[ prop ]; }      <br />&#160;&#160;&#160; if( /(Size|Space)$/.test( i ) ) { prop = bykb( prop, true ); }      <br />&#160;&#160;&#160; s.push( i.toCamelCase() + &#8216;:\t&#8217; + ( i.length &lt; 8 ? &#8216;\t&#8217; : &#8221; ) + prop );      <br />&#160;&#160; }      <br />&#160; },</p>
</blockquote>
<p>Then folders</p>
<blockquote><p>function getfolder( s ) { s = trim( s ) || &#8216;C:&#8217;;     <br /> var fso = new ActiveXObject( &#8216;Scripting.FileSystemObject&#8217; ),      <br />&#160; e, f, i, r = [];      <br /> if( fso.FolderExists( s ) ) {      <br />&#160; f = fso.GetFolder( s );      <br />&#160; e = new Enumerator(f.SubFolders);      <br />&#160; for( ; !e.atEnd(); e.moveNext() ) {      <br />&#160;&#160; if( ( i = e.item() ) ) { r.push( &#8216; &#8216; + i ); }      <br />&#160; }      <br />&#160; e = new Enumerator(f.files);      <br />&#160; for( ; !e.atEnd(); e.moveNext() ) {      <br />&#160;&#160; if( ( i = e.item() ) ) { r.push( &#8221; + i ); }      <br />&#160; }      <br /> }      <br /> return r;      <br />}</p>
</blockquote>
<p>And files at the end</p>
<blockquote><p>function getfile( form ) {     <br /> var fso = new ActiveXObject( &#8216;Scripting.FileSystemObject&#8217; ),      <br />&#160; forReading = 1, forWriting = 2, forAppending = 8,      <br />&#160; dd = function( o, s ) {      <br />&#160;&#160; try {      <br />&#160;&#160;&#160; s = f[s] + &#8221;;      <br />&#160;&#160;&#160; o.value = s.replace( /^(\w{3}) (\w+) (\d\d?) ([\d:]+) ([\w+]+) (\d+)$/, &#8216;$3 $2 $6 $4&#8242; );      <br />&#160;&#160; } catch(e) {      <br />&#160;&#160;&#160; o.value = e.message;      <br />&#160;&#160; }      <br />&#160; },</p>
</blockquote>
<p>Very cool we have files by using <em>f = fso.GetFile( name );</em> method, now we can do anything with it. For example get or set attributes <em>f.attributes</em>, or rename <em>f.Name = s</em>, or, even delete it <em>f.Delete();</em> Isn’t it really evil?</p>
<p>We done. Now you can run Silverlight as full trust desktop application and, even host it wherever you want. Even inside calculator…</p>
<blockquote><p>ProcessStartInfo calc = new ProcessStartInfo(&quot;calc&quot;);     <br />using (Process p = Process.Start(calc))      <br />{      <br />&#160;&#160;&#160; p.WaitForInputIdle();      <br />&#160;&#160;&#160; SetParent(ptr, p.MainWindowHandle);      <br />&#160;&#160;&#160; SendMessage(ptr, WM_SYSCOMMAND, SC_MAXIMIZE, 0);      <br />&#160;&#160;&#160; p.WaitForExit();      <br />}</p>
</blockquote>
<p>Happy programming and be good people.</p>
<div style="padding-right: 0px; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px; display: inline" id="scid:4c033bbc-1f2f-4686-a55f-26926c847a06:2898d5d6-b1a4-4450-bf95-f070a257036f" class="wlWriterSmartContent">
<p><a href="http://blogs.microsoft.co.il/blogs/tamir/WindowsLiveWriter/HowtomakeSilverlightbeAiR_11FF0/SilverForms_1.zip" title="SilverForms.zip [53.7 Kb]">SilverForms.zip [53.7 Kb]</a></p>
</div>
<p/>]]></content:encoded>
			<wfw:commentRss>http://khason.net/blog/how-to-make-silverlight-be-air/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Using Vista Preview Handlers in WPF application</title>
		<link>http://khason.net/blog/using-vista-preview-handlers-in-wpf-application/</link>
		<comments>http://khason.net/blog/using-vista-preview-handlers-in-wpf-application/#comments</comments>
		<pubDate>Fri, 18 Apr 2008 14:08:56 +0000</pubDate>
		<dc:creator>Tamir</dc:creator>
				<category><![CDATA[BLOG]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[source]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[Vista]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[WPF crossbow]]></category>
		<category><![CDATA[XPS]]></category>

		<guid isPermaLink="false">http://khason.net/blog/using-vista-preview-handlers-in-wpf-application/</guid>
		<description><![CDATA[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&#8217;s content in a reading pane. You can find preview handlers in Microsoft Outlook 2007, Windows Vista and, even sometimes [...]<p/>]]></description>
			<content:encoded><![CDATA[<p>First of all what is Preview Handler? <a href="http://msdn2.microsoft.com/en-us/library/bb776867.aspx" target="_blank">Preview Handler</a> 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&#8217;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&#8217;s see how we can do it.</p>
<p>&#160;<img border="0" alt="image" src="http://khason.net/images/2008/12/image-58e0c4d5-f2ad-4cb8-91e7-ed10aaa17fd2.png" width="610" height="259" /> </p>
<p>Let&#8217;s create simple WPF window, that displays file list from left and preview of items in right side. We&#8217;ll use simple file list string collection as our datasource, bind it to Listbox Items and then bind selected item to some contentpresenter. I <a href="http://khason.net/blog/binding-to-current-item-external-collection-management-datatemplates-and-datatriggers/" target="_blank">blogged about this approach earlier</a>.</p>
<blockquote><p>&lt;Grid DataContext={StaticResource files}&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Grid.ColumnDefinitions&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;ColumnDefinition Width=&quot;.2*&quot;/&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;ColumnDefinition Width=&quot;.8*&quot;/&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/Grid.ColumnDefinitions&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;ListBox ItemsSource={Binding} IsSynchronizedWithCurrentItem=&quot;True&quot; /&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;ContentPresenter Grid.Column=&#8221;1&#8221; Content={Binding Path=/}/&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;GridSplitter Width=&quot;5&quot;/&gt;      <br />&#160;&#160;&#160; &lt;/Grid&gt;</p>
</blockquote>
<p>Our data source should be updated automatically within changes of file system. So, this is very good chance to use FileSystemWatcher object.</p>
<blockquote><p>class ListManager:ThreadSafeObservableCollection&lt;string&gt;     <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; string dir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public ListManager()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FileSystemWatcher fsw = new FileSystemWatcher(dir);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; fsw.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; fsw.Created += new FileSystemEventHandler(fsw_Created);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; fsw.Deleted += new FileSystemEventHandler(fsw_Deleted); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; fsw.EnableRaisingEvents = true; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; string[] files = Directory.GetFiles(dir);     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for (int i = 0; i &lt; files.Length; i++)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.Add(files[i]);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; void fsw_Deleted(object sender, FileSystemEventArgs e)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.Remove(e.FullPath);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; void fsw_Created(object sender, FileSystemEventArgs e)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.Add(e.FullPath);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160; }</p>
</blockquote>
<p>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.</p>
<p>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</p>
<blockquote><p>[ComImport]     <br />[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]      <br />[Guid(&quot;8895b1c6-b41f-4c1c-a562-0d564250836f&quot;)]      <br />interface IPreviewHandler      <br />{      <br />&#160;&#160;&#160; void SetWindow(IntPtr hwnd, ref RECT rect);      <br />&#160;&#160;&#160; void SetRect(ref RECT rect);      <br />&#160;&#160;&#160; void DoPreview();      <br />&#160;&#160;&#160; void Unload();      <br />&#160;&#160;&#160; void SetFocus();      <br />&#160;&#160;&#160; void QueryFocus(out IntPtr phwnd);      <br />&#160;&#160;&#160; [PreserveSig]      <br />&#160;&#160;&#160; uint TranslateAccelerator(ref MSG pmsg);      <br />} </p>
<p>[ComImport]     <br />[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]      <br />[Guid(&quot;b7d14566-0509-4cce-a71f-0a554233bd9b&quot;)]      <br />interface IInitializeWithFile      <br />{      <br />&#160;&#160;&#160; void Initialize([MarshalAs(UnmanagedType.LPWStr)] string pszFilePath, uint grfMode);      <br />} </p>
<p>[ComImport]     <br />[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]      <br />[Guid(&quot;b824b49d-22ac-4161-ac8a-9916e8fa3f7f&quot;)]      <br />interface IInitializeWithStream      <br />{      <br />&#160;&#160;&#160; void Initialize(IStream pstream, uint grfMode);      <br />}</p>
</blockquote>
<p>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&#8217;s do it</p>
<blockquote><p>string CLSID = &quot;8895b1c6-b41f-4c1c-a562-0d564250836f&quot;;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Guid g = new Guid(CLSID);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; string[] exts = fileName.Split(&#8216;.&#8217;);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; string ext = exts[exts.Length - 1];      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; using (RegistryKey hk = Registry.ClassesRoot.OpenSubKey(string.Format(@&quot;.{0}\ShellEx\{1:B}&quot;, ext, g)))      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (hk != null)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; g = new Guid(hk.GetValue(&quot;&quot;).ToString());</p>
</blockquote>
<p>Now, we know, that this file can be previewed, thus let&#8217;s initialize appropriate COM instance for preview handler</p>
<blockquote><p>Type a = Type.GetTypeFromCLSID(g, true);     <br />object o = Activator.CreateInstance(a);</p>
</blockquote>
<p>There are two kinds of initializations for preview handlers &#8211; file and stream based. Each one has it&#8217;s own interface. So, we can only check if the object created implements this interface to be able to initialize the handler</p>
<blockquote><p>IInitializeWithFile fileInit = o as IInitializeWithFile;     <br />IInitializeWithStream streamInit = o as IInitializeWithStream; </p>
<p>bool isInitialized = false;     <br />if (fileInit != null)      <br /> {      <br />&#160;&#160; fileInit.Initialize(fileName, 0);      <br />&#160;&#160; isInitialized = true;      <br />&#160; }      <br /> else if (streamInit != null)      <br />&#160; {      <br />&#160;&#160;&#160; COMStream stream = new COMStream(File.Open(fileName, FileMode.Open));      <br />&#160;&#160;&#160;&#160; streamInit.Initialize((IStream)streamInit, 0);      <br />&#160;&#160;&#160;&#160; isInitialized = true;      <br />&#160; }</p>
</blockquote>
<p>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.</p>
<blockquote><p>if (isInitialized)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pHandler = o as IPreviewHandler;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (pHandler != null)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RECT r = new RECT(viewRect);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pHandler.SetWindow(handler, ref r);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pHandler.SetRect(ref r); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pHandler.DoPreview();     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
</blockquote>
<p>So far so good, but we&#8217;re in WPF. Thus ContentPresenter we&#8217;re using has no handle! That&#8217;s right, but the main WPF application window has. So, let&#8217;s first get the main application window handle, then create rectangle bounds of the region, occupied by ContentControl.</p>
<p>In order to do it, we&#8217;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.</p>
<blockquote><p>class WPFPreviewHandler : ContentPresenter     <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; IntPtr mainWindowHandle = IntPtr.Zero;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; Rect actualRect = new Rect(); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (e.Property == ContentControl.ActualHeightProperty | e.Property == ContentControl.ActualWidthProperty)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (mainWindowHandle == IntPtr.Zero)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; HwndSource hwndSource = PresentationSource.FromVisual(App.Current.MainWindow) as HwndSource;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; mainWindowHandle = hwndSource.Handle;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Point p0 = this.TranslatePoint(new Point(),App.Current.MainWindow);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Point p1 = this.TranslatePoint(new Point(this.ActualWidth,this.ActualHeight),App.Current.MainWindow);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; actualRect = new Rect(p0, p1);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; mainWindowHandle.InvalidateAttachedPreview(actualRect);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#8230;      </p>
<p>public static void InvalidateAttachedPreview(this IntPtr handler, Rect viewRect)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (pHandler != null)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RECT r = new RECT(viewRect);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pHandler.SetRect(ref r);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
</blockquote>
<p>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</p>
<blockquote><p>if (e.Property == ContentControl.ContentProperty)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; mainWindowHandle.AttachPreview(e.NewValue.ToString(),actualRect);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
</blockquote>
<p>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)</p>
<blockquote><p>public sealed class COMStream : IStream, IDisposable     <br /> {      <br />&#160;&#160;&#160;&#160; Stream _stream; </p>
<p>&#160;&#160;&#160;&#160; ~COMStream()     <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (_stream != null)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _stream.Close();      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _stream.Dispose();      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _stream = null;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; private COMStream() { } </p>
<p>&#160;&#160;&#160;&#160; public COMStream(Stream sourceStream)     <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _stream = sourceStream;      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; #region IStream Members </p>
<p>&#160;&#160;&#160;&#160; public void Clone(out IStream ppstm)     <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; throw new NotSupportedException();      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; public void Commit(int grfCommitFlags)     <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; throw new NotSupportedException();      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)     <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; throw new NotSupportedException();      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; public void LockRegion(long libOffset, long cb, int dwLockType)     <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; throw new NotSupportedException();      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; [SecurityCritical]     <br />&#160;&#160;&#160;&#160; public void Read(byte[] pv, int cb, IntPtr pcbRead)      <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int count = this._stream.Read(pv, 0, cb);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (pcbRead != IntPtr.Zero)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Marshal.WriteInt32(pcbRead, count);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; public void Revert()     <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; throw new NotSupportedException();      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; [SecurityCritical]     <br />&#160;&#160;&#160;&#160; public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition)      <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; SeekOrigin origin = (SeekOrigin)dwOrigin;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; long pos = this._stream.Seek(dlibMove, origin);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (plibNewPosition != IntPtr.Zero)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Marshal.WriteInt64(plibNewPosition, pos);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; public void SetSize(long libNewSize)     <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this._stream.SetLength(libNewSize);      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; public void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag)     <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pstatstg = new System.Runtime.InteropServices.ComTypes.STATSTG();      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pstatstg.type = 2;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pstatstg.cbSize = this._stream.Length;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pstatstg.grfMode = 0;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (this._stream.CanRead &amp;&amp; this._stream.CanWrite)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pstatstg.grfMode |= 2;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else if (this._stream.CanWrite &amp;&amp; !_stream.CanRead)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pstatstg.grfMode |= 1;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; throw new IOException();      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; public void UnlockRegion(long libOffset, long cb, int dwLockType)     <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; throw new NotSupportedException();      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; [SecurityCritical]     <br />&#160;&#160;&#160;&#160; public void Write(byte[] pv, int cb, IntPtr pcbWritten)      <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this._stream.Write(pv, 0, cb);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (pcbWritten != IntPtr.Zero)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Marshal.WriteInt32(pcbWritten, cb);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; #endregion </p>
<p>&#160;&#160;&#160;&#160; #region IDisposable Members </p>
<p>&#160;&#160;&#160;&#160; public void Dispose()     <br />&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (this._stream != null)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this._stream.Close();      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this._stream.Dispose();      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this._stream = null;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; #endregion     <br /> } </p>
</blockquote>
<p>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 <a href="http://msdn2.microsoft.com/en-us/magazine/cc163487.aspx" target="_blank">create your own preview handlers</a> and they&#8217;ll appear in your WPF application as well as they&#8217;ll magically appear in Outlook. Following full source code for this article</p>
<div style="padding-right: 0px; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px; display: inline" id="scid:4c033bbc-1f2f-4686-a55f-26926c847a06:3f6b4e35-04e4-4892-a6ac-7691820e5b2a" class="wlWriterSmartContent">
<p><a href="http://blogs.microsoft.co.il/blogs/tamir/WindowsLiveWriter/UsingVistaPreviewHandlersinWPFapplicatio_C6E7/PreviewHandlerWPF_1.zip" title="PreviewHandlerWPF.zip [27.5 Kb]">PreviewHandlerWPF.zip [27.5 Kb]</a></p>
</div>
<p>Good day, Happy Passover and, as always, be good people.</p>
<p/>]]></content:encoded>
			<wfw:commentRss>http://khason.net/blog/using-vista-preview-handlers-in-wpf-application/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>To OLE / From OLE color translator in WPF</title>
		<link>http://khason.net/blog/to-ole-from-ole-color-translator-in-wpf/</link>
		<comments>http://khason.net/blog/to-ole-from-ole-color-translator-in-wpf/#comments</comments>
		<pubDate>Sun, 13 Apr 2008 19:07:46 +0000</pubDate>
		<dc:creator>Tamir</dc:creator>
				<category><![CDATA[BLOG]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[source]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[WPF crossbow]]></category>

		<guid isPermaLink="false">http://khason.net/blog/to-ole-from-ole-color-translator-in-wpf/</guid>
		<description><![CDATA[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&#8217;re working with old COM/COM+ application you have either reference System.Drawing.dll or write those two methods [...]
Related posts:<ol>
<li><a href='http://khason.net/dev/rsa-private-key-import-from-pem-format-in-c/' rel='bookmark' title='RSA private key import from PEM format in C#'>RSA private key import from PEM format in C#</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>In GDI+ (Winforms) world, there was very handy class inside System.Drawing. It named <a href="http://msdn2.microsoft.com/en-us/library/system.drawing.colortranslator.toole.aspx" target="_blank">ColorTranslator</a> and it used to translate from <a href="http://en.wikipedia.org/wiki/Object_Linking_and_Embedding" target="_blank">OLE</a> integer color value into GDI+ Color and vice verse. In WPF there is no such class, so if you&#8217;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 <img src='http://khason.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<blockquote><p>public static class ColorTranslator     <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; const int RedShift = 0;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; const int GreenShift = 8;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; const int BlueShift = 16;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; /// &lt;summary&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; /// Translates an Ole color value to a System.Media.Color for WPF usage      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; /// &lt;/summary&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; /// &lt;param name=&quot;oleColor&quot;&gt;Ole int32 color value&lt;/param&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; /// &lt;returns&gt;System.Media.Color color value&lt;/returns&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static Color FromOle(this int oleColor)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return Color.FromRgb(      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (byte)((oleColor &gt;&gt; RedShift) &amp; 0xFF),      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (byte)((oleColor &gt;&gt; GreenShift) &amp; 0xFF),      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (byte)((oleColor &gt;&gt; BlueShift) &amp; 0xFF)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; /// &lt;summary&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; /// Translates the specified System.Media.Color to an Ole color.       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; /// &lt;/summary&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; /// &lt;param name=&quot;wpfColor&quot;&gt;System.Media.Color source value&lt;/param&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; /// &lt;returns&gt;Ole int32 color value&lt;/returns&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static int ToOle(Color wpfColor)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return wpfColor.R &lt;&lt; RedShift | wpfColor.G &lt;&lt; GreenShift | wpfColor.B &lt;&lt; BlueShift;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160; }</p>
</blockquote>
<p>Have a nice day and be good people.</p>
<p>Related posts:<ol>
<li><a href='http://khason.net/dev/rsa-private-key-import-from-pem-format-in-c/' rel='bookmark' title='RSA private key import from PEM format in C#'>RSA private key import from PEM format in C#</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://khason.net/blog/to-ole-from-ole-color-translator-in-wpf/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Quick tip: How to open popup or ContextMenu in XBAP application</title>
		<link>http://khason.net/blog/quick-tip-how-to-open-popup-or-contextmenu-in-xbap-application/</link>
		<comments>http://khason.net/blog/quick-tip-how-to-open-popup-or-contextmenu-in-xbap-application/#comments</comments>
		<pubDate>Mon, 03 Mar 2008 15:27:55 +0000</pubDate>
		<dc:creator>Tamir</dc:creator>
				<category><![CDATA[BLOG]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[WPF crossbow]]></category>

		<guid isPermaLink="false">http://khason.net/blog/quick-tip-how-to-open-popup-or-contextmenu-in-xbap-application/</guid>
		<description><![CDATA[If you want to use ContextMenu in XBAP application this will work, only if your XBAP is in full trust mode. Else you&#8217;ll get &#34;Request for the permission of type &#8216;System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&#8242; failed&#34;. But even with Full Trust application, if you&#8217;ll try to open context menu explicitly it wont. The error, you&#8217;ll [...]<p/>]]></description>
			<content:encoded><![CDATA[<p>If you want to use ContextMenu in XBAP application this will work, only if your XBAP is in full trust mode. Else you&#8217;ll get &quot;Request for the permission of type &#8216;System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&#8242; failed&quot;. But even with Full Trust application, if you&#8217;ll try to open context menu explicitly it wont. The error, you&#8217;ll get will be &quot;Cannot create a top-level child window&quot;. This is right. You cannot use layered windows without explicitely set parent inside browser sandbox.</p>
<p>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 <u>while it raises ToolTipOpenning event</u>. More, then this, it uses internal dependency property OwnerProperty to do it. So pity.</p>
<blockquote><p>_currentToolTip.SetValue(OwnerProperty, o); </p>
</blockquote>
<p>And if it is not enough it probably has memory leak, I <a href="http://khason.net/blog/wpf-events-and-memory-leaks/" target="_blank">described earlier</a>. </p>
<blockquote><p>_currentToolTip.Closed += OnToolTipClosed;     <br />private void OnToolTipClosed(object sender, EventArgs e)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ToolTip toolTip = (ToolTip)sender;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; toolTip.Closed -= OnToolTipClosed;</p>
</blockquote>
<p>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.</p>
<blockquote><p>private void OnMouseDown(object sender, MouseEventArgs e)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (e.LeftButton == MouseButtonState.Pressed)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; contextMenu.PlacementTarget = sender as UIElement;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; contextMenu.IsOpen = true;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
</blockquote>
<p>&#160;</p>
<p>That&#8217;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.</p>
<p>Have a nice day. </p>
<p/>]]></content:encoded>
			<wfw:commentRss>http://khason.net/blog/quick-tip-how-to-open-popup-or-contextmenu-in-xbap-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

