Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > VB6 > пердать нажатие клавиши конкретному окну


Автор: Dad 12.11.2002, 08:06
ниже приведенная муть эмулирует нажатие клавиши, а
как послать нажатие клавиши конкретному окну (неактивному)

Private Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, _
ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Const KEYEVENTF_EXTENDEDKEY = &H1
Const KEYEVENTF_KEYUP = &H2
Const VK_Enter = &HD
'''''''''''''''''''''''''''''''''''''''''''
Private Timer1_Timer()
   keybd_event VK_Enter, 0, 0, 0  ' нажимаем
   keybd_event VK_Enter, 0, KEYEVENTF_KEYUP, 0  ' отпускаем

надо послать неактивному конкретному окну, кто играл в Ультиму Онлайн тот поймет,
я хочу зделать себе макркр который не будет захватывать управление компом,
чтоб я мог играть и лазить в инете одновременно....

Автор: Vit 12.11.2002, 14:33
SendMessage
PostMessage

Автор: Dad 12.11.2002, 19:15
ну блин, сенк конечно, но это я сам врубился, просто очень давно не писал... мне подробней надо вот как я написал так же напиши плиз.....
1) декларация:
      SendMessage
      PostMessage
2) пример вызова:
      SendMessage
      PostMessage

Автор: Dad 13.11.2002, 00:19
ой извини за прошлый топик это я чет втупил... давно не писал...
короче задаю вопрос по другому :

как послать нажатие клавиши НЕ АКТИВНОМУ окну зная его hwnd и заголовок ??????
вот такая фича, закрыть это окно я могу , а вот эмулировать нажатие F1  не получается,
че я неправильно делаю????
мне надо чтоб в НЕ АКТИВНОМ окне (игра)
по таймеру нажимались клавиши(F1, F2, ...)
может вообше можно как то по другому???? короче обязательно надо, чтоб
нажатие клавишь ловило НЕ АКТИВНОЕ окно.
это для игры Ультима Онлайн, там на клавиши можно написать
макрос и нажимая клавишу будет выполняться действие,
но это занимает комп,
я видел для нее самопальные проги,
которые жмут клавиши в неактивном окне игры,
но они хреново написаны и слишком тормозят комп...
'------------------------------------------
Private Declare Function FindWindow Lib "user32" _
         Alias "FindWindowA" (ByVal lpClassName As String, _
               ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" _
         Alias "PostMessageA" (ByVal hwnd As Long, _
               ByVal wMsg As Long, ByVal wParam As Long, _
                    ByVal lParam As Long) As Long
'''''''''Const VK_F1 = &H70
'''''''''Const WM_QUIT = &H12
Dim hW As Long
'----------------------------------------------
Private Sub tim1_Timer()
hW = FindWindow(vbNullString, "Безымянный - Блокнот" & Chr(0))
Call PostMessage(hW, &H12, 0, 0) 'работает блокнот закрывается !!!!!
   ''' Call PostMessage(hW, &H70, 0, 0) 'НЕ РАБОТАЕТ  !!!!!

Автор: Vit 13.11.2002, 00:25
VK_F1 - это не сообщение, это код клавиши, а сообщение - WM_KEYDOWN и WM_KEYUP  
Лично я это не делал, так что практическую консультацию не дам. Вот отрывок из хэлпа по WM_KEYDOWN


The WM_KEYDOWN message is posted to the window with the keyboard focus when a nonsystem key is pressed. A nonsystem key is a key that is pressed when the ALT key is not pressed.

WM_KEYDOWN  
nVirtKey = (int) wParam;    // virtual-key code
lKeyData = lParam;          // key data


Parameters

nVirtKey

Value of wParam. Specifies the virtual-key code of the nonsystem key.

lKeyData

Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table:

Value Description
0-15 Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user holding down the key.
16-23 Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24 Specifies whether the key is an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0.
25-28 Reserved; do not use.
29 Specifies the context code. The value is always 0 for a WM_KEYDOWN message.
30 Specifies the previous key state. The value is 1 if the key is down before the message is sent, or it is 0 if the key is up.
31 Specifies the transition state. The value is always 0 for a WM_KEYDOWN message.


Return Values

An application should return zero if it processes this message.

Автор: Dad 14.11.2002, 20:55
мда... ну то что это не сообшене дошло, но толку от хелпа мало...
ниче у меня не вышло....

Автор: Dad 17.11.2002, 03:44
мде... все просто оказалось....

const WM_KEYDOWN = &H100
const VK_F1 =&H70

Call PostMessage(hW, WM_KEYDOWN , VK_F1 , 1)

и работает как в сказке !

Автор: kapbepucm 16.6.2007, 11:04
A не подскажите, как тому-же окну послать сообщение о нажатии и отпуске клавиши [W]?

Автор: cardinal 16.6.2007, 14:40
Найди константу от этой буквы в том же MSDN...

Автор: Tectoder 17.6.2007, 20:29
Call PostMessage(hW, WM_KEYDOWN , VK_F1 , 1)
...
Call PostMessage(hW, WM_KEYUP , VK_F1 , 1)
?


Автор: cardinal 17.6.2007, 21:03
Это вопрос?

Автор: kapbepucm 18.6.2007, 08:34
"Найди константу от этой буквы в том же MSDN... "

Как я понял, здесь последний параметр играет большую роль. В данном случае функциональная клавиша [F1] "работает как в сказке", но написав нижеприведённое, поменяв на [W], как вы предложили:

    Dim HWND As Long
    Shell "c:\windows\system32\notepad.exe", vbMaximizedFocus
    HWND = GetForegroundWindow
    PostMessage HWND, WM_KEYDOWN, VK_W, 1
    PostMessage HWND, WM_CHAR, VK_W, 1
    PostMessage HWND, WM_KEYUP, VK_W, 1

результата я не увидел. Помогите разобраться с последним параметром для PostMessage c WM_KEYDOWN! 

Автор: cardinal 18.6.2007, 09:51
Код покажи полностью...

Автор: kapbepucm 18.6.2007, 10:31
В идеале я хочу, что-бы в текстовом редакторе вывелась буква "W", ещё лучше, если-бы вывелась в неактивном окне (для активнивного- kbd_event подходит). Для клавиши[F1] "работает как в сказке":

Код

        Public Const VK_F1 As Byte = &H70 'F1 key
        Public Const VK_W As Byte = &H57 'W key
        Public Const WM_KEYDOWN As Long = &H100
        Public Const WM_KEYUP As Long = &H101
        Public Const WM_CHAR As Long = &H102
        Public Declare Function GetForegroundWindow Lib "user32.dll" () As Long
        Public Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal HWND As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

' дальше основной код:

        Dim HWND As Long
        Shell "c:\windows\system32\notepad.exe", vbMaximizedFocus
        HWND = GetForegroundWindow' не самое лучшее решение найти handle, но всё-же 
        call PostMessage (HWND, WM_KEYDOWN, VK_F1, 1)
        call PostMessage (HWND, WM_CHAR, VK_F1, 1)
        call PostMessage (HWND, WM_KEYUP, VK_F1, 1)


...но если вместо VK_F1 написать VK_W, то результата я не ощущаю :(

код, который не работает:

Код

call  PostMessage (HWND, WM_KEYDOWN, VK_W, &H1570001)
call  PostMessage (HWND, WM_CHAR, VK_W, &H41570001)
call  PostMessage (HWND, WM_KEYUP, VK_W, &HC1570001)


Короче, разъясните непонятливым, что написать в lParam (проблема явно там), ну хотя-бы для активного окна, но обязательно используя PostMessage!

Автор: bom 18.6.2007, 21:52
Тренируйся:
Код

Option Explicit
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal HWND As Long, _
ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function FindWindow& Lib "user32" Alias "FindWindowA" (ByVal lpClassName$, _
                                                                        ByVal lpWindowName$)
Private Declare Function FindWindowEx& Lib "user32" Alias "FindWindowExA" (ByVal hWndParent&, _
                              ByVal hWndChildAfter&, ByVal lpClassName$, ByVal lpWindowName$)

Private Sub Form_Load()
Shell "notepad", vbMinimizedNoFocus
SendMessage FindWindowEx(FindWindow("Notepad", vbNullString), 0, "Edit", ""), &HC, 0, ByVal _
"Печатаем букву W в свернутом неактивном дочернем окне Edit блокнота:" & vbCrLf & "W"
End Sub


Добавлено через 8 минут и 38 секунд
Цитата(kapbepucm @  18.6.2007,  13:31 Найти цитируемый пост)
но обязательно используя PostMessage


Код

Private Sub Command1_Click()
        Dim HWND As Long
        Shell "c:\windows\system32\notepad.exe", vbMaximizedFocus
        HWND = FindWindowEx(GetForegroundWindow, 0, "Edit", "")
        Call PostMessage(HWND, WM_CHAR, VK_W, 1)
End Sub


Автор: kapbepucm 19.6.2007, 08:22
Ну, с блокнотом я разобрался. Но моя задача заключается в другом. Блокнот здесь я выбрал для примера, думая что ситуация похожа, оказалось не всё так просто. Оказывается, сообщение надо посылать дочернему окну на-прямую.
У меня проблема состоит в том, что я знаю Handle только главного окна. Что находится на нём- какие компоненты и каких типов мне не известно. Известно лишь то, что фокус ввода стоит в поле похожем на TextBox. В общем случае это типичное приветственное окно для входа в некую программу, где надо съэмулировать такую последовательность нажатий клавиш: [U][S][E][R][N][A][M][E][Tab][P][A][S][S][W][O][R][D][Enter]. Раньше я пользовался функцией kbd_event, но программа иногда глючит, и не делает своё окно активным, результат- запускается папка, расположенная у меня на Desktop'е с названием User (интересно почему?).
Наверное, есть только одна зацепка: если окно активизировать,то там, где будет установлен фокус ввода, надо каким-то образом извлечь Handle. Интересно, есть ли такой способ? А может есть способ, где, зная только Handle главного окна, можно выполнить поставленную задачу...

Автор: Tectoder 19.6.2007, 15:01
kapbepucm, а почему бы не заполнить поле функцией setwindowtext?

Автор: kapbepucm 19.6.2007, 15:12
Tectoder, дело в том, что я не знаю Handle дочернего окна (если это вообще окно). Хочу сделать именно грамотную эмуляцию нажатий и отпусканий клавиш кливиатуры. Визуально, поле только напоминает TextBox.

Автор: bom 19.6.2007, 16:19
Нельзя найти "то, не знаю что" и управлять "тем, не знаю чем".

Цитата(kapbepucm @  19.6.2007,  11:22 Найти цитируемый пост)
 Раньше я пользовался функцией kbd_event, но программа иногда глючит, и не делает своё окно активным


Ищи причину глюка.

Автор: kapbepucm 19.6.2007, 16:34
Причина глюка это параллельный запуск других программ. Вопрос в том, что мне нужна программа, которая может универсально работать- активно окно или нет. Вышеупомянутыми способами пробовал- но должного эффекта не наблюдал. Неужели нет такого способа посылающего некое сообщение главному окну, а окно уже само "решает", куда и что передавать дальше?

Автор: bom 19.6.2007, 18:27
Цитата(kapbepucm @  19.6.2007,  19:34 Найти цитируемый пост)
Неужели нет такого способа посылающего некое сообщение главному окну, а окно уже само "решает", куда и что передавать дальше?


Ну, если только повысить интеллектуальность окна "Ультима Онлайн" путем изменения его исходного кода smile Но это уже вопрос не для этого форума.

Автор: kapbepucm 19.6.2007, 18:53
Ясно, будем продолжать искать ответ...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)