none
windows Mobile 5.0程序源码 RRS feed

  • 常规讨论

  •         很少有机会完整的提供自己用VS2005开发的程序源码,正好微软举办移动大赛,所以抽时间做了一个程序。程序虽小,但包含的技术点不少。

            技术要点如下:

    1、图形双缓存技术
    多个图片快速移动的时候,如果不采用图形双缓存技术,图片在移动时,会非常闪烁。
    该实现还是沿用了我开发嵌入式组态的时方法:
    第一:重载OnPaintBackground函数,不要让系统自动绘背景。
    //避免闪烁,不绘制背景
            protected override void OnPaintBackground(PaintEventArgs paintg)
            {
                //不绘制背景
        }
      第二:创建位图场景
          bitmap = new Bitmap(this.Width, this.Height);
       graphics = Graphics.FromImage((System.Drawing.Image)bitmap);
         //绘图
           private void frmMain_Paint(object sender, PaintEventArgs e)
           {
               //绘背景
             graphics.Clear(Color.White);
    //实际绘图代码
              
               //绘图
               e.Graphics.DrawImage(bitmap, 0, 0);
          }
    2、获取毫秒值
    在.net精简框架集下,是无法通过现成的命令获得毫秒值的,一般最小时刻单位为秒。这对我获取手写笔移动的快慢是远远不够的,一次手写笔快速从屏蔽划过,一般也就十几毫秒,用秒来衡量就区分不出快慢了。
    要想获取毫秒值,必须用API函数,不过要有相应的硬件支持才行。幸好在模拟器和我的PPC上都支持。
    [DllImport("\\windows\\coredll.dll", EntryPoint = "GetTickCount")]
        public static extern int GetTickCount();
    这样当鼠标按下时记下当时的位置和时刻值,直到鼠标抬起时,算出位移值,然后在除以时间就是手写笔移动的速度了。
    3、区分单击和移动
    在PC机上是很容易区分单击和移动的,但是用手写笔则不然。我的思路是鼠标按下和抬起的位移值小于一定值,我就认为是单击,否则就是移动。
    //鼠标按下
            private void frmMain_MouseDown(object sender, MouseEventArgs e)
            {
                Rectangle rect = new Rectangle(0, 50, 240, 72);
                if (rect.Contains(e.X, e.Y))
                {
                    MouseFlag = true;
                    fStartX = e.X;
                    fTime = GetTickCount();
                }
                rect = new Rectangle(75, 50, 90, 72);
                if (rect.Contains(e.X, e.Y))
                {
                    MouseClickFlag = true;
                    bSelectDown = true;
                    this.Refresh();
                }
            }
     
            //鼠标抬起
            private void frmMain_MouseUp(object sender, MouseEventArgs e)
            {
                if (MouseFlag)
                {
                    MouseFlag = false;
                    fWidth = e.X - fStartX;
                    bWay = (fWidth > 0);
                    fWidth = Math.Abs(fWidth);
     
                    if (fWidth > intMoveSpace)
                    {
                        //计算鼠标移动的速度
                        fTime=GetTickCount() - fTime;
                        fMoveSpeed = fWidth / fTime;
                        if (fMoveSpeed < 0.5) fMoveSpeed = (float)0.6;
     
                        //启动时钟函数,图片开始滚动                  
                        tmrMove.Interval = (int)(20 /(fMoveSpeed-0.5));
                        tmrMove.Enabled = true;
                    }
                    else
                    {
                        //鼠标单击事件发生
                        if (MouseClickFlag)
                        {
                            MouseClickFlag = false;
                            bSelectDown = false;                
                            ShowInfoBar();
                        }
                    }
                }
            }
    4、动画移动
    虽然主界面最多显示三个图像索引,其实移动起来至少要有四个图形同时在移动效果才好。在这里就用到了数学的知识(有兴趣的朋友可以看看这篇文章:http://news.csdn.net/n/20071106/110350.html),不过只需简单的数学知识,我想有个小学初中的水平就够了,就是简单计算一下图形移动时,图像坐标变化的规律。别说,在做这部分的时候,我还是花费了不少时间,并在草纸上画了几个图,才明白左移和右移坐标和图形变化的规律。
    这部分的代码就不贴出了(请下载程序,自行看看源码)。
    5、XML反序列化
    原先我是把图片添加到ImageList组件里的,没有想到图片一多,不光VS2005 IDE在调试加载资源时报错(其实VS2005在加载资源的时候很不稳定,不知道VS2008是否进行了改善),程序运行到我PPC上的时候,十几兆的内存一下子就没有了。所以最后还是采用了XML序列化技术保存数据,同时图片也单独以文件方式存放,XML文件仅保存路径信息。(其实XML文件也可以保存图片数据,只是我觉得这样,XML文件会很大,反序列化时会很慢,影响用户的体验)。
    解析一个复杂的XML文件是很麻烦的事,所以我一般都采用XML序列化技术。所以我构建了两个类来完成该功能。
    值得说明的是,List<string>类在序列化和反序列化时会出问题(除非把string再封装到一个类里),所以我采用string数组保存数据,并适当的时候转换为List<string>模式。
    public class DataInfos
        {
            //主背景图片的路径
            public string strBackBmpPath = "";
            //主背景图片
            [XmlIgnore]
            public Image bmpBack = null;
            //场馆数据
            public List<DataInfo> Data = new List<DataInfo>();
            //反序列化
            public static DataInfos XMLDeserialize(string XmlFile)
            {
                try
                {
                    Type[] mtype = new Type[1];
                    mtype[0] = typeof(DataInfo);
                    DataInfos XmlData = new DataInfos();
                    Stream sf = new FileStream(XmlFile, FileMode.Open, FileAccess.Read, FileShare.None);
                    XmlSerializer xmls = new XmlSerializer(typeof(DataInfos), mtype);
                    XmlData = (DataInfos)xmls.Deserialize(sf);
                    sf.Close();
                    return XmlData;
                }
                catch (Exception e)
                {
                    MessageBox.Show("反序列化失败:" + XmlFile + "<" + e.Message + ">", "叶帆软件");
                    return null;
                }
            }
        }
     
        public class DataInfo
        {
            //场馆名称
            public string Text = "";
            //信息个数
            public int Count = 0;
            //信息索引
            [XmlIgnore]
            public int Index = 0;
            //图片说明
            public string[] mlstTitle = null;
            [XmlIgnore]
            public List<string> lstTitle
            {
                set { mlstTitle = value.ToArray(); }
                get
                {
                    List<string> mmlstTitle = new List<string>();
                    if (mlstTitle != null)
                    {
                        foreach (string str in mlstTitle)
                        {
                            mmlstTitle.Add(str);
                        }
                    }
                    return mmlstTitle;
                }
            }
     
            //信息说明
            public string[] mlstInfo = null;
            [XmlIgnore]
            public List<string> lstInfo
            {
                set { mlstInfo = value.ToArray(); }
                get
                {
                    List<string> mmlstInfo = new List<string>();
                    if (mlstInfo != null)
                    {
                        foreach (string str in mlstInfo)
                        {
                            mmlstInfo.Add(str);
                        }
                    }
                    return mmlstInfo;
                }
            }
            //图片路径
            public string[] mlstImagePath = null;
            [XmlIgnore]
            public List<string> lstImagePath
            {
                set { mlstImagePath = value.ToArray(); }
                get
                {
                    List<string> mmlstImagePath = new List<string>();
                    if (mlstImagePath != null)
                    {
                        foreach (string str in mlstImagePath)
                        {
                            mmlstImagePath.Add(str);
                        }
                    }
                    return mmlstImagePath;
                }
            }
     
            //图片
            [XmlIgnore]
            public List<Image> lstBmp = new List<Image>();
            //索引图片路径
            public string bmpPath = "";
            //索引图片
            [XmlIgnore]
            public Image bmp = null;     
     }
     
     
    有兴趣的朋友可以看一看,也可以品评一下。
    2007年11月14日 12:09
    版主

全部回复