Windows Mobile 5/6/.. - Customize ControlBox
Hello!
Couldn't find a similar question, sorry if it's been posted before.
I'm working on a mobile application written in C# .Net CF 2.0 for WM 5/6/6.1
Currently the client has asked us to customize the Close(X)/Ok button on the right upper corner of the screen (the button that closes the form/application).
I'm talking about this button.
http://img5.imageshack.us/my.php?ima...dlayoutwq5.jpg
He wants us to change it's look&feel (meaning that the button would be represented using a picture, and when clicking it, another form should open.)
Like this:
http://img5.imageshack.us/my.php?ima...clayoutyo7.jpg
Is this possible? I know this means redrawing the NonClient area, but how exactly do i do this?
And could this be done using API calls? what api calls should me made in this case?
Thanks.
Re: Windows Mobile 5/6/.. - Customize ControlBox
cmooon guys, the deadline is getting closer :(
Re: Windows Mobile 5/6/.. - Customize ControlBox
Okay. With the delivery set for tonite, I've managed to pull it through. In order to do this, we have to get the handle of the task Bar, using p/Invoke FindWindow("HHTaskBar",...). Then using a Graphics object created from the device context of the window "found" above, we paint a picture over the "OK" button (the form must have it's properties set to MinimizeBox = false and ControlBox = true, in order for the custom WndProc to handle messages when clicking the region of the task bar where we are painting. Below is the code sample. Cheers mates
public class MopForm : System.Windows.Forms.Form
{
#region members and delegates
delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImport("CoreDll.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string className, string WindowsName);
[DllImport("coredll.dll", EntryPoint = "GetWindowLong")]
private static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("coredll.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr newWndProc);
[DllImport("coredll.dll")]
static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("coredll.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("coredll.dll")]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
private const int GWL_WNDPROC = -4;
private static WndProcDelegate newWndProc;
private static IntPtr oldWndProc = IntPtr.Zero;
bool userPressed = false;
ResourceManager resManager;
#endregion
#region ctor
public MopForm()
{
InitializeComponent();
}
#endregion
#region meths
private void InitializeComponent()
{
this.ControlBox = false;
this.Closing += new System.ComponentModel.CancelEventHandler(this.OnCl osing);
this.Load += new System.EventHandler(this.OnLoad);
resManager = new ResourceManager("MobileOP.Utils.Resources", Assembly.GetCallingAssembly());
}
private void OnLoad(object sender, EventArgs e)
{
newWndProc = new WndProcDelegate(WndProc);
oldWndProc = GetWindowLong(this.Handle, GWL_WNDPROC);
int success = SetWindowLong(this.Handle, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(newWndProc)) ;
}
public IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
//we are targeting a specific sequence (31 , 273) that will tell us when the user clicks on the picture
IntPtr retVal = IntPtr.Zero;
switch (msg)
{
case 273:
if (userPressed)
{
userPressed = false;
Execute();
}
break;
case 31:
userPressed = true;
break;
default:
if (msg != 307)
userPressed = false;
DrawCustomBtn();
//retVal = CallWindowProc(oldWndProc, this.Handle, msg, wParam, lParam);
break;
}
return IntPtr.Zero;
}
private void Execute()
{
//do something
}
public void DrawCustomBtn()
{
try
{
IntPtr hwnd = FindWindow("HHTaskBar", null);
if (!hwnd.Equals(IntPtr.Zero))
{
IntPtr hDC = GetWindowDC(hwnd);
Graphics g = Graphics.FromHdc(hDC);
g.DrawImage((Bitmap)resManager.GetObject("icon_upp er_right"), this.Width - ((Bitmap)resManager.GetObject("icon_upper_right")) .Width - 4, 4);
g.Dispose();
ReleaseDC(hwnd, hDC);
}
}
catch (DllNotFoundException dllex)
{
throw dllex;
}
catch (Exception ex)
{
throw ex;
}
}
public void OnClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
try
{
if (Microsoft.WindowsCE.Forms.SystemSettings.ScreenOr ientation != Microsoft.WindowsCE.Forms.ScreenOrientation.Angle0 )
Microsoft.WindowsCE.Forms.SystemSettings.ScreenOri entation = Microsoft.WindowsCE.Forms.ScreenOrientation.Angle0 ;
}
catch (Exception ex)
{
Log.WriteInfoLog("RESIZING : rotation failed in : " + this.Name + " Message: " + ex.Message );
}
}
#endregion
}