Форум: "WinAPI";
Текущий архив: 2003.08.07;
Скачать: [xml.tar.bz2];
ВнизSendKeys и иже с ними. HELP ME Найти похожие ветки
← →
Kreo (2003-06-05 21:41) [0]Задача: управление произвольной программой из своей dll либо формы.
Уважаемые мастера, объясните как передать (эмулировать) нажатие клавиш в чужое окно.
Копал функции keyb_event, TranslateMessage, SendMessage, Set.. Get..
Top(Foreground) Window и т.д. но видимо подвело незнание
английского... Нажатие клавиш передается только верхнему окну...
В принципе это не проблема, но хотелось бы иметь возможность отсылать сообщения
о нажатии клавиш и в минимизированные окна. (Я хочу сделать программу принимающую
сигнал с ПДУ через СОМ порт и управляющую другими приложениями.
С приемом и расшифровкой IR сигнала нет проблем, а вот передать Проигывателю
Windows Media например последовательность клавиш Ctrl+1 - заморочки ->
клавиши передаются, но окно (если было минимизировано) восстанавливает размеры
и активизируется :( ) Как я понял из справки, сообщения о соостоянии клавиш
передаются ТОЛЬКО тому окну, которое имеет фокус ввода. (мучал функцию SetFocus,
но нужного результата не получил :( )
Помогите решить задачку, pls... :)
(Как всегда, попошу кусочек работающего кода, но не потому что мне нужен готовый результат,
а потому что слушать обяснения - это одно, а оттрассировать и ПОНЯТЬ что делается - это совсем другое)
P.S. Для передачи сообщения использовал свои процедуры, модуль SendKeys32 (Королевство
Дельфи) и др. Везде один и тот же подход. Тем не менее проблеме решаема, т.к.
сушествуют плагины (напр. для WinAMP - gen_ir.dll) выполняющие эту задачу.
Могу показать код, но думаю что в этом нет смысла, т.к. застрял собственно в
самом начале - передача окну сообщения о нажатии клавиш (для приема и анлиза данных
использую портированную на дельфи, и измененную мной WinLIRC)
Персоналии.
Очень расчитываю на ответ Юрия Зотова
Заранее спасибо.
← →
Song (2003-06-05 22:01) [1]Действительно, передавать надо не головному окну, а тому, которое должно обработать это сообщение. Автоматически найти это окно невозможно, т.к. строение разных приложений - разное. Поэтому можно посмотреть структуру приложения, например, через WinSight, а потом найти нужное окно в иерархии через FindWindowEx() и/или GetWindow() и послать ему WM_KEYDOWN/UP или WM_CHAR
← →
Spawn (2003-06-05 22:04) [2]Полсылать нажатия кнопок можно при помощи SendMessge(), тогда окна будут их воспринимать в любом состоянии - хоть в свернутом, хоть в активном и т.д. Но здесь есть маленькая загвоздка)) необходимо правильно указать скен код кнопки и сам ее код. Вот тебе примерчик на эмуляцию нажатия (долго я в свое время это искал):
procedure KeyDown(Wnd:HWND; Key:Word);
var
ScanCode, LParam:LongInt;
begin
ScanCode:=MapVirtualKey(Key,0);
lParam := ScanCode shl 16 or 1;
SendMessage(Wnd,WM_KEYDOWN,Key,lParam);
end;
← →
Kreo (2003-06-06 08:38) [3]Большое спасибо за ответы. Будем копать далее.
← →
Kreo (2003-06-06 16:23) [4]Как я понял, WM_CHAR = WM_KEYDOWN + WM_KEYUP
Но почему тогда WM_CHAR обрабатывается Блокнотом, а WM_KEYDOWN
и WM_KEYUP - нет?
Как мне отослать комбинацию клавиш - с Ctrl, Alt или Shift
напр. Ctrl+F или Shift+p, ведь WM_CHAR "отпускает" клавищу?
← →
Kreo (2003-06-06 16:26) [5]Сорри. Вот код.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button3: TButton;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
mHandle : HWND;
implementation
{$R *.DFM}
function vFindHandle(): HWND;
begin
Result := FindWindow("Notepad", nil);
if Result <> 0 then
Result := GetWindow(Result, GW_CHILD) // class Edit
else ShowMessage("Блокнот не запущен");
end;
function vKeyDown(Wnd:HWND; Key:Word): integer;
var
ScanCode, LParam : LongInt;
begin
ScanCode := MapVirtualKey(Key, 0);
lParam := ScanCode shl 16 or 1;
Result := SendMessage(Wnd, WM_KEYDOWN, Key, lParam);
end;
function vKeyUp(Wnd:HWND; Key:Word): integer;
var
ScanCode, LParam : LongInt;
begin
ScanCode := MapVirtualKey(Key,0);
lParam := ScanCode shl 16 or 1;
Result := SendMessage(Wnd, WM_KEYUP, Key, lParam);
end;
function vChar(Wnd:HWND; Key:Word): integer;
var
ScanCode, LParam : LongInt;
begin
ScanCode := MapVirtualKey(Key,0);
lParam := ScanCode shl 16 or 1;
Result := SendMessage(Wnd, WM_CHAR, Key, lParam);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
mHandle := vFindHandle;
if mHandle <> 0 then
vChar(mHandle, Ord("x")); // работает
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
mHandle := vFindHandle;
if mHandle <> 0 then begin
vKeyDown(mHandle, VK_SHIFT); //-
vChar(mHandle, Ord("x")); // KeyDown & KeyUP не работают
vKeyUp(mHandle, VK_SHIFT); //-
end;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
mHandle := vFindHandle; //
if mHandle <> 0 then begin //
vKeyDown(mHandle, VK_SHIFT); // не работает :(
vKeyDown(mHandle, Ord("x")); //
vKeyUp(mHandle, Ord("x")); // а почему?
vKeyUp(mHandle, VK_SHIFT); //
end;
end;
end.
← →
Spawn (2003-06-06 20:08) [6]Посмотри GetKeyboardState и SetKeyBoardState для задания состояния Alt, Ctrl и Shift (если я правильно помню)
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2003.08.07;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.01 c