Форум: "WinAPI";
Текущий архив: 2004.11.07;
Скачать: [xml.tar.bz2];
ВнизКак послать в окно ctrl+L чере sendmessage? Найти похожие ветки
← →
Леонид (2004-09-26 17:50) [0]Пробывал нажимать ctrl, потом жать клавишу, потом их отпускать.
Handle окна известен.
Заранее спасибо.
← →
Cobalt © (2004-09-26 20:36) [1]Рекомендую почитать для начала, как окно определяет, что нажата ctrl+L. Отсюда узнаешь, что надо послать окну.
← →
Леонид (2004-09-26 20:44) [2]я пробывал посылать тоже самое окну что и оно пишет при просмотре winsign32...
не получается почему-то
пробывал и так:
ScanCode := MapVirtualKey(VK_CONTROL, 0);
lParam := ScanCode shl 16 or 1;
PostMessage(hWnd, WM_KEYDOWN, VK_CONTROL, lParam);
ScanCode := MapVirtualKey(76{VK_L}, 0);
lParam := ScanCode shl 16 or 1;
PostMessage(hWnd, WM_KEYDOWN, 76, lParam);
в итоге нажимается только L...
← →
Cobalt © (2004-09-27 10:07) [3]Господи...
В одно сообщение надо посылать.
Справку почитай.
Или посмотри обработчик TWinControl.WMKeyDown
Если совсем уж лениво - сделай свой обработчик WM_KEYDOWN и запиши содержимое параметров при нажатии Ctrl+L
← →
Леонид (2004-09-27 19:46) [4]Cobalt
Нет у меня нормальных книжек, в хелпе непонятно написано, инет перерыл, ничего путевого не нашел, многие этот вопрос задавали, но ответа нету.
Неужто трудно сказать как правильно сделать, если знаешь?
← →
Cobalt © (2004-09-27 22:33) [5]Неужели трудно посмотреть, если указано направление?!
TWinControl.DoKeyDown - там всё написано, на Паскале!!!
Именно там из кодов сообщения получают флаги и прочее. Обратно сделать - труда не составляет. Но Я за Тебя этого делать не буду. Сказано достаточно чтобы сделать это самому. а если ты неспособен сделать это сам - значит, пора задумываться о смене рода деятельности.
← →
Леонид (2004-09-27 23:02) [6]Зазнайство еще никому чЕсти не делало.
Каким бы спецом Ты не был.
← →
KSergey © (2004-09-28 09:06) [7]> [6] Леонид (27.09.04 23:02)
Самокритика? ;)
← →
serg128 (2004-09-28 09:53) [8]getAsyncKeyState(Key);
← →
Alex M.A. (2004-09-28 09:54) [9]забавно...
снобизм - штука хорошая... наверно...
смотрим навязанный OnKeyDown, видим, что ShiftState определяется функцией KeyDataToShiftState... идем дальше и с удивлением замечаем, что "у ей унутрё" лишь статус Alt определяется по Message.KeyData, все остальное, по состоянию системных клавиш на момент обработки... бишь посредством GetKeyState...
т.е. получаем, если послать окну просто клавишу "L" и, при этом, вручную зажать Ctrl, то окно отреагирует как на Ctrl+L...
в вопросе автора имеет место быть вполне однозначная комбинация... причем Alt там не упоминается...
тоже очень хотелось бы знать, как такое можно осуществить именно посредством SendMessage, да еще и неактивному приложению...
я пока решения не нашел...
← →
easy © (2004-09-28 10:59) [10]
Procedure PostKeyEx( hWindow: HWnd; key: Word; Const shift: TShiftState;
specialkey: Boolean );
Type
TBuffers = Array [0..1] of TKeyboardState;
Var
pKeyBuffers : ^TBuffers;
lparam: LongInt;
Begin
(* check if the target window exists *)
If IsWindow(hWindow) Then Begin
(* set local variables to default values *)
pKeyBuffers := Nil;
lparam := MakeLong(0, MapVirtualKey(key, 0));
(* modify lparam if special key requested *)
If specialkey Then
lparam := lparam or $1000000;
(* allocate space for the key state buffers *)
New(pKeyBuffers);
try
(* Fill buffer 1 with current state so we can later restore it.
Null out buffer 0 to get a "no key pressed" state. *)
GetKeyboardState( pKeyBuffers^[1] );
FillChar(pKeyBuffers^[0], Sizeof(TKeyboardState), 0);
(* set the requested modifier keys to "down" state in the buffer *)
If ssShift In shift Then
pKeyBuffers^[0][VK_SHIFT] := $80;
If ssAlt In shift Then Begin
(* Alt needs special treatment since a bit in lparam needs also be set*)
pKeyBuffers^[0][VK_MENU] := $80;
lparam := lparam or $20000000;
End;
If ssCtrl In shift Then
pKeyBuffers^[0][VK_CONTROL] := $80;
If ssLeft In shift Then
pKeyBuffers^[0][VK_LBUTTON] := $80;
If ssRight In shift Then
pKeyBuffers^[0][VK_RBUTTON] := $80;
If ssMiddle In shift Then
pKeyBuffers^[0][VK_MBUTTON] := $80;
(* make out new key state array the active key state map *)
SetKeyboardState( pKeyBuffers^[0] );
(* post the key messages *)
If ssAlt In Shift Then Begin
PostMessage( hWindow, WM_SYSKEYDOWN, key, lparam);
PostMessage( hWindow, WM_SYSKEYUP, key, lparam or $C0000000);
End
Else Begin
PostMessage( hWindow, WM_KEYDOWN, key, lparam);
PostMessage( hWindow, WM_KEYUP, key, lparam or $C0000000);
End;
(* process the messages *)
Application.ProcessMessages;
(* restore the old key state map *)
SetKeyboardState( pKeyBuffers^[1] );
finally
(* free the memory for the key state buffers *)
If pKeyBuffers <> Nil Then
Dispose( pKeyBuffers );
End; { If }
End;
End; { PostKeyEx }
....
PostKeyEx( handle, Ord("L"), [ssCtrl], False );
← →
MetalFan © (2004-09-28 11:15) [11]круто) где взял такое?
у меня на строке
> PostMessage( hWindow, WM_KEYUP, key, lparam or $C0000000);
ошибка вылетает в момент выполнения: Project.exe raised exception class ERangeError with message "Range check error".....
что за нафиг?
← →
easy © (2004-09-28 12:25) [12]
> MetalFan
{$R-}
← →
MetalFan © (2004-09-28 13:32) [13]заработало! надо взять на заметку)
← →
Леонид (2004-09-28 20:45) [14]aeasy ©
Что-то у меня не сработал этот пример
вот лог winsign:
Беру IExplorera
Жму вручную ctrl+a
000815:000009B8 {Internet Ex} WM_KEYDOWN (10004X) Dispatched wp=00000011 lp=001D0001 11h 17d VK_CONTROL Scan 1Dh Down
000816:000009B8 {Internet Ex} WM_KEYDOWN (10004X) Dispatched wp=00000041 lp=001E0001 41h 65d VK_A Scan 1Eh Down
000817:000009B8 {Internet Ex} WM_KEYUP (10104X) Dispatched wp=00000041 lp=C01E0001 41h 65d VK_A Scan 1Eh Up
000818:000009B8 {Internet Ex} WM_KEYUP (10104X) Dispatched wp=00000011 lp=C01D0001 11h 17d VK_CONTROL Scan 1Dh Up
программно:
000819:000009B8 {Internet Ex} WM_KEYDOWN (10004X) Dispatched wp=00000041 lp=001E0000 41h 65d VK_A Scan 1Eh Down
000820:000009B8 {Internet Ex} WM_KEYUP (10104X) Dispatched wp=00000041 lp=C01E0000 41h 65d VK_A Scan 1Eh Up
как я понял в этой процедуре ставиться состояние клавиатуры, поэтому и не видно ничего по поводу контрол в логе.
но с другой стороны, может это состояние действует только в окне запускающей это состояние проги?
пробывал совсем простой код:
GetKeyboardState(KeyboardState);
KeyboardState[VK_Control] := 1;
SetKeyboardState(KeyboardState);
PostMessage(WAmp_Hw, wm_KeyDown,Ord("L"),0);
PostMessage(WAmp_Hw, wm_KeyUp,Ord("L"),0);
KeyboardState[VK_Control] := 0;
SetKeyboardState(KeyboardState);
тоже не работает...
буду копать дальше...
← →
Леонид (2004-09-28 20:53) [15]нет, и при переключении на окно, куда надо послать ctrl+key тоже самое...
← →
Cobalt © (2004-09-28 23:47) [16]Хммм, возможно, что я и ошибался.
Попробуй посмотреть справку по функции keybd_event - как-то так она называется - точно не помню - видел несколько раз упоминания о ней - вроде эмулирует нажатия клавиш "железно".
← →
Леонид (2004-09-29 07:22) [17]Хммм, возможно, что я и ошибался. - ценЮ, не каждый бы такое написал.
Замнем для ясности :)
через keybd_event действительно проблем нет, но в ней не указывается Hwd, т.е. она шлет в текущее окно.
А мне хотелось бы обойтись без переключений между окнами.
← →
Alex M.A. (2004-09-29 14:33) [18]easy © (28.09.04 10:59) [10]
[skipped]
try
(* Fill buffer 1 with current state so we can later restore it.
Null out buffer 0 to get a "no key pressed" state. *)
AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessID(hWindow, nil), True);
GetKeyboardState( pKeyBuffers^[1] );
FillChar(pKeyBuffers^[0], Sizeof(TKeyboardState), 0);
[skipped]
(* restore the old key state map *)
SetKeyboardState( pKeyBuffers^[1] );
AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessID(hWindow, nil), False);
← →
Alex M.A. (2004-09-29 14:34) [19]The SetKeyboardState function copies a 256-byte array of keyboard key states into the calling thread"s keyboard-input state table. This is the same table accessed by the GetKeyboardState and GetKeyState functions. Changes made to this table do not affect keyboard input to any other thread.
← →
Леонид (2004-09-29 20:12) [20]Alex M.A.
К сожалению, что так, что так, все равно не работает.
У кого-нибудь работает?
← →
Леонид (2004-09-29 20:59) [21]Заработало :) !
Как не парадоксально, но надо поставить задержку перед восстановлением прежнего статуса :
(* restore the old key state map *)
Sleep(1);
SetKeyboardState( pKeyBuffers^[1] );
достаточно и 1 :)
иначе не работает!!!
ВСЕМ СПАСИБО!
P.s. Хотя конечно зачем нужна задержка, непонятно...
← →
Alex M.A. (2004-09-30 09:54) [22]вместо PostMessage используй SendMessage
и задержки не нужны
← →
Alex M.A. (2004-09-30 09:56) [23]The PostMessage function places (posts) a message in the message queue associated with the thread that created the specified window and then returns without waiting for the thread to process the message.
The SendMessage function sends the specified message to a window or windows. The function calls the window procedure for the specified window and does not return until the window procedure has processed the message.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.11.07;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.042 c