2009-01-26 7 views
12

Je crée un petit utilitaire en C#, qui ajoutera du texte à une zone de texte active quand un raccourci global est pressé, c'est un type de fonction auto complète. J'ai mon hotkey global fonctionnant, mais maintenant je ne sais pas comment obtenir le texte actuel dans la zone active (si la fenêtre active est une zone de texte qui est.) Ce que j'ai essayé jusqu'ici est d'utiliserObtenir le texte de la fenêtre active (et lui envoyer plus de texte)

une. GetForegroundWindow, puis en utilisant ce handle appelant GetWindowText. Cela m'a donné le titre de la fenêtre de la fenêtre active, pas le contenu de la zone de texte.

b. GetActiveWindow et en utilisant ce handle pour appeler GetWindowText. Cela ne me donne aucun texte.

Voici un exemple de ce que je l'ai fait

[DllImport("user32.dll")] 
private static extern bool UnregisterHotKey(IntPtr hWnd, int id); 
[ DllImport("user32.dll") ] 
static extern int GetForegroundWindow(); 
[ DllImport("user32.dll") ] 
static extern int GetWindowText(int hWnd, StringBuilder text, int count); 
[DllImport("user32.dll")] 
static extern int GetActiveWindow(); 

public static void TestA() { 
    int h = GetForegroundWindow(); 
    StringBuilder b = new StringBuilder(); 
    GetWindowText(h, b, 256); 
    MessageBox.Show(b.ToString()); 
} 

public static void TestB() { 
    int h = GetActiveWindow(); 
    StringBuilder b = new StringBuilder(); 
    GetWindowText(h, b, 256); 
    MessageBox.Show(b.ToString()); 
} 

Alors, des idées sur la façon d'y parvenir?

Modifier 28.01.2009: Ainsi, j'ai découvert comment faire ceci. Voici ce que je:

using System; 
using System.Text; 
using System.Runtime.InteropServices; 

public class Example 
{ 
[DllImport("user32.dll")] 
static extern int GetFocus(); 

[DllImport("user32.dll")] 
static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach); 

[DllImport("kernel32.dll")] 
static extern uint GetCurrentThreadId(); 

[DllImport("user32.dll")] 
static extern uint GetWindowThreadProcessId(int hWnd, int ProcessId);  

[DllImport("user32.dll") ] 
static extern int GetForegroundWindow(); 

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] 
static extern int SendMessage(int hWnd, int Msg, int wParam, StringBuilder lParam); 

const int WM_SETTEXT = 12; 
const int WM_GETTEXT = 13; 

public static void Main() 
{ 
    //Wait 5 seconds to give us a chance to give focus to some edit window, 
    //notepad for example 
    System.Threading.Thread.Sleep(5000); 
    StringBuilder builder = new StringBuilder(500); 

    int foregroundWindowHandle = GetForegroundWindow(); 
    uint remoteThreadId = GetWindowThreadProcessId(foregroundWindowHandle, 0); 
    uint currentThreadId = GetCurrentThreadId(); 

    //AttachTrheadInput is needed so we can get the handle of a focused window in another app 
    AttachThreadInput(remoteThreadId, currentThreadId, true); 
    //Get the handle of a focused window 
    int focused = GetFocus(); 
    //Now detach since we got the focused handle 
    AttachThreadInput(remoteThreadId, currentThreadId, false); 

    //Get the text from the active window into the stringbuilder 
    SendMessage(focused, WM_GETTEXT, builder.Capacity, builder); 
    Console.WriteLine("Text in active window was " + builder); 
    builder.Append(" Extra text"); 
    //Change the text in the active window 
    SendMessage(focused, WM_SETTEXT, 0, builder); 
    Console.ReadKey(); 
    } 
} 

Quelques notes à ce sujet. L'exemple attend 5 secondes avant de faire quoi que ce soit, ce qui vous donne la possibilité de vous concentrer sur une fenêtre d'édition. Dans ma vraie application, j'utilise un raccourci clavier pour déclencher cela, mais cela ne ferait que compliquer cet exemple. En outre, dans le code de production, vous devez vérifier les valeurs de retour des appels win32 pour voir s'ils ont réussi ou non.

Répondre

Questions connexes