/// <summary>Finds the specified string in the content of the control and selects it if it exists.</summary> /// <param name="searchString">The string to find</param> /// <param name="matchCase">Set to true to match casing of the string.</param> /// <param name="wholeWord">Set to true to only find whole words.</param> /// <returns></returns> public bool Find(string searchString, bool matchCase, bool wholeWord, bool searchUp) { NativeMethods.IHTMLSelectionObject selectionObj = this.site.Document.GetSelection(); // Check if a selection actually exists. bool selectionExists = false; if (selectionObj != null) { selectionExists = selectionObj.GetSelectionType().Equals("Text"); } NativeMethods.IHTMLTxtRange textRange = null; if (selectionExists) { object o = selectionObj.CreateRange(); textRange = o as NativeMethods.IHTMLTxtRange; } if (textRange == null) { // If no selection exists, select the entire body. NativeMethods.IHtmlBodyElement bodyElement = this.site.Document.GetBody() as NativeMethods.IHtmlBodyElement; Debug.Assert(bodyElement != null, "Couldn't get body element in HtmlControl.Find"); selectionExists = false; textRange = bodyElement.createTextRange(); } // Set up the bounds of the search. if (searchUp) { // If we're search up in the document. if (selectionExists) { // If a selection exists, move the range's end to one character before the selection. textRange.MoveEnd("character", -1); } // Move the range's beginning to the start of the document. int temp = 1; while (temp == 1) { temp = textRange.MoveStart("textedit", -1); } } else { // If we're searching down in the document. if (selectionExists) { // If a selection exists, start one char after the selection. textRange.MoveStart("character", 1); } // Move the range's end to the end of the document. int temp = 1; while (temp == 1) { temp = textRange.MoveEnd("textedit", 1); } } // Set up the flags for matching case and whole word search int flags = (matchCase ? 0x4 : 0) | (wholeWord ? 0x2 : 0); int direction = searchUp ? -10000000 : 10000000; // Do the search. bool success = textRange.FindText(searchString, direction, flags); if (success) { // If we succeeded, select the text, scroll it into view, and we're done! textRange.Select(); textRange.ScrollIntoView(true); return(true); } else if (selectionExists) { // If we only searched a portion of the document we need to wrap around the document... textRange = selectionObj.CreateRange() as NativeMethods.IHTMLTxtRange; // Set up the bounds of the search. if (searchUp) { // If we're searching up in the document. Start one char after the selection. textRange.MoveStart("character", 1); // Move the range's end to the end of the document. int temp = 1; while (temp == 1) { temp = textRange.MoveEnd("textedit", 1); } } else { // If we're searching down in the document. Move the range's end to one character before the selection. textRange.MoveEnd("character", -1); // Move the range's beginning to the start of the document. int temp = 1; while (temp == 1) { temp = textRange.MoveStart("textedit", -1); } } success = textRange.FindText(searchString, direction, flags); if (success) { // If we succeeded, select the text, scroll it into view, and we're done! textRange.Select(); textRange.ScrollIntoView(true); return(true); } } return(false); }
/// <summary>Synchronizes the selection state held in this object with the selection state in MSHTML.</summary> /// <returns>true if the selection has changed</returns> public bool SynchronizeSelection() { if (this.document == null) { this.document = this.control.HtmlDocument; } NativeMethods.IHTMLSelectionObject selection = this.document.GetSelection(); object currentSelection = null; try { currentSelection = selection.CreateRange(); } catch { } ArrayList oldItems = this.items; HtmlSelectionType oldType = this.type; int oldLength = this.selectionLength; // Default to an empty selection this.type = HtmlSelectionType.Empty; this.selectionLength = 0; if (currentSelection != null) { this.selection = currentSelection; this.items = new ArrayList(); //If it's a text selection if (currentSelection is NativeMethods.IHTMLTxtRange) { NativeMethods.IHTMLTxtRange textRange = (NativeMethods.IHTMLTxtRange)currentSelection; NativeMethods.IHTMLElement parentElement = textRange.ParentElement(); // If the document is in full document mode or we're selecting a non-body tag, allow it to select // otherwise, leave the selection as empty (since we don't want the body tag to be selectable on an ASP.NET User Control) if (this.IsSelectableElement(new HtmlElement(parentElement, this.control))) { // Add the parent of the text selection if (parentElement != null) { this.text = textRange.GetText(); if (this.text != null) { this.selectionLength = this.text.Length; } else { this.selectionLength = 0; } this.type = HtmlSelectionType.TextSelection; this.items.Add(parentElement); } } } // If it is a control selection else if (currentSelection is NativeMethods.IHtmlControlRange) { NativeMethods.IHtmlControlRange controlRange = (NativeMethods.IHtmlControlRange)currentSelection; int selectedCount = controlRange.GetLength(); // Add all elements selected if (selectedCount > 0) { this.type = HtmlSelectionType.ElementSelection; for (int i = 0; i < selectedCount; i++) { NativeMethods.IHTMLElement currentElement = controlRange.Item(i); this.items.Add(currentElement); } this.selectionLength = selectedCount; } } } this.sameParentValid = false; bool selectionChanged = false; //Now check if there was a change of selection //If the two selections have different lengths, then the selection has changed if (this.type != oldType) { selectionChanged = true; } else if (this.selectionLength != oldLength) { selectionChanged = true; } else { if (this.items != null) { //If the two selections have a different element, then the selection has changed for (int i = 0; i < this.items.Count; i++) { if (this.items[i] != oldItems[i]) { selectionChanged = true; break; } } } } if (selectionChanged) { //Set this.elements to null so no one can retrieve a dirty copy of the selection element wrappers this.elements = null; OnSelectionChanged(EventArgs.Empty); return(true); } return(false); }