Smartphone2003开发总结一:Form总结
2009-06-11 01:13 老羽 阅读(1759) 评论(5) 收藏 举报在过去的几个月中,完成了一款较旧的手机smartphone2003的项目开发。smartphone2003项目只能以.net cf1.1框架创建,所以导致有不少麻烦和诡异的情况发生。这里总结一下自己的经验。
一.启动主界面还不简单,有什么好讲的。我也是这么认为的,但是我碰到的情况并非如此(我用的机器是多普达585, 环境:vs2005 CF1.1)。请看我的代码:
public class Program { static void Main() { LoginForm login = new LoginForm(); if (login.ShowDialog() == DialogResult.OK) { login.Dispose(); login = null; MainForm main = new MainForm(); Application.Run(main); } } }没有任何问题吧,但是MainForm始终都显示不出来。后来测试了隐藏LoginForm,然后显示MainForm,可以正常显示(但是这样写不符合习惯)。后来我想利用API函数SetForegroundWindow显示MainForm,结果发现Form中没有Handle属性,也就是获取不到窗体Hwnd,API函数也用不了,郁闷吧!如何得到窗体句柄呢?可以通过GetCapture获取某个Control的句柄。
[DllImport("coredll.dll")] public static extern IntPtr GetCapture();public static IntPtr GetHandle(Control ctl) { if (ctl != null) { ctl.Capture = true; try { return GetCapture(); } finally { ctl.Capture = false; } } return IntPtr.Zero; }
Ok,终于得到了窗体句柄,这个窗体句柄非常重要,在以后的介绍中还要用到它。
这样第一段代码不用修改,在MainForm的FormLoad事件中或OnLoad方法中调用API函数SetForegroundWindow可以正常显示主界面了。
二.显示Form
请看下面测试代码,MainForm中menuItem1_Click事件。
private void menuItem1_Click(object sender, EventArgs e) { Form2 form = new Form2(); //form.Parent = this; form.ShowDialog(); }
这个代码显示窗体没有问题,但是smartphone2003手机中有个返回键(<—),很容易按到,模态对话框的窗体就会关闭,影响操作。
如是,代码就改成了:
Form2 form = new Form2(); form.Show();这样的代码又有什么不妥呢?这样显示Form2,会导致在任务管理器中看到2个任务(MainForm和Form2),请注意:CF1.1中Form没有Owner属性的.
接着修改,Hide当前窗体,Show新窗体,可以避免任务栏中有多个任务显示。但是一定要封装,否则新窗体关闭后,如何显示当前窗体???
我们利用继承基类窗体来实现,建立一个基类窗体BaseForm,重载Show的方法,实现隐藏当前窗体,Show新窗体,并且在新窗体关闭时,显示当前窗体。
/// <summary> /// BaseForm 的摘要说明。 /// </summary> public class BaseForm : System.Windows.Forms.Form { private IntPtr _handler; private BaseForm _parentForm; public IntPtr Handler { get { return _handler; } } protected override void OnLoad(EventArgs e) { _handler = FormUtility.GetHandle(this); base.OnLoad(e); FormUtility.SetForegroundWindow(_handler); } public void Show(BaseForm parent) { _parentForm = parent; parent.Hide(); this.Show(); } protected override void OnClosed(EventArgs e) { base.OnClosed(e); ShowParentForm(); } protected virtual void ShowParentForm() { try { if (_parentForm != null) { _parentForm.Show(); FormUtility.SetForegroundWindow(_parentForm.Handler); Application.DoEvents(); } } catch (Exception) { } } }这样就隐藏了Show Form 的细节,完善后的代码如下(Form2继承BaseForm):Form2 form = new Form2(); form.Show(this);
三.Dispose Form
在CF2.0中,调用Form.Close()方法后,会调用Dispose方法。但是CF1.1中,则不会。为什么呢?我们来看看。
public class Component : MarshalByRefObject关键就是Compoent没有继承IDispose接口,所以Form.Close()调用后,是不会调用Dispose()方法的。我们在BaseForm中封装调用Dispose的实现:
protected override void OnClosed(EventArgs e) { base.OnClosed(e); ShowParentForm(); this.Dispose(true); }DEMO下载请点击这里