新浪微博桌面應用--仿qq界面的完美實現


界面我覺得可以做到跟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);

 http://www.linhang.net/file.axd?file=2012%2f4%2fSkinEngine.rar

整個微博桌面應用:

DesktopIM.rar (1.48 mb)

直接用帳號登錄是登錄不了的,因為新浪已經不允許直接用帳號登錄了,做這軟件時是可以的

 

更正一點,圓角的處理在這里:

        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相關的用法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM