public void app_WindowBeforeRightClick(Word.Selection selection, ref bool Cancel) { if (null == selection) { return; } range = selection.Range; switch (selection.Type) { case Word.WdSelectionType.wdSelectionIP: range.Expand(Word.WdUnits.wdWord); // expand range to be a whole word break; case Word.WdSelectionType.wdSelectionNormal: // word(s) selected break; default: return; } // Trim range, so when we replace the query we don't trample on the spaces between words while (range.Characters.First.Text == " ") { range.MoveStart(Word.WdUnits.wdCharacter); } while (range.Characters.Last.Text == " ") { range.MoveEnd(Word.WdUnits.wdCharacter, -1); } if (!string.IsNullOrEmpty(range.Text)) { ShowMenu(range.Text); } }
private async void GetUpdateSentenceText() { ////通过选取类型来获取光标位置 Word.Selection currentSelection = Application.Selection; //// 暂存当前用户的 Overtype 设置 bool userOvertype = Application.Options.Overtype; // 确保 Overtype false. if (Application.Options.Overtype) { Application.Options.Overtype = false; } // 判断当前选取是否是一个插入点(编辑区光标) if (currentSelection.Type == Word.WdSelectionType.wdSelectionIP) { // 当前选取的Range位置,即光标位置 int _cur_start = currentSelection.Range.Start; int _cur_end = currentSelection.Range.End; //// 以当前光标位置作为Range起始区间 Word.Range rng = this.Application.ActiveDocument.Range(_cur_start, _cur_end); ////通过扩展Range范围来获取更新后的句子 rng.MoveStart(Word.WdUnits.wdSentence, -1); rng.MoveEnd(Word.WdUnits.wdSentence, 1); string _curRangeText = rng.Text; // Debug.WriteLine(_curRangeText); TaskPanel.DetectTextLabel.Text = _curRangeText; //// 正则匹配,如果是完整句子,发送到服务端。 string _sentenceRegex = @"(\.|。|\?|?|\!|!|……)"; if (Regex.IsMatch(_curRangeText, _sentenceRegex)) { //// 去掉重复句子 if (cacheUpdateText != _curRangeText) { string _jsonParam = "{\"sentence\":\"" + _curRangeText + "\"}"; string _requestUrl = ConfigurationManager.AppSettings["RequestSentenceUrl"]; HttpWebResponse hwr = await HttpTool.RequesPostAsync(_requestUrl, _jsonParam); HttpTool.ResponseResult _curResult = HttpTool.GetResponseJson <HttpTool.ResponseResult>(hwr); cacheUpdateText = _curRangeText; } } } // 恢复用户 Overtype Application.Options.Overtype = userOvertype; }
public Action AddToWordDocument(IResumeDataObject rdo, IResumeFormatObject rfo, Word.Document wordDoc) { return(() => { if (rdo.ExpertiseEntities.Count > 0) { // Expertise label Word.Paragraph tagLineLabelPara = wordDoc.Content.Paragraphs.Add(); Word.Range r4label = tagLineLabelPara.Range; r4label.Text = "Expertise"; r4label.InsertParagraphAfter(); r4label.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft; r4label.Font.Name = rfo.HeaderFontName; r4label.Font.Color = rfo.HeaderColorWord; r4label.Font.Size = rfo.HeaderFontSize; // Expertise item-headers List <string> cats = rdo.ExpertiseEntities.Select(T => T.Category).Distinct().ToList(); for (int i = 0; i < cats.Count; i++) { Word.Paragraph p = wordDoc.Content.Paragraphs.Add(); Word.Range r4 = p.Range; r4.Text = cats[i] + ": "; int titleLength = r4.Text.Length; // Insert expertise(s) List <string> exps = rdo.ExpertiseEntities.Where(T => T.Category == cats[i]).Select(T => T.Expertise).ToList(); for (int j = 0; j < exps.Count; j++) { r4.Font.Name = rfo.BodyFontName; r4.Font.Size = rfo.BodyFontSize; r4.InsertAfter(exps[j] + " " + '\u2022' + " "); } r4.Text = r4.Text.Remove(r4.Text.Length - 2); Word.Range titleRange = r4.Duplicate; titleRange.MoveEnd(Word.WdUnits.wdCharacter, titleLength - 1 - titleRange.Characters.Count); titleRange.MoveStart(Word.WdUnits.wdCharacter, 0); titleRange.Font.Name = rfo.CategoryFontName; titleRange.Font.Size = rfo.CategoryFontSize; r4.InsertParagraphAfter(); } } }); }
//--------------------------------------------------------------------- private void Test8() { //<Snippet38> // Define a range of 7 characters. //<Snippet39> Word.Range rng = this.Application.ActiveDocument.Range(0, 7); //</Snippet39> // Move the start position 7 characters. //<Snippet40> rng.MoveStart(Word.WdUnits.wdCharacter, 7); //</Snippet40> // Move the end position 7 characters. //<Snippet41> rng.MoveEnd(Word.WdUnits.wdCharacter, 7); //</Snippet41> //</Snippet38> }
//--------------------------------------------------------------------- private void Test8() { //<Snippet38> // Define a range of 7 characters. //<Snippet39> object start = 0; object end = 7; Word.Range rng = this.Range(ref start, ref end); //</Snippet39> // Move the start position 7 characters. //<Snippet40> rng.MoveStart(Word.WdUnits.wdCharacter, 7); //</Snippet40> // Move the end position 7 characters. //<Snippet41> rng.MoveEnd(Word.WdUnits.wdCharacter, 7); //</Snippet41> //</Snippet38> }
//</Snippet22> //--------------------------------------------------------------------- //<Snippet26> private void ReplaceParagraphText() { //<Snippet27> Word.Range firstRange = this.Paragraphs[1].Range; Word.Range secondRange = this.Paragraphs[2].Range; string firstString = firstRange.Text; string secondString = secondRange.Text; //</Snippet27> //<Snippet28> firstRange.Text = secondString; secondRange.Text = firstString; //</Snippet28> //<Snippet29> firstRange.Select(); MessageBox.Show(firstRange.Text); secondRange.Select(); MessageBox.Show(secondRange.Text); //</Snippet29> //<Snippet30> object charUnit = Word.WdUnits.wdCharacter; object move = -1; // move left 1 firstRange.MoveEnd(ref charUnit, ref move); //</Snippet30> //<Snippet31> firstRange.Text = "New content for paragraph 1."; //</Snippet31> //<Snippet32> secondRange.Text = "New content for paragraph 2."; //</Snippet32> //<Snippet33> firstRange.Select(); MessageBox.Show(firstRange.Text); secondRange.Select(); MessageBox.Show(secondRange.Text); //</Snippet33> //<Snippet34> move = 1; // move right 1 firstRange.MoveEnd(ref charUnit, ref move); //</Snippet34> //<Snippet35> secondRange.Delete(ref missing, ref missing); //</Snippet35> //<Snippet36> firstRange.Text = firstString; //</Snippet36> //<Snippet37> firstRange.InsertAfter(secondString); firstRange.Select(); //</Snippet37> }
//note that this saves existing highlight and highlights //this is because looping through document twice will increase runtime by 2n //where n is around 15 seconds per page \(*o*)/ private void SaveExistingAndHighlightRange(Word.Range range, LowerAndUpperBounds bounds) { //range to search int wordCount = range.Words.Count; //***lower bound for arrays is 1 in Word object model*** // (array[0] does exist but is not used) // (array[1] is the first word in the array) int lowerBoundWordCount = 1; int upperBoundWordCount = wordCount + 1; Word.Words words = range.Words; //we have two saved colors (one for continuing range of same color) //so we can bulk highlight a sequence of words with the same color //for faster runtime (updating word one by one takes too long) Word.WdColorIndex tempColor = Word.WdColorIndex.wdNoHighlight; Word.WdColorIndex tempColor2 = Word.WdColorIndex.wdNoHighlight; Word.Range tempRange = null; Globals.ThisAddIn.Application.System.Cursor = Word.WdCursorType.wdCursorWait; for (int i = lowerBoundWordCount; i < upperBoundWordCount; i++) { Word.Range wordRange = words[i]; //save existing highlight first if (wordRange.HighlightColorIndex != Colors.none) { this.SaveExistingHighlight(wordRange); } //get word string word = wordRange.Text; string cleanWord = CleanWord(word); //move page as necessary (kinda like progress bar but more intuitive) //right now, every 20 words if (i % 20 == 0) { wordRange.Select(); } /* * Periods, commas, etc are considered words * so skip through them if so. * However, for hyphens it may be one word * for example merry-go-round * or it may not be like -this hyphen acts as a bullet point. * Make an exception for hyphens and consider it as one word if necessary */ if (isPunctuation(cleanWord)) { if (tempRange == null) { continue; } //reset highlight color to nothing this.AddColoring(tempRange, tempColor); tempRange = null; tempColor = Word.WdColorIndex.wdNoHighlight; wordRange.HighlightColorIndex = Word.WdColorIndex.wdNoHighlight; continue; } //now highlight /* * For highlighting, looping word by word is extremely slow * 900 words about 1 minute * But highlighting the entire page a single color takes a second.. * So to lessen run time, bulk highlight words with same color. * */ if (Dictionary.ContainsKey(cleanWord)) { int wordIndex = Dictionary[cleanWord]; tempColor2 = bounds.GetColorOfIndex(wordIndex); } else { tempColor2 = Colors.unknown; UnknownWords.Add(cleanWord); } if (tempRange == null) //first instance { tempColor = tempColor2; tempRange = wordRange; } else { if (tempColor == tempColor2) //we continue to the next word { int rangeSize = wordRange.Characters.Count; tempRange.MoveEnd(Word.WdUnits.wdCharacter, rangeSize); } else //we highlight the range before { this.AddColoring(tempRange, tempColor); tempRange = wordRange; tempColor = tempColor2; } } } //end for loop of words Globals.ThisAddIn.Application.System.Cursor = Word.WdCursorType.wdCursorNormal; //pointer back to normal //highlight last set of words if (tempRange != null) //in case last word is a punctuation mark { this.AddColoring(tempRange, tempColor); } //remove selected text Globals.ThisAddIn.Application.Selection.Move(); //save range so the next time we highlight, //we can remove highlight on this range prevRange = range; }
/* * Note the THREE places style info can appear: * * <w:sdt> * <w:sdtPr> * <w:rPr> * <w:rStyle w:val="Heading1Char"/> * </w:rPr> * <w:id w:val="968472055"/> * <w:placeholder> * <w:docPart w:val="DefaultPlaceholder_1082065158"/> * </w:placeholder> * <w:showingPlcHdr/> * <w:text/> * </w:sdtPr> * <w:sdtEndPr> * <w:rPr> * <w:rStyle w:val="DefaultParagraphFont"/> * <w:rFonts w:asciiTheme="minorHAnsi" w:eastAsiaTheme="minorEastAsia" w:hAnsiTheme="minorHAnsi" w:cstheme="minorBidi"/> * <w:b w:val="0"/> * <w:bCs w:val="0"/> * <w:color w:val="FF0000"/> * <w:sz w:val="36"/> * <w:szCs w:val="22"/> * </w:rPr> * </w:sdtEndPr> * * <w:sdtContent> * <w:r w:rsidRPr="00616F57"> * <w:rPr> * <w:u w:val="single"/> * </w:rPr> * <w:t>ahhaaaaaaaaaa</w:t> * </w:r> * </w:sdtContent> * * A content control inserted programmatically or via Word 2010 Developer * menu appears to set: * * <w:sdt> * <w:sdtPr> * <w:rPr> * <w:color w:val="FF0000"/> * <w:sz w:val="32"/> * </w:rPr> * <w:id w:val="1015963520"/> * <w:placeholder> * <w:docPart w:val="DefaultPlaceholder_1082065158"/> * </w:placeholder> * <w:text/> * </w:sdtPr> * <w:sdtContent> * <w:proofErr w:type="gramStart"/> * <w:r w:rsidR="00EF4BC6"> * <w:rPr> * <w:color w:val="FF0000"/> * <w:sz w:val="32"/> * </w:rPr> * <w:t>kkk</w:t> * </w:r> * <w:proofErr w:type="gramEnd"/> * </w:sdtContent> * </w:sdt> * * ie not w:sdtEndPr, which cc.set_DefaultTextStyle(ref style) sets * * Tested insertion at : * - first character in paragraph * - last character in paragraph (with and without paragraph mark formatted) * - between 2 differently formatted runs * * The rule seems to be that Word uses the formatting to the left, * except when it is at the beginning, in which case it uses the formatting * of the character to the right. If the character to the right is the * paragraph mark, it will use that. * */ //public Word.ContentControl CopyAdjacentFormat(Word.ContentControl cc, bool foo) // foo arg does nothing, it is just to match delegate signature //{ // return CopyAdjacentFormat(cc); //} public Word.ContentControl CopyAdjacentFormat(Word.ContentControl cc) { //Thread.Sleep(200); object collapseStart = Word.WdCollapseDirection.wdCollapseStart; object collapseEnd = Word.WdCollapseDirection.wdCollapseEnd; object unitCharacter = Word.WdUnits.wdCharacter; Word.Document activeDoc = Globals.ThisAddIn.Application.ActiveDocument; Word.Range leftRange = cc.Range.Duplicate; Word.Range rightRange = cc.Range.Duplicate; Word.Range pRange = activeDoc.Windows[1].Selection.Paragraphs[1].Range; int pStartPos = pRange.Start; object countL = -2; // -1 is not enough leftRange.MoveStart(ref unitCharacter, ref countL); leftRange.Collapse(ref collapseStart); // it is ok for the range to be completely collapsed //leftRange.Text = "@"; if (pStartPos > leftRange.Start) { // Oops, we were at the start of the paragraph, // so use the character to the right log.Info("Applying RIGHT formatting..."); object countR = +1; // -1 is not enough rightRange.MoveEnd(ref unitCharacter, ref countR); rightRange.Collapse(ref collapseEnd); rightRange.Select(); } else { // Usual case log.Info("Applying LEFT formatting..."); leftRange.Select(); } // Now apply the formatting activeDoc.Windows[1].Selection.CopyFormat(); cc.Range.Select(); activeDoc.Windows[1].Selection.PasteFormat(); cc.Application.ScreenUpdating = true; cc.Application.ScreenRefresh(); return(cc); //WORKS ////cc.Range.Font = leftRange.Font; //cc.Range.Bold = 1; //cc.Range.Underline = Word.WdUnderline.wdUnderlineDotDashHeavy; //cc.Range.Italic = 1; // but DOESN'T WORK- NOT CLEAR WHY ////cc.Range.Font = leftRange.Font; //cc.Range.Bold = leftRange.Bold; //cc.Range.Underline = leftRange.Underline; //cc.Range.Italic = leftRange.Italic; //string te = cc.Range.Text; //cc.Range.FormattedText = leftRange.FormattedText; //Tools.PlainTextContentControl pptc = cc as Tools.PlainTextContentControl; }