2010-01-22 6 views
5

Desidero impostare una determinata finestra, da un'app esterna (ad esempio textedit), in primo piano.Impostazione della finestra più frontale utilizzando l'API di accessibilità

Posso ottenere correttamente un riferimento all'app stessa utilizzando GetFrontProcess e verificare se è frontalmente la maggior parte. Se non lo è, posso usare setFrontProcess per renderlo focalizzato.

Posso quindi utilizzare l'API di accessibilità per esaminare tutte le finestre in tale applicazione. Sto controllando l'esistenza di una determinata finestra, e in tal caso la paragono contro il fronte più finestra dell'applicazione:

//get the front window of textEditApp and store it in 'currentFrontWindow' 
    AXUIElementCopyAttributeValue(textEditApp, kAXFocusedWindowAttribute, (CFTypeRef *)&currentFrontWindow); 

Se la finestra mi interessa non è in primo piano, ho bisogno di impostarlo in modo. Ho pensato che potrei usare AXUIElement Set AttributeValue per fare questo, ma non sto ottenendo alcun successo. Di seguito è riportato come ho provato a farlo.

//set the front window of textEditApp to be desiredFrontWindow 
AXUIElementSetAttributeValue(textEditApp, kAXFocusedUIElementAttribute, desiredFrontWindow); 

Ho verificato che la finestra esista e che l'applicazione sia 'passata a' con successo. Ma perché questa linea di codice non porta in primo piano la finestra specificata?

Grazie.

risposta

8

Ma perché questa riga di codice non porta in primo piano la finestra specificata?

Perché si è tentato di impostare un attributo di sola lettura.

Per rendere una finestra in primo piano, è necessario impostare la proprietà appropriata della finestra. Lo stesso vale per un'applicazione: per rendere un'applicazione in primo piano, è necessario impostare la proprietà appropriata dell'applicazione.

Il nome Cocoa/Mac OS X per la finestra in primo piano è "la finestra principale". (Vedere, ad esempio, NSApplication's e NSWindow's methods relativi a tale concetto.) Accessibilità utilizza lo stesso nome, quindi per rendere una finestra singola in primo piano, impostare il valore di kAXMainAttribute su kCFBooleanTrue.

Il modo per rendere l'applicazione in primo piano è simile: impostare il valore di kAXFrontmostAttribute su kCFBooleanTrue. Sarà necessario eseguire entrambe le operazioni per impostare la finestra in primo piano dell'applicazione e rendere l'applicazione attiva.

Per quanto posso dire, non c'è modo di portare solo una singola finestra di un'applicazione in primo piano e dargli fuoco di sessione.

+0

Grazie (ancora una volta) Peter - questo funziona un fascino. Per quanto riguarda l'applicazione, sto usando setFrontProcess piuttosto che kAXFrontMostAttribute - è una cattiva idea? Avendo navigato la mia strada attraverso l'applicazione e la finestra, c'è un certo AXUIElementRef che mi interessa portarlo in primo piano (cioè dandogli il focus sulla tastiera). Posso seppellire attraverso gli strati di elementi per ottenere un riferimento ad esso, ma come faccio a metterlo a fuoco? Esiste un equivalente di kAXMainAttribute per gli elementi? Forse dovrei postare (ancora) un altro Q. –

1

Recentemente ho scoperto che, se non ti dispiace un po 'di Carbonio, puoi usare SetFrontProcessWithOptions per portare una finestra in primo piano e dargli fuoco se passi kSetFrontProcessFrontWindowOnly come secondo argomento.

2

Sono riuscito a farlo in un'app I worked on portando l'applicazione in primo piano, quindi portando una singola finestra in primo piano.

Prima portando l'applicazione alla parte anteriore:

let currentPid = NSRunningApplication.currentApplication().processIdentifier 
if let pid = (the pid of the app in question) where pid != currentPid { 
    NSRunningApplication(processIdentifier: pid)?.activateWithOptions(.ActivateIgnoringOtherApps) 
} 

Poi l'invio della finestra in primo piano:

let window = (window AXUIElement) 
AXUIElementSetAttributeValue(window, NSAccessibilityMainAttribute, true) 
+1

Works for me. Grazie. –