C#问题用我当前的Word Word文字选择方法 [英] C# Problem With My Current Word by Word text Selection Method

查看:110
本文介绍了C#问题用我当前的Word Word文字选择方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hello Everyone!

BillWoodruff给了我这个方法将文本框的文本拆分成数组,这有助于帮助我根据TTS操作说话的内容逐字逐句突出显示文本框中的文本。请参阅我的上一篇文章问题。

现在我能够实现他的建议:



这在我开始演讲之前运行

Hello Everyone!
BillWoodruff gave me this method to break up the text of a text box into an array, this was to aid in helping me to highlight text in the textbox word by word based on what a TTS operation was speaking. please refer to my previous post on this question.
now i was able to implement his suggestions like so:

this runs right before i start the Speech operation

//this runs right before i start the Speech operation
// split the RTB Text
theWords = TextToSpeak.Split(splitChar, StringSplitOptions.RemoveEmptyEntries);
// number of words
nWords = theWords.Length;

// location pointer
location = 0;

// build the List of word locations
foreach (string word in theWords)
{
    theWordsLocations.Add(new Point(location, word.Length));
    location += word.Length + 1;
}

// location pointer
location = 0;



接下来只要在TTS操作运行时说出一个单词,就会运行:(这是在SpeakProgress事件方法中)


next whenever a word is spoken when the TTS operation is running, this runs:(this is in the SpeakProgress event method)

private void synth_SpeakProgress(object sender, SpeakProgressEventArgs e)
{
    if (currentWord == 0)
    {
        currentSelection = new Point(location, theWords[currentWord].Length);
        oldlocation = location;
        location = theWords[currentWord + 1].Length;
    }
    else
    {
        if (currentWord + 1 == theWords.Length)
        {
            previousSelection = new Point(oldlocation, theWords[currentWord - 1].Length);
            currentSelection = new Point(location, theWords[currentWord].Length);
            oldlocation = location;
            location = theWords[currentWord].Length;
        }
        else
        {
            previousSelection = new Point(oldlocation, theWords[currentWord - 1].Length);
            currentSelection = new Point(location, theWords[currentWord + 1].Length);
            oldlocation = location;
            location = theWords[currentWord + 1].Length;
        }


    }

    currentWord += 1;
}





现在当我想在我的文本框中选择一些东西我就这样做(这是因为我正在使用计时器,所以每100到1毫秒运行一次):

仅供参考,ThreadOperation对象是我的ManualThread类的一个实例。如果需要,我可以发布这个课程。



now when i want to select something in my text box i just do this(this is being ran every 100 to 1 milliseconds because i am using a timer):
and just for reference the ThreadOperation object is an instance of my "ManualThread" class. if need be i can post this class.

private void ThreadTimer_Tick(object sender, EventArgs e)
{
    if (ThreadOperation.currentSelection == null)
    {

    }
    else
    {
        TB.Select(ThreadOperation.currentSelection.X, ThreadOperation.currentSelection.Y);
        TB.SelectionColor = Color.Black;
        TB.SelectionBackColor = Color.White;

        TB.Select(ThreadOperation.previousSelection.X, ThreadOperation.previousSelection.Y);
        TB.SelectionColor = Color.White;
        TB.SelectionBackColor = Color.FromArgb(255, 51, 153, 255);
    }
    //TB.Text = ThreadOperation.CharPos.ToString();
    txtSpoken.Text = ThreadOperation.LastTextSpoken;

}



现在我的问题是关于synth_SpeakProgress方法。

抱歉,如果这看起来很复杂:

当我运行此设置时,系统不会只选择TTS opp(我只是缩写操作,我厌倦了写这个词)这个词,而是它可能会选择当前说出的单词前面的空格,先前说出的单词或当前说出的单词后面的空格。

i已经彻底使用了Visual Studio调试器,我已经将问题追溯到当我访问theWords数组时出现数学错误。

无论我对此方法做了多少更改(即synth_SpeakProgress方法),我都无法做到正确。可以有人帮助我吗?

感谢您提前的帮助,

MasterCodeon


now my question is about the synth_SpeakProgress method.
sorry if this seems complicated:
when ever i run this setup the system does't select just the word that the TTS opp(i just abbreviated operation, i am getting tired of writing that word) is speaking, but instead it might select either the space in front of the currently spoken word, the previously spoken word or the space behind the currently spoken word.
i have made thorough use of the Visual Studio debugger and i have traced the problem down to being a math error when i am accessing the "theWords" array.
no matter how many changes i have made to this method(that being the synth_SpeakProgress method) i just can't get it right. can some one help me out here?
thanks for your help in advance,
MasterCodeon

推荐答案

For每个不知道如何使用语音合成器实现此功能的人,请执行以下操作:

步骤1:

添加对System.Speech名称空间的引用,如下所示:

右键单击references文件夹并单击添加引用...

然后会弹出一个窗口,单击.NET选项卡然后滚动在列表中,直到找到名为System.Speech的条目。选择它并单击确定按钮



步骤2:

将以下内容添加到winform应用程序代码的顶部(我们正在添加对System.Speech.Synthesis命名空间的引用)

For everyone who doesn't know how to implement this with a speech synthesizer, do as follows:
Step 1:
add a reference to the System.Speech Name space like this:
Right click on the references folder and click "Add Reference..."
then a window should pop up, click the tab that says ".NET" then scroll down the list until you find the entry named System.Speech. select it and click the "Ok" button

Step 2:
add the following to the the top of your winform app code(we are adding a reference to the System.Speech.Synthesis namespace)
using System.Speech.Synthesis;



第3步:在apps constructer(在课堂级别)正上方添加:


Step 3: right above the apps constructer(at the class level) add this:

// Initialize a new instance of the SpeechSynthesizer.
SpeechSynthesizer synth = new SpeechSynthesizer();

//Add The "SpeakProgress" Event Handler
synth.SpeakProgress += new EventHandler<speakprogresseventargs>(synth_SpeakProgress);

//Add The "SpeakCompleted" Event Handler
synth.SpeakCompleted += new EventHandler<speakcompletedeventargs>(SpeakOperationCompleted);
</speakcompletedeventargs></speakprogresseventargs>



步骤4:现在添加此方法:


Step 4: now add this method:

#region SpeakProgress
private void synth_SpeakProgress(object sender, SpeakProgressEventArgs e)
{
    if (currentWord == theWordsLocations.Count)
    {
        WhateverTheNameOfYourTextBox.SelectionColor = previousSelectionForeColor;
        WhateverTheNameOfYourTextBox.SelectionBackColor = previousSelectionBackColor;
    }
    else
    {
        // get current selection locations
        previousSelection = new Point(TB.SelectionStart, TB.SelectionLength);

        // reset the previous word's state Colors
        if (previousSelection != Point.Empty)
        {
            WhateverTheNameOfYourTextBox.SelectionColor = previousSelectionForeColor;
            WhateverTheNameOfYourTextBox.SelectionBackColor = previousSelectionBackColor;
        }

        // save the current Selection state Colors
        previousSelectionForeColor = TB.SelectionColor;
        previousSelectionBackColor = TB.SelectionBackColor;

        // get the location of the next word
        var location = theWordsLocations[currentWord];

        // select it
        WhateverTheNameOfYourTextBox.Select(location.X, location.Y);

        // highlight it
        WhateverTheNameOfYourTextBox.SelectionColor = HighLightForeColor;
        WhateverTheNameOfYourTextBox.SelectionBackColor = HighLightBackColor;

        // finished ?
        if (currentWord == nWords)
        {
            WhateverTheNameOfYourTextBox.SelectionColor = previousSelectionForeColor;
            WhateverTheNameOfYourTextBox.SelectionBackColor = previousSelectionBackColor;
        }

        // move on
        currentWord++;
    }
}



步骤5:现在将SpeakOperationCompleted方法添加到您的代码中


Step 5: now add the this "SpeakOperationCompleted" method to your code

#region Speak Operation Completed
public void SpeakOperationCompleted(object sender, SpeakCompletedEventArgs e)
{
    WhateverTheNameOfYourTextBox.ReadOnly = false;
    WhateverTheNameOfYourTextBox.SelectAll();
    WhateverTheNameOfYourTextBox.SelectionColor = previousSelectionForeColor;
    WhateverTheNameOfYourTextBox.SelectionBackColor = previousSelectionBackColor;
}
#endregion





步骤5:将此方法添加到您的代码中(这是将被调用以实际说出您指定的文本的方法):



Step 5: add this method to your code(this is the method that will be called to actually speak the text you specify):

public void SpeakSynthText(String TextToSpeak)
{
    #region SpeechSynth
    //Set The Audio Output Device To The Defualt Output Device
    synth.SetOutputToDefaultAudioDevice();

    // Select a voice that matches a specific gender.  
    synth.SelectVoiceByHints(VoiceGender.Female);

    // Speak The Text Asynchronously And If Wave Save Is Enable Play Back The Wave File.            
    synth.SpeakAsync(TextToSpeak);
    #endregion
}





步骤6:现在向表单添加一个按钮,双击它并粘贴以下代码:



Step 6: now add a button to the form, double click on it and paste the following code:

public void SpeakText_Click_1(object sender, EventArgs e)
{
    //Make Sure The User Can't Edit The Text That Is Going To Be Spoken
    TB.ReadOnly = true;

    //Clear The text Selector Variables
    nWords = 0;
    theWords.Clear();
    theWordsLocations.Clear();
    loc = 0;

    //Text Selector Starts Here
    theWords = TB.Text.Split(splitChar, StringSplitOptions.RemoveEmptyEntries).ToList();

    nWords = theWords.Count;

    foreach (var word in theWords)
    {
        theWordsLocations.Add(new Point(loc, word.Length));
        loc += word.Length + 1;
    }

    currentWord = 0;
    //The synth_SpeakProgress Method Will Do The Actual Text Selection
    //End Text Selector            

    //Speak The Contents Of The RichTextBox "WhateverTheNameOfYourTextBox"
    SpeakSynthText(WhateverTheNameOfYourTextBox.Text);
}
#endregion





,你有它!

只需键入你想要的语音Synth Say,然后点击你添加到表单的按钮并观看文本框,因为它会突出显示正在说的当前单词通过TTS引擎。

如果这对您不起作用或您有任何疑问,请在本文的评论中说明问题或疑问。

所有信用卡文本选择的想法去了BillWoodruff。

非常感谢Bill!

MasterCodeon



and there you have it!
just type whatever you want to have the Speech Synth Say and click the button you added to the form and watch the text box as it will highlight the current word being spoken by the TTS engine.
if this doesn't work for you or you have any questions please state the problem or question in the comments of this post.
all credit for the text selection idea goes to BillWoodruff.
Thank you soo much Bill!
MasterCodeon


这是我用来测试的完整代码我之前发布的内容;我怀疑它可以简化,因为我写得很快:
Here's the complete code I used to test what I previously posted; I suspect it can be simplified since I wrote it quickly:
Controls used:
    Form Form1
    RichTextBox richTextBox1
    Button btnHighLightWords
    System.Windows.Forms.Timer timer1<

代码:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace RTFWordByWord
{
    public partial class Form1 : Form
    {
        private readonly List<point> theWordsLocations = new List<point>();

        private List<string> theWords = new List<string>();

        private readonly Color HighLightBackColor = Color.Navy;
        private readonly Color HighLightForeColor = Color.Yellow;
        private Color previousSelectionBackColor;
        private Color previousSelectionForeColor;

        private Point previousSelection;

        private int currentWord;
        private int nWords;

        private readonly char[] splitChar = { ' ', '\n' };

        private string theText;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            theWords = richTextBox1.Text.Split(splitChar, StringSplitOptions.RemoveEmptyEntries).ToList();

            nWords = theWords.Count;

            var location = 0;

            foreach (var word in theWords)
            {
                theWordsLocations.Add(new Point(location, word.Length));
                location += word.Length + 1;
            }
        }

        private void btnHighLightWords_Click(object sender, EventArgs e)
        {
            currentWord = 0;
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            // get current selection locations
            previousSelection = new Point(richTextBox1.SelectionStart, richTextBox1.SelectionLength);

            // reset the previous word's state Colors
            if (previousSelection != Point.Empty)
            {
                richTextBox1.SelectionColor = previousSelectionForeColor;
                richTextBox1.SelectionBackColor = previousSelectionBackColor;
            }

            // save the current Selection state Colors
            previousSelectionForeColor = richTextBox1.SelectionColor;
            previousSelectionBackColor = richTextBox1.SelectionBackColor;

            // get the location of the next word
            var location = theWordsLocations[currentWord];

            // select it
            richTextBox1.Select(location.X, location.Y);

            // highlight it
            richTextBox1.SelectionColor = HighLightForeColor;
            richTextBox1.SelectionBackColor = HighLightBackColor;

            // finished ?
            if (currentWord == nWords) timer1.Stop();

            // move on
            currentWord++;
        }
    }
}


这篇关于C#问题用我当前的Word Word文字选择方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆