c#编写的基于TCP通信的微风IM 版本3 新年新UI

在微风 IM 版本2中我们实现了局域网内的p2p通信,具体见:

【开源下载】c#编写的聊天程序微风IM 版本2 增加局域网P2P通信

前面有朋友说微风IM的UI有点朴素,也确实,于是到网上去淘了件新衣服。

新的UI来自于网上开源程序,由“翱翔的雄鹰”老师编写的完全开源的QQ2010.(c# WinForm).新的UI中有许多自定义控件,我从其中学到了很多Winfrom控件制作的知识。

比如,带边框的文本框

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using SimpleIMClient.Skin;

namespace SimpleIMClient.Skin
{
    public partial class BasicQQTextBox : UserControl
    {
        private Graphics g = null;
        private Bitmap Bmp = null;
        private Color borderColor = Color.FromArgb(84, 165, 213);
        private Bitmap _icon;
        
        public BasicQQTextBox()
        {
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            Bmp = ResClass.GetImgRes("frameBorderEffect_normalDraw");
            Icon = ResClass.GetImgRes("keyboard");
            InitializeComponent();
        }

        [Description("文本"), Category("Appearance")]
        public string Texts
        {
            get
            {
                return textBox1.Text;
            }
            set
            {
                textBox1.Text = value;
                this.Invalidate();
            }
        }

        [Description("图标"), Category("Appearance")]
        public Bitmap Icon
        {
            get
            {
                return _icon;
            }
            set
            {
                _icon = value;
                this.Invalidate();
            }
        }

        [Description("密码框"), Category("Appearance")]
        public bool IsPass
        {
            get
            {
                return textBox1.UseSystemPasswordChar;
            }
            set
            {
                textBox1.UseSystemPasswordChar = value;
                if(value)
                    Icon = ResClass.GetImgRes("keyboard");
            }
        }

        [Description("只读"), Category("Appearance")]
        public bool ReadOn
        {
            get
            {
                return textBox1.ReadOnly;
            }
            set
            {
                textBox1.ReadOnly = value;
                if (value)
                    textBox1.BackColor = Color.Gray;
                else
                    textBox1.BackColor = Color.White;
            }
        }

        public System.Windows.Forms.TextBox textBox
        {
            get
            {
                return textBox1;
            }
            set
            {
                textBox1 = value;
            }
        }

        [Description("右键菜单"), Category("Appearance")]
        public override ContextMenuStrip ContextMenuStrip
        {
            get
            {
                return textBox1.ContextMenuStrip;
            }
            set
            {
                textBox1.ContextMenuStrip = value;
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            g = e.Graphics;
            if(Bmp==null)
                Bmp = ResClass.GetImgRes("frameBorderEffect_normalDraw");
            if (Bmp != null)
            {
                g.DrawImage(Bmp, new Rectangle(0, 0, 4, 4), 0, 0, 4, 4, GraphicsUnit.Pixel);
                g.DrawImage(Bmp, new Rectangle(4, 0, this.Width - 8, 4), 4, 0, Bmp.Width - 8, 4, GraphicsUnit.Pixel);
                g.DrawImage(Bmp, new Rectangle(this.Width - 4, 0, 4, 4), Bmp.Width - 4, 0, 4, 4, GraphicsUnit.Pixel);

                g.DrawImage(Bmp, new Rectangle(0, 4, 4, this.Height - 6), 0, 4, 4, Bmp.Height - 8, GraphicsUnit.Pixel);
                g.DrawImage(Bmp, new Rectangle(this.Width - 4, 4, 4, this.Height - 6), Bmp.Width - 4, 4, 4, Bmp.Height - 6, GraphicsUnit.Pixel);

                g.DrawImage(Bmp, new Rectangle(0, this.Height - 2, 2, 2), 0, Bmp.Height - 2, 2, 2, GraphicsUnit.Pixel);
                g.DrawImage(Bmp, new Rectangle(2, this.Height - 2, this.Width - 2, 2), 2, Bmp.Height - 2, Bmp.Width - 4, 2, GraphicsUnit.Pixel);
                g.DrawImage(Bmp, new Rectangle(this.Width - 2, this.Height - 2, 2, 2), Bmp.Width - 2, Bmp.Height - 2, 2, 2, GraphicsUnit.Pixel);
            }
                if (Icon != null)
                g.DrawImage(Icon, new Rectangle(1, 1, Bmp.Width, Bmp.Height), 0, 0, Bmp.Width, Bmp.Height, GraphicsUnit.Pixel);
        }

        private void textBox1_MouseEnter(object sender, EventArgs e)
        {
            Bmp = ResClass.GetImgRes("frameBorderEffect_mouseDownDraw");
            this.Invalidate();
        }

        private void textBox1_MouseLeave(object sender, EventArgs e)
        {
            Bmp = ResClass.GetImgRes("frameBorderEffect_normalDraw");
            this.Invalidate();
        }

        protected override void OnParentFontChanged(EventArgs e)
        {
            base.OnParentFontChanged(e);
            textBox1.Font = this.Font;
        }

        protected override void OnParentForeColorChanged(EventArgs e)
        {
            base.OnParentForeColorChanged(e);
            textBox1.ForeColor = this.ForeColor;
        }

        private void textBox1_Enter(object sender, EventArgs e)
        {
            if (!textBox1.UseSystemPasswordChar)
            {
                if (textBox1.Text.Equals("<请输入帐号>"))
                {
                    textBox1.Text = "";
                    textBox1.ForeColor = Color.Black;
                }
            }
        }

        private void textBox1_Leave(object sender, EventArgs e)
        {
            if (!textBox1.UseSystemPasswordChar)
            {
                if (textBox1.Text.Equals(""))
                {
                    textBox1.Text = "<请输入帐号>";
                    textBox1.ForeColor = Color.DarkGray;
                }
            }
        }
    }
}
文本框

鼠标经过时,显示边框的按钮

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using SimpleIMClient.Skin;

namespace SimpleIMClient.Skin
{
    public partial class LoginButton : UserControl
    {
        private Graphics g = null;
        private Bitmap Bmp = null;

        public LoginButton()
        {
            Bmp = ResClass.GetImgRes("login_btn_normal");
            if (this.Focused)
                Bmp = ResClass.GetImgRes("login_btn_focus");
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.BackColor = Color.Transparent;
            this.Size = new Size(74,27);
        }

        [Description("文本"), Category("Appearance")]
        public string Texts
        {
            get
            {
                return Text;
            }
            set
            {
                Text = value;
                this.Invalidate();
            }
        }

        private PointF GetPointF(string text)
        {
            float x, y;

            switch (text.Length)
            {
                case 1:
                    x = (float)(this.Width - 12.5 * 1) / 2;
                    y = 4;
                    break;
                case 2:
                    x = (float)(this.Width - 12.5 * 2) / 2;
                    y = 4;
                    break;
                case 3:
                    x = (float)(this.Width - 12.5 * 3) / 2;
                    y = 4;
                    break;
                case 4:
                    x = (float)(this.Width - 12.5 * 4) / 2;
                    y = 4;
                    break;
                case 5:
                    x = (float)(this.Width - 12.3 * 5) / 2;
                    y = 4;
                    break;
                case 6:
                    x = (float)(this.Width - 12.3 * 6) / 2;
                    y = 4;
                    break;
                default:
                    x = (float)(this.Width - 12.3 * 4) / 2;
                    y = 4;
                    break;
            }
            return new PointF(x, y);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            g = e.Graphics;
            if (Bmp != null)
            {
                g.DrawImage(Bmp, new Rectangle(0, 0, this.Width, this.Height), 0, 0, Bmp.Width, Bmp.Height, GraphicsUnit.Pixel);
            }
                PointF point = GetPointF(this.Text);
            if (this.Enabled)
                g.DrawString(this.Texts, new Font("微软雅黑", 9F), Brushes.Black, point);
            else
                g.DrawString(this.Texts, new Font("微软雅黑", 9F), Brushes.Gray, point);
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            Bmp = ResClass.GetImgRes("login_btn_highlight");
            this.Invalidate();
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            Bmp = ResClass.GetImgRes("login_btn_normal");
            if (this.Focused)
                Bmp = ResClass.GetImgRes("login_btn_focus");
            this.Invalidate();
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            Bmp = ResClass.GetImgRes("login_btn_down");
            this.Invalidate();
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            Bmp = ResClass.GetImgRes("login_btn_normal");
            if (this.Focused)
                Bmp = ResClass.GetImgRes("login_btn_focus");
            this.Invalidate();
        }
    }
}
按钮

鼠标经过时显示边框效果的CheckBox

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using SimpleIMClient.Skin;

namespace SimpleIMClient.Skin
{
    [DefaultEvent("CheckedChanged")]
    public partial class BasicCheckBox : UserControl
    {
        private Graphics g = null;
        private bool m_Checked = false;
        private string m_buttonText = "CheckBox";
        public enum CheckStates { Unchecked, Checked, Indeterminate }
        private CheckStates m_CheckState = CheckStates.Unchecked;
        public delegate void CheckedChangedEventHandler(object sender, bool Checked);
        public event CheckedChangedEventHandler CheckedChanged;
        private Bitmap Bmp = null;
        public BasicCheckBox()
        {
            if (Checked)
            {
                switch (CheckState)
                {
                    case CheckStates.Checked:
                        Bmp = ResClass.GetImgRes("cb_c_l");
                        break;
                    case CheckStates.Indeterminate:
                        Bmp = ResClass.GetImgRes("cb_b_l");
                        break;
                    default:
                        Bmp = ResClass.GetImgRes("cb_c_l");
                        break;
                }
            }
            else
            {
                Bmp = ResClass.GetImgRes("cb_n_l");
            }
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.BackColor = Color.Transparent;
            this.Size = new Size(95,20);
        }

        [Description("按钮上的文本"), Category("Appearance")]
        public string Texts
        {
            get
            {
                return m_buttonText;
            }
            set
            {
                m_buttonText = value;
                this.Invalidate();
            }
        }

        [Description("是否选中"), Category("Appearance")]
        public bool Checked
        {
            get
            {
                return m_Checked;
            }
            set
            {
                m_Checked = value;
                if (value)
                    CheckState = CheckStates.Checked;
                else
                    CheckState = CheckStates.Unchecked;
                if (CheckedChanged != null)
                    CheckedChanged(this, value);
            }
        }

        [Description("选中状态"), Category("Appearance")]
        public CheckStates CheckState
        {
            get
            {
                return m_CheckState;
            }
            set
            {
                m_CheckState = value;
                switch (value)
                {
                    case CheckStates.Unchecked:
                        m_Checked = false;
                        Bmp = ResClass.GetImgRes("cb_n_e");
                        break;
                    case CheckStates.Checked:
                        m_Checked = true;
                        Bmp = ResClass.GetImgRes("cb_c_e");
                        break;
                    case CheckStates.Indeterminate:
                        m_Checked = true;
                        Bmp = ResClass.GetImgRes("cb_b_e");
                        break;
                }
                this.Invalidate(new Rectangle(0, (Height - 15) / 2, 15, 15));
            }
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            if (Bmp != null)
            {
                g = e.Graphics;
                g.DrawImage(Bmp, new Rectangle(0, (this.Height - 15) / 2, 15, 15), 0, 0, Bmp.Width, Bmp.Height, GraphicsUnit.Pixel);
                g.DrawString(m_buttonText, this.Font, Brushes.Black, 16, (this.Height - 15) / 2);
            }
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            this.MinimumSize = new Size(15, 15);
        }

        protected override void OnClick(EventArgs e)
        {
            if (!Checked)
            {
                Checked = true;

            }
            else
            {
                Checked = false;
            }
        }

        protected override void OnDoubleClick(EventArgs e)
        {
            if (!Checked)
            {
                Checked = true;

            }
            else
            {
                Checked = false;
            }
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            if (Checked)
            {
                switch (CheckState)
                {
                    case CheckStates.Checked:
                        Bmp = ResClass.GetImgRes("cb_c_e");
                        break;
                    case CheckStates.Indeterminate:
                        Bmp = ResClass.GetImgRes("cb_b_e");
                        break;
                    default:
                        Bmp = ResClass.GetImgRes("cb_c_e");
                        break;
                }
            }
            else
            {
                Bmp = ResClass.GetImgRes("cb_n_e");
            }
            this.Invalidate(new Rectangle(0,(Height - 15)/2,15,15));
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            if (Checked)
            {
                switch (CheckState)
                {
                    case CheckStates.Checked:
                        Bmp = ResClass.GetImgRes("cb_c_l");
                        break;
                    case CheckStates.Indeterminate:
                        Bmp = ResClass.GetImgRes("cb_b_l");
                        break;
                    default:
                        Bmp = ResClass.GetImgRes("cb_c_l");
                        break;
                }
            }
            else
            {
                Bmp = ResClass.GetImgRes("cb_n_l");
            }
            this.Invalidate(new Rectangle(0, (Height - 15) / 2, 15, 15));
        }
    }
}
CheckBox

  我们看一下新的微风V3的UI

c#编写的基于TCP通信的微风IM 版本3 新年新UI_第1张图片

我们实现了登陆功能,注册新账号,找回密码等都没有实现,是原来UI 上面有的

c#编写的基于TCP通信的微风IM 版本3 新年新UI_第2张图片

聊天窗口:

c#编写的基于TCP通信的微风IM 版本3 新年新UI_第3张图片

支持更换皮肤

c#编写的基于TCP通信的微风IM 版本3 新年新UI_第4张图片

c#编写的基于TCP通信的微风IM 版本3 新年新UI_第5张图片

c#编写的基于TCP通信的微风IM 版本3 新年新UI_第6张图片

 

服务器端、数据库、通信框架没有变化,请去  微风IM V1,或 微风IM V2相关文章下载。

微风IM V3客户端EXE文件

祝大家新年快乐

谢谢大家的支持

源码包含以下四个工程文件,通信框架需要另行下载

 

c#编写的基于TCP通信的微风IM 版本3 新年新UI_第7张图片

源码  ( 包含客户端与服务器端)   数据库下载

3.1版本已经发布 

[c#源码]微风IM V3.1 支持TCP通信发送图片

微风IM3.2已发布  

请见  [源码分享]微风IM 3.2 实现新用户注册 含详细过程

有朋友问性能的问题,请参见下面这篇文章

NetworkComms通信框架 V3 性能测试

你可能感兴趣的:(c#编写的基于TCP通信的微风IM 版本3 新年新UI)