2009-01-26 46 views
12

Tôi đang tạo một tiện ích nhỏ trong C#, sẽ thêm một số văn bản vào một hộp văn bản đang hoạt động khi nhấn phím nóng toàn cục, đó là một loại chức năng tự động hoàn thành. Tôi có phím nóng toàn cầu của tôi làm việc, nhưng bây giờ tôi không biết làm thế nào để có được văn bản hiện tại trong hộp văn bản hoạt động (nếu cửa sổ đang hoạt động là một hộp văn bản đó là.) Những gì tôi đã cố gắng cho đến nay là sử dụngNhận văn bản cửa sổ đang hoạt động (và gửi nhiều văn bản hơn)

a. GetForegroundWindow và sau đó sử dụng xử lý đó gọi GetWindowText. Điều này đã cho tôi tiêu đề cửa sổ của cửa sổ hiện hoạt, không phải là nội dung của hộp văn bản.

b. GetActiveWindow và sử dụng tay cầm đó để gọi GetWindowText. Điều đó mang lại cho tôi không có văn bản nào cả.

Dưới đây là một ví dụ về những gì tôi đã làm

[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()); 
} 

Vì vậy, bất kỳ ý tưởng về làm thế nào để đạt được điều này?

Chỉnh sửa 28.01.2009: Vì vậy, tôi đã tìm hiểu cách thực hiện việc này. Đây là những gì tôi đã sử dụng:

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(); 
    } 
} 

Một số lưu ý về điều này. Ví dụ chờ 5 giây trước khi làm bất cứ điều gì, cho bạn cơ hội để tập trung vào một số cửa sổ chỉnh sửa. Trong ứng dụng thực sự của tôi, tôi đang sử dụng một phím nóng để kích hoạt điều này, nhưng điều đó sẽ gây nhầm lẫn cho ví dụ này. Ngoài ra, trong mã sản xuất, bạn nên kiểm tra giá trị trả về của cuộc gọi win32 để xem họ có thành công hay không.

Trả lời

Các vấn đề liên quan