C# 获取活动窗口文本(并向其发送更多文本)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/479548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get active window text (and send more text to it)
提问by Einar Egilsson
I'm creating a small utility in C#, that will add some text to an active textbox when a global hotkey is pressed, it's a type of auto complete function. I have my global hotkey working, but now I don't know how to get the current text in the active textbox (if the active window is a textbox that is.) What I've tried so far is to use
我正在用 C# 创建一个小实用程序,它会在按下全局热键时向活动文本框添加一些文本,这是一种自动完成功能。我有我的全局热键工作,但现在我不知道如何在活动文本框中获取当前文本(如果活动窗口是一个文本框。)到目前为止我尝试过的是使用
a. GetForegroundWindow and then using that handle calling GetWindowText. This gave me the window title of the active window, not the textbox contents.
一种。GetForegroundWindow 然后使用该句柄调用 GetWindowText。这给了我活动窗口的窗口标题,而不是文本框内容。
b. GetActiveWindow and using that handle to call GetWindowText. That gives me no text at all.
湾 GetActiveWindow 并使用该句柄调用 GetWindowText。这根本没有给我任何文字。
Here's an example of what I've done
这是我所做的一个例子
[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());
}
So, any ideas on how to achieve this?
那么,关于如何实现这一目标的任何想法?
Edit 28.01.2009:So, I found out how to do this. This is what I used:
28.01.2009 编辑:所以,我发现了如何做到这一点。这是我使用的:
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();
}
}
Some notes about this. The example waits for 5 seconds before doing anything, giving you the chance to give focus to some edit window. In my real app I'm using a hotkey to trigger this, but that would just confuse this example. Also, in production code you should check the return values of the win32 calls to see if they succeeded or not.
关于这个的一些注意事项。该示例在执行任何操作之前等待 5 秒,让您有机会将焦点放在某个编辑窗口上。在我的真实应用程序中,我使用热键来触发这个,但这只会混淆这个例子。此外,在生产代码中,您应该检查 win32 调用的返回值以查看它们是否成功。
回答by sinm
It's reasonable to send keystrokes if you aware of active window and focused input field. See http://www.pinvoke.net/default.aspx/user32/keybd_event.htmlfor API.
如果您知道活动窗口和焦点输入字段,则发送击键是合理的。API见http://www.pinvoke.net/default.aspx/user32/keybd_event.html。
回答by lakshmanaraj
Please check, even em_replacesel message may not work across different process, You might need to use WM_COPYDATA or by calling window procedure as given in the url,
请检查,即使 em_replacesel 消息可能无法在不同的进程中工作,您可能需要使用 WM_COPYDATA 或通过调用 url 中给出的窗口过程,