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


Автор: ProggerXandCo 1.7.2010, 15:59
Помогите, пожалуйста, с синтаксисом функции SendMessage (VB 6.0). Если можно, дайте пример. Зараннее благодарен!

Автор: neic 1.7.2010, 16:30
Вот смотри:
Код

SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)


Код

SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1L)


тут:
hwnd - идентификатор окна (куда будешь посылать сообщение)
WM_KEYDOWN - в данном случае указываем, что мы нажимаем виртуальную клавишу на клаве
VK_DELETE - указываем, что нажимаем кнопку Delete
1L - пока без понятия, да думаю он и не важен, т.к. он дополнительный

Добавлено @ 16:36
Чтобы найти hwnd можно сделать следующее:
Код

caption_prog = GetActiveWindowTitle(True) 
hwnd = FindWindow(vbNullString, caption_prog)

или так:
Код

hwnd = FindWindow(vbNullString, "Блокнот")
SendMessage(hwnd, WM_CHAR, "П")

Автор: ~FoX~ 1.7.2010, 17:03
Цитата(neic @  1.7.2010,  17:30 Найти цитируемый пост)
1L - пока без понятия, да думаю он и не важен, т.к. он дополнительный

Так же важен как и нижний параметр... Например
Код

SendMessage(SLV, LVM_REDRAWITEMS, 0, IconCount-1) ' WParm - передает номер первого обновляемого итема, LParm соотвественно последнего

ProggerXandCo
http://vingrad.ru/VB-ART-003067

Автор: neic 1.7.2010, 17:06
~FoX~
Я тут так попробовал попробовал. Но сам понял, что не разобрался =)

Вот смотри как послать калькулятору цифру 1?
Код

    ' Находим манипулятор окна Блокнота по заголовку окна
    rc& = FindWindow(vbNullString, "Калькулятор Плюс")
    ' Получаем манипулятор тестового поля Блокнота
    res& = GetWindow(rc&, GW_CHILD)
    ' Отправляем текстовому полю блокнота символ A
    Call SendMessage(res&, WM_CHAR, vbKey1, 0&)

И ни не получается. Я так понимаю трабла в res& = GetWindow(rc&, GW_CHILD), но какая?

Автор: ProggerXandCo 1.7.2010, 21:54
А как тогда будет выражаться нажатие на кнопку чужой формы?Или выделение текстового поля?

Автор: ~FoX~ 1.7.2010, 22:49
Ну во первых кто такой "Калькулятор плюс"?
Цитата(neic @  1.7.2010,  18:06 Найти цитируемый пост)
res& = GetWindow(rc&, GW_CHILD)

Честно не знаю что за потомок вернется по GetWindow, я бы использовал FindWindowsEx
Код

  WindowHWND = FindWindow(nil, "Калькулятор")
  EditHWND = FindWindowEx(WindowHWND, nil, "Edit", nil)

Ну а дальше надо посмотреть что там едиту можно заслать

Автор: I_Am_Rock 2.7.2010, 13:24
Цитата(ProggerXandCo @ 1.7.2010,  21:54)
А как тогда будет выражаться нажатие на кнопку чужой формы?Или выделение текстового поля?

Нажатие 
SendMessage c WM_COMMAND и BN_CLICKED как wparam (в принципе просто 0)

Выделение текста
SendMessage c WM_SETFOCUS
или
функция SetFocus

если я ничего не путаю )

Автор: ProggerXandCo 2.7.2010, 21:08
Цитата(neic @ 1.7.2010,  16:30)




SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1L)


тут:
hwnd - идентификатор окна (куда будешь посылать сообщение)
WM_KEYDOWN - в данном случае указываем, что мы нажимаем виртуальную клавишу на клаве
VK_DELETE - указываем, что нажимаем кнопку Delete
1L - пока без понятия, да думаю он и не важен, т.к. он дополнительный


Извините,пожалуйста,нельзя ли объяснить понятнее? с 1L - просит list separator и непонятно последнее сообщение I_Am_Rock - а. Помогите, пожалуйста с синтаксисом нажатия кнопки чужого контрола!(последнее сообщение I_Am_Rock)

Автор: I_Am_Rock 3.7.2010, 00:21
А вот сам I_Am_Rock и объяснит.  smile  Я правда сразу скажу - делать так, как я сказал не надо.)) Не то сообщение надо посылать. Перепутал я)

Вот вобщем пример как надо
.
Перед запуском программы нужно открыть Пуск - Выполнить. В текст поле нужно ввести calc (чтоб потом калькулятор запустился)

Затем нужно запустить форму с кодом, который ниже.
При загрузке она
1) Найдет родительское окно по заголовку,
2) Найдет дочернее окно по заголовку (вообще это кнопка, конечно, но для windows все такие объекты управления - это "окна")
3) Отошлет сообщение этому дочернему окну-кнопке о том, что ему пора нажиматься.
Ясное дело - в итоге должен запустить Калькулятор.

Код

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 As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Dim z1, z2 As Long

Private Sub Form_Load()
z1 = FindWindow(vbNullString, "Запуск программы")
z2 = FindWindowEx(z1, 0, vbNullString, "ОК")
SendMessage z2, &HF5, 0, 0
End Sub



Автор: ProggerXandCo 3.7.2010, 23:37
А как можно просто обратить "внимание" программы на окно, чтобы пускать оператор SendKeys(для этого окна)?
Простая его постановка в конце примера I_Am_Rock - а ничем не помогла (Процедура - загрузка
Form1).

Автор: ~FoX~ 4.7.2010, 23:08
Цитата(ProggerXandCo @  4.7.2010,  00:37 Найти цитируемый пост)
А как можно просто обратить "внимание" программы на окно

FindWindow

Автор: ProggerXandCo 8.7.2010, 10:28
Не помогло, ~FoX~.Окно находит, но SendKeys не работают.

Автор: ~FoX~ 8.7.2010, 16:38
Поглядев с помощью WinSight на калькулятор - понял, что в Edit нажимать кнопки бесполезно, ибо он выключен )))
Есть два варианта решения 
1. нажимать кнопки в окне
Код

Dim WindowHWND As Long
Dim EditHWND As Long
Const WM_KEYDOWN = &H100
Const WM_KEYUP = &H101
  
  WindowHWND = FindWindow(vbNullString, "Калькулятор")
  EditHWND = FindWindowEx(WindowHWND, 0, "Button", "3")
  SendMessage EditHWND, WM_KEYDOWN, vbKeySpace, vbKeySpace
  SendMessage EditHWND, WM_KEYUP, vbKeySpace, vbKeySpace

2. Слать в едит непосредственно нужный текст WM_SENDTEXT, но тут геморойно потому что приходиться сначала получить текст, посчитать длинну прибавить к полученному число и увеличить длинну, не забывая про запятую....

Добавлено @ 16:45
Модуль
Код

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
        (ByVal lpClassName As String, _
        ByVal lpWindowName As String) As Long

Public Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _
        (ByVal hwndParent As Long, _
        ByVal hwndChildAfter As Long, _
        ByVal lpszClass As Any, _
        ByVal lpszWindow As Any) As Long

Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hwnd As Long, _
        ByVal wMsg As Long, _
        ByVal wParam As Long, _
        ByVal lParam As Long) As Long


Public Const WM_KEYDOWN = &H100
Public Const WM_KEYUP = &H101

Кнопа
Код

  Dim WindowHWND As Long
  Dim EditHWND As Long
  
  WindowHWND = FindWindow(vbNullString, "Калькулятор")
  EditHWND = FindWindowEx(WindowHWND, 0, "Button", "3")
  SendMessage EditHWND, WM_KEYDOWN, vbKeySpace, vbKeySpace
  SendMessage EditHWND, WM_KEYUP, vbKeySpace, vbKeySpace


Автор: ProggerXandCo 8.7.2010, 19:13
Извините, пожалуйста, но я имел в виду вначале включить обнаружение уже запущенного окна,  
например, Блокнота, а потом управлять им с помощью SendKeys. Или это невозможно?

Автор: ~FoX~ 8.7.2010, 19:33
Цитата(ProggerXandCo @  8.7.2010,  20:13 Найти цитируемый пост)
обнаружение уже запущенного окна

Еще раз 
Цитата(~FoX~ @  5.7.2010,  00:08 Найти цитируемый пост)
FindWindow 

Забудь ты про SendKeys, не все контролы обрабатывают нажатие кнопок... Например: 
Цитата(~FoX~ @  8.7.2010,  17:38 Найти цитируемый пост)
понял, что в Edit нажимать кнопки бесполезно, ибо он выключен )))


Цитата(ProggerXandCo @  1.7.2010,  22:54 Найти цитируемый пост)
А как тогда будет выражаться нажатие на кнопку чужой формы?Или выделение текстового поля? 

Ты определись....Нажатие кнопки чего? Мыши, клавиатуры, программной, etc...?
Нажатие кнопки WM_KEYDOWN/WM_KEYUP/WM_CHAR... Нажатие кнопы мыши  WM_L/R/MBUTTONUP/DBLCLICK... Выделение WM_SETFOCUS и т.д.

Цитата(ProggerXandCo @  8.7.2010,  20:13 Найти цитируемый пост)
а потом управлять им с помощью SendKeys

Нельзя управлять контролами внутри приложения с помощью клавиатуры.... Все действия не обязательно обрабатываются самим контролом, в большинстве случаев этим занимается окно предок объекта, именно окно Application или Form (не знаю как в ВБ)...

Автор: Jkyskienuh 12.12.2020, 12:05
Модератор: Сообщение скрыто.

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