Объясните пожалуйста про глюки с хуками.

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

Сообщение Gigahard » 25.01.2006 (Ср) 16:09

Не хочу. Если все время пользоваться готовыми "кирпичами", не вникая в суть вопроса, то так никогда ничему и не научишся. А я создал тему чтобы разобраться...
Старый глюк лучше новых двух!

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

Сообщение keks-n » 25.01.2006 (Ср) 16:39

А ты посмотри как там сделано!
Изображение

Gigahard
Бывалый
Бывалый
 
Сообщения: 253
Зарегистрирован: 24.07.2002 (Ср) 11:15
Откуда: Russia

Сообщение Gigahard » 26.01.2006 (Чт) 11:12

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

Смысл этой темы не разобраться, как хуки ставить, а понять из за чего происходит падение среды разработки. Виновник найден, это End после восстановления WindowProc. Только вот почему End с сабклассингом дает такую гремучую смесь, не понятно.

В случае с "кирпичем" происходит тоже самое. Если хук поставить на объект, который потом будет снимать хук и завершать работу через End, то вылет IDE обеспечен.
Старый глюк лучше новых двух!

Pantalone
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 687
Зарегистрирован: 12.11.2005 (Сб) 16:46
Откуда: Сапог

Сообщение Pantalone » 01.02.2006 (Ср) 3:29

Gigahard
Вот блин, кто бы мог подумать, тоже мучаюсь этой проблемой, только щас нашел веку, а она создана буквально недавно :) Пришлось от End отказаться и мучаться вспоминать все ли у меня закрывается и выгружается ли прога.
И при том интересно, почему же VB вылетает при сабклассинге и использовании End? Что такого сабклассинг делает нехорошего что такое происходит?

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 01.02.2006 (Ср) 4:04

Использование end - яркий признак лени и кривых рук.
Сабклассинг, в данном случае, призван просто всё это выявить.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Pantalone
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 687
Зарегистрирован: 12.11.2005 (Сб) 16:46
Откуда: Сапог

Сообщение Pantalone » 01.02.2006 (Ср) 13:47

GSerg
Это надо сказать его разработчикам.

Gigahard
Бывалый
Бывалый
 
Сообщения: 253
Зарегистрирован: 24.07.2002 (Ср) 11:15
Откуда: Russia

Сообщение Gigahard » 01.02.2006 (Ср) 15:00

В VB вообще много веселых моментов. И End не уникален в этом плане. Например представте себе ситуацию, когда при загрузке формы, вы делаете перехват исключительных ситуаций. И по итогу одной исключительной ситуации, Вам нужно завершить программу, а при ином раскладе продолжить. Как завершать программу в этом случае? Что поставить? End или Unload Me... Результат можно посмотреть... В данном случае End решает.

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

Private Sub Form_Load()
Dim res As String
res = "c"
Select Case res
Case a
MsgBox "Выплняем план А"
Case "b"
MsgBox "Выполням план B"
Case "c"
MsgBox "Провал! Завершаем операцию!"
'Код завершения программы. Нужно оставить только один вариант
'Unload Me
End
End Select
'Код который должен запускаться, если проверка прошла
MsgBox "Основной код программы"
End Sub
Старый глюк лучше новых двух!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 01.02.2006 (Ср) 15:02

Достаточно правильно проектировать приложение, чтобы таких ситуаций не возникало.
Lasciate ogni speranza, voi ch'entrate.

Gigahard
Бывалый
Бывалый
 
Сообщения: 253
Зарегистрирован: 24.07.2002 (Ср) 11:15
Откуда: Russia

Сообщение Gigahard » 01.02.2006 (Ср) 15:04

Это уже немного другой разговор :)
Старый глюк лучше новых двух!

gvozd1989
Новичок
Новичок
 
Сообщения: 38
Зарегистрирован: 13.01.2005 (Чт) 9:16
Откуда: Украина

Сообщение gvozd1989 » 01.02.2006 (Ср) 15:52

Так лучше Унлоадить все формы, чем ендить?
Изображение

Gigahard
Бывалый
Бывалый
 
Сообщения: 253
Зарегистрирован: 24.07.2002 (Ср) 11:15
Откуда: Russia

Сообщение Gigahard » 01.02.2006 (Ср) 16:01

Вообще как я заметил, VB имеет проблемы с досрочной выгрузкой формы или выходом из программы, если эта самая загрузка не завершена. Т.е. если не дошло до End Sub или Exit Sub, то не факт, что сработает завершение программы. В данном случае End срабатывает, Unload нет.
Старый глюк лучше новых двух!

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

Сообщение Amed » 01.02.2006 (Ср) 16:14

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

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 01.02.2006 (Ср) 16:27

Gigahard писал(а):В данном случае End решает.

Что за глупость?..
Unload не срабатывает, если после него есть другие команды. В этом случае после unload сразу вызывается load.

Код: Выделить всё
Private Sub Form_Load()
  Dim res As String
 
  res = "c"
 
  if res = "c" then
    MsgBox "Провал! Завершаем операцию!"
    Unload Me
  else
    Select Case res
    Case a
      MsgBox "Выплняем план А"
    Case "b"
      MsgBox "Выполням план B"
    End Select
    'Код который должен запускаться, если проверка прошла
    MsgBox "Основной код программы"
  end if
End Sub
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 01.02.2006 (Ср) 19:07

Код: Выделить всё
Кстати вылет IDE происходит только если End содержится в одной процедуре со снятием хука или если в эта процедура вызывает другую в которой содержится End.

Н-да... А ты никогда не задумывался, какая такая процедура вызвала процедуру Form_Unload? Неужели твоя самая "хучная" процедура?
А теперь представь, что в form_unload ты вызываеш end. Отладчик выкидывает код "хучной" процедуры... Но Вероятно, ему еще надо почистить стэк за form_unload и тут он такыется на указатель того, чего уже нет
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Gigahard
Бывалый
Бывалый
 
Сообщения: 253
Зарегистрирован: 24.07.2002 (Ср) 11:15
Откуда: Russia

Сообщение Gigahard » 01.02.2006 (Ср) 21:43

Н-да... А ты никогда не задумывался, какая такая процедура вызвала процедуру Form_Unload? Неужели твоя самая "хучная" процедура?
А теперь представь, что в form_unload ты вызываеш end. Отладчик выкидывает код "хучной" процедуры... Но Вероятно, ему еще надо почистить стэк за form_unload и тут он такыется на указатель того, чего уже нет

Если ты имеешь ввиду то, что ход выполнения процедуры прерываемый хуком не восстанавливается после End, и поэтому происходит ее вылет, хочу в который раз заметить, что перед End происходит восстановление хода процедуры, хук снимается, т.е. End срабатывает уже тогда, когда процедура идет своим обычным ходом без вклиненого хука...

GSerg: Не столь важно, как и когда срабатывает Unload, важно то, что он далеко не всегда применим. Это скорее вопрос о судьбе и роли End. Например в приведенной ситуации экстренного завершения загрузки формы. А такая ситуация может возникнуть. Не всегда такие ситуации можно обработать до загрузки формы в модуле. Например ошибки в инициализации контролов, которые располагаются на форме.
Старый глюк лучше новых двух!

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 01.02.2006 (Ср) 23:18

2Gigahard
хочу в который раз заметить, что перед End происходит восстановление хода процедуры

Хочу тебе еще раз заметить, что восстановление происходит в процедуре Form_Unload, которая была вызвана процедурой-хуком.
У меня есть все основания полагать, что vb совершает обратную "прогулку" по стэку, что бы корректно завершить операцию закрытия окна, и там встречается, верятно, с тем, что оконная процедура уже удалена из памяти, сильно на это сердится...
Understand?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 02.02.2006 (Чт) 4:57

Gigahard писал(а):Не столь важно, как и когда срабатывает Unload, важно то, что он далеко не всегда применим. Это скорее вопрос о судьбе и роли End. Например в приведенной ситуации экстренного завершения загрузки формы. А такая ситуация может возникнуть. Не всегда такие ситуации можно обработать до загрузки формы в модуле.

Ты вообще код смотрел, который я привёл?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Gigahard
Бывалый
Бывалый
 
Сообщения: 253
Зарегистрирован: 24.07.2002 (Ср) 11:15
Откуда: Russia

Сообщение Gigahard » 02.02.2006 (Чт) 11:11

Ты вообще код смотрел, который я привёл?

Все... Понял... :) :oops: .

ANDLL Вообще проявление вылета не завязано конкрентно на событие Unload. Точно такой же эффект будет если снятие хука и End повесить на обработку нажатия кнопки. Процедура Unload в данном случае не будет привязана к снятию хука, однако ж вылет все равно происходит.
Старый глюк лучше новых двух!

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 02.02.2006 (Чт) 11:18

Да, потому что процедура Button_Click то же вызывается процедурой хуком.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Pantalone
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 687
Зарегистрирован: 12.11.2005 (Сб) 16:46
Откуда: Сапог

Сообщение Pantalone » 02.02.2006 (Чт) 11:52

Еще и с отладной проблемы, поставил точку останове в коде никак не связанном с хуком, прога остановилась, а в дебагер не залезть, повисло все нахрен :) Приходится хук отключать на время разработки, не забыть бы потом включить :)

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 02.02.2006 (Чт) 12:11

Господи, мистер Pantalone, почему бы Вам не взять на себя труд и не перечитать этот топик? Какой смысл писать то, что уже было написано?
Приходится хук отключать на время разработки, не забыть бы потом включить

Для этих целей, кстати, весьма удобны константы компиляции.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Gigahard
Бывалый
Бывалый
 
Сообщения: 253
Зарегистрирован: 24.07.2002 (Ср) 11:15
Откуда: Russia

Сообщение Gigahard » 02.02.2006 (Чт) 15:26

А... Ты имеешь ввиду то, что сами обработчики событий построены на тех же хуках и отрубая хук мы удаляем информацию о вызове самой процедуры :?:
Старый глюк лучше новых двух!

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 02.02.2006 (Чт) 19:42

Отрубая ПРОГРАММУ(вызовом End) а не хук, ты уничтожаеш процедуру, ссылка на которую лежит в стэке на данный момент. Для транслятора это большая неожиданность, поэтому он и вылетает. Ну в общем, что-то типа того.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Gigahard
Бывалый
Бывалый
 
Сообщения: 253
Зарегистрирован: 24.07.2002 (Ср) 11:15
Откуда: Russia

Сообщение Gigahard » 03.02.2006 (Пт) 10:55

Так... По порядку... Идет допустим стандартная виндовая процедура... Мы вклиниваем туда хук и подменяем адресс текущей процедуры своей... Т.е. теперь системные сообщения сначала проходят через наш вклиненый обработчик, а потом уже дальше передаются основной процедуре... Так? Если мы вызываем End не восстанавливая адресс текущей процедуры, то естественно обработчик не может найти нить и вылетает. Но почему он вылетает, когда нормальный ход процедуры восстановлен после снятия хука? Или End в данном случае каким то непнятным образом привязывается к хучной процедуре которая уже удалена со снятием хука? Как такое может произойти, если End вызывался не из тела хучной процедуры, а из основной, когда хук уже был снят и по идее упоминания о нем уже нет...?
Старый глюк лучше новых двух!

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 03.02.2006 (Пт) 11:00

Но почему он вылетает, когда нормальный ход процедуры восстановлен после снятия хука?

Потому что он не восттановлен. Каким образом ты его восстановиш?
Как такое может произойти, если End вызывался не из тела хучной процедуры, а из основной, когда хук уже был снят и по идее упоминания о нем уже нет...?

Тело этой основной процедуры лежит внутри тела хука. Т.е. ты вызываеш основную процедуру ИЗ хука. И упоминание про него еще есть в стэке, ты не до конца понимаеш механизм этого процесса.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 03.02.2006 (Пт) 11:12

Обрисую все попдробнее

Вот что происходит в стандартной ситуации:
1)некто_или_нечто вызывает DispatchMessage
2) DispatchMessage вызывает стандартную оконную процедуру
3) стандартная оконная процедура вызывает Form_Unload
4) From_Unload вызывает End. End очищает внутренности программы и передает управление стандартной окнной процедуре
5) стандартная окнная процедура должна завершить уничтожение окна, именно поэттому End возвращает ей управление(хотя в теории мог бы этого не делать, а сразу завершать нить)
6) После окончательного удаления окна, оконная процедура возвращает управление DispatchMessage

А вот, что происходит, если на данной окнной процедуре был хук:
1)некто_или_нечто вызывает DispatchMessage
2) DispatchMessage вызывает процедуру хук
2а) Процедура хук вызывает стандартную оконную процедуру
3) стандартная оконная процедура вызывает Form_Unload
4) From_Unload вызывает End. End очищает внутренности программы и передает управление стандартной окнной процедуре
5) стандартная окнная процедура должна завершить уничтожение окна, именно поэттому End возвращает ей управление(хотя в теории мог бы этого не делать, а сразу завершить нить)
6) После окончательного удаления окна, оконная процедура возвращает управление процедуре хуку(она то думает, что ее вызвала DispatchMessage...)
7) А процедуры-хука уже нету...
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

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

Сообщение Kovu » 03.02.2006 (Пт) 12:09

По поводу 5 пункта: ВБ не создает в IDE отдельной нити для запуска проекта, мы работаем в нити среды, конкретно в той, которой принадлежит основное окно разработки (для проверки этого достаточно вызвать ExitThread 0) :roll:
Если всё делать своими ручками, они скоро отвалятся !

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 03.02.2006 (Пт) 12:13

Ну тогда тем более, он обязан пробежать по стэку в обратном направлении.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Gigahard
Бывалый
Бывалый
 
Сообщения: 253
Зарегистрирован: 24.07.2002 (Ср) 11:15
Откуда: Russia

Сообщение Gigahard » 03.02.2006 (Пт) 14:38

Если предположить, что End воспринимает программу, как родную нить IDE, то вылет по идее должен был бы происходить во всех случаях применения End.
Старый глюк лучше новых двух!

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 03.02.2006 (Пт) 15:08

то вылет по идее должен был бы происходить во всех случаях применения End

Не понимаю, по какой такой идеи, так должно происходить?
То что это так, наглядно демонстрирует Spy++.
2Kovu:Не поделитесь секретом, почему вы берете на себя труд присовокуплять смайлик rolling eyes к каждому своему посту?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Пред.След.

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

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

Сейчас этот форум просматривают: Yandex-бот и гости: 18

    TopList