C#透明TextBox

1  using System;
  2  using System.Collections;
  3  using System.ComponentModel;
  4  using System.Drawing;
  5  using System.Data;
  6  using System.Windows.Forms;
  7  
  8  using System.Drawing.Imaging;
  9  
 10  namespace ZBobb
 11  {
 12      /// <summary>
 13      /// AlphaBlendTextBox: A .Net textbox that can be translucent to the background.
 14      /// (C) 2003 Bob Bradley / ZBobb@hotmail.com
 15      /// </summary>
 16      /// 
 17  
 18  
 19  
 20      public class AlphaBlendTextBox : System.Windows.Forms.TextBox
 21      {
 22          #region private variables
 23  
 24          private uPictureBox myPictureBox;
 25          private  bool   myUpToDate = false;
 26          private  bool   myCaretUpToDate = false;
 27          private  Bitmap myBitmap;
 28          private  Bitmap myAlphaBitmap;
 29  
 30          private int myFontHeight = 10;
 31  
 32          private System.Windows.Forms.Timer myTimer1;
 33  
 34          private bool myCaretState = true;
 35  
 36          private bool myPaintedFirstTime = false;
 37  
 38          private Color myBackColor = Color.White;
 39          private int myBackAlpha = 10;       
 40          
 41          /// <summary> 
 42          /// Required designer variable.
 43          /// </summary>
 44          private System.ComponentModel.Container components = null;
 45  
 46          #endregion // end private variables
 47  
 48  
 49          #region public methods and overrides
 50  
 51          public AlphaBlendTextBox()
 52          {
 53              // This call is required by the Windows.Forms Form Designer.
 54              InitializeComponent();
 55              // TODO: Add any initialization after the InitializeComponent call
 56  
 57              this.BackColor = myBackColor; 
 58  
 59              this.SetStyle(ControlStyles.UserPaint,false);
 60              this.SetStyle(ControlStyles.AllPaintingInWmPaint,true);
 61              this.SetStyle(ControlStyles.DoubleBuffer,true);
 62  
 63  
 64              myPictureBox = new uPictureBox();
 65              this.Controls.Add(myPictureBox);
 66              myPictureBox.Dock = DockStyle.Fill;
 67          }
 68  
 69  
 70          protected override void OnResize(EventArgs e)
 71          {
 72              
 73              base.OnResize (e);
 74              this.myBitmap = new Bitmap(this.ClientRectangle.Width,this.ClientRectangle.Height);//(this.Width,this.Height);
 75              this.myAlphaBitmap = new Bitmap(this.ClientRectangle.Width,this.ClientRectangle.Height);//(this.Width,this.Height);
 76              myUpToDate = false;
 77              this.Invalidate();
 78          }
 79  
 80  
 81          //Some of these should be moved to the WndProc later
 82  
 83          protected override void OnKeyDown(KeyEventArgs e)
 84          {
 85              base.OnKeyDown (e);
 86              myUpToDate = false;
 87              this.Invalidate();
 88          }
 89  
 90          protected override void OnKeyUp(KeyEventArgs e)
 91          {
 92              base.OnKeyUp (e);
 93              myUpToDate = false;
 94              this.Invalidate();
 95  
 96          }
 97  
 98          protected override void OnKeyPress(KeyPressEventArgs e)
 99          {
100              base.OnKeyPress (e);
101              myUpToDate = false;
102              this.Invalidate();
103          }
104  
105          protected override void OnMouseUp(MouseEventArgs e)
106          {
107              base.OnMouseUp (e);
108              this.Invalidate();
109          }
110  
111          protected override void OnGiveFeedback(GiveFeedbackEventArgs gfbevent)
112          {
113              base.OnGiveFeedback (gfbevent);
114              myUpToDate = false;
115              this.Invalidate();
116          }
117  
118  
119          protected override void OnMouseLeave(EventArgs e)
120          {
121              //found this code to find the current cursor location
122              //at http://www.syncfusion.com/FAQ/WinForms/FAQ_c50c.asp#q597q
123  
124              Point ptCursor = Cursor.Position; 
125              
126              Form f = this.FindForm();
127              ptCursor = f.PointToClient(ptCursor); 
128              if( !this.Bounds.Contains(ptCursor) )  
129                  base.OnMouseLeave (e);
130          }       
131          
132                      
133          protected override void OnChangeUICues(UICuesEventArgs e)
134          {
135              base.OnChangeUICues (e);
136              myUpToDate = false;
137              this.Invalidate();
138          }
139          
140          
141  //--
142          protected override void OnGotFocus(EventArgs e)
143          {
144              base.OnGotFocus (e);
145              myCaretUpToDate = false;
146              myUpToDate = false;
147              this.Invalidate();
148              
149  
150              myTimer1 = new System.Windows.Forms.Timer(this.components);
151              myTimer1.Interval = (int) win32.GetCaretBlinkTime(); //  usually around 500;
152              
153              myTimer1.Tick +=new EventHandler(myTimer1_Tick);
154              myTimer1.Enabled = true;
155                  
156          }
157  
158          protected override void OnLostFocus(EventArgs e)
159          {
160              base.OnLostFocus (e);
161              myCaretUpToDate = false;
162              myUpToDate = false;
163              this.Invalidate();
164  
165              myTimer1.Dispose();
166          }
167  
168  //--        
169  
170          protected override void OnFontChanged(EventArgs e)
171          {
172              if (this.myPaintedFirstTime)
173                  this.SetStyle(ControlStyles.UserPaint,false);
174  
175              base.OnFontChanged (e);
176  
177              if (this.myPaintedFirstTime)
178                  this.SetStyle(ControlStyles.UserPaint,true);
179  
180                  
181              myFontHeight = GetFontHeight();
182  
183  
184              myUpToDate = false;
185              this.Invalidate();
186          }
187  
188          protected override void OnTextChanged(EventArgs e)
189          {
190              base.OnTextChanged (e);
191              myUpToDate = false;
192              this.Invalidate();
193          }
194  
195          
196          protected override void WndProc(ref Message m)
197          {
198  
199              base.WndProc (ref m);
200  
201              // need to rewrite as a big switch
202  
203              if (m.Msg == win32.WM_PAINT)
204              {
205                  myPaintedFirstTime = true;
206  
207                  if (!myUpToDate || !myCaretUpToDate)
208                      GetBitmaps();
209                  myUpToDate = true;
210                  myCaretUpToDate = true;
211  
212                  if (myPictureBox.Image != null) myPictureBox.Image.Dispose();
213                  myPictureBox.Image = (Image)myAlphaBitmap.Clone();
214  
215              }
216  
217              else if (m.Msg ==  win32.WM_HSCROLL || m.Msg == win32.WM_VSCROLL)
218              {
219                  myUpToDate = false;
220                  this.Invalidate();          
221              }
222  
223              else if (m.Msg == win32.WM_LBUTTONDOWN 
224                  || m.Msg == win32.WM_RBUTTONDOWN
225                  || m.Msg == win32.WM_LBUTTONDBLCLK
226                  //  || m.Msg == win32.WM_MOUSELEAVE  ///****
227                  )
228              {
229                  myUpToDate = false;
230                  this.Invalidate();          
231              }
232  
233              else if (m.Msg == win32.WM_MOUSEMOVE )
234              {
235                  if (m.WParam.ToInt32() != 0)  //shift key or other buttons
236                  {
237                      myUpToDate = false;
238                      this.Invalidate();          
239                  }
240              }
241  
242  
243          
244              //System.Diagnostics.Debug.WriteLine("Pro: " + m.Msg.ToString("X"));
245  
246          }
247  
248  
249          /// <summary> 
250          /// Clean up any resources being used.
251          /// </summary>
252          protected override void Dispose( bool disposing )
253          {
254              if( disposing )
255              {
256                  //this.BackColor = Color.Pink;
257                  if(components != null)
258                  {
259                      components.Dispose();
260                  }
261              }
262              base.Dispose( disposing );
263          }
264  
265          #endregion      //end public method and overrides
266  
267  
268          #region public property overrides
269  
270          public new BorderStyle BorderStyle
271          {
272              get {return base.BorderStyle;}
273              set 
274              {
275                  if (this.myPaintedFirstTime)
276                      this.SetStyle(ControlStyles.UserPaint,false);
277  
278                  base.BorderStyle = value;
279                  
280                  if (this.myPaintedFirstTime)
281                      this.SetStyle(ControlStyles.UserPaint,true);
282  
283                  this.myBitmap = null;
284                  this.myAlphaBitmap = null;
285                  myUpToDate = false;
286                  this.Invalidate();
287              }
288          }
289  
290          public  new Color BackColor
291          {
292              get
293              {
294                  return Color.FromArgb(base.BackColor.R, base.BackColor.G, base.BackColor.B);
295              }
296              set
297              {
298                  myBackColor = value;
299                  base.BackColor = value;
300                  myUpToDate = false;
301              }
302          }
303          public override bool Multiline
304          {
305              get{return base.Multiline;}
306              set
307              {
308                  if (this.myPaintedFirstTime)
309                      this.SetStyle(ControlStyles.UserPaint,false);
310                  
311                  base.Multiline = value;
312  
313                  if (this.myPaintedFirstTime)
314                      this.SetStyle(ControlStyles.UserPaint,true);
315  
316                  this.myBitmap = null;
317                  this.myAlphaBitmap = null;
318                  myUpToDate = false;
319                  this.Invalidate();
320              }
321          }
322  
323          
324          #endregion    //end public property overrides
325  
326  
327          #region private functions and classes
328  
329          private int GetFontHeight()
330          {
331              Graphics g = this.CreateGraphics();
332              SizeF sf_font = g.MeasureString("X",this.Font);
333              g.Dispose();
334              return  (int) sf_font.Height;
335          }
336          
337          
338          private void GetBitmaps()
339          {
340  
341              if (myBitmap == null
342                  || myAlphaBitmap == null
343                  || myBitmap.Width != Width 
344                  || myBitmap.Height != Height        
345                  || myAlphaBitmap.Width != Width 
346                  || myAlphaBitmap.Height != Height)
347              {
348                  myBitmap = null;
349                  myAlphaBitmap = null;
350              }
351  
352  
353  
354          if (myBitmap == null)
355              {
356                  myBitmap = new Bitmap(this.ClientRectangle.Width,this.ClientRectangle.Height);//(Width,Height);
357                  myUpToDate = false;
358              }
359  
360  
361              if (!myUpToDate)
362              {
363                  //Capture the TextBox control window
364  
365                  this.SetStyle(ControlStyles.UserPaint,false);
366                  
367                  win32.CaptureWindow(this,ref myBitmap);
368  
369                  this.SetStyle(ControlStyles.UserPaint,true);
370                  this.SetStyle(ControlStyles.SupportsTransparentBackColor,true);
371                  this.BackColor = Color.FromArgb(myBackAlpha,myBackColor);
372  
373              }
374              //--
375              
376  
377          
378              Rectangle r2 = new Rectangle(0,0,this.ClientRectangle.Width,this.ClientRectangle.Height);
379              ImageAttributes tempImageAttr = new ImageAttributes();
380                          
381  
382              //Found the color map code in the MS Help
383  
384              ColorMap[] tempColorMap = new ColorMap[1];
385              tempColorMap[0] = new ColorMap();
386              tempColorMap[0].OldColor = Color.FromArgb(255,myBackColor); 
387              tempColorMap[0].NewColor = Color.FromArgb(myBackAlpha,myBackColor);
388  
389              tempImageAttr.SetRemapTable(tempColorMap);
390  
391              if (myAlphaBitmap != null)
392                  myAlphaBitmap.Dispose();
393                      
394                      
395              myAlphaBitmap = new Bitmap(this.ClientRectangle.Width,this.ClientRectangle.Height);//(Width,Height);
396  
397              Graphics tempGraphics1 = Graphics.FromImage(myAlphaBitmap);
398  
399              tempGraphics1.DrawImage(myBitmap,r2,0,0,this.ClientRectangle.Width,this.ClientRectangle.Height,GraphicsUnit.Pixel,tempImageAttr);
400  
401              tempGraphics1.Dispose();
402              
403  //----
404  
405              if (this.Focused && (this.SelectionLength == 0))
406              {
407                  Graphics tempGraphics2 = Graphics.FromImage(myAlphaBitmap);
408                  if (myCaretState)
409                  {
410                      //Draw the caret
411                      Point caret = this.findCaret();
412                      Pen p = new Pen(this.ForeColor,3);
413                      tempGraphics2.DrawLine(p,caret.X,caret.Y + 0,caret.X,caret.Y + myFontHeight);
414                      tempGraphics2.Dispose();
415                  }
416                          
417              }
418  
419  
420  
421          }
422  
423  
424  
425          private Point findCaret() 
426          {
427              /*  Find the caret translated from code at 
428               * http://www.vb-helper.com/howto_track_textbox_caret.html
429               * 
430               * and 
431               * 
432               * http://www.microbion.co.uk/developers/csharp/textpos2.htm
433               * 
434               * Changed to EM_POSFROMCHAR
435               * 
436               * This code still needs to be cleaned up and debugged
437               * */
438  
439              Point pointCaret = new Point(0);
440              int i_char_loc = this.SelectionStart;
441              IntPtr pi_char_loc = new IntPtr(i_char_loc);
442  
443              int i_point = win32.SendMessage(this.Handle,win32.EM_POSFROMCHAR,pi_char_loc,IntPtr.Zero);
444              pointCaret = new Point(i_point);
445  
446              if (i_char_loc == 0) 
447              {
448                  pointCaret = new Point(0);
449              }
450              else if (i_char_loc >= this.Text.Length)
451              {
452                  pi_char_loc = new IntPtr(i_char_loc - 1);
453                  i_point = win32.SendMessage(this.Handle,win32.EM_POSFROMCHAR,pi_char_loc,IntPtr.Zero);
454                  pointCaret = new Point(i_point);
455  
456                  Graphics g = this.CreateGraphics();
457                  String t1 = this.Text.Substring(this.Text.Length-1,1) + "X";
458                  SizeF sizet1 = g.MeasureString(t1,this.Font);
459                  SizeF sizex  = g.MeasureString("X",this.Font);
460                  g.Dispose();
461                  int xoffset = (int)(sizet1.Width - sizex.Width);
462                  pointCaret.X = pointCaret.X + xoffset;
463  
464                  if (i_char_loc == this.Text.Length)
465                  {
466                      String slast = this.Text.Substring(Text.Length-1,1);
467                      if (slast == "
")
468                      {
469                          pointCaret.X = 1;
470                          pointCaret.Y = pointCaret.Y + myFontHeight;
471                      }
472                  }
473  
474              }
475  
476  
477  
478              return pointCaret;
479          }
480  
481  
482          private void myTimer1_Tick(object sender, EventArgs e)
483          {
484              //Timer used to turn caret on and off for focused control
485  
486              myCaretState = !myCaretState;
487              myCaretUpToDate = false;
488              this.Invalidate();
489          }
490  
491  
492          private class uPictureBox : PictureBox 
493          {
494              public uPictureBox() 
495              {
496                  this.SetStyle(ControlStyles.Selectable,false);
497                  this.SetStyle(ControlStyles.UserPaint,true);
498                  this.SetStyle(ControlStyles.AllPaintingInWmPaint,true);
499                  this.SetStyle(ControlStyles.DoubleBuffer,true);
500  
501                  this.Cursor = null;
502                  this.Enabled = true; 
503                  this.SizeMode = PictureBoxSizeMode.Normal;
504                  
505              }
506  
507  
508  
509  
510              //uPictureBox
511              protected override void WndProc(ref Message m)
512              {
513                  if (m.Msg == win32.WM_LBUTTONDOWN 
514                      || m.Msg == win32.WM_RBUTTONDOWN
515                      || m.Msg == win32.WM_LBUTTONDBLCLK
516                      || m.Msg == win32.WM_MOUSELEAVE
517                      || m.Msg == win32.WM_MOUSEMOVE )
518                  {
519                      //Send the above messages back to the parent control
520                      win32.PostMessage(this.Parent.Handle,(uint) m.Msg,m.WParam,m.LParam);
521                  }
522  
523                  else if (m.Msg == win32.WM_LBUTTONUP)
524                  {
525                      //??  for selects and such
526                      this.Parent.Invalidate();
527                  }
528  
529  
530                  base.WndProc (ref m);
531              }
532  
533  
534          }   // End uPictureBox Class
535  
536  
537          #endregion  // end private functions and classes
538  
539  
540          #region Component Designer generated code
541          /// <summary> 
542          /// Required method for Designer support - do not modify 
543          /// the contents of this method with the code editor.
544          /// </summary>
545          private void InitializeComponent()
546          {
547              components = new System.ComponentModel.Container();
548          }
549          #endregion
550  
551  
552          #region New Public Properties
553  
554          [
555          Category("Appearance"),
556          Description("The alpha value used to blend the control's background. Valid values are 0 through 255."),
557          Browsable(true),
558          DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)
559  
560          ]
561          public int BackAlpha
562          {
563              get { return myBackAlpha; }
564              set 
565              {
566                  int v = value;
567                  if (v > 255)
568                      v = 255;
569                  myBackAlpha = v;
570                  myUpToDate = false; 
571                  Invalidate();
572              }
573          }
574  
575          #endregion
576  
577  
578  
579      }  // End AlphaTextBox Class
580  
581  
582  }  // End namespace ZBobb
583  
584  
585  //----
586  
原文地址:https://www.cnblogs.com/blogpro/p/11463111.html