Если ваше целевое приложение не является окном переднего плана, вам необходимо использовать PostMessage
для отправки нажатий клавиш дескриптору окна. Вы можете получить этот дескриптор окна, используя FindWindow
. Приведенный ниже код отправляет клавишу Enter в текстовую область запущенного экземпляра Блокнота (обратите внимание, что он использует дополнительный FindWindowEx
, чтобы сначала найти область заметок). Он был протестирован с использованием Delphi 2007 и Delphi XE4 (32-разрядная цель) в Windows 7 64.
uses Windows;
procedure TForm1.Button1Click(Sender: TObject);
var
NpWnd, NpEdit: HWnd;
begin
NpWnd := FindWindow('Notepad', nil);
if NpWnd <> 0 then
begin
NpEdit := FindWindowEx(NpWnd, 0, 'Edit', nil);
if NpEdit <> 0 then
begin
PostMessage(NpEdit, WM_KEYDOWN, VK_RETURN, 0);
PostMessage(NpEdit, WM_KEYUP, VK_RETURN, 0);
end;
end;
end;
Чтобы найти окно по заголовку (заголовку), вы можете просто использовать второй параметр FindWindow
. Это находит новый экземпляр Блокнота с открытым файлом «Без названия» по умолчанию:
NpWnd := FindWindow(nil, 'Untitled - Notepad');
Обратите внимание, что для этого требуется точное совпадение с заголовком окна. Дополнительный пробел перед или после -
, например, приведет к сбою сопоставления и невозможности получения дескриптора окна.
Вы можете использовать как класс окна, так и заголовок, если у вас запущено несколько экземпляров. Чтобы найти копию Блокнота, работающую с загруженным Readme.txt
, вы должны использовать
NpWnd := FindWindow('Notepad', 'Readme.txt - Notepad');
Чтобы найти другие приложения, вам нужно будет использовать что-то вроде WinSpy или WinSight, чтобы найти имена оконных классов. (Есть и другие, такие как Wspawn или WinDowse (оба написаны на Delphi).)
В вашем комментарии упоминается Calculator
; Согласно Wинспекции, главное окно Calculator
относится к классу окна, называемому CalcFrame
в Windows 7, а область, в которой отображаются числа, представляет собой окно Static
(это означает, что оно, похоже, не получает нажатия клавиш напрямую). Кнопки называются просто Button
, поэтому вам придется перебирать их, используя EnumChildWindows
ищет отдельные кнопки, чтобы идентифицировать их, чтобы получить их дескрипторы.
(Как перечислить дочерние окна — это отдельный вопрос; вы, вероятно, можете найти пример, выполнив поиск здесь или через Google. Если вы не можете, опубликуйте новый отдельный вопрос об этом, и мы можем попытаться дать вам ответ.)
Вот краткий пример отправки ключей в Калькулятор после его нахождения по классу окна. Он не делает ничего полезного, потому что ему нужно некоторое время, чтобы определить различные кнопки и клавиши, на которые каждая из них реагирует (и правильную комбинацию сообщений). Этот код просто отправляет 11Numpad+22 в окно калькулятора (a быстрый тест показал, что они правильно принимаются и отображаются, и это примерно все время, которое я хотел потратить на процесс).
uses Windows;
procedure TForm1.Button1Click(Sender: TObject);
var
NpWnd: HWnd;
begin
NpWnd := FindWindow('CalcFrame', nil);
if NpWnd <> 0 then
begin
PostMessage(NpWnd, WM_KEYDOWN, VK_NUMPAD1, 0);
PostMessage(NpWnd, WM_KEYDOWN, VK_ADD, 0);
PostMessage(NpWnd, WM_KEYDOWN, VK_NUMPAD2, 0);
end;
end;
person
Ken White
schedule
10.08.2013
VK_RETURN
вошел в этот текст, где находится курсор, или просто отправил нажатие клавиши туда, где находится фокус? - person Jerry Dodge   schedule 10.08.2013