2015-09-12 9 views
7

Il codice funziona per Word e Outlook ma non riesce con PowerPoint in quanto solo il primo carattere o prima parola della casella di testo viene sempre selezionato. è un insetto? C'è qualche soluzione? Prova questo su un semplice diapositiva di PowerPoint in PowerPoint 2013.Quando provo a utilizzare UI Automation per PowerPoint 2013, posso solo ottenere il primo carattere/parola quando utilizzo RangeFromPoint

private static async Task<string> getText(double x, double y) 
{ 
    string result = null; 

    try 
    { 
     var location = new System.Windows.Point(x, y); 
     AutomationElement element = AutomationElement.FromPoint(location); 

     object patternObj; 
     if (element.TryGetCurrentPattern(TextPattern.Pattern, out patternObj)) 
     { 
      var textPattern = (TextPattern)patternObj; 

      var range = textPattern.RangeFromPoint(location); 
      range.ExpandToEnclosingUnit(TextUnit.Word); 
      range.Select(); 

      var text = range.GetText(-1).TrimEnd('\r'); 
      return text.Trim(); 
     } 
     else 
     { 
      return "no text found"; 
     } 
    } 
    catch (Exception ex) 
    { 
     return ex.Message; 
    } 
} 

Non può vedere dallo screenshot, ma il mouse è in "prima" non "bloccata", ma indipendentemente da dove il mouse è posizionato, sempre è bloccato. Forse questo è stato risolto in PowerPoint 2016?

enter image description here

Quando guardo il rettangolo di selezione per la gamma è sempre l'intero elemento, piuttosto che la parola selezionata. Questo potrebbe essere parte del problema del perché RangeToPoint non funziona.

originale pubblicato in MSDN ma nessuna risposta ...

Update. Se uso

text = printRange(range, text); 
while (range.Move(TextUnit.Word, 1) > 0) 
{ 
    text += Environment.NewLine; 
    text = printRange(range, text); 
} 

ottengo

enter image description here

+0

Perché non utilizzare l'interfaccia COM di Power Point? Puoi accedervi come oggetto 'PowerPoint.Application'. Ogni prodotto MS Office ha un ottimo modello di oggetto disponibile come interfaccia COM. –

+0

Non ho tempo per scrivere il codice C#, ma in Python potrei ottenere del testo così: 'pp.Presentations [0] .Slides [8] .Shapes [0] .TextFrame.TextRange.Text' (didascalia della 9a diapositiva) . –

+0

Dove 'pp' è un'istanza di' PowerPoint.Application'. –

risposta

3

Questo comportamento è probabilmente dovuto ad una limitazione in PowerPoint 2013, e mi aspetto che non si può lavorare intorno ad esso utilizzando UIA. Quando chiamate RangeFromPoint(), il provider UIA viene colpito sotto il mouse (ovvero quello che sta implementando IUIAutomationTextPattern :: RangeFromPoint(),) ha lo scopo di restituire un intervallo degenerativo (cioè vuoto) in cui si trova il cursore del mouse. Quindi il client UIA può espandere l'intervallo restituito per ottenere il carattere, la parola, la linea o il paragrafo circostanti.

Tuttavia, come si fa notare, PowerPoint 2013 non lo fa. Ho appena scritto il codice di prova qui sotto (utilizzando un wrapper gestito per l'API UIA Windows nativa generata da tlbimp.exe) e ho scoperto che PowerPoint restituisce apparentemente un TextRange per l'intera casella di testo sotto il cursore. Quando ho eseguito il codice, ho scoperto che ho ottenuto la parola prevista sotto il cursore in WordPad, Word 2013 e PowerPoint OnLine, ma non in PowerPoint 2013. Ho ottenuto gli stessi risultati quando ho eseguito lo strumento Text Explorer che fa parte di Inspect SDK strumento. L'immagine sotto mostra Text Explorer che segnala che il testo restituito da PowerPoint 2013 è l'intero testo nella casella di testo, quando il mouse passa con il mouse su una di quelle parole.

(Devo aggiungere che per il codice di prova riportato di seguito non funziona affatto, penso che l'attuale impostazione di ridimensionamento dello schermo debba essere al 100% .Non ho aggiunto il codice per tenere in considerazione l'attivazione di altri ridimensionamenti.)

Non so se questo problema è stato risolto in PowerPoint 2016, proverò a esaminarlo e a farvi sapere.

Grazie,

Guy

enter image description here

private void buttonGetTheText_Click(object sender, EventArgs e) 
{ 
    labelText.Text = "No text found."; 

    IUIAutomation uiAutomation = new CUIAutomation8(); 

    Point ptCursor = Cursor.Position; 

    tagPOINT pt; 
    pt.x = ptCursor.X; 
    pt.y = ptCursor.Y; 

    // Cache the Text pattern that's available through the element beneath 
    // the mouse cursor, (if the Text pattern's supported by the element,) in 
    // order to avoid another cross-process call to get the pattern later. 
    int patternIdText = 10014; // UIA_TextPatternId 
    IUIAutomationCacheRequest cacheRequestTextPattern = 
     uiAutomation.CreateCacheRequest(); 
    cacheRequestTextPattern.AddPattern(patternIdText); 

    // Now get the element beneath the mouse. 
    IUIAutomationElement element = 
     uiAutomation.ElementFromPointBuildCache(pt, cacheRequestTextPattern); 

    // Does the element support the Text pattern? 
    IUIAutomationTextPattern textPattern = 
     element.GetCachedPattern(patternIdText); 
    if (textPattern != null) 
    { 
     // Now get the degenerative TextRange where the mouse is. 
     IUIAutomationTextRange range = textPattern.RangeFromPoint(pt); 
     if (range != null) 
     { 
      // Expand the range to include the word surrounding 
      // the point where the mouse is. 
      range.ExpandToEnclosingUnit(TextUnit.TextUnit_Word); 

      // Show the word in the test app. 
      labelText.Text = "Text is: \"" + range.GetText(256) + "\""; 
     } 
    } 
} 
+0

Grazie per aver esaminato questo ragazzo. Qualche possibilità di rintracciare qualcuno in Microsoft che può risolvere o offrire una soluzione alternativa? – tofutim

+0

Vedrò se riesco a scoprire qualcosa di più su questo, e farti sapere. Ho installato l'anteprima di Office 2016 stamattina e ho indirizzato l'Explorer di testo di Inspect a PowerPoint 2016, e mi è sembrato comportarsi allo stesso modo di PowerPoint 2013. Cioè, quando provo a trovare l'intervallo di testo sotto il cursore del mouse, PowerPoint restituisce il intero testo per la casella di testo sotto il cursore, piuttosto che l'intervallo degenerativo nel punto in cui si trova il cursore. –

+0

Grazie per averlo testato per me. Qualsiasi aiuto sarebbe molto apprezzato. – tofutim

0

Posso solo suggerire codice Python ricevendo testo della didascalia della slitta (per esempio). Scusa, non ho tempo per riscriverlo su C#. È possibile giocare con l'oggetto COM PowerPoint.Application e MSDN example of Power Point automation.

from __future__ import print_function 
import win32com.client as com 
pp = com.Dispatch('PowerPoint.Application') 
print(pp.Presentations[0].Slides[8].Shapes[0].TextFrame.TextRange.Text) 
Problemi correlati