附件 http://files.cnblogs.com/xe2011/CSharpTextRuler.rar
原文 http://www.codeproject.com/Articles/22783/Advanced-Text-Editor-with-Ruler
原文的附件:http://files.cnblogs.com/xe2011/TextRuler.rar
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Drawing; 5 using System.Text; 6 using System.Windows.Forms; 7 using System.Drawing.Drawing2D; 8 using System.Drawing.Imaging; 9 //using TextRuler.TextRulerControl; 10 11 namespace WindowsFormsApplication1 12 { 13 internal partial class TextRuler : UserControl 14 { 15 16 #region Variables 17 //control dimensions 18 RectangleF me = new RectangleF(); 19 //drawzone area 20 RectangleF drawZone = new RectangleF(); 21 //area which is bounded by margins 22 RectangleF workArea = new RectangleF(); 23 //items of the ruler 24 List<RectangleF> items = new List<RectangleF>(); 25 //tab stops 26 List<RectangleF> tabs = new List<RectangleF>(); 27 //pen to draw with 28 Pen p = new Pen(Color.Transparent); 29 //margins and indents in pixels (that is why float) 30 private int lMargin = 20, rMargin = 15, llIndent = 20, luIndent = 20, rIndent = 15; 31 //border color 32 Color _strokeColor = Color.Black; 33 //background color 34 Color _baseColor = Color.White; 35 //position 36 int pos = -1; 37 //indicates if mouse button is being pressed and object is captured 38 bool mCaptured = false; 39 //indicates if margins are used 40 bool noMargins = false; 41 //index of the captured object 42 int capObject = -1, capTab = -1; 43 //are tabs enabled? 44 bool _tabsEnabled = false; 45 //value which represents dots per millimiter in current system 46 readonly float dotsPermm; 47 48 internal enum ControlItems 49 { 50 LeftIndent, 51 LeftHangingIndent, 52 RightIndent, 53 LeftMargin, 54 RightMargin 55 } 56 57 #region Events declarations 58 public delegate void IndentChangedEventHandler(int NewValue); 59 public delegate void MultiIndentChangedEventHandler(int LeftIndent, int HangIndent); 60 public delegate void MarginChangedEventHandler(int NewValue); 61 public delegate void TabChangedEventHandler(TabEventArgs args); 62 63 public event IndentChangedEventHandler LeftHangingIndentChanging; 64 public event IndentChangedEventHandler LeftIndentChanging; 65 public event IndentChangedEventHandler RightIndentChanging; 66 public event MultiIndentChangedEventHandler BothLeftIndentsChanged; 67 68 public event MarginChangedEventHandler LeftMarginChanging; 69 public event MarginChangedEventHandler RightMarginChanging; 70 71 public event TabChangedEventHandler TabAdded; 72 public event TabChangedEventHandler TabRemoved; 73 public event TabChangedEventHandler TabChanged; 74 75 #endregion 76 77 #endregion 78 79 #region Constructor 80 private void InitializeComponent() 81 { 82 this.SuspendLayout(); 83 // 84 // TextRuler 85 // 86 this.Name = "TextRuler"; 87 this.Size = new System.Drawing.Size(100, 20); 88 this.ResumeLayout(false); 89 90 } 91 92 public TextRuler() 93 { 94 this.SetStyle(ControlStyles.UserPaint, true); 95 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); 96 this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 97 this.SetStyle(ControlStyles.ResizeRedraw, true); 98 this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); 99 this.BackColor = Color.Transparent; 100 this.Font = new Font("Arial", 7.25f); 101 102 tabs.Clear(); 103 104 //margins and indents 105 items.Add(new RectangleF()); 106 items.Add(new RectangleF()); 107 items.Add(new RectangleF()); 108 items.Add(new RectangleF()); 109 items.Add(new RectangleF()); 110 items.Add(new RectangleF()); 111 items.Add(new RectangleF()); 112 113 /* 114 * items[0] - left margin 115 * items[1] - right margin 116 * items[2] - left indent upper mark 117 * items[3] - left indent lower mark (picture region) 118 * items[4] - right indent mark 119 * items[5] - left indent mark (self-moving region) 120 * items[6] - left indent mark (all-moving region) 121 */ 122 123 using (Graphics g = Graphics.FromHwnd(this.Handle)) 124 { 125 dotsPermm = g.DpiX / 25.4f; 126 } 127 } 128 #endregion 129 130 #region Painting 131 private void DrawBackGround(Graphics g) 132 { 133 //clear background 134 p.Color = Color.Transparent; 135 g.FillRectangle(p.Brush, me); 136 137 //fill background 138 p.Color = _baseColor; 139 g.FillRectangle(p.Brush, drawZone); 140 } 141 142 private void DrawMargins(Graphics g) 143 { 144 items[0] = new RectangleF(0f, 3f, lMargin * dotsPermm, 14f); 145 items[1] = new RectangleF(drawZone.Width - ((float)rMargin * dotsPermm) + 1f, 3f, rMargin * dotsPermm + 5f, 14f); 146 p.Color = Color.DarkGray;//SystemColors.ActiveCaption;/ 147 g.FillRectangle(p.Brush, items[0]); 148 g.FillRectangle(p.Brush, items[1]); 149 150 g.PixelOffsetMode = PixelOffsetMode.None; 151 //draw border 152 p.Color = _strokeColor; 153 g.DrawRectangle(p, 0, 3, me.Width - 1, 14); 154 } 155 156 private void DrawTextAndMarks(Graphics g) 157 { 158 int points = (int)(drawZone.Width / dotsPermm) / 10; 159 float range = 5 * dotsPermm; 160 int i = 0; 161 p.Color = Color.Black; 162 SizeF sz; 163 for (i = 0; i <= points * 2 + 1; i++) 164 { 165 if (i % 2 == 0 && i != 0) 166 { 167 sz = g.MeasureString((Convert.ToInt32(i / 2)).ToString(), this.Font); 168 g.DrawString((Convert.ToInt32(i / 2)).ToString(), this.Font, p.Brush, new PointF((float)(i * range - (float)(sz.Width / 2)), (float)(me.Height / 2) - (float)(sz.Height / 2))); 169 } 170 else 171 { 172 g.DrawLine(p, (float)(i * range), 7f, (float)(i * range), 12f); 173 } 174 } 175 g.PixelOffsetMode = PixelOffsetMode.Half; 176 } 177 178 private void DrawIndents(Graphics g) 179 { 180 items[2] = new RectangleF((float)luIndent * dotsPermm - 4.5f, 0f, 9f, 8f); 181 items[3] = new RectangleF((float)llIndent * dotsPermm - 4.5f, 8.2f, 9f, 11.8f); 182 items[4] = new RectangleF((float)(drawZone.Width - ((float)rIndent * dotsPermm - 4.5f) - 7f), 11f, 9f, 8f); 183 184 //regions for moving left indentation marks 185 items[5] = new RectangleF((float)llIndent * dotsPermm - 4.5f, 8.2f, 9f, 5.9f); 186 items[6] = new RectangleF((float)llIndent * dotsPermm - 4.5f, 14.1f, 9f, 5.9f); 187 188 g.DrawImage(Properties.Resources.l_indet_pos_upper, items[2]); 189 g.DrawImage(Properties.Resources.l_indent_pos_lower, items[3]); 190 g.DrawImage(Properties.Resources.r_indent_pos, items[4]); 191 192 193 } 194 195 private void DrawTabs(Graphics g) 196 { 197 if (_tabsEnabled == false) 198 return; 199 200 int i = 0; 201 202 if (tabs.Count == 0) 203 return; 204 205 for (i = 0; i <= tabs.Count - 1; i++) 206 { 207 g.DrawImage(Properties.Resources.tab_pos, tabs[i]); 208 } 209 } 210 #endregion 211 212 #region Actions 213 private void AddTab(float pos) 214 { 215 RectangleF rect = new RectangleF(pos, 10f, 8f, 8f); 216 tabs.Add(rect); 217 if (TabAdded != null) 218 TabAdded.Invoke(CreateTabArgs(pos)); 219 } 220 221 /// <summary> 222 /// Returns List which contains positions of the tabs converted to millimeters. 223 /// </summary> 224 public List<int> TabPositions 225 { 226 get 227 { 228 List<int> lst = new List<int>(); 229 int i = 0; 230 for (i = 0; i <= tabs.Count - 1; i++) 231 { 232 lst.Add((int)(tabs[i].X / dotsPermm)); 233 } 234 lst.Sort(); 235 return lst; 236 } 237 } 238 239 /// <summary> 240 /// Returns List which contains positions of the tabs in pixels. 241 /// </summary> 242 public List<int> TabPositionsInPixels 243 { 244 get 245 { 246 List<int> lst = new List<int>(); 247 int i = 0; 248 for (i = 0; i <= tabs.Count - 1; i++) 249 { 250 lst.Add((int)(tabs[i].X)); 251 } 252 lst.Sort(); 253 return lst; 254 } 255 } 256 257 /// <summary> 258 /// Sets positions for tabs. It uses positions represented in pixels. 259 /// </summary> 260 /// <param name="positions"></param> 261 public void SetTabPositionsInPixels(int[] positions) 262 { 263 if (positions == null) 264 { 265 tabs.Clear(); 266 } 267 else 268 { 269 tabs.Clear(); 270 int i = 0; 271 for (i = 0; i <= positions.Length - 1; i++) 272 { 273 RectangleF rect = new RectangleF(Convert.ToSingle(positions[i]), 10f, 8f, 8f); 274 tabs.Add(rect); 275 } 276 } 277 this.Refresh(); 278 } 279 280 /// <summary> 281 /// Sets positions for tabs. It uses positions represented in millemeters. 282 /// </summary> 283 /// <param name="positions"></param> 284 public void SetTabPositionsInMillimeters(int[] positions) 285 { 286 if (positions == null) 287 { 288 tabs.Clear(); 289 } 290 else 291 { 292 tabs.Clear(); 293 int i = 0; 294 RectangleF rect; 295 for (i = 0; i <= positions.Length - 1; i++) 296 { 297 if (positions[i] != 0) 298 { 299 rect = new RectangleF(positions[i] * dotsPermm, 10f, 8f, 8f); 300 tabs.Add(rect); 301 } 302 } 303 this.Refresh(); 304 } 305 } 306 307 internal int GetValueInPixels(ControlItems item) 308 { 309 switch (item) 310 { 311 case ControlItems.LeftIndent: 312 return (int)(luIndent * dotsPermm); 313 314 case ControlItems.LeftHangingIndent: 315 return (int)(llIndent * dotsPermm); 316 317 case ControlItems.RightIndent: 318 return (int)(rIndent * dotsPermm); 319 320 case ControlItems.LeftMargin: 321 return (int)(lMargin * dotsPermm); 322 323 case ControlItems.RightMargin: 324 return (int)(rMargin * dotsPermm); 325 326 default: 327 return 0; 328 329 } 330 } 331 332 public float DotsPerMillimeter 333 { 334 get { return dotsPermm; } 335 } 336 #endregion 337 338 #region Properties 339 /// <summary> 340 /// Gets or sets color for the border 341 /// </summary> 342 [DefaultValue(typeof(Color), "Black")] 343 [Description("Color of the border drawn on the bounds of control.")] 344 public Color BorderColor 345 { 346 get { return _strokeColor; } 347 set { _strokeColor = value; this.Refresh(); } 348 } 349 350 /// <summary> 351 /// Gets or sets color for the background 352 /// </summary> 353 [DefaultValue(typeof(Color), "White")] 354 [Description("Base color for the control.")] 355 public Color BaseColor 356 { 357 get 358 { 359 return _baseColor; 360 } 361 set 362 { 363 _baseColor = value; 364 } 365 } 366 367 /// <summary> 368 /// Enables or disables usage of the margins. If disabled, margins values are set to 1. 369 /// </summary> 370 [Category("Margins")] 371 [Description("If true Margins are disabled, otherwise, false.")] 372 [DefaultValue(false)] 373 public bool NoMargins 374 { 375 get { return noMargins; } 376 set 377 { 378 noMargins = value; 379 if (value == true) 380 { 381 this.lMargin = 1; 382 this.rMargin = 1; 383 } 384 this.Refresh(); 385 } 386 } 387 388 /// <summary> 389 /// Specifies left margin 390 /// </summary> 391 [Category("Margins")] 392 [Description("Gets or sets left margin. This value is in millimeters.")] 393 [DefaultValue(20)] 394 public int LeftMargin 395 { 396 get { return lMargin; } 397 set 398 { 399 if (noMargins != true) 400 { 401 lMargin = value; 402 } 403 this.Refresh(); 404 } 405 } 406 407 /// <summary> 408 /// Specifies right margin 409 /// </summary> 410 [Category("Margins")] 411 [Description("Gets or sets right margin. This value is in millimeters.")] 412 [DefaultValue(15)] 413 public int RightMargin 414 { 415 get { return rMargin; } 416 set 417 { 418 if (noMargins != true) 419 { 420 rMargin = value; 421 } 422 this.Refresh(); 423 } 424 } 425 426 /// <summary> 427 /// Gets or sets indentation of the first line of the paragraph 428 /// </summary> 429 [Category("Indents")] 430 [Description("Gets or sets left hanging indent. This value is in millimeters.")] 431 [DefaultValue(20)] 432 public int LeftHangingIndent 433 { 434 get { return llIndent - 1; } 435 set 436 { 437 llIndent = value + 1; 438 this.Refresh(); 439 } 440 } 441 442 /// <summary> 443 /// Gets or sets indentation from the left of the base text of the paragraph 444 /// </summary> 445 [Category("Indents")] 446 [Description("Gets or sets left indent. This value is in millimeters.")] 447 [DefaultValue(20)] 448 public int LeftIndent 449 { 450 get { return luIndent - 1; } 451 set 452 { 453 luIndent = value + 1; 454 this.Refresh(); 455 } 456 } 457 458 /// <summary> 459 /// Gets or sets right indentation of the paragraph 460 /// </summary> 461 [Category("Indents")] 462 [Description("Gets or sets right indent. This value is in millimeters.")] 463 [DefaultValue(15)] 464 public int RightIndent 465 { 466 get { return rIndent - 1; } 467 set 468 { 469 rIndent = value + 1; 470 this.Refresh(); 471 } 472 } 473 474 [Category("Tabulation")] 475 [Description("True to display tab stops, otherwise, False")] 476 [DefaultValue(false)] 477 public bool TabsEnabled 478 { 479 get { return _tabsEnabled; } 480 set { _tabsEnabled = value; this.Refresh(); } 481 } 482 #endregion 483 484 #region Overriders 485 protected override void OnPaint(PaintEventArgs e) 486 { 487 base.OnPaint(e); 488 //set compositing to high quality because of using images for indents 489 e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 490 491 e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; 492 //make smooth control 493 e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; 494 //this will braw smoother control, without blur and fast ;). 495 e.Graphics.PixelOffsetMode = PixelOffsetMode.Half; 496 //this will braw text with highest quality 497 e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; 498 499 me = new RectangleF(0f, 0f, (float)this.Width, (float)this.Height); 500 drawZone = new RectangleF(1f, 3f, me.Width - 2f, 14f); 501 workArea = new RectangleF((float)lMargin * dotsPermm, 3f, drawZone.Width - ((float)rMargin * dotsPermm) - drawZone.X * 2, 14f); 502 503 //firstly, draw background. 504 DrawBackGround(e.Graphics); 505 506 //then, draw margins 507 DrawMargins(e.Graphics); 508 509 //then, draw text (numbers) and marks (vertical lines) 510 DrawTextAndMarks(e.Graphics); 511 512 //then, draw indent marks 513 DrawIndents(e.Graphics); 514 515 //finally, draw tab stops 516 DrawTabs(e.Graphics); 517 } 518 519 protected override void OnResize(EventArgs e) 520 { 521 base.OnResize(e); 522 this.Height = 20; 523 } 524 525 protected override void OnMouseDown(MouseEventArgs e) 526 { 527 base.OnMouseDown(e); 528 int i = 0; 529 530 mCaptured = false; 531 532 //process left mouse button only 533 if (e.Button != MouseButtons.Left) 534 return; 535 536 for (i = 0; i <= 6; i++) 537 { 538 if (items[i].Contains(e.Location) == true && i != 3) //i must not be equal to 3, as this is region for whole image 539 { 540 if (noMargins == true && (i == 0 || i == 1)) 541 break; 542 543 capObject = i; 544 mCaptured = true; 545 break; 546 } 547 } 548 549 if (mCaptured == true) 550 return; 551 552 if (tabs.Count == 0) 553 return; 554 555 if (_tabsEnabled == false) 556 return; 557 558 i = 0; 559 560 for (i = 0; i <= tabs.Count - 1; i++) 561 { 562 if (tabs[i].Contains(e.Location) == true) 563 { 564 capTab = i; 565 pos = (int)(tabs[i].X / dotsPermm); 566 mCaptured = true; 567 break; 568 } 569 } 570 571 } 572 573 protected override void OnMouseUp(MouseEventArgs e) 574 { 575 base.OnMouseUp(e); 576 577 //process left mouse button only 578 if (e.Button != MouseButtons.Left) 579 return; 580 581 if (workArea.Contains(e.Location) == false) 582 { 583 if (mCaptured == true && capTab != -1 && _tabsEnabled == true) 584 { 585 try 586 { 587 float pos = tabs[capTab].X * dotsPermm; 588 tabs.RemoveAt(capTab); 589 if (TabRemoved != null) 590 TabRemoved.Invoke(CreateTabArgs(pos)); 591 } 592 catch (Exception) 593 { 594 } 595 } 596 } 597 else if (workArea.Contains(e.Location) == true) 598 { 599 if (mCaptured != true && _tabsEnabled == true) 600 { 601 AddTab((float)e.Location.X); 602 } 603 else if (mCaptured == true && capTab != -1) 604 { 605 if (TabChanged != null && _tabsEnabled == true) 606 TabChanged.Invoke(CreateTabArgs(e.Location.X)); 607 } 608 } 609 610 capTab = -1; 611 mCaptured = false; 612 capObject = -1; 613 this.Refresh(); 614 } 615 616 protected override void OnMouseMove(MouseEventArgs e) 617 { 618 base.OnMouseMove(e); 619 620 if (mCaptured == true && capObject != -1) 621 { 622 switch (capObject) 623 { 624 case 0: 625 if (noMargins == true) 626 return; 627 if (e.Location.X <= (int)(me.Width - rMargin * dotsPermm - 35f)) 628 { 629 this.lMargin = (int)(e.Location.X / dotsPermm); 630 if (this.lMargin < 1) 631 this.lMargin = 1; 632 if (LeftMarginChanging != null) 633 LeftMarginChanging.Invoke(lMargin); 634 this.Refresh(); 635 } 636 break; 637 638 case 1: 639 if (noMargins == true) 640 return; 641 if (e.Location.X >= (int)(lMargin * dotsPermm + 35f)) 642 { 643 this.rMargin = (int)((drawZone.Width / dotsPermm) - (int)(e.Location.X / dotsPermm)); 644 if (this.rMargin < 1) 645 this.rMargin = 1; 646 if (RightMarginChanging != null) 647 RightMarginChanging.Invoke(rMargin); 648 this.Refresh(); 649 } 650 break; 651 652 case 2: 653 if (e.Location.X <= (int)(me.Width - rIndent * dotsPermm - 35f)) 654 { 655 this.luIndent = (int)(e.Location.X / dotsPermm); 656 if (this.luIndent < 1) 657 this.luIndent = 1; 658 if (LeftIndentChanging != null) 659 LeftIndentChanging.Invoke(luIndent - 1); 660 this.Refresh(); 661 } 662 break; 663 664 665 case 4: 666 if (e.Location.X >= (int)(Math.Max(llIndent, luIndent) * dotsPermm + 35f)) 667 { 668 this.rIndent = (int)((me.Width / dotsPermm) - (int)(e.Location.X / dotsPermm)); 669 if (this.rIndent < 1) 670 this.rIndent = 1; 671 if (RightIndentChanging != null) 672 RightIndentChanging.Invoke(rIndent - 1); 673 this.Refresh(); 674 } 675 break; 676 677 case 5: 678 if (e.Location.X <= (int)(drawZone.Width - rIndent * dotsPermm - 35f)) 679 { 680 this.llIndent = (int)(e.Location.X / dotsPermm); 681 if (this.llIndent < 1) 682 this.llIndent = 1; 683 if (LeftHangingIndentChanging != null) 684 LeftHangingIndentChanging.Invoke(llIndent - 1); 685 this.Refresh(); 686 } 687 break; 688 689 case 6: 690 if (e.Location.X <= (int)(drawZone.Width - rIndent * dotsPermm - 35f)) 691 { 692 this.luIndent = luIndent + (int)(e.Location.X / dotsPermm) - llIndent; 693 this.llIndent = (int)(e.Location.X / dotsPermm); 694 if (this.llIndent < 1) 695 this.llIndent = 1; 696 if (this.luIndent < 1) 697 this.luIndent = 1; 698 if (BothLeftIndentsChanged != null) 699 BothLeftIndentsChanged.Invoke(luIndent - 1, llIndent - 1); 700 this.Refresh(); 701 } 702 break; 703 704 } 705 } 706 else if (mCaptured == true && capTab != -1) 707 { 708 if (workArea.Contains(e.Location) == true) 709 { 710 tabs[capTab] = new RectangleF((float)e.Location.X, tabs[capTab].Y, tabs[capTab].Width, tabs[capTab].Height); 711 this.Refresh(); 712 } 713 } 714 else 715 { 716 int i = 0; 717 718 for (i = 0; i <= 4; i++) 719 { 720 if (items[i].Contains(e.Location) == true) 721 { 722 switch (i) 723 { 724 case 0: 725 if (noMargins == true) return; 726 Cursor = Cursors.SizeWE; 727 break; 728 729 case 1: 730 if (noMargins == true) return; 731 Cursor = Cursors.SizeWE; 732 break; 733 } 734 break; 735 } 736 this.Cursor = Cursors.Default; 737 } 738 } 739 740 } 741 #endregion 742 743 #region Events classes 744 internal class TabEventArgs : EventArgs 745 { 746 private int _posN = -1; 747 private int _posO = -1; 748 749 internal int NewPosition 750 { 751 get { return _posN; } 752 set { _posN = value; } 753 } 754 755 internal int OldPosition 756 { 757 get { return _posO; } 758 set { _posO = value; } 759 } 760 } 761 762 private TabEventArgs CreateTabArgs(float newPos) 763 { 764 TabEventArgs tae = new TabEventArgs(); 765 tae.NewPosition = (int)(newPos / dotsPermm); 766 tae.OldPosition = pos; 767 return tae; 768 } 769 770 #endregion 771 } 772 }
使用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Runtime.InteropServices; 10 11 12 13 namespace WindowsFormsApplication1 14 { 15 public partial class Form1 : Form 16 { 17 public Form1() 18 { 19 InitializeComponent(); 20 21 } 22 23 private void button1_Click(object sender, EventArgs e) 24 { 25 26 } 27 #region richTextBox1 Margin 28 public struct Rect 29 { 30 public int Left; 31 public int Top; 32 public int Right; 33 public int Bottom; 34 } 35 36 [DllImport("user32.dll")] 37 private static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, ref Rect lParam); 38 39 private const int EM_GETRECT = 0x00b2; 40 private const int EM_SETRECT = 0x00b3; 41 42 public Rect RichTextBoxMargin 43 { 44 get 45 { 46 Rect rect = new Rect(); 47 SendMessage(richTextBox1.Handle, EM_GETRECT, IntPtr.Zero, ref rect); 48 rect.Left += 1; 49 rect.Top += 1; 50 rect.Right = 1 + richTextBox1.ClientSize.Width - rect.Right; 51 rect.Bottom = richTextBox1.ClientSize.Height - rect.Bottom; 52 return rect; 53 } 54 set 55 { 56 Rect rect; 57 rect.Left = richTextBox1.ClientRectangle.Left + value.Left; 58 rect.Top = richTextBox1.ClientRectangle.Top + value.Top; 59 rect.Right = richTextBox1.ClientRectangle.Right - value.Right; 60 rect.Bottom = richTextBox1.ClientRectangle.Bottom - value.Bottom; 61 62 SendMessage(richTextBox1.Handle, EM_SETRECT, IntPtr.Zero, ref rect); 63 } 64 65 } 66 67 68 public int LeftMargin 69 { 70 get 71 { 72 return RichTextBoxMargin.Left; 73 } 74 set 75 { 76 Rect rect1; 77 rect1 = RichTextBoxMargin; 78 79 Rect rect; 80 rect.Left = value; 81 rect.Top = rect1.Top; 82 rect.Right = rect1.Right; 83 rect.Bottom = rect1.Bottom; 84 85 RichTextBoxMargin = rect; 86 } 87 } 88 89 90 public int RightftMargin 91 { 92 get 93 { 94 return RichTextBoxMargin.Right; 95 } 96 set 97 { 98 Rect rect1; 99 rect1 = RichTextBoxMargin; 100 101 Rect rect; 102 rect.Left = rect1.Left; 103 rect.Top = rect1.Top; 104 rect.Right = value; 105 rect.Bottom = rect1.Bottom; 106 107 RichTextBoxMargin = rect; 108 } 109 } 110 111 112 public int TopMargin 113 { 114 get 115 { 116 return RichTextBoxMargin.Top; 117 } 118 set 119 { 120 Rect rect1; 121 rect1 = RichTextBoxMargin; 122 123 Rect rect; 124 rect.Left = rect1.Left; 125 rect.Top = value; 126 rect.Right = rect1.Right; 127 rect.Bottom = rect1.Bottom; 128 129 RichTextBoxMargin = rect; 130 } 131 } 132 133 public int BottomMargin 134 { 135 get 136 { 137 return RichTextBoxMargin.Bottom; 138 } 139 set 140 { 141 Rect rect1; 142 rect1 = RichTextBoxMargin; 143 144 Rect rect; 145 rect.Left = rect1.Left; 146 rect.Top = rect1.Top; 147 rect.Right = rect1.Right; 148 rect.Bottom = value; 149 RichTextBoxMargin = rect; 150 } 151 } 152 153 #endregion 154 155 private void textRuler1_BothLeftIndentsChanged(int LeftIndent, int HangIndent) 156 { 157 richTextBox1.SelectionIndent = 158 (int)(this.textRuler1.LeftIndent * this.textRuler1.DotsPerMillimeter); 159 160 richTextBox1.SelectionHangingIndent = 161 (int)(this.textRuler1.LeftHangingIndent * this.textRuler1.DotsPerMillimeter) 162 - (int)(this.textRuler1.LeftIndent * this.textRuler1.DotsPerMillimeter); 163 164 165 } 166 167 private void textRuler1_LeftHangingIndentChanging(int NewValue) 168 { 169 try 170 { 171 richTextBox1.SelectionHangingIndent = 172 (int)(this.textRuler1.LeftHangingIndent * this.textRuler1.DotsPerMillimeter) - 173 (int)(this.textRuler1.LeftIndent * this.textRuler1.DotsPerMillimeter); 174 } 175 catch (Exception) 176 { 177 } 178 } 179 180 private void textRuler1_LeftIndentChanging(int NewValue) 181 { 182 try 183 { 184 richTextBox1.SelectionIndent = (int)(this.textRuler1.LeftIndent * this.textRuler1.DotsPerMillimeter); 185 richTextBox1.SelectionHangingIndent = (int)(this.textRuler1.LeftHangingIndent * this.textRuler1.DotsPerMillimeter) - (int)(this.textRuler1.LeftIndent * this.textRuler1.DotsPerMillimeter); 186 } 187 catch (Exception) 188 { 189 } 190 } 191 192 private void textRuler1_RightIndentChanging(int NewValue) 193 { 194 try 195 { 196 richTextBox1.SelectionRightIndent = (int)(this.textRuler1.RightIndent * this.textRuler1.DotsPerMillimeter); 197 } 198 catch (Exception) 199 { 200 } 201 } 202 203 private void textRuler1_TabAdded(TextRuler.TabEventArgs args) 204 { 205 try 206 { 207 richTextBox1.SelectionTabs = this.textRuler1.TabPositionsInPixels.ToArray(); 208 } 209 catch (Exception) 210 { 211 } 212 } 213 214 private void textRuler1_TabChanged(TextRuler.TabEventArgs args) 215 { 216 try 217 { 218 richTextBox1.SelectionTabs = this.textRuler1.TabPositionsInPixels.ToArray(); 219 } 220 catch (Exception) 221 { 222 } 223 } 224 225 private void textRuler1_TabRemoved(TextRuler.TabEventArgs args) 226 { 227 try 228 { 229 richTextBox1.SelectionTabs = this.textRuler1.TabPositionsInPixels.ToArray(); 230 } 231 catch (Exception) 232 { 233 } 234 } 235 236 private void richTextBox1_SelectionChanged(object sender, EventArgs e) 237 { 238 239 this.textRuler1.SetTabPositionsInPixels(this.richTextBox1.SelectionTabs); 240 241 242 if (this.richTextBox1.SelectionLength < this.richTextBox1.TextLength - 1) 243 { 244 this.textRuler1.LeftIndent = (int)(this.richTextBox1.SelectionIndent / this.textRuler1.DotsPerMillimeter); //convert pixels to millimeter 245 246 this.textRuler1.LeftHangingIndent = (int)((float)this.richTextBox1.SelectionHangingIndent / this.textRuler1.DotsPerMillimeter) + this.textRuler1.LeftIndent; //convert pixels to millimeters 247 248 this.textRuler1.RightIndent = (int)(this.richTextBox1.SelectionRightIndent / this.textRuler1.DotsPerMillimeter); //convert pixels to millimeters 249 } 250 } 251 252 private void textRuler1_LeftMarginChanging(int NewValue) 253 { 254 LeftMargin = (int)(NewValue * 3.77); 255 textRuler1.LeftIndent = NewValue; 256 textRuler1.LeftHangingIndent = NewValue; 257 } 258 259 260 private void textRuler1_RightMarginChanging(int NewValue) 261 { 262 RightftMargin = (int)(NewValue * 3.77); 263 textRuler1.RightIndent = NewValue; 264 } 265 266 private void Form1_Load(object sender, EventArgs e) 267 { 268 textRuler1.LeftMargin = LeftMargin; 269 textRuler1.RightMargin = RightftMargin; 270 richTextBox1_SelectionChanged(sender, e); 271 } 272 } 273 }