• winform消息提示框


    摘自:http://www.cnblogs.com/risen/archive/2008/01/15/1039751.html

    public partial class AlertForm : Form
        {
            /*
             * 在类AlertForm定义的下方,
             * 我们创建用于显示的字符串和其颜色的变量,
             * 再定义几个Rectangle对象的变量用于放置标题、
             * 提示内容以及可以拖动窗体的区域和关闭按钮的区域。
             * 然后,我们需要保存窗体在浮动时的高度以便计算移动后的新高度,
             * intervalValue变量用来确定窗体显示和隐藏的速度。
             * 进行平台调用时我们需要提前定义好常量的值用来传递给函数,
             * WM_NCLBUTTONDOWN和HT_CAPTION常量用于拖动窗体,
             * 他们的值都保存在WinUser.h头文件中,
             * 所对应的动态链接库名为:user32.dll。
             * 我们用到的Win32API为:SendMessage、ReleaseCapture和ShowWindow,
             * 通过使用DllImportAttribute可以导入相应的函数并在程序中重新进行定义,如下:
             */
            public Bitmap BackgroundBitmap = null;

            private string titleText;
            private string contentText;
            private Color normalTitleColor = Color.FromArgb(0, 0, 0);
            private Font normalTitleFont = new Font("宋体", 12, FontStyle.Regular, GraphicsUnit.Pixel);
            private Color normalContentColor = Color.FromArgb(0, 0, 0);
            private Font normalContentFont = new Font("宋体", 12, FontStyle.Regular, GraphicsUnit.Pixel);

            public Rectangle TitleRectangle;
            public Rectangle TitlebarRectangle;
            public Rectangle ContentRectangle;
            public Rectangle CloseBtnRectangle;

            private Rectangle WorkAreaRectangle;

            private int SavedTop;
            private int currentTop = 1;
            private int intervalValue = 2;

            public const int WM_NCLBUTTONDOWN = 0x00A1; //消息:左键点击 winuser.h
            public const int HT_CAPTION = 0x0002; //标题栏

            [DllImportAttribute("user32.dll")]
            public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); //发送消息 //winuser.h 中有函数原型定义
            [DllImportAttribute("user32.dll")]
            public static extern bool ReleaseCapture(); //释放鼠标捕捉 winuser.h
            /*
             * SendMessage向消息循环发送标题栏被按下的消息来模拟窗体的拖动,
             * ShowWindow用来将特定句柄的窗体显示出来,
             * 注意第二个参数nCmdShow,它表示窗体应该怎样显示出来,
             * 而我们需要窗体不获得焦点显示出来,
             * SW_SHOWNOACTIVATE可以满足我们要求,
             * 继续在WinUser.h文件中搜索找到该常量对应的值为4,
             * 于是我们就可以这样调用来显示窗体了:
             */
            [DllImportAttribute("user32.dll")] //winuser.h
            private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow);

            public int CurrentState=0; //0=hide 1=uptoshow 2=showing 3=downtohide        

            private AlertForm()
            {
                InitializeComponent();
                SetBackgroundBitmap(snnu.ccs.Properties.Resources.popup2, Color.FromArgb(255, 0, 255));
            }
            public static void Show(string ftitletext, string fcontenttext)
            {
                AlertForm alert = new AlertForm();
                alert.ShowForm(ftitletext, fcontenttext);
            }
            /*
             * 当窗体需要升起时将窗体的Top属性值不断减少,
             * 而窗体回落时将Top属性值增加并超过屏幕的高度窗体就消失了,
             * 虽然原理很简单但仍需精确控制。
             * SetBackgroundBitmap函数首先将窗体背景图像保存到BackgroundBitmap变量中,
             * 然后根据该位图图像轮廓和透明色创建Region,BitmapToRegion就用于完成Bitmap到Region的转换,
             * 程序再将这个Region付值给窗体的Region属性以完成不规则窗体的创建。
             */
            protected void SetBackgroundBitmap(Image image, Color transparencyColor)
            {
                BackgroundBitmap = new Bitmap(image);
                Width = BackgroundBitmap.Width;
                Height = BackgroundBitmap.Height;
                TitleRectangle = new Rectangle(2, 1, 70, 25);
                TitlebarRectangle = new Rectangle(1, 1, Width, 25);
                ContentRectangle = new Rectangle(1, 25, Width, Height - 25);
                CloseBtnRectangle = new Rectangle(Width - 25, 1, 25, 25);
                Region = BitmapToRegion(BackgroundBitmap, transparencyColor);
            }

            protected Region BitmapToRegion(Bitmap bitmap, Color transparencyColor)
            {
                if (bitmap == null)
                    throw new ArgumentNullException("Bitmap", "Bitmap cannot be null!");

                int height = bitmap.Height;
                int width = bitmap.Width;

                GraphicsPath path = new GraphicsPath();

                for (int j = 0; j < height; j++)
                    for (int i = 0; i < width; i++)
                    {
                        if (bitmap.GetPixel(i, j) == transparencyColor)
                            continue;

                        int x0 = i;

                        while ((i < width) && (bitmap.GetPixel(i, j) != transparencyColor))
                            i++;

                        path.AddRectangle(new Rectangle(x0, j, i - x0, 1));
                    }

                Region region = new Region(path);
                path.Dispose();
                return region;
            }

            protected void DrawText(Graphics grfx)
            {
                if (titleText != null && titleText.Length != 0)
                {
                    StringFormat sf = new StringFormat();
                    sf.Alignment = StringAlignment.Near;
                    sf.LineAlignment = StringAlignment.Center;
                    sf.FormatFlags = StringFormatFlags.NoWrap;
                    sf.Trimming = StringTrimming.EllipsisCharacter;
                    grfx.DrawString(titleText, normalTitleFont, new SolidBrush(normalTitleColor), TitleRectangle, sf);
                }

                if (contentText != null && contentText.Length != 0)
                {
                    StringFormat sf = new StringFormat();
                    sf.Alignment = StringAlignment.Center;
                    sf.LineAlignment = StringAlignment.Center;
                    sf.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
                    sf.Trimming = StringTrimming.Word;    
                    grfx.DrawString(contentText, normalContentFont, new SolidBrush(normalContentColor), ContentRectangle, sf);
                }
            }
            /*
             * 通知窗体背景以及文字的绘制在重载的OnPaintBackground方法中完成,
             * 而且利用了双重缓冲区技术来进行绘制操作,代码如下:
             */
            protected override void OnPaintBackground(PaintEventArgs e)
            {
                Graphics grfx = e.Graphics;
                grfx.PageUnit = GraphicsUnit.Pixel;

                Graphics offScreenGraphics;
                Bitmap offscreenBitmap;

                offscreenBitmap = new Bitmap(BackgroundBitmap.Width, BackgroundBitmap.Height);
                offScreenGraphics = Graphics.FromImage(offscreenBitmap);

                if (BackgroundBitmap != null)
                {
                    offScreenGraphics.DrawImage(BackgroundBitmap, 0, 0, BackgroundBitmap.Width, BackgroundBitmap.Height);
                }

                DrawText(offScreenGraphics);

                grfx.DrawImage(offscreenBitmap, 0, 0);
            }
            /*
             * CurrentState变量表示窗体的状态是显示中、停留中还是隐藏中,
             * 两个计时器根据窗体不同状态对窗体的位置进行更改,
             * 我们会使用SetBounds来执行该操作:
             * this.SetBounds(WorkAreaRectangle.Width - this.Width, WorkAreaRectangle.Height - currentTop, this.Width, this.Height);
             */
            protected void ShowForm(string ftitletext, string fcontenttext)
            {
                titleText = ftitletext;
                contentText = fcontenttext;
                WorkAreaRectangle = Screen.GetWorkingArea(WorkAreaRectangle);
                this.Top = WorkAreaRectangle.Height + this.Height;
                FormBorderStyle = FormBorderStyle.None;
                WindowState = FormWindowState.Normal;
                this.SetBounds(WorkAreaRectangle.Width - this.Width, WorkAreaRectangle.Height - currentTop, this.Width, this.Height);
                CurrentState = 1;
                timer1.Enabled = true;

                ShowWindow(this.Handle, 4); //#define SW_SHOWNOACTIVATE   4
            }

            private void timer1_Tick(object sender, EventArgs e)
            {
                if (CurrentState == 1)
                {
                    this.SetBounds(WorkAreaRectangle.Width - this.Width, WorkAreaRectangle.Height - currentTop, this.Width, this.Height);
                    currentTop = currentTop + intervalValue;
                    if (this.Top <= WorkAreaRectangle.Height - this.Height)
                    {
                        timer1.Enabled = false;
                        CurrentState = 2;
                        timer2.Enabled = true; //显示停留计时
                        currentTop = 1;
                    }
                }
                else if (CurrentState==3)
                {
                    this.SetBounds(WorkAreaRectangle.Width - this.Width, SavedTop + currentTop, this.Width, this.Height);
                    currentTop = currentTop + intervalValue;
                    if (this.Top >= WorkAreaRectangle.Height)
                    {
                        timer1.Enabled = false;

                        this.Close();
                        CurrentState = 0;
                        currentTop = 1;
                    }
                }
            }
            /*
             上述代码首先返回窗体绘制表面的Graphics并保存在变量grfx中,
             * 然后创建一个内存Graphics对象offScreenGraphics和内存位图对象offscreenBitmap,
             * 将内存位图对象的引用付值给offScreenGraphics,
             * 这样所有对offScreenGraphics的绘制操作也都同时作用于offscreenBitmap,
             * 这时就将需要绘制到通知窗体表面的背景图像BackgroundBitmap绘制到内存的Graphics对象上,
             * DrawText函数根据需要显示文字的大小和范围调用Graphics.DrawString将文字显示在窗体的特定区域。
             * 最后,调用Graphics.DrawImage将内存中已经绘制完成的图像显示到通知窗体表面。
             * 我们还需要捕获窗体的鼠标操作,有三个操作在这里进行,
             * 1、处理拖动窗体操作,
             * 2、处理通知窗体的关闭操作,
             * 3、内容区域的单击操作。
             * 三个操作都需要检测鼠标的当前位置与每个Rectangle区域的包含关系,
             * 只要单击落在特定区域我们就进行相应的处理,代码如下
             */
            private void TaskbarForm_MouseDown(object sender, MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Left)
                {
                    if (TitlebarRectangle.Contains(e.Location)) //单击标题栏时拖动
                    {
                        ReleaseCapture(); //释放鼠标捕捉
                        SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0); //发送左键点击的消息至该窗体(标题栏)
                    }
                    if (CloseBtnRectangle.Contains(e.Location)) //单击Close按钮关闭
                    {
                        this.Close();
                        currentTop = 1;
                    }
                }
            }

            private void timer2_Tick(object sender, EventArgs e)
            {
                timer2.Enabled = false;
                CurrentState = 1;
                currentTop = 1;
                SavedTop = this.Top;
                CurrentState = 3;
                timer1.Enabled = true;
            }

            private void TaskbarForm_MouseMove(object sender, MouseEventArgs e)
            {
                if (ContentRectangle.Contains(e.Location))
                {
                    Cursor = Cursors.Hand;
                }
                else
                    Cursor = Cursors.Default;
            }
        }

  • 相关阅读:
    CodeForces 546C(队列)
    N皇后摆放问题
    士兵队列
    货币问题
    C
    B
    ACM第三次比赛 Big Chocolate
    ACM比赛(第三次D)
    ACM第三次比赛UVA11877 The Coco-Cola Store
    uva 10382
  • 原文地址:https://www.cnblogs.com/jecyhw/p/3722048.html
Copyright © 2020-2023  润新知