Проблемка с Shell

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Dummiel
Бывалый
Бывалый
 
Сообщения: 235
Зарегистрирован: 11.06.2004 (Пт) 9:15
Откуда: Алтай

Проблемка с Shell

Сообщение Dummiel » 14.06.2006 (Ср) 13:07

Еще проблемка, други мои!

После команды Shell выполняется приложение Windows, а проект на VB продолжает работать дальше, не завися от
выполняемого приложения, вызванного командой Shell.

...
Shell C:prog.exe, vbNormalFocus
MsgBox "Ура, товарищи!"
...

пошла на выполнение prog.exe, и тут же выскакивает MsgBox, и две проги работают параллельно.

Вопрос: как сделать, чтобы проект ожидал окончания работы prog.exe, и только потом продолжал работу, т.е., выполнял
следующую за Shell строку программы?

В выполняемы системных файлах file.bat все так и происходит - следующая строка начинает работать только после
отработки предыдущей команды.

И дополнительный вопрос:
При запуске prog.exe сначала появляется форма, где юзеру дается на выбор 2 кнопки - "выход"/"работа", по умолчанию активна
кнопка "работа". Т.е., нажимаешь <Enter> и вкалываешь:) Так вот - как при вызове prog.exe через Shell передать ей нажатие
клавиши <Enter>? Или не через Shell, тогда через КТО?

С уважением - Dummiel

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 14.06.2006 (Ср) 13:13

Изображение

Dummiel
Бывалый
Бывалый
 
Сообщения: 235
Зарегистрирован: 11.06.2004 (Пт) 9:15
Откуда: Алтай

Сообщение Dummiel » 19.06.2006 (Пн) 14:00

Хай! Прошу прощения за длительное остутствие.

Конечно, краткость - сестра таланта, но матюкается комп на эту ссылку: "Темы, которую вы запросили, не существует."

И шо делать? Погибать в неведении?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 19.06.2006 (Пн) 14:04

А ты кликни по ней ещё раз, залогиненный.
Изображение

Amed
Алфизик
Алфизик
 
Сообщения: 5346
Зарегистрирован: 09.03.2003 (Вс) 9:26

Сообщение Amed » 19.06.2006 (Пн) 14:04


Dummiel
Бывалый
Бывалый
 
Сообщения: 235
Зарегистрирован: 11.06.2004 (Пт) 9:15
Откуда: Алтай

Сообщение Dummiel » 19.06.2006 (Пн) 14:15

Вот и спасибочки, вот и все получилось.

Век живи - век учись. Ща буду учиться.

Dummiel
Бывалый
Бывалый
 
Сообщения: 235
Зарегистрирован: 11.06.2004 (Пт) 9:15
Откуда: Алтай

Сообщение Dummiel » 20.07.2006 (Чт) 8:24

Хай, други!
В общем, хоча у меня такая:
Мой проект работает с БД Access, затем подставляет эту БД в другую (готовую чужую программу) с соответствующими копированиями, закрытиями и переименованиями, чтобы "чужая" прога отработала по данным моей БД определенную статистику. Затем эта БД удаляется, "Чужая" прога закрывается, ей подставляется (своя для нее) БД и работа возвращается к моему проекту с моей БД. Как вы понимаете, структуры своей и "чужой" БД идентичны. Мало того, моя прога работает тупо с копией "чужой" БД.

Резюме: БД заполняется в моей проге, а обрабатывается в "чужой". Для обработки "чужая" вызывается, отрабатывает, и выгружается, а моя должна ждать, пока "чужая" отработает и выгрузится, и только потом продолжать работу.

Задачка:
1. Сделать моей проге МояГлавнаяФорма.WindowState = 1 (Minimized)
2. Вызвать чужую (предполагается, что работа с взлохмачиванием БД уже проведена), и работать с ней.
3. Выйти из "чужой" проги, и чтоб по ВЫХОДУ из нее программно отработалась МояГлавнаяФорма.WindowState = 2 (Maximized)

С Shell не получается - все отрабатывается подряд:
1. МояГлавнаяФорма.WindowState = 1 (Minimized)
2. Затем следует запуск "чужой" проги
3. И тут же отрабатывается МояГлавнаяФорма.WindowState = 2 (Maximized), т.е., моя прога продолжает работу.

т.е., моя прога не ждет, пока отработается "чужая". А мне нужно, чтобы моя продолжала работу после Shell только по закрытию "чужой" проги.

Уважаемый GSerg скинул ссылку на контрол Waiter, и я чегой-то не смог с ним разобраться, то ли в API-шках запутался (особенно, когда не знаешь, для чего какая), то ли еще чего, но контрол опять же не задерживает выполнение моей проги до отработки чужой:

Me.WindowState = 1

h(1) = OpenProcess(SYNCHRONIZE, 0, Shell("notepad", vbNormalNoFocus))
h(2) = OpenProcess(SYNCHRONIZE, 0, Shell("notepad", vbNormalNoFocus))
h(3) = OpenProcess(SYNCHRONIZE, 0, Shell("notepad", vbNormalNoFocus))

'Здесь хочу остановку

Waiter1.WaitForMany h, True, 5000

'или здесь? :)

Me.WindowState = 2

и здесь все точно так же: только отрабатывает h(1-3), тут же "пролетает" Waiter1.WaitForMany h, True, 5000, и тут же
отрабатывается Me.WindowState = 2, задержки по времени практически нет.

В bat-файле все именно так работает, как мне нужно, но не хочется все усложнять, и к двум прогам цеплять лишний *.bat, да и для того, чтобы отработал *.bat, перед запуском "чужой" проги нужно выйти из своей, а после отработки "чужой" снова запускать мою. Лишние заморочки, короче.

Вытекающие вопросы:
1. Возможна ли все же остановка моей проги? Время ожидания предвидеть практически невозможно - м.б. 10 мин, м.б. 2 часа.
2. Если да, то как через 1-2 секунды после h(3) = OpenProcess(SYNCHRONIZE, 0, Shell("notepad", vbNormalNoFocus)) передать "чужую" прогу нажатие клавиши <Enter>? Через 1-2 сек потому, что пока прога загружается, она ничего не воспринимает.
3. И объясните, please, чем принципиально отличается OpenProcess(SYNCHRONIZE, 0, Shell("notepad", vbNormalNoFocus)) от просто Shell("notepad", vbNormalNoFocus)? Только без понтов, по человечески.
4. Я так понимаю, что Waiter1.WaitForMany h, True, 5000 нужна только для задержки программы, но не для ее остановки?

Конечно, объяснить бы контрол Waiter построчно, но это, я понимаю, ваще несбыточная мечта? :(

С уважением - Dummiel.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 20.07.2006 (Чт) 8:43

1. Да: WaitForSingleObject достаточно
2. Лучше не закладываться на одну-две секунды, а сделать последовательность из WaitForInputIdle+SendKeys+WaitForSingleObject
3. В чём разница между именем файла и хендлом файла, не нужно объяснять? Между PID и hProcess -- точно такая же.
4. WaitForMany указывает, что по истечении ожидания нужно сгенерировать событие. Нет ни задержки, ни остановки.
Изображение

Dummiel
Бывалый
Бывалый
 
Сообщения: 235
Зарегистрирован: 11.06.2004 (Пт) 9:15
Откуда: Алтай

Сообщение Dummiel » 20.07.2006 (Чт) 12:47

Спасибо, буду дальше мозг плавить :)

Glyckmen
Обычный пользователь
Обычный пользователь
 
Сообщения: 72
Зарегистрирован: 30.04.2006 (Вс) 15:32
Откуда: Санкт-Петербург

Сообщение Glyckmen » 20.07.2006 (Чт) 13:31

Dummiel
Мне тоже в проге понадобилось останавливаться и ждать завершения вызываемой, и где то здесь на форуме нашел такой пример (где не помню, но пример у меня сохранился), этот модуль замораживает твою прогу пока запускаемая не закроется

Попробуй вот это:
Код модуля:
Код: Выделить всё

Public Enum PriorityEnum
  NORMAL_PRIORITY_CLASS = &H20
  IDLE_PRIORITY_CLASS = &H40
  HIGH_PRIORITY_CLASS = &H80
End Enum

Public Enum WindowStyle
  SW_HIDE = 0
  SW_NORMAL = 1
  SW_MAXIMIZE = 3
  SW_MINIMIZE = 6
End Enum

Declare Function CreateProcessA Lib "kernel32" (ByVal lpApplicationName As Long, ByVal lpCommandLine As String, ByVal lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long

Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long

Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Public Const INFINITE = -1&
Public Const STARTF_USESHOWWINDOW = &H1
Public Type STARTUPINFO
  cb As Long
  lpReserved As String
  lpDesktop As String
  lpTitle As String
  dwX As Long
  dwY As Long
  dwXSize As Long
  dwYSize As Long
  dwXCountChars As Long
  dwYCountChars As Long
  dwFillAttribute As Long
  dwFlags As Long
  wShowWindow As Integer
  cbReserved2 As Integer
  lpReserved2 As Long
  hStdInput As Long
  hStdOutput As Long
  hStdError As Long
End Type
Public Type PROCESS_INFORMATION
  hProcess As Long
  hThread As Long
  dwProcessID As Long
  dwThreadID As Long
End Type

'**********************************************************

Public Function SystemExecute(ByRef CmdLine As String, Optional Show As WindowStyle = SW_NORMAL) As Long
Dim proc As PROCESS_INFORMATION
Dim start As STARTUPINFO
Dim Res As Long
 
  ' Initialize the STARTUPINFO structure:
  start.cb = Len(start)
  start.dwFlags = STARTF_USESHOWWINDOW
  start.wShowWindow = Show
 
  ' Start the shelled application:
  Res = CreateProcessA(0&, CmdLine$, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)

  ' Wait for the shelled application to finish:
  Res = WaitForSingleObject(proc.hProcess, INFINITE)
  Call GetExitCodeProcess(proc.hProcess, Res)
  Call CloseHandle(proc.hThread)
  Call CloseHandle(proc.hProcess)
  SystemExecute = Res
End Function



На форме размести кнопку и такой код:
Код: Выделить всё

Private Sub Command1_Click()
SystemExecute "Запускаемая прога" 'Например так SystemExecute "c:\program files\winrar\WinRAR.exe -a *.*"
MsgBox "CLOSE "
End Sub

Dummiel
Бывалый
Бывалый
 
Сообщения: 235
Зарегистрирован: 11.06.2004 (Пт) 9:15
Откуда: Алтай

Сообщение Dummiel » 21.07.2006 (Пт) 8:25

Glyckmen, спасибо, ща разбираться буду, но писмо все равно оставлю - глядишь, кому еще пригодится.

Письмо:

Краткость - сестра таланта! Лучше бы с понтами объяснили. :)

В чём разница между именем файла и хендлом файла, не нужно объяснять?


А в чем разница?

WaitForSingleObject требует (ByVal hHandle As Long, ByVal dwMilliseconds As Long). Как получить hHandle "чужого" *.exe?
И для чего dwMilliseconds, какое значение д.б., чтобы моя прога ждала "вечно"?

Лучше не закладываться на одну-две секунды, а сделать последовательность из WaitForInputIdle+SendKeys+WaitForSingleObject


А здесь вообще загруз - тупой перебор вариантов результата, естественно, не дал, а "острый" код написать - не по уму и
не по опыту (мой ник обо всем говорит). А научиться-то хочется.

Так что, отцы-командиры, накропайте хотя бы подобие кода для разбора. В глуши нашей в И-нет-то выйти проблематично - один салон на деревню с тремя рабочими местами, пока очереди дождесси... :(
А в одиночку разобраться с API-шками, не имея справочников, нереально.

Не от лени, а от безысходности к состраданию взываю! Не рубите на корню потенциального Билла Гейтца! :)

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 21.07.2006 (Пт) 8:47

Dummiel писал(а):
В чём разница между именем файла и хендлом файла, не нужно объяснять?


А в чем разница?

Что делает оператор Open в VB, ты себе как представляешь? :-)

Dummiel писал(а):WaitForSingleObject требует (ByVal hHandle As Long, ByVal dwMilliseconds As Long). Как получить hHandle "чужого" *.exe?
И для чего dwMilliseconds, какое значение д.б., чтобы моя прога ждала "вечно"?

OpenProcess, блин. Он там, по-твоему, зачем был?

Чтобы ждала "вечно", передавай константу INFINITE, а это -1.
Изображение

Glyckmen
Обычный пользователь
Обычный пользователь
 
Сообщения: 72
Зарегистрирован: 30.04.2006 (Вс) 15:32
Откуда: Санкт-Петербург

Сообщение Glyckmen » 21.07.2006 (Пт) 9:46

Dummiel Да забыл предупредить, что этот способ напроч замораживает твою прогу (даже окна не перерисовываются, оператор DoEvents не помогает) но только до тех пор пока ты не закроешь вызванную программу. Что-бы не смущать пользователя что твоя прога зависла можно просто убрать форму (или формы) с экрана Form.Visible=False, после того как вызванная прога отработала и завершилась, снова выводишь форму (или формы) на экран Form.Visible=True

neic
Жираф
Жираф
 
Сообщения: 492
Зарегистрирован: 13.02.2005 (Вс) 23:44
Откуда: Сланцы

Сообщение neic » 21.07.2006 (Пт) 11:19

Glyckmen писал(а):Dummiel Да забыл предупредить, что этот способ напроч замораживает твою прогу (даже окна не перерисовываются, оператор DoEvents не помогает) но только до тех пор пока ты не закроешь вызванную программу. Что-бы не смущать пользователя что твоя прога зависла можно просто убрать форму (или формы) с экрана Form.Visible=False, после того как вызванная прога отработала и завершилась, снова выводишь форму (или формы) на экран Form.Visible=True

А лучше вывести сообщение об обработке инфы и убрать форму ;) Думаю так будет лучше.

Glyckmen
Обычный пользователь
Обычный пользователь
 
Сообщения: 72
Зарегистрирован: 30.04.2006 (Вс) 15:32
Откуда: Санкт-Петербург

Сообщение Glyckmen » 21.07.2006 (Пт) 14:22

neic

А лучше вывести сообщение об обработке инфы и убрать форму Думаю так будет лучше.


Не совсем будет лутче, то сообщение об обработке так-же заморозится и если пользователь захочет поменять фокус с вызванной программы на сообщение (или просто переместить окно вызванной программы) то вместо формы сообщения появится белый прямоугольник (при этом окно вызванной программы будет нормальным) и он не исчезнет пока вызванная прога не закроется, при этом возникает ощущение зависания (даже в диспетчере задач твоя прога будет иметь значение "Не отвечает"). В данном случае все-таки будет лутче спрятать все свои окна, и пусть вызываемая программа сама отоброжает информацию о своей работе и по ее окончании вернуть все свои окна на место. Это ИМХО самый лутчий вариант.

Dummiel
Бывалый
Бывалый
 
Сообщения: 235
Зарегистрирован: 11.06.2004 (Пт) 9:15
Откуда: Алтай

Сообщение Dummiel » 26.07.2006 (Ср) 3:53

Glyckmen, спасибо, это как раз то, что мне нужно.

Tyomitch, ща снова удар по твоим нежным нервам :)

OpenProcess, блин. Он там, по-твоему, зачем был?


Ну не знаком я с API, откуда ж мне еще про OpenProcess узнать, блин? :)

Лучше не закладываться на одну-две секунды, а сделать последовательность из WaitForInputIdle+SendKeys+WaitForSingleObject


А на этот вопрос так и не ответили :( Так как же все-таки передать проге имитацию нажатия <Enter>? У меня по приведенному примеру ничего не получилось.

Dummiel
Бывалый
Бывалый
 
Сообщения: 235
Зарегистрирован: 11.06.2004 (Пт) 9:15
Откуда: Алтай

Сообщение Dummiel » 27.07.2006 (Чт) 3:58

Glyckmen, а мне и не надо других процессов. Ведь моя прога подсовывает "чужой" свою БД, и пока идет обработка данных, моей проге работать незачем. Так что я просто минимизирую окно, а после отработки "чужой" максимизирую. Можно и .Visible = False, тоже работает.

Кстати, экспериментально я пришел к тому, что при вызове другой проги просто Shell, без OpenProcess, затем задержка (API - Sleep), затем SendKeys "{Enter}", дает нужный мне результат, хотя с примером Glyckmen'а это не проканывает. Действительно, все зависает наглухо. И в этом случае нужно делать активным вызываемое окно, только потом передавать <Enter>. Соответственно возник вопрос - как сделать активным вызываемое окно? Я так понимаю, тоже через API. Но сначала узнать системные "реквизиты" окна. Опять OpenProcess, блин? :)
Будьте людьми, накропайте в общих чертах код!

Kovu
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 924
Зарегистрирован: 29.04.2005 (Пт) 17:38

Сообщение Kovu » 27.07.2006 (Чт) 13:58

Чтобы сделать активным вызываемое окно используй SetForegroundWindow. И SendKeys лучше заменить на
Код: Выделить всё
PostMessage wndHandle, WM_KEYDOWN, 13, ByVal 0&
Если всё делать своими ручками, они скоро отвалятся !

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 27.07.2006 (Чт) 14:35

Kovu, SendKeys лучше оставить. Либо слать и WM_KEYUP тоже.
ПереAPIзм -- зло.
Изображение

Kovu
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 924
Зарегистрирован: 29.04.2005 (Пт) 17:38

Сообщение Kovu » 27.07.2006 (Чт) 14:54

tyomitch писал(а):Kovu, SendKeys лучше оставить. Либо слать и WM_KEYUP тоже.
ПереAPIзм -- зло.

Гы, протестируй пожалуйста на окне блокнота, там если ему шлешь ещё и KEYUP букву добавляет 2 раза :)
Переапизм зло, но SendKeys не всегда срабатывает даже при вроде активном фокусе :roll:
Если всё делать своими ручками, они скоро отвалятся !

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 27.07.2006 (Чт) 15:04

Kovu писал(а):
tyomitch писал(а):Kovu, SendKeys лучше оставить. Либо слать и WM_KEYUP тоже.
ПереAPIзм -- зло.

Гы, протестируй пожалуйста на окне блокнота, там если ему шлешь ещё и KEYUP букву добавляет 2 раза :)

Значит, параметры не те передаёшь. Покажи свой код.
Изображение

Kovu
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 924
Зарегистрирован: 29.04.2005 (Пт) 17:38

Сообщение Kovu » 27.07.2006 (Чт) 15:56

tyomitch писал(а): Значит, параметры не те передаёшь. Покажи свой код.

Код: Выделить всё

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" ( _
     ByVal hWnd1 As Long, _
     ByVal hWnd2 As Long, _
     ByVal lpsz1 As String, _
     ByVal lpsz2 As String) As Long
Private Declare Function SetFocus1 Lib "user32.dll" Alias "SetFocus" ( _
     ByVal hwnd As Long) As Long
Private Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" ( _
     ByVal hwnd As Long, _
     ByVal wMsg As Long, _
     ByVal wParam As Long, _
     ByVal lParam As Long) As Long


Private Const WM_KEYDOWN As Long = &H100
Private Const WM_KEYUP As Long = &H101

Private Sub Command1_Click()
    Dim lHandle As Long
    lHandle = FindWindow("notepad", vbNullString)
    SetForegroundWindow lHandle
    lHandle = FindWindowEx(lHandle, ByVal 0&, "Edit", vbNullString)
    SetFocus1 lHandle
    PostMessage lHandle, WM_KEYDOWN, vbKeyS, ByVal 0&
    PostMessage lHandle, WM_KEYUP, vbKeyS, ByVal 0&

End Sub

Если всё делать своими ручками, они скоро отвалятся !

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 27.07.2006 (Чт) 16:52

А теперь почитай в описании WM_KEYxxx, что должно быть вместо ByVal 0&.
Изображение

Kovu
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 924
Зарегистрирован: 29.04.2005 (Пт) 17:38

Сообщение Kovu » 27.07.2006 (Чт) 16:58

tyomitch писал(а):А теперь почитай в описании WM_KEYxxx, что должно быть вместо ByVal 0&.

Видишь ли, Tyomitch, там раньше был просто 0, т.е. не повторять символ несколько раз. Тем не менее срабатывает 2 раза.
Если всё делать своими ручками, они скоро отвалятся !

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 27.07.2006 (Чт) 17:32

Видишь ли, Kovu, там только в нижнем слове счётчик повтора. Там, кстати, стоит единица при разовом нажатии. А не 0.
Но дело не в этом: верхнее слово кто за тебя заполнять будет?
Изображение

Kovu
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 924
Зарегистрирован: 29.04.2005 (Пт) 17:38

Сообщение Kovu » 27.07.2006 (Чт) 20:25

tyomitch писал(а):Видишь ли, Kovu, там только в нижнем слове счётчик повтора. Там, кстати, стоит единица при разовом нажатии. А не 0.
Но дело не в этом: верхнее слово кто за тебя заполнять будет?

MSDN писал(а):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 for the current message. The value is the number of times the keystroke is auto-repeated as a result of the user holding down the key. If the keystroke is held long enough, multiple messages are sent. However, the repeat count is not cumulative.
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.

И где здесь написано, что lParam состоит из верхнего и нижнего слова?
Если всё делать своими ручками, они скоро отвалятся !

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 27.07.2006 (Чт) 20:31

Издеваешься, что ли?

Kovu писал(а):
MSDN писал(а):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 for the current message. The value is the number of times the keystroke is auto-repeated as a result of the user holding down the key. If the keystroke is held long enough, multiple messages are sent. However, the repeat count is not cumulative.
------------------------------------------------------------------------------
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.

И где здесь написано, что lParam состоит из верхнего и нижнего слова?

Внимательно прочитай, что ниже черты.
Изображение

keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Сообщение keks-n » 28.07.2006 (Пт) 9:36

Да шлите вы WM_CHAR - всё равно после GetMessage итоит TranslateMessage. Хотя, там, по хорошему, всё равно нужно правильно формировать lParam, но одно сообщение лучше двух.
Изображение

Kovu
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 924
Зарегистрирован: 29.04.2005 (Пт) 17:38

Сообщение Kovu » 28.07.2006 (Пт) 13:55

tyomitch
Не издеваюсь, скорее недопонимаю. Там же явно не написано "lParam consists of high-word and low-word". Тогда вопрос: как правильно его заполнить(верхнее слово)? :roll:
Если всё делать своими ручками, они скоро отвалятся !

keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Сообщение keks-n » 28.07.2006 (Пт) 14:07

0–15 Specifies the repeat count for the current message. The value is the number of times the keystroke is auto-repeated as a result of the user holding down the key. If the keystroke is held long enough, multiple messages are sent. However, the repeat count is not cumulative.

Первые 16 байт и есть нижнее слово
Изображение

След.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot и гости: 88

    TopList