Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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.47 MB
Время: 0.014 c
9-20374
R2D2
2003-02-04 23:35
2003.08.07
GLScene - Управление объектами, созданными динамически


1-20626
Zhuchok
2003-07-25 01:52
2003.08.07
IniFiles


6-20648
Woolen
2003-05-31 22:10
2003.08.07
TIdSMTP


1-20503
sir_lammer
2003-07-25 15:08
2003.08.07
Delphi и IE


14-20688
gfksx
2003-07-23 03:06
2003.08.07
Нужен совет по сокетам в обмен на USD





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский