隨筆-348  評論-598  文章-0  trackbacks-0

          前言

            關(guān)鍵字:.NetCF 半透明、AlphaBlend

            用C#開放Windows Mobile剛好滿一個(gè)月,一直是邊看文章邊寫點(diǎn)小例子,而這些例子里面半透明效果是最讓人心動(dòng)的,本文主要收集和實(shí)踐了關(guān)于.Net CF半透明效果例子,以及自己一點(diǎn)點(diǎn)經(jīng)驗(yàn)和需要注意的問題。

           

          正文

            一、繪制透明標(biāo)簽控件(Label)

              1.1  效果圖

               

              1.2  代碼

                1.2.1  實(shí)現(xiàn)代碼

                  /// <summary>
                  
          /// 透明Label控件
                  
          ///     注意,將Label的Visible設(shè)置為false;適合背景為圖片(PictureBox)
                  
          /// </summary>
                  
          /// <param name="label"></param>
                  
          /// <param name="g"></param>
                  public static void TransparentLabel(Label label, Graphics g)
                  {
                      Rectangle rect = label.Bounds;
                      SolidBrush sb = new SolidBrush(label.ForeColor);
                      SizeF size;
                      
          //計(jì)算字符串的位置
                      switch (label.TextAlign)
                      {
                          
          case ContentAlignment.TopLeft:
                              
          break;
                          
          case ContentAlignment.TopCenter:
                              
          //計(jì)算字符串長度
                              size = g.MeasureString(label.Text, label.Font);
                              rect.X += (int)((rect.Width - size.Width) / 2);
                              rect.Y += (int)((rect.Height - size.Height) / 2);
                              
          break;
                          
          case ContentAlignment.TopRight:
                              size = g.MeasureString(label.Text, label.Font);
                              rect.X += rect.Width - (int)size.Width;
                              rect.Y += rect.Height - (int)size.Height;
                              
          break;
                      }
                      g.DrawString(label.Text, label.Font, sb, rect);
                      sb.Dispose();
                  }

                1.2.2  調(diào)用代碼

                  private void pictureBox1_Paint(object sender, PaintEventArgs e)
                  {
                      TransparentLabel(this.label1, e.Graphics);
                  }

                1.2.3  代碼說明

                  雖然本節(jié)說的是Label透明化,實(shí)際上可以看得出并沒有將字透明化,只是"去掉"了Label的背景。這里L(fēng)abel控件充當(dāng)了保存字符串信息的作用,實(shí)際調(diào)用DrawString直接畫在屏幕上去的。

                  a).  因?yàn)槭荓abel是在PictureBox上,所以在其Paint事件中繪制Label中的字符串;如果沒有PictureBox作為背景,而是直接在Form窗體上,那么把這段代碼寫到窗體的OnPain中即可。

              1.3  注意問題

                 1.3.1  需要將Label的Visiable設(shè)置為false!

           

            二、繪制透明圖片(PictureBox)

              2.1  效果圖

               

              2.2  代碼

                2.2.1  實(shí)現(xiàn)代碼

                  /// <summary>
                  
          /// 繪制透明圖片
                  
          /// </summary>
                  
          /// <param name="gxBuffer"></param>
                  
          /// <param name="barImage"></param>
                  
          /// <param name="barRect"></param>
                  
          /// <param name="transp"></param>
                  public static void DrawAlpha(Graphics gxBuffer, Image barImage, Rectangle barRect, byte transp)
                  {
                      
          using (Graphics gxSrc = Graphics.FromImage(barImage))
                      {
                          IntPtr hdcDst = gxBuffer.GetHdc();
                          IntPtr hdcSrc = gxSrc.GetHdc();
                          BlendFunction blendFunction = new BlendFunction();
                          blendFunction.BlendOp = (byte)BlendOperation.AC_SRC_OVER;
                          blendFunction.BlendFlags = (byte)BlendFlags.Zero;
                          blendFunction.SourceConstantAlpha = transp;
                          blendFunction.AlphaFormat = (byte)0;
                          AlphaBlend(hdcDst, barRect.Left, barRect.Top, barRect.Size.Width, barRect.Size.Height, hdcSrc, 00, barImage.Width, barImage.Height, blendFunction);
                          gxBuffer.ReleaseHdc(hdcDst);
                          gxSrc.ReleaseHdc(hdcSrc);
                      }
                  }

                  
          /// <summary>
                  
          /// 繪制透明圖象
                  
          /// </summary>
                  
          /// <param name="hdcDest">生成畫面的Handle</param>
                  
          /// <param name="xDest">生成畫面的x</param>
                  
          /// <param name="yDest">生成畫面的y</param>
                  
          /// <param name="cxDest">生成畫面的width</param>
                  
          /// <param name="cyDest">生成畫面的height</param>
                  
          /// <param name="hdcSrc">原圖的Handle</param>
                  
          /// <param name="xSrc">原圖的x</param>
                  
          /// <param name="ySrc">原圖的y</param>
                  
          /// <param name="cxSrc">原圖的width</param>
                  
          /// <param name="cySrc">原圖的height</param>
                  
          /// <param name="blendFunction">控制 Alpha 混合的結(jié)構(gòu)</param>
                  
          /// <returns></returns>
                  [DllImport("coredll.dll")]
                  
          extern public static Int32 AlphaBlend(IntPtr hdcDest, Int32 xDest, Int32 yDest, Int32 cxDest, Int32 cyDest, IntPtr hdcSrc, Int32 xSrc, Int32 ySrc, Int32 cxSrc, Int32 cySrc, BlendFunction blendFunction);

                2.2.2  調(diào)用代碼

                  private void pictureBox1_Paint(object sender, PaintEventArgs e)
                  {
                      CFControlUtility.DrawAlpha(e.Graphics, pbBar.Image, pbBar.Bounds, 170);
                  }

                2.2.3  代碼說明

                  a).  transp值為0-255,0為完全透明,255為無透明效果。

              2.3  注意問題

                需要透明效果圖片的Visiable設(shè)置為false!

           

            三、繪制透明表格

              3.1  效果圖

               

              3.2  實(shí)現(xiàn)代碼

                  private void pictureBox1_Paint(object sender, PaintEventArgs e)
                  {
                      Bitmap offBitmap = new Bitmap(100100);
                      Graphics gxBuffer = Graphics.FromImage(offBitmap);
                      
          //清空底色
                      gxBuffer.Clear(this.BackColor);

                      Pen pen = new Pen(Color.DodgerBlue);
                      Font font = new Font("Arial"10, FontStyle.Regular);
                      SolidBrush brush = new SolidBrush(Color.Black);

                      
          int width, height = 0;
                      
          //繪制2列4行數(shù)據(jù)
                      for (int i = 0; i < 4; i++)
                      {
                          width = 0;
                          
          for (int j = 0; j < 2; j++)
                          {
                              
          //繪制數(shù)據(jù)
                              gxBuffer.DrawString("測試數(shù)據(jù)", font, brush, width, height);

                              width += 50;
                              
          //繪制豎線
                              if (i == 0)
                                  gxBuffer.DrawLine(pen, width, 0, width, offBitmap.Height);
                              
                          }
                          height += 25;
                          
          //繪制橫線
                          gxBuffer.DrawLine(pen, 0, height, offBitmap.Width, height);
                      }

                      brush.Dispose();
                      font.Dispose();
                      pen.Dispose();
                      gxBuffer.Dispose();

                      
          //將內(nèi)存中的圖片繪制到界面上來
                      DrawAlpha(e.Graphics, offBitmap, new Rectangle(50100, offBitmap.Width, offBitmap.Height), 170);
                      
          //e.Graphics.DrawImage(offBitmap, 50, 100);
                  }

              3.3  代碼說明

                a).  這里在內(nèi)存中繪制了臨時(shí)圖片offBitmap,然后再將臨時(shí)圖片繪制顯示到設(shè)備上面來的,這樣可以極大提高性能,大家可以直接用e.Graphics一筆筆繪制比較看下性能。

                b).  用完繪圖對象相關(guān)對象之后記得Dispose掉,或者用using代碼塊。

           

            四、 其他

              4.1  屏幕閃爍問題

                  protected override void OnPaintBackground(PaintEventArgs e)
                  {
                      
          //base.OnPaintBackground(e);        
                  }

              4.2  直接用e.Graphics繪制文字+圖片的時(shí)候可能出現(xiàn)閃爍的問題

                在繪制完文字后再覆蓋一張透明度為0的空圖片即可,用內(nèi)存臨時(shí)圖片不會(huì)有這問題的。

              4.3  繪制控件透明時(shí),千萬記得把控件的Visible設(shè)置為false。該控件只是充當(dāng)繪制信息存儲作用,其鼠標(biāo)事件(Mouse)全部會(huì)沒有(這不廢話- - #,控件都隱藏了),所以要做判斷得再PictureBox或窗體的相關(guān)事件里面做判斷,然后再判斷點(diǎn)擊的位置來識別到底是否點(diǎn)擊的透明控件。

              4.4  Graphics相關(guān)方法需要都弄清楚用熟練了,非常有用,比如MeasureString可以計(jì)算字符串的長度,可以控制繪制字符串的位置;FillRectangle可以填充矩陣,畫行的背景色的時(shí)候可以用。

              4.5  如果大規(guī)模的繪制透明效果,需要特別注意性能問題,可以采取措施如臨時(shí)圖片、內(nèi)存緩存數(shù)據(jù)等。

              4.6  通過取消單色顯示來達(dá)到透明效果,但是效果不太理想,相關(guān)的對象:ImageAttributes。

           

           

          結(jié)束語

             如果被這種透明效果吸引甚至打算在項(xiàng)目中使用,那么要做好吃苦耐勞的準(zhǔn)備,大部分控件都要重繪,處理非常多的邏輯判斷,比較麻煩- - #。



          ---------------------------------------------------------
          專注移動(dòng)開發(fā)

          Android, Windows Mobile, iPhone, J2ME, BlackBerry, Symbian
          posted on 2010-02-13 19:57 TiGERTiAN 閱讀(929) 評論(0)  編輯  收藏 所屬分類: DotNet
          主站蜘蛛池模板: 仲巴县| 安徽省| 松江区| 疏勒县| 余干县| 剑河县| 新田县| 清水河县| 灯塔市| 华坪县| 洪泽县| 白河县| 抚松县| 象州县| 寿阳县| 沂南县| 永平县| 定州市| 商都县| 淅川县| 高州市| 温宿县| 手游| 农安县| 花莲县| 清水河县| 塔城市| 丰原市| 嵩明县| 榆中县| 偃师市| 建平县| 疏附县| 佛山市| 涿鹿县| 通江县| 新沂市| 巴中市| 白沙| 修武县| 绵阳市|