在WinCE5.0下实现透明背景按钮(.net C#)

转载于https://www.cnblogs.com/pcode/articles/1687313.html

在学习C#编程应用到广州微嵌的wince平板的过程中,想做个透明图片一直不可得,搜索到一篇比较有参考价值的博文及无需积分可下载的例程。详细如下:

问题:

      需要在wince5.0下实现图形化界面,用于功能导航,用过GPS导航就知道了,类似的界面。众所周知gif,PNG等图片,都是可以实现透明背景的,在win下这应该不是个问题。但在ce5.0下,无论是透明背景的ICON、PNG、GIF都无法简单实现透明背景,alpha通道会丢失。网上搜索了些资料,当然也有办法解决,大家可以查一下,但性能较低。最终按微软SDK自带的一个计算器的源码思路解决了透明背景按钮问题。

要点:

  1. 如何画透明背景的BMP
  2. 如何画按钮并实现事件

思路及解决:

  1. 画按钮的思路:

  ImageAttributes imageAttr=new ImageAttributes();

  imageAttr.SetColorKey(Color.FromArgb(255, 0, 255),Color.FromArgb(255, 0, 255));

  然后使用Graphics.DrawImage(,,,,,imageAttr)函数在指定的位置上画出透明的图片。

  2. 事件驱动的思路:

    事先定义好各按钮的指令

  public enum Command {
           cmd1 = 0,//无操作
           cmd2,//第一项操作
           cmd3,//第二项操作
           cmd4,//可自己扩展
           max
       }

     在创建按钮的同时明确以下几个参数 容器控件、资源存放的目录、X坐标、Y坐标、背景图片、按钮的标题、非激活时的文字颜色、激活时的文字颜色、触发的指令。创建窗口,针对窗体事件做如下定义

  • 在Form_Load时生成按钮,
  • 在Form_OnPaint时使用按钮自身的Render函数根据自己状态(有没有被点中)重画,
  • 在MouseDown时判断点击位置是否在某个按钮的内部,如果是在它内部就改变它的状态,设置状态的同时调用窗口控件的Graphics局部重画这个按钮,    
  • 在Form_MouseUp时判断现在的位置是不是在按钮内部,如果按下了,抬起时又移出了范围则不处理。如果按下与抬起都是在同一个按钮的边界内部则执行这个按钮所设置的指令。

以下是我使用的资源,将作为按钮的图片需要透明的部分设置成RGB(255,0,255),那种非常刺眼的颜色。以下图片可以另存为BMP使用,设置的分辨是800*600的CE设备。

按钮未点击时背景:

      

按钮点中时背景:

      

窗体抬头的背景:

放置按钮的大背景:

      第三步:代码实现

 创建窗体名称ImageButton,设置窗体的Menu为空TopMost=true,Size=800,600,ControlBox=false,FormBorderStyle=None

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Text;
using  System.Windows.Forms;
using  System.IO;
using  System.Reflection;
 
namespace  DZB
{
     public  partial  class  ImageButton : Form
     {
         private  IList<IButton> btnlist;
         private  IButton capturedButton;
         private  Font windowFont = new  Font(FontFamily.GenericSansSerif, 12, FontStyle.Regular);
         private  string  CurrentPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
         private  Bitmap bg, title;
         public  ImageButton()
         {
             InitializeComponent();
         }
 
         private  void  ImageButton_Load( object  sender, EventArgs e)
         {
             title = new  Bitmap(CurrentPath + @"\Resources\title.bmp" );
             bg = new  Bitmap(CurrentPath + @"\Resources\mainbg.bmp" );
             btnlist = new  List<IButton>();
             btnlist.Add( new  IButton( this , CurrentPath + @"\Resources\" , 100, 100, "button.bmp ", " 按钮1", Color.White, Color.Blue, Command.cmd1));
             btnlist.Add( new  IButton( this , CurrentPath + @"\Resources\" , 100, 200, "button.bmp ", " 按钮2", Color.White, Color.Blue, Command.cmd1));
             btnlist.Add( new  IButton( this , CurrentPath + @"\Resources\" , 100, 300, "button.bmp ", " 按钮3", Color.White, Color.Blue, Command.cmd2));
             btnlist.Add( new  IButton( this , CurrentPath + @"\Resources\" , 100, 400, "button.bmp ", " 按钮4", Color.White, Color.Blue, Command.cmd2));
             btnlist.Add( new  IButton( this , CurrentPath + @"\Resources\" , 400, 100, "button.bmp ", " 按钮5", Color.White, Color.Blue, Command.cmd2));
             btnlist.Add( new  IButton( this , CurrentPath + @"\Resources\" , 400, 200, "button.bmp ", " 按钮6", Color.White, Color.Blue, Command.cmd2));
             btnlist.Add( new  IButton( this , CurrentPath + @"\Resources\" , 400, 300, "button.bmp ", " 按钮7", Color.White, Color.Blue, Command.cmd2));
             btnlist.Add( new  IButton( this , CurrentPath + @"\Resources\" , 400, 400, "button.bmp ", " 按钮8", Color.White, Color.Blue, Command.cmd3));
         }
 
         private  void  ImageButton_Paint( object  sender, PaintEventArgs e)
         {
             // Buttons
             Graphics graphics;
 
             graphics = e.Graphics;
             graphics.DrawImage(title, 0, 0);
             graphics.DrawImage(bg, 0, 63);
             // Edit line
             foreach  (IButton btn in  btnlist)
             {
                 btn.Render(graphics);
             }
         }
         protected  override  void  OnPaintBackground(PaintEventArgs paintArgs)
         {
 
             //gr.DrawImage(img, 0, 0);
             base .OnPaintBackground(paintArgs);
         }
         ~ImageButton()
         {
             windowFont.Dispose();
         }
 
         private  void  ImageButton_MouseDown( object  sender, MouseEventArgs e)
         {
             foreach  (IButton btn in  btnlist)
             {
                 if  (btn.IsHit(e.X, e.Y))
                 {
                     btn.IsSelected = true ;
                     capturedButton = btn;
                     break ;
                 }
             }
         }
 
         private  void  ImageButton_MouseMove( object  sender, MouseEventArgs e)
         {
             if  (capturedButton != null )
             {
                 capturedButton.IsSelected = capturedButton.IsHit(e.X, e.Y);
             }
         }
 
         private  void  ImageButton_MouseUp( object  sender, MouseEventArgs e)
         {
             if  (capturedButton != null )
             {
                 if  (capturedButton.IsHit(e.X, e.Y))
                     DoCommand(capturedButton.Cmd);
                 try
                 {
                     capturedButton.IsSelected = false ;
                     capturedButton = null ;
                 }
                 catch
                 {
 
                 }
             }
         }
         /// <summary>
         /// 执行指令
         /// </summary>
         /// <param name="command"></param>
         private  void  DoCommand(Command command)
         {
             switch  (command)
             {
                 case  Command.cmd1: //0
                     // this.Close();
                     break ;
                 case  Command.cmd2: //1
                     MessageBox.Show( "cmd2" );
                     break ;
                 case  Command.cmd3: //2
                     this .Close();
                     break ;
                 case  Command.cmd4: //3
                     {
                         Line nl = new  Line();
                         nl.Show();
 
                     }
                     break ;
                 default :
                     break ;
             }
         }
 
     }
}

      

IButton.cs 类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//======================================================================
//
//        Copyright (C) 2008-2009 PCODE TEAM.  All rights reserved.
//
//       CLR Version: 2.0.50727.1433
//        NameSpace: DZB        FileName: IButton.Cs
//
//        Created by Jy at  2009/9/10 22:07:34
//        Email:[email protected]
//
//======================================================================
 
 
using  System;
 
using  System.Collections.Generic;
using  System.Text;
using  System.Windows.Forms;
using  System.Drawing;
using  System.Drawing.Imaging;
 
namespace  DZB {
     public  class  IButton {
         private  Control MainForm;
         private  Font sFont = new  Font(FontFamily.GenericSansSerif,16, FontStyle.Bold);
         private  Font sFont_ = new  Font(FontFamily.GenericSansSerif, 16, FontStyle.Bold);
         private  bool  IsSelectedValue;
         private  Command ButtonCommand;
         private  Rectangle selfRec;
         private  string  _caption;
         private  float  _cx, _cy; //画标题的位置
         private  Bitmap btnbg, btnbg_;
         private  string  _CurrentPath;
         Color transpColor = Color.FromArgb(255, 0, 255); //资源文件的透明色
         ImageAttributes imageAttr;
         Color _ncolor, _fcolor;
         Graphics g, g_;
         /// <summary>
         /// 初始化
         /// </summary>
         /// <param name="form">容器名称</param>
         /// <param name="CurrentPath">当前程序路径</param>
         /// <param name="x">按钮位置X</param>
         /// <param name="y">按钮位置Y</param>
         /// <param name="bgfilename">按钮图片名称</param>
         /// <param name="caption">标题</param>
         /// <param name="nColor">正常颜色</param>
         /// <param name="fColor">激活颜色</param>
         /// <param name="cmd">指令</param>
         public  IButton(Control form, string  CurrentPath, int  x, int  y, string  bgfilename, string  caption,Color nColor,Color fColor, Command cmd) {
             MainForm = form;
             _ncolor = nColor;
             _fcolor = fColor;
             ButtonCommand = cmd;
             _caption = caption;
             _CurrentPath = CurrentPath;
             string  bg = CurrentPath + bgfilename;
             string  bg_ = CurrentPath +System.IO.Path.GetFileNameWithoutExtension(bg) + "_.bmp" ;
             btnbg = new  Bitmap(bg);
             selfRec = new  Rectangle(x, y, btnbg.Width,btnbg.Height);
             g = Graphics.FromImage(btnbg);
             _cx = (219 - g.MeasureString(_caption, sFont).Width) / 2;
             _cy = (48 - g.MeasureString(_caption, sFont).Height) / 2;          
             btnbg_= new  Bitmap(bg_);
             g_ = Graphics.FromImage(btnbg_);
             imageAttr = new  ImageAttributes();
             imageAttr.SetColorKey(transpColor, transpColor);
         }
 
         public  void  Render(Graphics graphics) {
              
             if  (IsSelectedValue) { //点下的状态
                 g_.DrawString(_caption, sFont_, new  SolidBrush(_fcolor), _cx,_cy);
                  graphics.DrawImage(btnbg_, selfRec, 0, 0, selfRec.Width, selfRec.Height, GraphicsUnit.Pixel, imageAttr);
             }
             else  {
                 g.DrawString(_caption, sFont, new  SolidBrush(_ncolor),_cx, _cy);
                 graphics.DrawImage(btnbg, selfRec, 0, 0, selfRec.Width, selfRec.Height, GraphicsUnit.Pixel, imageAttr);
             }
 
         }
         private  static  Color GetTransparentColor(Image image) {
             return  ((Bitmap)image).GetPixel(image.Width - 1, image.Height - 1);
         }
         public  bool  IsHit( int  x, int  y) {
             return  (x >= selfRec.X &&
                     x < selfRec.X +selfRec.Width &&
                     y >= selfRec.Y &&
                     y <selfRec.Y+selfRec.Height);
         }
 
 
         public  bool  IsSelected {
             get  {
                 return  IsSelectedValue;
             }
             set  {
                 Graphics graphics;
 
                 if  (value != IsSelectedValue) {
                     IsSelectedValue = value;
 
                     // Redraw right away
                     graphics = MainForm.CreateGraphics();
                     this .Render(graphics);
                     graphics.Dispose();
 
                 }
             }
         }
 
         public  Command Cmd {
             get  {
                 return  (ButtonCommand);
             }
         }
     }
}

最终效果:

透明背景的按钮实现成功

 

总结:

此方案的优点:

  1. 思路简单,实现过程没有特别复杂的技术环节
  2. 因是局部重画,即使在800*600这样的分辨率下也能达到不闪烁的效果
  3. 按钮可配置性高,更换资源文件即可实现对按钮及整体风格的改变

此方案的缺点:

  1. 按钮图片与背景间不能实现ALPHA的渐透明
  2. 按钮的驱动虽然实现,但没有很OO。(微软也是这么写代码的,所以也不算大问题)
  3. 资源图片要按像素级处理透明色,有些麻烦。(项目组有美工的话还好做些)

以下再列几个我自己做的风格给大家参考

山水皮肤

冬奥皮肤

希望我的综合对大家有帮助。


猜你喜欢

转载自blog.csdn.net/WQFAE01/article/details/79230318
今日推荐