Thursday, July 17, 2008

Implementing the gradient fade look and feel Windows Mobile

You will notice on Windows Mobile (and pre WM) many core applications, Outlook, excel etc use a horizontal fade from right to left and normally the system Control colour combined with white generally.

An example of this is as follows:



An example of an application I've written looks like the following:



The above is a custom owner drawn list with of course no items. Here is the code to achieve the gradient background effect:
gOffScreen.FillRectangle(
new SolidBrush(Color.White),
0, 0, Convert.ToInt32(20 * grfx.DpiY / DESIGNPOINTSPERINCH), Height);
Rectangle rc = this.ClientRectangle;
rc.X = Convert.ToInt32(20 * grfx.DpiY / DESIGNPOINTSPERINCH);
rc.Width = Convert.ToInt32(rc.Width - 20 * grfx.DpiY / DESIGNPOINTSPERINCH);

NativeMethods.TRIVERTEX[] tva = new NativeMethods.TRIVERTEX[2];
tva[0] = new NativeMethods.TRIVERTEX(rc.X, rc.Y, Color.White);
tva[1] = new NativeMethods.TRIVERTEX(rc.Right,
rc.Bottom, SystemColors.Control);
NativeMethods.GRADIENT_RECT[] gra = new NativeMethods.GRADIENT_RECT[]
{
new NativeMethods.GRADIENT_RECT(0, 1)
};
//Get the hDC from the Graphics object.
IntPtr hdc = gOffScreen.GetHdc();
//P/Invoke to GradientFill.
NativeMethods.GradientFill(
hdc,
tva,
(uint)tva.Length,
gra,
(uint)gra.Length,
(uint)NativeMethods.GRADIENT_FILL_RECT_H);
//Release the hDC from the Graphics object.
gOffScreen.ReleaseHdc(hdc);
Where grfx is an instance of the Graphics object for this drawing surface and DESIGNPOINTSPERINCH is the design time DPI - normally 92. And the gOffScreen is a bitmap as we are using double buffering.

The unmanaged declarations look like the following:
public const int GRADIENT_FILL_RECT_H = 0x00000000;
public const int GRADIENT_FILL_RECT_V = 0x00000001;
public struct GRADIENT_RECT
{
public uint LowerRight;
public uint UpperLeft;
public GRADIENT_RECT(uint ul, uint lr);
}
[DllImport("coredll.dll", SetLastError = true,
EntryPoint = "GradientFill")]
public extern static bool GradientFill(IntPtr hdc,
TRIVERTEX[] pVertex,
uint dwNumVertex,
GRADIENT_RECT[] pMesh,
uint dwNumMesh,
uint dwMode);
There is an MSDN article for this subject here: http://msdn.microsoft.com/en-us/library/ms229655(VS.80).aspx

No comments: