博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
新浪微博桌面应用--仿qq界面的完美实现
阅读量:5240 次
发布时间:2019-06-14

本文共 7828 字,大约阅读时间需要 26 分钟。

界面我觉得可以做到跟QQ一样都没问题,本来不想搞成这样的,不过搞来搞去就变成这样了

背景是可以换的,或自定义背景图,或背景颜色

这个界面是怎么做的呢?很多初学者可能比较头疼,用第三方控件有时是很难做成自已想要的效果的,而且有些控件是通过拦截系统消息更改实现的,这样方法虽然用起来简单,但很耗系统资源,建议不要用。

要做自定义界面重点要是这里:

void form_Paint(object sender, PaintEventArgs e)        {            if (backgroundpic == null)            {                bodybrush = new LinearGradientBrush(new Rectangle(0, 0, form.Width, form.Height), backGroundColorA, backGroundColorB, LinearGradientMode.Vertical);                e.Graphics.FillPath(bodybrush, CreateRoundedRectanglePath(new Rectangle(0, 0, form.Width, form.Height), cornerSiz, CornerPostionType.Body)); //画底色            }            else            {               // e.Graphics.DrawImage(backgroundpic, new Rectangle(0, 0, form.ClientSize.Width, form.ClientSize.Height), 0, 0, backgroundpic.Width, backgroundpic.Height, GraphicsUnit.Pixel);                e.Graphics.DrawImage(backgroundpic, new Rectangle(0, 0, form.ClientSize.Width, form.ClientSize.Height), 0, 0, form.ClientSize.Width, form.ClientSize.Height, GraphicsUnit.Pixel, BackGroundImageAttributes);               // e.Graphics.DrawImage(backgroundpic, new Rectangle(0, 0, form.ClientSize.Width, form.ClientSize.Height), 0, 0, backgroundpic.Width, backgroundpic.Height, GraphicsUnit.Pixel, BackGroundImageAttributes);            }            captionBrush = new LinearGradientBrush(new Rectangle(0, 0, e.ClipRectangle.Width, captionTopHeight), Color.FromArgb(captionTopAlpha, Color.White), Color.FromArgb(captionCenterAlpha, Color.White), LinearGradientMode.Vertical);            e.Graphics.FillPath(captionBrush, CreateRoundedRectanglePath(new Rectangle(0, 0, form.ClientSize.Width, captionTopHeight), cornerSiz, CornerPostionType.Top)); //画标题栏            captionBrush2 = new LinearGradientBrush(new Rectangle(0, captionTopHeight - 1, e.ClipRectangle.Width, captionBottomHeight+1), Color.FromArgb(captionCenterAlpha, Color.White), Color.FromArgb(captionBottomAlpha, Color.White), LinearGradientMode.Vertical);            e.Graphics.FillRectangle(captionBrush2, new Rectangle(0, captionTopHeight, form.ClientSize.Width, captionBottomHeight)); //画标题栏            /            PaintBackgroundStyle(e);        }

另外自定义后还有一个比较常见的问题,就是没有拖拉窗口大小功能了,这个可以通过程序实现,比较好的方法是拦截窗口消息实现原来的拖拉功能,代码奉上:

protected override void WndProc(ref Message m)        {                switch (m.Msg)                {                    case Win32Message.WM_NCPAINT:                        break;                    case Win32Message.WM_NCACTIVATE:                        if (m.WParam == (IntPtr)0)                        {                            m.Result = (IntPtr)1;                        }                        if (m.WParam == (IntPtr)2097152)                        {                            m.Result = (IntPtr)1;                        }                        break;                    case Win32Message.WM_NCCALCSIZE:                        break;                    case Win32Message.WM_NCHITTEST:                        Point vPoint = new Point((int)m.LParam & 0xFFFF, (int)m.LParam >> 16 & 0xFFFF);                        vPoint = PointToClient(vPoint);                        if (MaximizeBox)                        {                            if (vPoint.X <= 3)                            {                                if (vPoint.Y <= 3)                                    m.Result = (IntPtr)Win32Message.HTTOPLEFT;                                else if (vPoint.Y >= Height - 3)                                    m.Result = (IntPtr)Win32Message.HTBOTTOMLEFT;                                else m.Result = (IntPtr)Win32Message.HTLEFT;                            }                            else if (vPoint.X >= Width - 3)                            {                                if (vPoint.Y <= 3)                                    m.Result = (IntPtr)Win32Message.HTTOPRIGHT;                                else if (vPoint.Y >= Height - 3)                                    m.Result = (IntPtr)Win32Message.HTBOTTOMRIGHT;                                else m.Result = (IntPtr)Win32Message.HTRIGHT;                            }                            else if (vPoint.Y <= 3)                            {                                m.Result = (IntPtr)Win32Message.HTTOP;                            }                            else if (vPoint.Y >= Height - 3)                                m.Result = (IntPtr)Win32Message.HTBOTTOM;                        }                        break;                    default:                        base.WndProc(ref m);                        break;                }        }

另外附上我的界面实现类,调用很方便简单 ,在窗口构造函数(初始加载的地方就行)处实例化即可 new SkinEngineForm(this);

 

整个微博桌面应用:

直接用帐号登录是登录不了的,因为新浪已经不允许直接用帐号登录了,做这软件时是可以的

 

更正一点,圆角的处理在这里:

void cform_SizeChanged(object sender, EventArgs e)        {            if (form.FormBorderStyle == FormBorderStyle.None)            {                form.Region = new Region(CreateRoundedRectanglePath(form.ClientRectangle, cornerSiz, cornerPosition));                outRectangleWidth = form.ClientSize.Width - 1;                outRectangleHeight = form.ClientSize.Height - 1;                intRectangleWidth = form.ClientSize.Width - 2;                intRectangleHeight = form.ClientSize.Height - 2;                form.Invalidate();            }        }

 

public GraphicsPath CreateRoundedRectanglePath(Rectangle rect, int cornerRadius, CornerPostionType cornerPostion)        {            roundedRect = new GraphicsPath();            if (cornerPostion == CornerPostionType.Top)            {                roundedRect.AddBezier(0, 2, 1, 1, 1, 1, 2, 0);                roundedRect.AddLine(3, 0, rect.Width - 3, 0);                roundedRect.AddBezier(rect.Width - 2, 0, rect.Width - 1, 1, rect.Width - 1, 1, rect.Width, 2);                roundedRect.AddLine(rect.Width, 3, rect.Width, rect.Height);                roundedRect.AddLine(rect.Width, rect.Height, 0, rect.Height);                roundedRect.AddLine(0, rect.Height, 0, 3);            }            else if (cornerPostion == CornerPostionType.Bottom)            {                roundedRect.AddLine(0, 0, rect.Width, 0);                roundedRect.AddLine(rect.Width, 0, rect.Width, rect.Height - 3);                roundedRect.AddBezier(rect.Width, rect.Height - 2, rect.Width - 1, rect.Height - 1, rect.Width - 1, rect.Height - 1, rect.Width - 2, rect.Height);                roundedRect.AddLine(rect.Width - 3, rect.Height, 3, rect.Height);                roundedRect.AddBezier(0, rect.Height - 2, 1, rect.Height - 1, 1, rect.Height - 1, 2, rect.Height - 1);                roundedRect.AddLine(0, rect.Height - 3, 0, 0);            }            else            {                roundedRect.AddBezier(0, 2, 1, 1, 1, 1, 2, 0);                roundedRect.AddLine(3, 0, rect.Width - 3, 0);                roundedRect.AddBezier(rect.Width - 2, 0, rect.Width - 1, 1, rect.Width - 1, 1, rect.Width, 2);                roundedRect.AddLine(rect.Width, 3, rect.Width, rect.Height - 3);                roundedRect.AddBezier(rect.Width, rect.Height - 2, rect.Width - 1, rect.Height - 1, rect.Width - 1, rect.Height - 1, rect.Width - 2, rect.Height);                roundedRect.AddLine(rect.Width - 3, rect.Height, 3, rect.Height);                roundedRect.AddBezier(0, rect.Height - 2, 1, rect.Height - 1, 1, rect.Height - 1, 2, rect.Height - 1);                roundedRect.AddLine(0, rect.Height - 3, 0, 3);            }            roundedRect.CloseFigure();            return roundedRect;        }    }

 

完整代码请看我提供下载的类库

补充:

有同学留言说到改变窗口大小时界面闪烁比较严重的问题,因为这功能现在也没时间去修改优化,以后有空闲时间可能会把这个皮肤做成独立完整的类,到时在一起优化程序代码。

因为现在的代码是窗口大小变化时是全刷新了,这方面是可以优化的,是先确定需要刷新的区块,只刷新需要更新的区块,这样闪烁就能去掉或减至最低,可以在绘图事件中先定义区块e.Graphics.SetClip(freshClipRectangle);这个freshClipRectangle是需要更新的区域,想研究的同学可以去找找SetClip相关的用法。

转载于:https://www.cnblogs.com/easywebfactory/archive/2012/04/24/2468804.html

你可能感兴趣的文章
C# Dynamic通用反序列化Json类型并遍历属性比较
查看>>
128 Longest Consecutive Sequence 一个无序整数数组中找到最长连续序列
查看>>
定制jackson的自定义序列化(null值的处理)
查看>>
auth模块
查看>>
javascript keycode大全
查看>>
前台freemark获取后台的值
查看>>
log4j.properties的作用
查看>>
游戏偶感
查看>>
Leetcode: Unique Binary Search Trees II
查看>>
C++ FFLIB 之FFDB: 使用 Mysql&Sqlite 实现CRUD
查看>>
Spring-hibernate整合
查看>>
c++ map
查看>>
exit和return的区别
查看>>
discuz 常用脚本格式化数据
查看>>
洛谷P2777
查看>>
PHPStorm2017设置字体与设置浏览器访问
查看>>
Django 相关
查看>>
git init
查看>>
训练记录
查看>>
IList和DataSet性能差别 转自 http://blog.csdn.net/ilovemsdn/article/details/2954335
查看>>