2015-09-04 16 views
8

Mi piacerebbe conoscere la parola sotto il cursore del mouse in Powerpoint in modo che possa essere utilizzata per uno screen reader. Le soluzioni di accessibilità sono accettabili se possono distinguere tra parole diverse (rispetto a un blocco).Come posso ottenere la parola sotto il cursore del mouse in Powerpoint 2013 usando C#?

+0

Vuoi dire in modalità di modifica quando l'utente ha posizionato il cursore sopra testo e cliccato, in modalità modifica quando l'utente ha spostato il cursore su un testo, in modalità presentazione o ??? In ogni caso, è probabile che sia piuttosto complicato. –

+0

Non necessariamente nella modalità di presentazione, ma durante la modalità di modifica quando l'utente ha posizionato il cursore sul testo (ma non ha fatto clic per accedere alla modifica in modalità ext). – tofutim

+1

L'unico modo in cui posso immaginare che funzioni è quello di ottenere la posizione del cursore e quindi scorrere tutto il testo sulla diapositiva, osservare le proprietà del riquadro di delimitazione per ciascun carattere per determinare se la posizione del cursore si trova all'interno del riquadro di delimitazione. C'è qualche ragione per cui non puoi chiedere all'utente di selezionare prima il testo? Ciò semplificherebbe enormemente le cose. –

risposta

3

Questo è davvero molto difficile, se non sai cosa stai facendo. C'è un modo semplice e un modo difficile per farlo. Un modo semplice sarebbe utilizzare il framework di automazione di Microsoft UI (che include l'automazione Powerpoint). Possono anche essere usati quadri alternativi.

Difficile usare wold api.

Ad esempio: per ottenere il titolo della finestra attualmente sotto il mouse.

public static class dllRef 
    { 
     [DllImport("user32.dll")] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     private static extern bool GetCursorPos(out Point lpPoint); 
     [DllImport("user32.dll")] 
     private static extern IntPtr WindowFromPoint(Point point); 
     [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
     public static extern int RegisterWindowMessage(string lpString); 
     [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] 
     public static extern bool SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam); 
     [DllImport("user32.dll", SetLastError = true)] 
     public static extern IntPtr SendMessage(int hWnd, int Msg, int wparam, int lparam); 

     public const int WM_USER = 0x400; 
     public const int WM_COPYDATA = 0x4A; 
     public const int WM_GETTEXT = 0x000D; 
     public const int WM_GETTEXTLENGTH = 0x000E; 

     public static void RegisterControlforMessages() 
     { 
      RegisterWindowMessage("WM_GETTEXT"); 
     } 

     public static string GetText() 
     { 
      StringBuilder title = new StringBuilder(); 
      Point p = dllRef.getMousePosition(); 
      var lhwnd = dllRef.WindowFromPoint(p); 
      var lTextlen = dllRef.SendMessage((int)lhwnd, dllRef.WM_GETTEXTLENGTH, 0, 0).ToInt32(); 
      if (lTextlen > 0) 
      { 
       title = new StringBuilder(lTextlen + 1); 
       SendMessage(lhwnd, WM_GETTEXT, title.Capacity, title); 
      } 
      return title.ToString(); 
     } 

     public static Point getMousePosition() 
     { 
      Point p = new Point(); 
      GetCursorPos(out p); 
      return p; 
     } 
    } 

e

private void Form1_Load(object sender, EventArgs e) 
    { 
     Timer t = new Timer(); 
     t.Interval = 25; 
     t.Tick += new EventHandler(Timer_Tick); 
     t.Start(); 
    } 
    public void Timer_Tick(object sender, EventArgs eArgs) 
    { 
     this.label1.Text = dllRef.GetText(); 
    } 

Inoltre è possibile utilizzare Microsoft Spy ++

enter image description here

da trovare se informazioni che state cercando è esposto. Altro che posso davvero raccomandare di usare un framework di automazione che è stato costruito su un livello superiore. Google ha più di sufficienti esempi su questo (oltre a come creare sofisticati keylogger).

+0

Mostrami un esempio che tira il testo da Powerpoint e tu vincere – tofutim

+0

E sì, lo so che è davvero difficile - quindi +500 - è necessario farlo su Powerpoint 2015. (Ho versioni precedenti funzionanti ...) – tofutim

+0

Non c'è PowerPoint 2015. Se Windows, puoi avere 2016 (anteprima rilascio), 2013, 2010, 2007 e così via, di nuovo nella notte dei tempi. Se Mac, 2016, 2011, ecc. Quindi, se funziona in alcune versioni, in quale versione non funziona e cosa non funziona esattamente? –

2

Le stesse soluzioni di Margus mi sono venute in mente. O Interoperabilità dell'interfaccia utente o di PowerPoint. Fortunatamente l'automazione dell'interfaccia utente funziona.

Quanto segue funziona nel mio test posizionando il mouse su una casella di testo PowerPoint 2013. Fammi sapere se pensi che manchi qualcosa.

using System.Windows.Automation; 
using UIAutomationClient;  

String TextUnderCursor() 
    { 
     System.Windows.Point point = new System.Windows.Point(Cursor.Position.X, Cursor.Position.Y); 
     AutomationElement element = AutomationElement.FromPoint(point); 
     object patternObj; 
     if (element.TryGetCurrentPattern(TextPattern.Pattern, out patternObj)) 
     { 
      var textPattern = (TextPattern)patternObj; 
      return textPattern.DocumentRange.GetText(-1).TrimEnd('\r'); // often there is an extra '\r' hanging off the end.) 
     } else 
     { 
      return "no text found"; 
     } 
    } 

Aggiornamento Esempiohttp://download.veodin.com/misc/PowerPoint_Screen_Reader.zip

fuoco Visual Studio, mettere il mouse sopra il PowerPoint quindi utilizzare F5 per eseguire il codice

+0

Sembra promettente. Quale riferimento dovrei includere per "UIAutomationClient"? Esiste una DLL UIAutomationClient, ma contiene solo System.Windows.Automation. (.NET 4.5) - oops, immagino che non sia davvero necessario. – tofutim

+0

Quindi è ancora una domanda? Ho fatto riferimento a UIAutomationClient, UIAutomationTypes e WindowsBase. – Cilvic

+0

Non so come sia stato possibile ottenere "usando UIAutomationClient" ma l'ho appena estratto. In questo momento sono bloccato con "Non è possibile effettuare una chiamata in uscita poiché l'applicazione sta inviando una chiamata sincrona in ingresso". probabilmente a causa di come sto facendo la chiamata ... – tofutim

Problemi correlati