iphone UI on windows mobile

 

iPhone UI in Windows Mobile

 

Contents  

What is iPhoneUI?

It's an interface that works with transparency effects. As a sample I used an interface just like the iPhone one.
In this tutorial I am explaining how simple is working with transparency and animation on Windows Mobile.

Introduction

In all this article I have been mentioning Alpha blending. Alpha blending is a convex combination of two colours allowing transparency effects.
In order to raise more interest in this article I added an animation (status bar), events notifications (battery, GPS signal, timer), fingered movement of the objects (unlock button) and the second part concerning buttons view and their respective interactions with mobile native programs.
As a project base I used an example by Alex Yakhnin that concerns, of course, the use of API AlphaBlend in c#.

Info:  If you are interested in: Resolution-aware and Orientation-aware, Dynamic graphic text resize I suggest to you my new article: iPod touch UI[^].   

Background  

As already mentioned, this program shows how to display bitmaps that have transparent or semitransparent pixels with c#.

Using the Code

The solution

I have chosen C#/.Net to make things simpler and we will be using Visual Studio 2005 as the IDE.
If you have a bit of understanding of writing with C# or C++ (Windows GDI) this reading can be quicker and useful.
To debug the project you need the Windows Mobile 6 Professional and Standard Software Development Kits Refresh[^]. The project contains:

·  Two form Home.cs and MainMenu.cs

·  The class to manage the P/Invoke PlatformAPIs

·  The class for the image ImageButton

·  The class to move the Image SlideButton

·  The class to Intercept the touched button InterceptButtonPressed

·  The class to execute the programsProcessExecute

·  and a lot of BMP files.  
Originally I have released only one form, but successively I have split it in two to make things more clear and removed the Topbar from the
MainMenu.cs.
This is a sample with 4 different wallpapers, all included in the solution.



The forms are in full screen (WindowState = Maximize) for best image and I have overridden the
OnPaint().

Home

In order to draw the background, you need to clear the screen and put on it (in the right order) your back ground first and the transparency object after. In the end you can add the items that require interaction.

Drawing off screen

In order to draw quicker, I drew all the controls off screen (in memory) in advance and at the end I have put them on the screen.

Collapse Copy Code

protected override void OnPaint(PaintEventArgs e)

{

    gxBuffer = Graphics.FromImage(offBitmap);

    //Graphics gxBuffer = e.Graphics;

    gxBuffer.Clear(this.BackColor);

    ...

    ...

    this.Invalidate();

    e.Graphics.DrawImage(offBitmap, 0, 0);

}

Draw with transparency

In order to draw the alpha I used the DrawAlpha that uses the P/Invoke to AlphaBlend.

Collapse Copy Code

public class PlatformAPIs

{

    [DllImport("coredll.dll")]

    extern public static Int32 AlphaBlend(

           IntPtr hdcDest, Int32 xDest, Int32yDest, Int32 cxDest, Int32 cyDest,

           IntPtr hdcSrc, Int32 xSrc, Int32 ySrc, Int32 cxSrc, Int32 cySrc,

           BlendFunction blendFunction);                

}

Collapse Copy Code

private void DrawAlpha(Graphics gx, Bitmap image, byte transp, int x, int y)

 {

     using (Graphics gxSrc = Graphics.FromImage(image))

    {

        IntPtr hdcDst = gx.GetHdc();

        IntPtr hdcSrc = gxSrc.GetHdc();

        BlendFunction blendFunction = new BlendFunction();

        blendFunction.BlendOp = (byte)BlendOperation.AC_SRC_OVER;  

        blendFunction.BlendFlags = (byte)BlendFlags.Zero;          

        blendFunction.SourceConstantAlpha = transp;

        blendFunction.AlphaFormat = (byte)0;                       

        PlatformAPIs.AlphaBlend(hdcDst, x, y, image.Width, image.Height, hdcSrc,

                                0, 0, image.Width, image.Height, blendFunction);

        gx.ReleaseHdc(hdcDst);   

        gxSrc.ReleaseHdc(hdcSrc);

    }

}

Initalize the image

I have loaded all the images of the Form in the constructor of the class on the OnPaint(), firtly I positioned the images that do not have interaction and, in the end, I added the buttons that require interaction.
Sample of constructor

Collapse Copy Code

    path = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);

    backImage = new Bitmap(path + @"/BMP/wallpaper.bmp");

    topBar = new Bitmap(path + @"/BMP/topbar.bmp");

    topLock = new Bitmap(path + @"/BMP/toplock.bmp");

    ...

Drawing all the images

Sample of drawing (OnPaint)

Collapse Copy Code

    DrawAlpha(gxBuffer, signal, 200, 0, 0);

    DrawAlpha(gxBuffer, topLock, 200, signal.Width, 0);

    DrawAlpha(gxBuffer, GetBatteryImage(), 200, topLock.Width + signal.Width, 0);

    ...

Battery level

The screen isn't static'. The battery image changes when the SO changes this registry key. To do this I used the notification broker and split the image in more several parts and added a more comprehensive step.

I also added a method that decides which image is the right to see (of course, this is used in the OnPaint())

Collapse Copy Code

private Bitmap GetBatteryImage()

{           

    switch (SystemState.PowerBatteryStrength)

    {

        case BatteryLevel.VeryHigh:

            return batteryLevelVeryHigh;                   

        case BatteryLevel.High:

            return batteryLevelHigh;                   

        case BatteryLevel.Medium:

            return batteryLevelMedium;

        case BatteryLevel.Low:

            return batteryLevelLow;

        case BatteryLevel.VeryLow:

            _HideBattery = !_HideBattery;

            if (_HideBattery)

                return batteryLevelVeryLow1;

            else

                return batteryLevelVeryLow2;                   

                   

    }

    return null;    

}


Battery animation sample

GSM signal strenght

Same thing for the GPS signal.

Collapse Copy Code

private Bitmap GetGPSSignalImage()

{

    int SignalStrength = SystemState.PhoneSignalStrength;

 

    if (SignalStrength > 80)

        return signalLevelVeryHigh;

 

    if (SignalStrength > 60)

        return signalLevelHigh;

 

    if (SignalStrength > 50)

        return signalLevelMedium;

 

    if (SignalStrength > 20)

        return signalLevelLow;

 

    //else

    {

        _HideSignal = !_HideSignal;

            if (_HideSignal)

                return signalLevelVerylow1;

            else

                return signalLevelVerylow2;

    }

    return null;

}


Signal animation sample

  Info:  WM 6 emulators must be connected to the Fake Network through Cellular Emulator. Below I add some steps that may be useful.

Running Cellular Emulator

  1. Launch the Cellular Emulator (Start/All Programs / Windows Mobile 6 SDK / Tools / Cellular Emulator ) and the Device Emulator.
  2. Read the COM port configuration from the status bar of the Cellular Emulator main window.
  3. In the Device Emulator, go to File / Configure and select the Peripherals tab.
  4. Map the Serial port 0 of Device Emulator to the specific COM number obtained from step 2
  5. Soft reset the Device Emulator (File / Reset / Soft).  

Drawing the animated slide

In the end of the form I added another animation but the image does not change along with the system situation.
As this is an animation, I chose to load everything onto a single image and added all the frames that are necessary for displaying it.

In order to create the animation I move the area to view. In other words, only the frame that is necessary in that exact moment is displayed.

Drawing the time

I added a timer that regularly checks the time and updates it on the display.

Collapse Copy Code

private void DrawDateAndTime(string time, Graphics gx, int y)

{

    SizeF sizeTime = gx.MeasureString(time, timeFont);

    int xTime = this.Width / 2 - (int)sizeTime.Width / 2;

    gx.DrawString(time, timeFont, new SolidBrush(Color.White), xTime, y);

 

    SizeF sizeDate = gxBuffer.MeasureString(date, dateFont);

    int xDate = this.Width / 2 - (int)sizeDate.Width / 2;

 

    gxBuffer.DrawString(date, dateFont, whiteBrush, xDate, 70);

}


This is the view with the windows clock.

Draw the button 

All my button not need the transparency and i've create ImageButton.cs a class for its.
The
ImageButton have two bitmaps image and imageDown, it overrides the, MouseDown, MouseUp, and draw it selfs in the Paint().

Collapse Copy Code

public void Paint(Graphics gx)

{

    ImageAttributes attrib = new ImageAttributes();

    Color color = GetTransparentColor(image);

    attrib.SetColorKey(color, color);

    if (!pushed || imageDown == null)

        gx.DrawImage(image, clientArea, 0, 0, clientArea.Width, clientArea.Height,

                     GraphicsUnit.Pixel, attrib);               

    else

        gx.DrawImage(imageDown, clientArea, 0, 0, clientArea.Width, clientArea.Height,

                     GraphicsUnit.Pixel, attrib);

}

The transparency colour is set based on the first pixel of the image.

Collapse Copy Code

private Color GetTransparentColor(Bitmap image)

{

    return image.GetPixel(0, 0);

}


This is a sample of the button images. 

Moving the button

In order to move the arrow button I used the SlideButton that inherits the previous one and adds functions to the movement. Once the mouse is released, the owner_MouseUp triggers the timer start with timeAnimation_Tick hereunder you can see the code.

Collapse Copy Code

private void timeAnimation_Tick(object sender, EventArgs e)

{

    int x = (start.X - 20);

    Move(x);

}

Collapse Copy Code

void Move(int x)

{

    int shift = x - start.X;

    int newX = (this.clientArea.X + shift);// -mousePos;

    if (newX <= leftLimit)

    {

        newX = leftLimit;

        timeAnimation.Enabled = false;

    }

    if (newX + this.clientArea.Width >= rightLimit)

    {

        newX = rightLimit - this.clientArea.Width;

        unLock = true;

    }

 

    this.clientArea = new Rectangle(newX, clientArea.Y, this.clientArea.Width, this.clientArea.Height);

    //owner.Invalidate(new Rectangle(0, 258, 240, 70));

    start.X = x;

}

MainMenu

The Main menu is displayed when the arrow button gets to the end of the race.
It hides itself when the key button is pressed.

Drawing the buttons

All my buttons do not need the transparency. I created ImageButton.cs class for this.
The ImageButton has two bitmaps images and imageDown, it overrides the ,MouseDown, and ,MouseUp, and is drawn in the
Paint
In the constructor I loaded all the bitmaps and set the Button GridPosition. The
OnPaint draws all the Buttons.
A timer monitors which button is pressed and closes itself if necessary

Collapse Copy Code

private void timerCheckButtonPressed_Tick(object sender, EventArgs e)

{

    try

    {

         CheckButtonPress();

 

         IntPtr activeWindowHandle = GetForegroundWindow();

         IntPtr thisWindowHandle = this.Handle;

         if (activeWindowHandle != thisWindowHandle)

         {

             if (DialogResult != DialogResult.OK)

                 NeedRepaint = true;

         }

         else

         {

             if (NeedRepaint)

             {

                 this.Invalidate();

                 NeedRepaint = false;

             }

 

         }

     }

     catch (Exception ex)

     {

         Close();

     }

 }

The CheckButtonPress checks if a button is pressed and executes its command.

Collapse Copy Code

private bool CheckButtonPress()

{

 

    if (buttonCalendar.IsPressedOneTime)

    {

        buttonCalendar.IsPressedOneTime = false;

        ProcessExecute.Calendar();

        return true;

    }

    if (buttonPhoto.IsPressedOneTime)

    {

        buttonPhoto.IsPressedOneTime = false;

        ProcessExecute.Picture();

        return true;

    } 

    if (buttonMail.IsPressedOneTime)

    {

        buttonMail.IsPressedOneTime = false;

        ProcessExecute.Notes();

        return true;

    }

    if (buttonPhone.IsPressedOneTime)

    {

        buttonPhone.IsPressedOneTime = false;

         ...

}       

 

Executing the programs or links

In order to execute the program I created the ProcessExecute that directly executes the program or the link I need.
Here’s a sample:

Collapse Copy Code

public static void Phone()

{

    keybd_event(VK_TTALK, 0, KEYEVENTF_KEYDOWN, 0);

    //StartProcess(@"/windows/cprog.exe");

}

Collapse Copy Code

public static void MediaPlayer()

{

     StartProcess(@"/windows/WMPlayer.exe");

}

 

internal static void TaskManager()

{

    StartProcess(@"/Windows/TaskMgr.exe");

}

Collapse Copy Code

public static void Picture()

{

    StartLink(@"/Windows/Start Menu/Programs/Pictures & Videos.lnk");

}  

Collapse Copy Code

public static void Camera()

{

    //Namespace: Microsoft.WindowsMobile.Forms

    //Assembly: Microsoft.WindowsMobile.Forms (in microsoft.windowsmobile.forms.dll)

 

    CameraCaptureDialog cameraCapture = new CameraCaptureDialog();

    cameraCapture.ShowDialog();

}

And this is the StartProcess

Collapse Copy Code

public static void StartProcess(string FileName)

{

    ...

    System.Diagnostics.Process myProcess = new System.Diagnostics.Process();

    myProcess.StartInfo.FileName = FileName;

    myProcess.Start();

    ... 

}

Info about Task Manager: The  TaskMgr.exe is only available in WM 6.1 or higher.  However I search it and I don't show the button if it's not present. As the image below.

Links  

<body><body><body>

·  Msdn AlphaBlend function [^]  

·  Msdn BLENDFUNCTION structure[^]

·  Msdn Imaging Structures for Imaging API[^]  

·  Wiki Alpha compositing definition[^]

·  Blog Chris Lorton Alphablending with NETCF[^]

·  Blog Alex Yakhnin (ex Blog) Compelling UI's in NetCF anybody?[^]

·  Blog Fernando Zandoná WM 6 SDK and Cellular Emulator (Can you hear me now?) [^]</body></body></body>

Points of Interest

I would like to remind that this program is not a complete interface. It does not really lock the telephone like iPhone does, it does not display the iPhone calendar when calendar is pressed and it does not modify the telephone Home.
I believe I have proved how simple is drawing with transparencies and animations, both using a single image or several.
I also believe that a skilled developer should not take much to make it screen aware and add menus, buttons and animation between the forms of its application.

History  

  • 11 Dec 2008 - First release. 
  • 13 Dec 2008 - Solved bug after closing an external application.         
  • 24 Mar 2009 - New minor release v1.1  
    •  
      •  
        •  
          • Added CameraCaptureDialog  
          • Added TaskManager (only for WM 6.1 or higher)   
          • Added Exit button  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值