![]() |
Platforms, Frameworks & Libraries »
Mobile Development »
GDI+
Beginner
License: The Code Project Open License (CPOL)
iPhone UI in Windows MobileBy Dr.LuijiIt'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 on Windows Mobile. |
C#, WinMobile (PocketPC-2002, WinMobile2003, WinMobile5, WinMobile6), GDI+
|
||||||||||||
|
Advanced Search Add to IE Search |
|
|
||||||||||||||||||

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[^].
MainMenu.cs.

OnPaint().
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);
}
AlphaBlend.
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);
}
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);
}
}
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");
...
DrawAlpha(gxBuffer, signal, 200, 0, 0);
DrawAlpha(gxBuffer, topLock, 200, signal.Width, 0);
DrawAlpha(gxBuffer, GetBatteryImage(), 200, topLock.Width + signal.Width, 0);
...
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())
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;
}

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;
}

Info: WM 6 emulators must be connected to the Fake Network through Cellular Emulator. Below I add some steps that may be useful.
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.

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);
}

ImageButton.cs a class for its.
ImageButton image imageDown, MouseDown MouseUp, Paint()
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.
private Color GetTransparentColor(Bitmap image)
{
return image.GetPixel(0, 0);
}

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.
private void timeAnimation_Tick(object sender, EventArgs e)
{
int x = (start.X - 20);
Move(x);
}
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;
}
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
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.
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;
...
}
ProcessExecute that directly executes the program or the link I need.
public static void Phone()
{
keybd_event(VK_TTALK, 0, KEYEVENTF_KEYDOWN, 0);
//StartProcess(@"\windows\cprog.exe");
} public static void MediaPlayer()
{
StartProcess(@"\windows\WMPlayer.exe");
}
internal static void TaskManager()
{
StartProcess(@"\Windows\TaskMgr.exe");
}
public static void Picture()
{
StartLink(@"\Windows\Start Menu\Programs\Pictures & Videos.lnk");
} 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
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.

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.
after closing an external application.
General
News
Question
Answer
Joke
Rant
Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads.
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 24 Mar 2009 Editor: Jeff Hadfield |
Copyright 2008 by Dr.Luiji Everything else Copyright © CodeProject, 1999-2010 Web18 | Advertise on the Code Project |