//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods // returns the range that is visible in the RichEdit window internal ITextRange GetVisibleRange() { // get a range from the center point of the client rectangle Rect rect = BoundingRectangle; int x = ((int)rect.Left + (int)rect.Right) / 2; int y = ((int)rect.Top + (int)rect.Bottom) / 2; ITextRange range = _document.RangeFromPoint(x, y); // expand it to fill the window. range.Expand(TomUnit.tomWindow); // There is a bug with RichEdit 3.0. The expand to tomWindow may gets 0 as the range's cpBegin (Start). // So need to trim off what is outside of the window. int start = range.Start; // The ITextRange::SetRange method sets this range's Start = min(cp1, cp2) and End = max(cp1, cp2). // If the range is a nondegenerate selection, cp2 is the active end; if it's a degenerate selection, // the ambiguous cp is displayed at the start of the line (rather than at the end of the previous line). // Set the end to the start and the start to the end to create an ambiguous cp. range.SetRange(range.End, range.Start); bool gotPoint = WindowsRichEditRange.RangeGetPoint(range, TomGetPoint.tomStart, out x, out y); while (!gotPoint || !Misc.PtInRect(ref rect, x, y)) { range.MoveStart(TomUnit.tomWord, 1); gotPoint = WindowsRichEditRange.RangeGetPoint(range, TomGetPoint.tomStart, out x, out y); } if (start != range.Start) { // The trimming was done based on the left edge of the range. The last visiable partial // character/word has been also added back into the range, need to remove it. Do the comparing // against the characters right edge and the window rectangle. ITextRange rangeAdjust = _document.Range(0, range.Start - 1); gotPoint = WindowsRichEditRange.RangeGetPoint(rangeAdjust, TomGetPoint.TA_BOTTOM | TomGetPoint.TA_RIGHT, out x, out y); while (gotPoint && Misc.PtInRect(ref rect, x, y) && rangeAdjust.Start != rangeAdjust.End) { rangeAdjust.MoveEnd(TomUnit.tomCharacter, -1); range.MoveStart(TomUnit.tomCharacter, -1); gotPoint = WindowsRichEditRange.RangeGetPoint(rangeAdjust, TomGetPoint.TA_BOTTOM | TomGetPoint.TA_RIGHT, out x, out y); } } // There is a bug with RichEdit 3.0. The expand to tomWindow gets the last cp of the bottom // line in the window as the range's cpLim (End). The cpLim may be passed the right side of // the window. // So need to trim off what is on the right side of the window. int end = range.End; gotPoint = WindowsRichEditRange.RangeGetPoint(range, TomGetPoint.TA_RIGHT, out x, out y); while (!gotPoint || !Misc.PtInRect(ref rect, x, y)) { range.MoveEnd(TomUnit.tomWord, -1); gotPoint = WindowsRichEditRange.RangeGetPoint(range, TomGetPoint.TA_RIGHT, out x, out y); } if (end != range.End) { // The trimming was done based on the right edge of the range. The last visiable partial // character/word has been also trimmed so add it back to the range. Do the comparing // against the characters left edge and the window rectangle. ITextRange rangeAdjust = _document.Range(range.End, end); do { if (range.MoveEnd(TomUnit.tomCharacter, 1) == 0) { break; } rangeAdjust.MoveStart(TomUnit.tomCharacter, 1); gotPoint = WindowsRichEditRange.RangeGetPoint(rangeAdjust, TomGetPoint.tomStart, out x, out y); } while (gotPoint && Misc.PtInRect(ref rect, x, y)); } return(range); }