Windows Mobile上实现可拖动的窗口

转:http://www.cnblogs.com/qilinzhi/archive/2008/04/19/1160977.html

 

 在Windows CE上的Form可以控制它的大小,但是不能像winform上的窗体一样随意拖动,并且当控制Form大小后Form只会显示其工作区,而不会显示它的caption。
    为了实现窗体拖动,我们可以使用模拟的方式实现,用鼠标的事件来模拟拖动。最下面有示例代码下载。
    
    为了实现可以拖动的窗体,首先要为窗体做如下设置:
    将要拖动的Form的如下属性全部设为false
    ControlBoxMinimizeBoxMaximizeBox
    将FormBorderStyle设为FormBorderStyle.None
    这样才能使窗体以自定义的大小显示。

    由于浮动的窗体不会显示caption,所以我们要自己模拟一个capting,首先我们写一个继承于Panel的类TitleBarPanel,用作captiong,代码如下:

 1public class TitleBarPanel : System.Windows.Forms.Panel
 2    {
 3        internal bool mouseDown = false;
 4        internal Point oldPoint = Point.Empty;
 5
 6        protected System.Windows.Forms.Label titleLabel;
 7
 8
 9        public TitleBarPanel (string title)
10        {
11            this.titleLabel = new Label();
12            titleLabel.Top = 0;
13            this.Controls.Add(this.titleLabel);
14            this.titleLabel.Font = new System.Drawing.Font("Tahoma", 8F, System.Drawing.FontStyle.Bold);
15            this.titleLabel.ForeColor = System.Drawing.Color.White;
16            this.titleLabel.Location = new System.Drawing.Point(42);
17            this.titleLabel.Size = new System.Drawing.Size(10016);
18            this.titleLabel.Text = title;
19        }

20
21
22        override protected void OnMouseDown (MouseEventArgs e)
23        {
24            mouseDown = true;
25            oldPoint = new Point(e.X, e.Y);
26            ((FloatingDialog)this.Parent).Moving = true;
27        }

28
29
30        override protected void OnMouseMove (MouseEventArgs e)
31        {
32            if (mouseDown)
33            {
34                int dx, dy;
35                dx = e.X - oldPoint.X;
36                dy = e.Y - oldPoint.Y;
37
38                this.Parent.Location = new Point(this.Parent.Left + dx, this.Parent.Top + dy);
39
40                this.Parent.Refresh();
41            }

42        }

43
44        override protected void OnMouseUp (MouseEventArgs e)
45        {
46            mouseDown = false;
47            ((FloatingDialog)this.Parent).Moving = false;
48            this.Parent.Refresh();
49        }

50    }

其中有一个Label用于caption显示的标题。
mouseDown属性用于表示鼠标是否处于按下状态。
该类重写了OnMouseDown,OnMouseMove,OnMouseUp事件,用于实现拖动。
在MouseDown事件触发的时候,将当olePoint设为当前点,并将包含该标题的窗体的moving属性设为true。
FloatingDialog的代码在下面。
当MouseMove事件触发时,如果鼠标是按下状态,就计算出位移量dx,dy,并将窗体的位置加上算出的偏移量。接着调用Refresh方法刷新窗体,使窗体触发OnPaint方法重画。
OnMouseUp触发时,将mouseDown设为false,并将窗体的moving属性设为false,并刷新窗体。


为了实现可拖动的窗体,我写了一个基类FloatingDialog,只要继承于该类的窗体即可实现拖动。代码如下:

public class FloatingDialog: Form
    
{
        
private System.ComponentModel.IContainer components = null;
        
/// <summary>
        
/// 清理所有正在使用的资源。
        
/// </summary>
        
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>

        protected override void Dispose (bool disposing)
        
{
            
if (disposing && (components != null))
            
{
                components.Dispose();
            }

            
base.Dispose(disposing);
        }


        
protected TitleBarPanel titlePanel;

        
protected Pen blackPen = new Pen(Color.Black);
        
private bool moving = false;

        
internal bool Moving
        
{
            
get return moving; }
            
set { moving = value; }
        }


        
public FloatingDialog(string title)
        
{
            InitializeComponent(title);
        }


        
public void InitializeComponent (string title)
        
{
            
this.SuspendLayout();

            
//实例化TitlePanel
            this.titlePanel = new TitleBarPanel(title);

            
//使Form浮动
            this.FormBorderStyle = FormBorderStyle.None;
            
this.ControlBox = false;
            
this.MinimizeBox = false;
            
this.MaximizeBox = false;

            
//设置titlepanel
            this.titlePanel.Bounds = new Rectangle(00this.Width, 16);
            
this.titlePanel.BackColor = System.Drawing.SystemColors.ActiveCaption;
            
this.Controls.Add(this.titlePanel);

            
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
            
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
            
this.AutoScroll = false;
            
//this.ClientSize = new System.Drawing.Size(240, 100);
            
            
            
this.ResumeLayout(false);
        }


        
protected override void OnPaint (PaintEventArgs e)
        
{
            Graphics g 
= e.Graphics;

            
if (!titlePanel.mouseDown)
            
{
                
base.OnPaint(e);
            }


            Rectangle r 
= this.ClientRectangle;
            
//r.X = 1;
            
//r.Y = 1;
            r.Height -= 1;

            r.Width 
-= 1;
            g.DrawRectangle(blackPen, r);


        }
 
    }

该类中有三个属性,titlePanel, blackPen, moving.
titlePanel即为前面写的TitleBarPanel类,为窗体的标题。
由于窗体浮动显示的时候是没有边框,所以要自己画一个边框上去,balckPen就是用来画边框的。
moving用于表示窗体是否在移动。
该类重写了OnPaint事件,用于画边框。

剩下的工作就是添加一个FloatingForm窗体,并继承于FloatingDialog类,
在主Form中调用如下方法:

public void AddFloatingForm()
        
{
            
this.SuspendLayout();

            FloatingForm floatingForm 
= new FloatingForm();
            floatingForm.Location 
= new Point((this.Width - floatingForm.Width) / 250);

            
this.Controls.Add(floatingForm);
            floatingForm.Show();
            floatingForm.BringToFront();

            
this.ResumeLayout();
        }

即可实现FloatingForm拖动

示例代码:下载

posted @ 2010-02-02 12:37  张兴业  阅读(190)  评论(0编辑  收藏  举报