Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / WinMobile

Windows Mobile - Attractive UI Part-II

2.43/5 (8 votes)
2 Nov 2009GPL32 min read 35.6K  
Windows Mobile - Attractive UI Part-II

Introduction

On my first blog I promised of Part II. Here is the Part – II. We shall look deep inside into the AlphaImage Control here.

Using_AlphaButton.jpg

The first problem is: .NET CF does not support image transparency. So, when ever we ask for transparent color it is translated as white. To add to this the gif images with transparent background won’t work here.

AlphaMobileControls has a control “AlphaPictureBox” which derives from AlphaControl. If we use this one then it would fix the transparency prolem.

How to use

Just place an alphapicturebox control to your form. At the constructor of the form set the image that would be displayed in the picture box:

alphaPictureBox1.Image = AlphaImage.CreateFromResource("mConcierge.Resources.backgroundNormal.jpg");

You are done. If you need backgroung transparency then the image shound a normal background transparent gif.

What’s happening Inside

The image property that is exposed by AlphaPicture box is a AlphaImage.

This Alpha Image is created form a normal image.

///<br>
        /// Creates a new AlphaImage from the given memory stream.<br>
        ///<br>
        public static AlphaImage CreateFromStream(MemoryStream stream)<br>
        {<br>
        PlatformAPI.IImaging.IImagingFactory factory = CreateFactory();<br>
        AlphaImage alphaImage = new AlphaImage();<br>
        byte[] pbBuf = stream.GetBuffer();<br>
        uint cbBuf = (uint)stream.Length;<br>
        factory.CreateImageFromBuffer(pbBuf, cbBuf, PlatformAPI.IImaging.BufferDisposalFlag.BufferDisposalFlagNone,
        out alphaImage._image);<br>
        }

IImagingFactory interface defines native (COM) OS operations as shown below:

[ComImport, Guid("327ABDA7-072B-11D3-9D7B-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]<br>
        [ComVisible(true)]<br>
        public interface IImagingFactory<br>
        {<br>
        uint CreateImageFromStream(IStream stream, out IImage image);<br>
        uint CreateImageFromFile(string filename, out IImage image);<br>
        uint CreateImageFromBuffer([MarshalAs(UnmanagedType.LPArray)] byte[] buffer, uint
        size, BufferDisposalFlag disposalFlag, out IImage image);<br>
        uint CreateNewBitmap(uint width, uint height, PixelFormatID pixelFormat, out IBitmapImage
        bitmap);
        uint CreateBitmapFromImage(IImage image, uint width, uint height, PixelFormatID
        pixelFormat, InterpolationHint hints, out IBitmapImage bitmap);
        uint CreateBitmapFromBuffer(BitmapData bitmapData, out IBitmapImage bitmap);
        uint CreateImageDecoder();
        uint CreateImageEncoderToStream();
        uint CreateImageEncoderToFile();
        uint GetInstalledDecoders();
        uint GetInstalledEncoders();
        uint InstallImageCodec();
        uint UninstallImageCodec();
        }

Rest of things are Pretty simple. As alphapicturebox controls derives from alphacontrol base class, it overrides the draw method of alphacontrol. This inturn calls draw method of alphaimage. Draw method inside alpha image draws the image on the form calling a COM function as defined here :

[ComImport, Guid("327ABDA9-072B-11D3-9D7B-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [ComVisible(true)]
        public interface IImage
        {<br>
        uint GetPhysicalDimension(out Size size);
        uint GetImageInfo(out ImageInfo info);
        uint SetImageFlags(uint flags);
        uint Draw(IntPtr hdc, ref Rectangle dstRect, IntPtr srcRect);<br>
        uint PushIntoSink(); // pominięte
        uint GetThumbnail(uint thumbWidth, uint thumbHeight, out IImage thumbImage);
        }

Sleepless Nights

The shock came to me when I was planning for a party. My application started to get excetions when I was navigating through the forms. I reached everywhere for a solution but it took long time to find one from codeplex.

The problem is because a managed array is passed to the COM object. Once the garbage collector decides to free/move this array all hell break loose.

Here’s a fix:

In IImagingFactory.cs, replace:

// We need the MarshalAs attribute here to keep COM interop from sending the buffer down as a Safe Array.
uint CreateImageFromBuffer([MarshalAs(UnmanagedType.LPArray)] byte[] buffer, uint
size, BufferDisposalFlag disposalFlag, out IImage image);

With:

uint CreateImageFromBuffer(IntPtr buffer, uint size, BufferDisposalFlag disposalFlag, out IImage image);

In AlphaImage.cs add this in the top of the file:

using System.Runtime.InteropServices;

And replace:

factory.CreateImageFromBuffer(pbBuf, cbBuf,BufferDisposalFlag.BufferDisposalFlagNone,
   out alphaImage._image);

With:

// Copy stream data into an unmanaged global buffer that will be freed by the factory
once image is decoded<br>
// note that we cannot pass pbBuf directly since it might be moved around or freed by the gc.
IntPtr p = Marshal.AllocHGlobal((int)cbBuf);
Marshal.Copy(pbBuf, 0, p, (int)cbBuf);
factory.CreateImageFromBuffer(p, cbBuf, BufferDisposalFlag.BufferDisposalFlagGlobalFree,
out alphaImage._image);

The code and the controls could be here here

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)