Как сделать чтобы прога с сабклассингом не падала в IDE

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

Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение jangle » 24.12.2013 (Вт) 19:55

Забыл уже как. В гугле ссылки мертвые.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение The trick » 24.12.2013 (Вт) 21:28

Убирать сабклассинг перед закрытием проги, или через асм-вставку можно
UA6527P

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение jangle » 24.12.2013 (Вт) 21:30

Кривоус Анатолий писал(а):Убирать сабклассинг перед закрытием проги, или через асм-вставку можно


Пример?

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение The trick » 24.12.2013 (Вт) 21:53

Да какой пример то? Вызывай Unhook перед закрытием и все (не останавливай проект кнопкой стоп). До этого стояла WinXP - вылетало при нажатии "стоп" (бывает забудешь или ошибка какая), недавно поставил Win7 x64 перестало, теперь торможу сабклассинг как хочу (хотя 7-ка честно не нравится мне).
Вложения
RichHyperLink.rar
(3 Кб) Скачиваний: 135
UA6527P

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение jangle » 24.12.2013 (Вт) 22:08

Если проект валится с ошибкой в коде? Как я могу его не останавливать?

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение The trick » 24.12.2013 (Вт) 22:11

jangle писал(а):Если проект валится с ошибкой в коде? Как я могу его не останавливать?
Ну тык должно без ошибок быть. Запусти оконную процедуру перед сабклассингом напрямую и посмотри что за ошибка, либо если все нормально On error и смотри код ошибки через Debug.Print, брейкпоинт поставить тоже можно, не забывая DefWindowProc или CallWindowProc выполнять.
UA6527P

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение Хакер » 25.12.2013 (Ср) 7:48

jangle, тут arthur2 целый труд написал на эту тему. Ищи его топик.

Кстати, напомню, что причина падения в баге IDE. При остановке проекта все высунутые наружу процедуры не уничтожаются, а просто, так сказать «переводятся стрелки», чтобы они не выполнялись, а сразу эмулировался выход из них. Вот эта эмуляция делает неправильный retn — всегда делается retn 0 независимо от кол-ва аргументов, к которой относится переходничок. Переходнички генерируются средой на лету и там предусмотрено правильное выставление «аргумента» для retn, но то, откуда берётся значение — это поле тоже почему-то всегда содержит ноль.

Можно написать плагин, который исправляет это.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение jangle » 25.12.2013 (Ср) 10:51

Хакер спасибо! Код работает.

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

Public Event KeyDown(ByVal KeyCode As Long)

Private Const WM_KEYDOWN As Long = &H100
Private Const cNull As Long = &H0

Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Const AsmMain As String = "558BEC83C4FC8D45FC50FF7514FF7510FF750CFF75086800000000B800000000FFD08B45FCC9C21000"

'    0  1  2  3  4  5  6  7    8  9  A  B  C  D  E  F
' ---------------------------------------------------
'|  55 8B EC 83 C4 FC 8D 45   FC 50 FF 75 14 FF 75 10
'|  FF 75 0C FF 75 08 68 00   00 00 00 B8 00 00 00 00
'|  FF D0 8B 45 FC C9 C2 10   00


Private OldCtl      As Long, OldCtl1     As Long
Private ASM_Ctl()   As Byte
Private ASM()   As Byte
Dim mHwnd As Long, mHwnd1 As Long

'адрес этой функции получается по номеру ProcNumber
Public Function winProc0(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  Select Case uMsg
  Case WM_KEYDOWN
    RaiseEvent KeyDown(wParam)
  End Select
   winProc0 = CallWindowProc(OldCtl, hWnd, uMsg, wParam, lParam)
End Function

'адрес этой функции получается по номеру ProcNumber
Public Function winProc1(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'  Select Case uMsg
'  Case WM_KEYDOWN
'    RaiseEvent KeyDown(wParam)
'  End Select
   winProc1 = CallWindowProc(OldCtl, hWnd, uMsg, wParam, lParam)
End Function

Public Function Hook(ByVal hWnd As Long)
  mHwnd = hWnd
  Call StartSubclass(hWnd, OldCtl, 0)
End Function


Private Sub StartSubclass(ByVal hWnd As Long, _
                          ByRef OldWndProc As Long, _
                          ByVal ProcNumber As Long)
  Dim lng As Long
  Dim tPtr As Long

  ASM = ASM_Ctl
  Call CopyMemory(tPtr, ByVal ObjPtr(Me), 4&)
  Call CopyMemory(lng, ByVal tPtr + &H1C + (4& * ProcNumber), 4&)
  Call CopyMemory(ASM(23), ObjPtr(Me), 4&)
  Call CopyMemory(ASM(28), lng, 4&)
  OldWndProc = SetWindowLong(hWnd, &HFFFC, VarPtr(ASM(0)))

' ProcNumber - номер функции в этом  классе, начиная сверху по порядку вниз...
End Sub

Public Sub Unhook()
  If OldCtl Then Call SetWindowLong(mHwnd, &HFFFC, OldCtl)
End Sub


Private Sub Class_Initialize()
  Dim lng As Long
  Dim tPtr As Long
  lng = Len(AsmMain) \ 2&
  ReDim ASM_Ctl(cNull To lng - vbNull)
  For lng = cNull To lng - vbNull
    ASM_Ctl(lng) = Val("&H" & Mid$(AsmMain, (lng) * 2& + vbNull, 2&))
  Next

End Sub

Private Sub Class_Terminate()
  Call Unhook
End Sub

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение Хакер » 25.12.2013 (Ср) 10:57

За такой код надо убивать. Не-DEP-compatible.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение jangle » 25.12.2013 (Ср) 11:17

Хакер писал(а):За такой код надо убивать. Не-DEP-compatible.


Чем это может грозить? Проверил проект на 3 машинах с Win7, Win8, Win8.1 везде работает без сбоев

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение The trick » 25.12.2013 (Ср) 11:19

Ты почитай тот пост весь до конца, целесообразней использовать вставку Хакера, с небольшой доработкой. Насчет DEP, можно создать кучу с разрешением на выполнение и в массиве поменять указатель на данные на адрес выделенной из этой кучи памяти. В таком случае можно работать через массив напрямую в разрешенной для области выполнения. Тут был пост про побитовый сдвиг, там можешь пример посмотреть. Только перед всеми манипуляциями надо сначала выделить размер, а после всего поменять все назад.
Кстати к чему это вообще? Для чего весь изврат для вызова внутри класса? Чем стандартный модуль не устраивает? Если есть ошибки внутри кода в модуле, также они будут и в модуле класса. Если у тебя все заработало через класс, значит скорее всего что-то ты с параметрами WindowProc намудрил. Мой пример с RichTextBox'ом работает? Вылетает?
UA6527P

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение Хакер » 25.12.2013 (Ср) 11:43

jangle писал(а):Чем это может грозить?

Ясное дело чем:
crappy_code_crashing_with_dep.png
crappy_code_crashing_with_dep.png (9.59 Кб) Просмотров: 7936


jangle писал(а):Проверил проект на 3 машинах с Win7, Win8, Win8.1 везде работает без сбоев

Это говорит лишь о том, что DEP не поддерживается там процессором или же выключен в настройках ОС для прикладных программ.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение jangle » 25.12.2013 (Ср) 11:49

Посмотрел настройки на всех машинах, DEP включен по дефолту только для программ и служб Windows.
Думаю особо беспокоится не о чем.

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

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение alibek » 25.12.2013 (Ср) 13:18

jangle писал(а):Думаю особо беспокоится не о чем.

viewtopic.php?t=41756
Lasciate ogni speranza, voi ch'entrate.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение jangle » 25.12.2013 (Ср) 14:14

Кривоус Анатолий писал(а):Ты почитай тот пост весь до конца, целесообразней использовать вставку Хакера, с небольшой доработкой. Насчет DEP, можно создать кучу с разрешением на выполнение и в массиве поменять указатель на данные на адрес выделенной из этой кучи памяти. В таком случае можно работать через массив напрямую в разрешенной для области выполнения. Тут был пост про побитовый сдвиг, там можешь пример посмотреть. Только перед всеми манипуляциями надо сначала выделить размер, а после всего поменять все назад.
Кстати к чему это вообще? Для чего весь изврат для вызова внутри класса? Чем стандартный модуль не устраивает? Если есть ошибки внутри кода в модуле, также они будут и в модуле класса. Если у тебя все заработало через класс, значит скорее всего что-то ты с параметрами WindowProc намудрил. Мой пример с RichTextBox'ом работает? Вылетает?


Да вроде все работает. Но мне категорически лень напрягать мозг. :alien:

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение iGrok » 25.12.2013 (Ср) 15:34

jangle писал(а):Чем это может грозить?

Ничем, пока твоему софту не понадобится работать на любой серверной ОС, или просто на машине с включенным DEP (как у Хакера, или, например, у меня).
А к тому времени, как понадобится, ты и думать забудешь про какой-то там DEP. Так что happy debugging :mrgreen:!
label:
cli
jmp label

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение Хакер » 25.12.2013 (Ср) 18:56

jangle, я думал, ты вырос из той возрастной категории программистов, которые делают программы, которые работают только на их машине и нигде больше. Но, похоже, ты возвращаешься в неё?

Отличный пример того, как не надо делать. У тебя есть шанс сделать 5 дополнительных вызовов, или даже один (VirtualProtect), чтобы встать на правильный путь. Или ты можешь использовать свой ужасный подход, но применить мой трюк для проверки работы под IDE, чтобы этот неверный код не попадал в скомпилированную версию.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение jangle » 25.12.2013 (Ср) 21:01

Хакер - выложи если не трудно пример кода. Этим проектом я завершаю карьеру VB-программиста, хочется все сделать красиво.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение Хакер » 25.12.2013 (Ср) 21:07

Без примеров. Нужно вызвать HeapCreate с флагом ALLOW_EXECUTE (написанание без префиса, префикс не помню), затем в ней HeapAlloc'ом выделить память и уже в эту память писать любой native-код.

По ненадобности кусочек кучи с кодом освобождается вызовом HeapFree, а сама куча уничтожается вызовом HeapDestroy.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение jangle » 25.12.2013 (Ср) 21:22

Хакер писал(а):Без примеров. Нужно вызвать HeapCreate с флагом ALLOW_EXECUTE (написанание без префиса, префикс не помню), затем в ней HeapAlloc'ом выделить память и уже в эту память писать любой native-код.

По ненадобности кусочек кучи с кодом освобождается вызовом HeapFree, а сама куча уничтожается вызовом HeapDestroy.


Ок, напишу код и выложу сюда

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение The trick » 25.12.2013 (Ср) 21:58

jangle, Вы мой пост проигнорировали чтоли? Я Вам написал где посмотреть как правильно сделать. viewtopic.php?f=1&t=44779
К тому же непонятен смысл всех этих манипуляций? Зачем нужна ассемблерная вставка если Вы не хотите "напрягать мозги" и не понимаете как это работает? Делайте в обычном модуле, у Вас меньше головной боли будет.
UA6527P

bon818
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 267
Зарегистрирован: 29.08.2009 (Сб) 4:49
Откуда: Ташкент

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение bon818 » 25.12.2013 (Ср) 22:46

А если просто сабклассинг перенести в OCX , и убирать обратно в код после отладки

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 26.12.2013 (Чт) 0:07

jangle писал(а):Этим проектом я завершаю карьеру VB-программиста

Почему? А что дальше?

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re:

Сообщение jangle » 26.12.2013 (Чт) 9:29

Qwertiy писал(а):
jangle писал(а):Этим проектом я завершаю карьеру VB-программиста

Почему? А что дальше?


Давно уже пишу на тяжеловесном шарпе. Долго пришлось преодолевать отвращение к дотнету, но я справился)

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение Хакер » 26.12.2013 (Чт) 12:01

Кстати, перед тем, как выдать такое окошко, как я выше приаттачил, всё-таки выдаётся ещё вот такое:
dep_warning_snagit.png
dep_warning_snagit.png (15.94 Кб) Просмотров: 7845


Так что пожелание «Happy debugging», к сожалению одних и радости других, предвещает не такую уж мучительную отладку.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение iGrok » 26.12.2013 (Чт) 18:48

Хакер писал(а):Так что пожелание «Happy debugging», к сожалению одних и радости других, предвещает не такую уж мучительную отладку.

Это на XP. На Vista+ по DEP-исключению софт сразу падает с ошибкой и без каких-либо внятных комментариев.
Хотя, конечно, по имени ошибки (BEX) всё равно сходу гуглится "решение" по которому можно догадаться о причине проблемы.
Впрочем, иногда они падают и с APPCRASH, и там уже по коду ошибки догадаться о реальной причине в принципе невозможно.
label:
cli
jmp label

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение Хакер » 26.12.2013 (Чт) 21:18

iGrok писал(а):Это на XP. На Vista+ по DEP-исключению софт сразу падает с ошибкой и без каких-либо внятных комментариев.

Если это так, то кто ещё мне скажет, что Vista+ это прогресс по сравнению с XP?..
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение iGrok » 26.12.2013 (Чт) 23:04

[offtop]
Хакер писал(а):Если это так, то кто ещё мне скажет, что Vista+ это прогресс по сравнению с XP?..

Про то, как выглядят BSOD-ы в Win8 ты же слышал уже? :)
И да, с определённой точки зрения это прогресс, т.к. домохозяек больше не смущают лишней информацией. Прям будто Джоэлевское руководство по дизайну UI прочитали. Соответственно, с точки зрения неподготовленного пользователя система становится проще и удобнее. А кто у них основная масса покупателей сейчас? Вот-вот..
Другой вопрос, что нужно было не прибивать эту информацию нафиг, а спрятать за каким-нибудь "подробнее", или хотя бы запрятать включение отображения подробных сообщений в настройки системы. Но тогда стало бы меньше поводов ругать майкрософт. :mrgreen:
Ну а про равнение десктопных ОС на планшеты и сенсорное управление я лучше вообще промолчу...
[/offtop]
label:
cli
jmp label

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Как сделать чтобы прога с сабклассингом не падала в IDE

Сообщение jangle » 27.12.2013 (Пт) 9:33

Хакер писал(а):Кстати, перед тем, как выдать такое окошко, как я выше приаттачил, всё-таки выдаётся ещё вот такое:


Так что пожелание «Happy debugging», к сожалению одних и радости других, предвещает не такую уж мучительную отладку.

Код: Выделить всё
'API In General Declaration Section
Private Declare Function SetProcessDEPPolicy Lib "Kernel32.dll" (ByVal dwFlags As Long) As Long

'To Disable DEP
SetProcessDEPPolicy(0)

'To Enable DEP
SetProcessDEPPolicy(1)


ВНЕЗАПНО! Я просто отключу DEP для своей программы :D

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 27.12.2013 (Пт) 9:44

jangle писал(а):Private Declare Function SetProcessDEPPolicy Lib "Kernel32.dll" (ByVal dwFlags As Long) As Long

Что-то мне подсказывает, что она не будет работать без админских прав... Хотя не знаю. Ты не проверял?

След.

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

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9

    TopList