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