Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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.041 c
1-1098446830
Алексей Петухов
2004-10-22 16:07
2004.11.07
Clipboard


4-1096739153
Евгений2
2004-10-02 21:45
2004.11.07
Как определить, что окно что-то выполняет?


4-1096707415
alexsand_Vladimirovich
2004-10-02 12:56
2004.11.07
Процессы в NT


14-1098332642
Dmitriy O.
2004-10-21 08:24
2004.11.07
Lotus Notes 6 &amp; Delphi что лучше ?


4-1096706334
Antonmm2
2004-10-02 12:38
2004.11.07
Функция для определения DVD-ROMа





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский