<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      跟我做WinForm開發(fā)(1)-自定義UI

      2012-01-07 12:03  空逸云  閱讀(11122)  評論(84)    收藏  舉報

      前言

      前陣子,學(xué)英文的時候聽發(fā)音,意外之中發(fā)現(xiàn)Google的發(fā)音相比大部分TTS發(fā)音更準(zhǔn)確,而且讀句子也沒有普通TTS那種一聽就是機器人的聲音,心血來潮,想利用Google發(fā)音做一個小軟件,所以就有了本文。

      image

      這是最后的UI成品圖,可以看到,沒有了常見的按鈕,也沒有了常見的Title框,整個布局隨心所欲,GDI+?No。下面,就帶大家跟我一起來用最簡單的方式開發(fā)你所期望的UI吧!

      自定義窗體

      WinForm開發(fā)中,我們都知道窗體和控件的作用,實際上,以上的UI實現(xiàn)也是通過自定義窗體和用戶控件實現(xiàn),那該如何做,才能讓窗體變成我們所想要的樣子呢?

      首先,新建一個窗體,在這里,我命名為MainForm.cs,打開我們就可以見到以往的樣子:

      imageimage

      選中窗體,右鍵=》屬性,將FormBorderStyle設(shè)置成None, 窗體就變成了右圖所示;接著,我再將其拖拉成我需要的長度和寬度,此時若編譯運行,會發(fā)現(xiàn)實際上什么都東西都看不到,這正是我們所需要的效果,接著,就防止我們想呈現(xiàn)的元素。接著,我將其拉成一個長方形,并在四周放4個PictureBox,正中間放一個Panel。

      image

      這里需要注意的就是4個PictureBox的寬度,長度和未知,實際上我也不是拖控件,而是通過修改控件是屬性,這里就需要精確到像素,聰明的你應(yīng)該想到它們就是4條邊框線和中間的內(nèi)容塊了,在這里我推薦一個軟件,MarkMan,傳說中的標(biāo)注神器,做UI方面,特別是開發(fā)人員,很有幫助。

      image

      在將所需的圖片填充上去就可以了。

      private Image GetResourceImg(string name)
      {
          return Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(name));
      }
      
      void InitFormStyle()
      {
          //邊框
          var borderImg = GetResourceImg(@"Speaker.Resource.Images.border.jpg");
          Bitmap borderMap = new Bitmap(borderImg);
          borderMap.MakeTransparent(Color.FromArgb(255, 0, 255));
          this.pb_borderLeft.BackgroundImage = borderMap;
          this.pb_borderRight.BackgroundImage = borderMap;
          this.pb_borderTop.BackgroundImage = borderMap;
          this.pb_borderBottom.BackgroundImage = borderMap;
          //主面板
          var mainImg = GetResourceImg(@"Speaker.Resource.Images.main.jpg");
          this.pl_main.BackgroundImage = new Bitmap(mainImg);
          //Logo
          var logoImg = GetResourceImg(@"Speaker.Resource.Images.logo.jpg");
          this.btn_setting.NormalImage = new Bitmap(logoImg);
          btn_setting.Reset();
          //Speak Button
          var normalImg = GetResourceImg(@"Speaker.Resource.Images.button.png");
          var moveImg = GetResourceImg(@"Speaker.Resource.Images.buttonMove.png");
          var downImg = GetResourceImg(@"Speaker.Resource.Images.buttonDown.png");
          btn_speak.NormalImage = normalImg;
          btn_speak.MoveImage = moveImg;
          btn_speak.DownImage = downImg;
          btn_speak.Reset();
      }
      

      編譯通過之后,邊框雛形就出現(xiàn)了~:-)

      自定義控件

      窗體我們已經(jīng)有了,接下來就是里面一些控件的實現(xiàn),這里,我主要用到了兩個控件,ImageButton和LightTextBox,顧名思義,ImageButton就是一個圖片按鈕,但它還提供鼠標(biāo)按下,懸移時的圖片選擇;LightTextBox是一個TextBox,鼠標(biāo)懸移的時候,邊框高亮;

      LightTextBox

      新建用戶控件LightTextBox,選中控件,右鍵=》屬性,將BorderStyle改為None,這樣,控件也不可見了!拖出一個TextBox,并標(biāo)注為MultiLine,至此,UI就這樣了,接著是控件的繪制編碼;

      public LightTextBox()
      {
          SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
          InitializeComponent();
          BackColor = Color.Transparent;
          
          txt.Location = new Point(3, 6);
          txt.MouseEnter += new EventHandler(txt_MouseEnter);
          txt.MouseLeave += new EventHandler(txt_MouseLeave);
      }
      

      實現(xiàn)TextBox的鼠標(biāo)懸移事件就是為了實現(xiàn)邊框高亮效果;

      #region Events
      
      void txt_MouseLeave(object sender, EventArgs e)
      {
          _isFouse = false;
          this.Invalidate();
      }
      
      void txt_MouseEnter(object sender, EventArgs e)
      {
          _isFouse = true;
          this.Invalidate();
      }
      #endregion
      

      方法部分(控件實現(xiàn)的主要方法)

      #region Methods
      protected override void OnPaint(PaintEventArgs e)
      {
          Graphics g = e.Graphics;
          g.InterpolationMode = InterpolationMode.HighQualityBicubic;
          g.SmoothingMode = SmoothingMode.HighQuality;
      
          txt.Width = Width-6;
          CalculateSizeAndPosition();
          Draw(e.ClipRectangle, e.Graphics);
      
      
          base.OnPaint(e);
      }
      
      private void CalculateSizeAndPosition()
      {
          if (!txt.Multiline)
          {
              Height = txt.Height + 9;
          }
          else
          {
              txt.Height = Height - 9;
          }
      }
      private void Draw(Rectangle rectangle, Graphics g)
      {
      
          #region 畫背景
          using (SolidBrush backgroundBrush = new SolidBrush(Color.White))
          {
              g.FillRectangle(backgroundBrush, 2, 2, this.Width - 4, this.Height - 4);
          }
          #endregion
      
          #region 畫陰影(外邊框)
      
          Color drawShadowColor = _shadowColor;
          if (!_isFouse)    //判斷是否獲得焦點
          {
              drawShadowColor = Color.Transparent;
          }
          using (Pen shadowPen = new Pen(drawShadowColor))
          {
              if (_radius == 0)
              {
                  g.DrawRectangle(shadowPen, new Rectangle(rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1));
              }
              else
              {
                  g.DrawPath(shadowPen, DrawHelper.DrawRoundRect(rectangle.X, rectangle.Y, rectangle.Width - 2, rectangle.Height - 1, _radius));
              }
          }
          #endregion
      
          #region 畫邊框
          using (Pen borderPen = new Pen(_borderColor))
          {
              if (_radius == 0)
              {
                  g.DrawRectangle(borderPen, new Rectangle(rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 3, rectangle.Height - 3));
              }
              else
              {
                  g.DrawPath(borderPen, DrawHelper.DrawRoundRect(rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 3, rectangle.Height - 2, _radius));
              }
          }
          #endregion
      }
      
      #endregion
      

      由于字段,屬性比較多,我就不貼出來了,感興趣的可以在后續(xù)的源碼中查看;此時,若將該控件放到窗體中,鼠標(biāo)移

      動上去,則可發(fā)現(xiàn)邊框有一層光暈;

      ImageButton

      這里的自定義控件實現(xiàn)方式一致,都先去掉了BorderStyle,再自己控制呈現(xiàn)內(nèi)容,所以才能達(dá)到顯示特殊UI的目的;ImageButton的UI設(shè)計就不詳述了,直接放出后臺實現(xiàn)主代碼;

      public ImageButton()
      {
          this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
          InitializeComponent();
          Reset();
      }
      
      #region Methods
      public void Reset()
      {
          if (_normalImage != null)
          {
              this.BackgroundImage = _normalImage;
              this.Size = new Size(_normalImage.Width, _normalImage.Height);
          }
      }
      private void MakeTransparent(Image image)
      {
          Bitmap bitmap = image as Bitmap;
          bitmap.MakeTransparent(Color.FromArgb(255, 0, 255));
      }
      #endregion
      
      private void ImageButton_MouseEnter(object sender, EventArgs e)
      {
          if (_moveImage != null)
              this.BackgroundImage = _moveImage;
      }
      
      private void ImageButton_MouseLeave(object sender, EventArgs e)
      {
          this.BackgroundImage = _normalImage;
      }
      
      private void ImageButton_MouseDown(object sender, MouseEventArgs e)
      {
          if (_downImage != null)
              this.BackgroundImage = _downImage;
      }
      
      private void ImageButton_MouseUp(object sender, MouseEventArgs e)
      {
          if (_moveImage != null)
              this.BackgroundImage = _moveImage;
      }
      

      MainForm

      萬事俱備,只欠東風(fēng);把控件都放入MainForm中,并初始其狀態(tài)即可(上面第一部分代碼已放出);此時,編譯運行;已達(dá)到我們預(yù)期的UI效果;但是,UI效果是有了,移動效果,縮小(點擊任務(wù)欄圖標(biāo))等卻都失效了,該怎么辦?Win32API千呼萬喚使出來~

      private void pl_main_MouseDown(object sender, MouseEventArgs e)
      {
          if (e.Button == MouseButtons.Left)
          {
              Win32.ReleaseCapture();
              Win32.SendMessage(Handle, 274, 61440 + 9, 0);
          }
      }
      

      這里實際上是調(diào)用了Win32API,在這里,又有一個好東西分享;平時做這些Win32API交互/C#與C++交互,需

      要做類型轉(zhuǎn)換,特別是C++里面一些指針什么的,很是糾結(jié),http://clrinterop.codeplex.com能幫到你;它能根據(jù)你輸入的C++函數(shù)生成C#的代碼;不可謂不是一大殺器啊!

      移動解決了,那縮小的問題,也必須解決了;

      protected override CreateParams CreateParams
      {
          get
          {
              const int WS_MINIMIZEBOX = 0x00020000;  // Winuser.h中定義
              CreateParams cp = base.CreateParams;
              cp.Style = cp.Style | WS_MINIMIZEBOX;   // 允許最小化操作  
              return cp;
          }
      }
      

      重寫CreateParams屬性就可以了;到這里,我們的應(yīng)用已經(jīng)能正常顯示出我們所想要的UI;但還不夠,大部

      分輔助類型的軟件都有最小化的功能,那,我們也將其加上去吧;

      NotifyIcon

      這個其實很簡單,就是拖一個NotifyIcon到窗體中,并綁定一個ContextMenu到這個NotifyIcon中就可以了;然后在觸發(fā)一些事件;

      private void MainForm_Resize(object sender, EventArgs e)
      {
          if (WindowState == FormWindowState.Minimized)
          {
              this.Visible = false;
          }
      }
      

      后面,我還主要用NotifyIcon來通知用戶,做提示,錯誤提示等;到這里,整個UI方面就已經(jīng)完成了;只

      剩下后面的邏輯處理,就是輸入句子能發(fā)音,并且支持快捷鍵屏幕取詞等;

      更多資料

      跟我學(xué)做c#皮膚美化

      WinAPI使用大全

      跟我做WinForm開發(fā)(2)-后臺邏輯操作

      主站蜘蛛池模板: 成人激情视频一区二区三区| 国产精品99区一区二区三| 亚洲人妻中文字幕一区| 一区二区三区AV波多野结衣| 99中文字幕精品国产| 亚洲开心婷婷中文字幕| 亚洲高清国产拍精品熟女| 高清精品视频一区二区三区| 亚洲综合一区二区三区| 四虎国产精品免费久久| 无码抽搐高潮喷水流白浆| 亚洲国产天堂一区二区三区| 狠狠亚洲狠狠欧洲2019| 久久精品第九区免费观看| 欧洲中文字幕国产精品| 亚洲精品有码在线观看| 日韩精品一区二区亚洲专区| 99久久er热在这里只有精品99 | 日韩va中文字幕无码电影| 中文字幕国产精品资源| 南投县| 国产美女被遭强高潮免费一视频 | 精品无码久久久久久久久久| 人妻系列中文字幕精品| 最新亚洲av日韩av二区| 在熟睡夫面前侵犯我在线播放| 国产一区二区av天堂热| 夜夜爽免费888视频| 国产91午夜福利精品| 热久久这里只有精品国产| 欧洲性开放老太大| 久久久精品94久久精品| 亚洲人成电影在线天堂色| 欧洲人妻丰满av无码久久不卡| 无码国产偷倩在线播放老年人| 日本不卡码一区二区三区| 亚洲国产精品日韩av专区| 免费国产又色又爽又黄的网站| 狼人大伊人久久一区二区| 99RE6在线观看国产精品| 成人3D动漫一区二区三区|