惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Archives - TechRepublic
Security Archives - TechRepublic
Project Zero
Project Zero
K
Kaspersky official blog
G
Google Developers Blog
T
Threat Research - Cisco Blogs
T
The Blog of Author Tim Ferriss
Cyberwarzone
Cyberwarzone
Y
Y Combinator Blog
Recorded Future
Recorded Future
Blog — PlanetScale
Blog — PlanetScale
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cisco Talos Blog
Cisco Talos Blog
Latest news
Latest news
Microsoft Security Blog
Microsoft Security Blog
H
Help Net Security
S
Schneier on Security
P
Palo Alto Networks Blog
H
Hacker News: Front Page
N
News and Events Feed by Topic
N
Netflix TechBlog - Medium
博客园 - Franky
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
SecWiki News
SecWiki News
Cloudbric
Cloudbric
TaoSecurity Blog
TaoSecurity Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The Hacker News
The Hacker News
C
Check Point Blog
L
LangChain Blog
腾讯CDC
小众软件
小众软件
T
Tenable Blog
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
L
LINUX DO - 最新话题
A
About on SuperTechFans
Google Online Security Blog
Google Online Security Blog
C
Cisco Blogs
Recent Announcements
Recent Announcements
Hacker News: Ask HN
Hacker News: Ask HN
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Vercel News
Vercel News
雷峰网
雷峰网
美团技术团队
D
DataBreaches.Net
Martin Fowler
Martin Fowler
Help Net Security
Help Net Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
F
Full Disclosure
博客园_首页

博客园 - 老羽

推荐AspNetPager分页控件 SqlServer2005中分页代码测试 WM中实现Splash动画效果 自定义合并多文件协议设计 JScript中Date.getTime转.Net中的DateTime .net中处理C/C++中的位域 POOM(Pocket Outlook Object Model)开发介绍及应用(转) 多线程执行多任务的DEMO GPRS管理与创建APN拨号连接 WM中电话相关的技巧 - 老羽 - 博客园 一道面试题题解 【转】Windows Mobile控制面板程序 [转]Windows Mobile上的服务程序 C++常用技巧一(整理收集) [转]CString,string,char*的综合比较 [转] C++ Windows字符和字符指针类型 [转]C++ int,char,string,CString类型转换(整理总结) C++字符串函数详解[转] Smartphone2003中实现焦点在ListView控件与其它控件中切换
Smartphone2003开发总结一:Form总结
老羽 · 2009-06-11 · via 博客园 - 老羽

2009-06-11 01:13  老羽  阅读(1764)  评论()    收藏  举报

       在过去的几个月中,完成了一款较旧的手机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下载请点击这里