グローバルホットキーが押されたときにアクティブなテキストボックスにテキストを追加するC#で小さなユーティリティを作成しています。これはオートコンプリート機能の一種です。グローバルホットキーは機能していますが、現在のテキストをアクティブなテキストボックスに取得する方法がわかりません (アクティブなウィンドウがテキストボックスの場合)。
を。GetForegroundWindow を取得し、そのハンドルを使用して GetWindowText を呼び出します。これにより、テキストボックスの内容ではなく、アクティブなウィンドウのウィンドウタイトルが得られました。
b. GetActiveWindow を取得し、そのハンドルを使用して GetWindowText を呼び出します。それは私にテキストをまったく与えません。
これが私がやったことの例です
[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());
}
それで、これを達成する方法についてのアイデアはありますか?
編集 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();
}
}
これに関するいくつかのメモ。この例では、何かを実行する前に 5 秒間待機し、編集ウィンドウにフォーカスを移す機会を与えています。私の実際のアプリでは、これをトリガーするためにホットキーを使用していますが、それはこの例を混乱させるだけです. また、製品コードでは、win32 呼び出しの戻り値をチェックして、成功したかどうかを確認する必要があります。