C#制作高仿360安全衛士窗體<一>


開始寫這一系列博客之前先要向大家說聲抱歉,放肆雷特建立很久卻很少有更新。當然博客人氣也不旺,大部分都是看的人多評論收藏的人少。一直想要改變這種狀態,正好趕上了最近工作上做了一個高仿360安全衛士窗體。所以將開發歷程分享出來,一來希望能和大家交流共同學習成長;二來希望自己的放肆雷特能有人光顧。

這一系列的文章所用到的技術首先要感謝蘇飛大哥,我也是在很早以前看了他的QQ皮膚制作文章之后得到的靈感和一些相關知識。在這里幫他的C#論壇打個廣告,里面有不少比較有用的資料。蘇飛大哥也是很用心的打理這個論壇,論壇地址http://www.sufeinet.com/

說了這么多也該進入主題了,首先為了讓大家有興趣看下去而且認同我開發的這個皮膚,所以先傳上本程序的界面截圖(不喜勿噴)。同時本人也先聲明,本人屬屌絲一枚,想法和思路可能比較落后,如果你有比較不錯的想法和思路可以在本論壇中尋找本人qq或評論本文。

第一章:360安全衛士窗體素材提取

360安全衛士的窗體使用的素材比之前QQ的素材更容易提取首先安裝360安全衛士,如果怕自己電腦中毒的請使用虛擬機進行安裝。在這里不提供下載鏈接。安裝好之后打開安裝目錄,我這里以安裝到C盤為准:
C:\Program Files (x86)\360\360safe\Config\newui\themes\default
打開后,將default_theme.ui文件拷貝出來。再將它的后綴改名為rar。之后的操作你懂的呀。。操作之后得到

第二章:360安全衛士風格按鈕開發
得到以上素材之后開始正式的編碼,第一個要開發的控件是Button控件,為什么呢?因為窗體上的關閉、最大化、最小化這些按鈕都可以使用。系統里面用到的WinApi類我就不放上來了,網上一搜一大把,如果有需要的可以單獨向我索取。寫按鈕前,先枚舉該按鈕的所有狀態,我這里定義5個狀態,應該比較全了:

 1 /// <summary>
 2 /// 枚舉按鈕狀態
 3 /// </summary>
 4 public enum State
 5 {
 6     Normal = 1,//按鈕默認時
 7     MouseOver = 2,//鼠標移上按鈕時
 8     MouseDown = 3,//鼠標按下按鈕時
 9     Disable = 4,//當不啟用按鈕時(也就是按鈕屬性Enabled==Ture時)
10     Default = 5//控件得到Tab焦點時
11 }

重繪按鈕以及重繪其它控件及窗體用到的方法:
1、該方法是將素材切割后再進行繪制,這樣在按鈕大小發生改變時也不會對素材的大小有影響:

  1 /// <summary>
  2 /// 繪圖對像
  3 /// </summary>
  4 /// <param name="g">繪圖對像</param>
  5 /// <param name="img">圖片</param>
  6 /// <param name="r">繪置的圖片大小、坐標</param>
  7 /// <param name="lr">繪置的圖片邊界</param>
  8 /// <param name="index">當前狀態</param>
  9 /// <param name="Totalindex">狀態總數</param>
 10 public static void DrawRect(Graphics g, Bitmap img, Rectangle r, Rectangle lr, int index, int Totalindex)
 11 {
 12     if (img == null) return;
 13     Rectangle r1, r2;
 14     int x = (index - 1) * img.Width / Totalindex;
 15     int y = 0;
 16     int x1 = r.Left;
 17     int y1 = r.Top;
 18 
 19     if (r.Height > img.Height && r.Width <= img.Width / Totalindex)
 20     {
 21         r1 = new Rectangle(x, y, img.Width / Totalindex, lr.Top);
 22         r2 = new Rectangle(x1, y1, r.Width, lr.Top);
 23         g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 24 
 25         r1 = new Rectangle(x, y + lr.Top, img.Width / Totalindex, img.Height - lr.Top - lr.Bottom);
 26         r2 = new Rectangle(x1, y1 + lr.Top, r.Width, r.Height - lr.Top - lr.Bottom);
 27         if ((lr.Top + lr.Bottom) == 0) r1.Height = r1.Height - 1;
 28         g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 29 
 30         r1 = new Rectangle(x, y + img.Height - lr.Bottom, img.Width / Totalindex, lr.Bottom);
 31         r2 = new Rectangle(x1, y1 + r.Height - lr.Bottom, r.Width, lr.Bottom);
 32         g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 33     }
 34     else
 35         if (r.Height <= img.Height && r.Width > img.Width / Totalindex)
 36         {
 37             r1 = new Rectangle(x, y, lr.Left, img.Height);
 38             r2 = new Rectangle(x1, y1, lr.Left, r.Height);
 39             g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 40             r1 = new Rectangle(x + lr.Left, y, img.Width / Totalindex - lr.Left - lr.Right, img.Height);
 41             r2 = new Rectangle(x1 + lr.Left, y1, r.Width - lr.Left - lr.Right, r.Height);
 42             g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 43             r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y, lr.Right, img.Height);
 44             r2 = new Rectangle(x1 + r.Width - lr.Right, y1, lr.Right, r.Height);
 45             g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 46         }
 47         else
 48             if (r.Height <= img.Height && r.Width <= img.Width / Totalindex)             {                 r1 = new Rectangle((index - 1) * img.Width / Totalindex, 0, img.Width / Totalindex, img.Height);                 g.DrawImage(img, new Rectangle(x1, y1, r.Width, r.Height), r1, GraphicsUnit.Pixel);             }             else if (r.Height > img.Height && r.Width > img.Width / Totalindex)
 49             {
 50                 //top-left
 51                 r1 = new Rectangle(x, y, lr.Left, lr.Top);
 52                 r2 = new Rectangle(x1, y1, lr.Left, lr.Top);
 53                 g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 54 
 55                 //top-bottom
 56                 r1 = new Rectangle(x, y + img.Height - lr.Bottom, lr.Left, lr.Bottom);
 57                 r2 = new Rectangle(x1, y1 + r.Height - lr.Bottom, lr.Left, lr.Bottom);
 58                 g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 59 
 60                 //left
 61                 r1 = new Rectangle(x, y + lr.Top, lr.Left, img.Height - lr.Top - lr.Bottom);
 62                 r2 = new Rectangle(x1, y1 + lr.Top, lr.Left, r.Height - lr.Top - lr.Bottom);
 63                 g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 64 
 65                 //top
 66                 r1 = new Rectangle(x + lr.Left, y,
 67                     img.Width / Totalindex - lr.Left - lr.Right, lr.Top);
 68                 r2 = new Rectangle(x1 + lr.Left, y1,
 69                     r.Width - lr.Left - lr.Right, lr.Top);
 70                 g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 71 
 72                 //right-top
 73                 r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y, lr.Right, lr.Top);
 74                 r2 = new Rectangle(x1 + r.Width - lr.Right, y1, lr.Right, lr.Top);
 75                 g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 76 
 77                 //Right
 78                 r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y + lr.Top,
 79                     lr.Right, img.Height - lr.Top - lr.Bottom);
 80                 r2 = new Rectangle(x1 + r.Width - lr.Right, y1 + lr.Top,
 81                     lr.Right, r.Height - lr.Top - lr.Bottom);
 82                 g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 83 
 84                 //right-bottom
 85                 r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y + img.Height - lr.Bottom,
 86                     lr.Right, lr.Bottom);
 87                 r2 = new Rectangle(x1 + r.Width - lr.Right, y1 + r.Height - lr.Bottom,
 88                     lr.Right, lr.Bottom);
 89                 g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 90 
 91                 //bottom
 92                 r1 = new Rectangle(x + lr.Left, y + img.Height - lr.Bottom,
 93                     img.Width / Totalindex - lr.Left - lr.Right, lr.Bottom);
 94                 r2 = new Rectangle(x1 + lr.Left, y1 + r.Height - lr.Bottom,
 95                     r.Width - lr.Left - lr.Right, lr.Bottom);
 96                 g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
 97 
 98                 //Center
 99                 r1 = new Rectangle(x + lr.Left, y + lr.Top,
100                     img.Width / Totalindex - lr.Left - lr.Right, img.Height - lr.Top - lr.Bottom);
101                 r2 = new Rectangle(x1 + lr.Left, y1 + lr.Top,
102                     r.Width - lr.Left - lr.Right, r.Height - lr.Top - lr.Bottom);
103                 g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
104             }
105 }
106 
107 /// <summary>
108 /// 繪圖對像
109 /// </summary>
110 /// <param name="g"> 繪圖對像</param>
111 /// <param name="obj">圖片對像</param>
112 /// <param name="r">繪置的圖片大小、坐標</param>
113 /// <param name="index">當前狀態</param>
114 /// <param name="Totalindex">狀態總數</param>
115 public static void DrawRect(Graphics g, Bitmap img, Rectangle r, int index, int Totalindex)
116 {
117     if (img == null) return;
118     int width = img.Width / Totalindex;
119     int height = img.Height;
120     Rectangle r1, r2;
121     int x = (index - 1) * width;
122     int y = 0;
123     r1 = new Rectangle(x, y, width, height);
124     r2 = new Rectangle(r.Left, r.Top, r.Width, r.Height);
125     g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
126 }

2、該方法是將編譯好的圖片讀取出來

 1 /// <summary>
 2 /// 得到要繪置的圖片對像
 3 /// </summary>
 4 /// <param name="str">圖像在程序集中的地址</param>
 5 /// <returns></returns>
 6 public static Bitmap GetResBitmap(string str)
 7 {
 8     Stream sm;
 9     sm = FindStream(str);
10     if (sm == null) return null;
11     return new Bitmap(sm);
12 }
13 
14 /// <summary>
15 /// 得到圖程序集中的圖片對像
16 /// </summary>
17 /// <param name="str">圖像在程序集中的地址</param>
18 /// <returns></returns>
19 private static Stream FindStream(string str)
20 {
21     Assembly assembly = Assembly.GetExecutingAssembly();
22     string[] resNames = assembly.GetManifestResourceNames();
23     foreach (string s in resNames)
24     {
25         if (s == str)
26         {
27             return assembly.GetManifestResourceStream(s);
28         }
29     }
30     return null;
31 }

Ok,基礎打好之后就可以開始正式的進行按鈕繪制,代碼比較長,里面包括定義變量,定義按鈕屬性,處理按鈕構造函數。這里我分享關鍵部分重寫OnPaint代碼:

 1 /// <summary>
 2 /// 重繪控件
 3 /// </summary>
 4 /// <param name="e"></param>
 5 protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
 6 {
 7     if (BackImg == null)
 8     {
 9         base.OnPaint(e);
10         return;
11     }
12 
13     int i = (int)state;
14     if (this.Focused && state != State.MouseDown && _IsTabFocus == true) i = 5;
15     if (!this.Enabled) i = 4;
16     Rectangle rc = this.ClientRectangle;
17     Graphics g = e.Graphics;
18 
19     base.InvokePaintBackground(this, new PaintEventArgs(e.Graphics, base.ClientRectangle));
20     try
21     {
22         if (BackImg != null)
23         {
24             if (_BacklightLTRB != Rectangle.Empty)
25             {
26 
27                 ImageDrawRect.DrawRect(g, BackImg, rc, Rectangle.FromLTRB(_BacklightLTRB.X, _BacklightLTRB.Y, _BacklightLTRB.Width, _BacklightLTRB.Height), i, 5);
28             }
29             else
30             {
31                 ImageDrawRect.DrawRect(g, BackImg, rc, Rectangle.FromLTRB(10, 10, 10, 10), i, 5);
32             }
33 
34         }
35     }
36     catch
37     { }
38 
39     Image img = null;
40     Size txts, imgs;
41 
42     txts = Size.Empty;
43     imgs = Size.Empty;
44 
45     if (this.Image != null)
46     {
47         img = this.Image;
48     }
49     else if (this.ImageList != null && this.ImageIndex != -1)
50     {
51         img = this.ImageList.Images[this.ImageIndex];
52     }
53 
54     if (img != null)
55     {
56         imgs.Width = img.Width;
57         imgs.Height = img.Height;
58     }
59 
60     StringFormat format1;
61     using (format1 = new StringFormat())
62     {
63         format1.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show;
64         SizeF ef1 = g.MeasureString(this.Text, this.Font, new SizeF((float)rc.Width, (float)rc.Height), format1);
65         txts = Size.Ceiling(ef1);
66     }
67 
68     rc.Inflate(-4, -4);
69     if (imgs.Width * imgs.Height != 0)
70     {
71         Rectangle imgr = rc;
72         imgr = ImageDrawRect.HAlignWithin(imgs, imgr, this.ImageAlign);
73         imgr = ImageDrawRect.VAlignWithin(imgs, imgr, this.ImageAlign);
74         if (!this.Enabled)
75         {
76             ControlPaint.DrawImageDisabled(g, img, imgr.Left, imgr.Top, this.BackColor);
77         }
78         else
79         {
80             g.DrawImage(img, imgr.Left, imgr.Top, img.Width, img.Height);
81         }
82     }
83 
84     Rectangle txtr = rc;
85     txtr = ImageDrawRect.HAlignWithin(txts, txtr, this.TextAlign);
86     txtr = ImageDrawRect.VAlignWithin(txts, txtr, this.TextAlign);
87 
88     format1 = new StringFormat();
89     format1.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show;
90 
91     if (this.RightToLeft == RightToLeft.Yes)
92     {
93         format1.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
94     }
95     brush = new SolidBrush(this.ForeColor);
96     g.DrawString(this.Text, this.Font, brush, (RectangleF)txtr, format1);
97     brush.Dispose();
98 
99 }

其中關鍵部分已經出來,按鈕也基本繪制完成。下一篇我將分享重繪主窗體,其中過程也沒有詳細講解,主要原因是文采不好。如果有不了解的可以留言給我,我會及時回復。該皮膚的源碼由於項目上正在使用暫時不進行公布,如果本文的反響和關注度都不錯,我再決定是否提供下載。最后謝謝大家的關注。請期待下一篇的重繪主窗體。


本文來自 放肆雷特 | 胖子的技術博客


免責聲明!

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



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