Почему in-process компонент не может сабклассить приложение

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Почему in-process компонент не может сабклассить приложение

Сообщение Eugenio » 24.01.2005 (Пн) 7:56

Собсна, сабж. DLL загружена приложением,
GetActiveWindow возвращает дескриптор главного окна приложения (т.е., компонент приаттачен в тот же thread), а при попытке указать вместо оконной процедуры одного из дочерних окон приложения адрес своей процедуры - ошибка, не может memory быть written. Объясните тупому, что за черт
Есть ли у меня вопрос? У меня всегда есть вопрос

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

Сообщение tyomitch » 24.01.2005 (Пн) 9:26

Наверняка ошибка где-нибудь в коде, пропустил ByVal либо поставил лишний.

Показывай код ;-)
Изображение

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 24.01.2005 (Пн) 9:55

Оно со мной бывает (насчет лишних и недостающих ByVal), но здесь именно в API вызовах, вроде, все в порядке. Весь код в одном модуле
Код: Выделить всё
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Перезапись адреса процедуры:
Код: Выделить всё
Public Sub AddFormsData(ByVal hWnd As Long)
    Dim hAppForm As AppForm
   
    FormsCount = FormsCount + 1
   
    hAppForm.hWnd = hWnd
    hAppForm.hOwnWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf FormWndProc)
    'отладка
    MsgBox "Перезаписан!"
    ReDim Preserve FormsData(1 To FormsCount)
    FormsData(FormsCount) = hAppForm
End Sub

Оконная процедура:
Код: Выделить всё
Public Function FormWndProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim hAppForm As AppForm, hFormWndProc As Long
   
    hAppForm = FindFormData(CStr(hWnd))
    hFormWndProc = hAppForm .hOwnWndProc
   
    On Error Resume Next
    Select Case Msg
        Case WM_NOTIFY
            Select Case lParam
                    .........................
            End Select
        Case WM_LBUTTONDOWN
               ..............
        Case Else
    End Select
    FormWndProc = CallWindowProc(hFormWndProc, hWnd, Msg, wParam, lParam)
End Function

(до MsgBox "Перезаписан!" не доходит)
ОПА! В итоге, вот сейчас (раньше только "could not be written") - ругается так:
the exception Floating-point inexact result (0xc000008f)

про 0xc000008f не нашел ничего. Была проблема с CoolBar'ом, которая вызывала что-то похожее, надо посмотреть...
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 24.01.2005 (Пн) 12:11

Что, я чего-то очевидного не замечаю? :) :?
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 24.01.2005 (Пн) 15:00

Люди? Лю-у-ди! :?
Есть ли у меня вопрос? У меня всегда есть вопрос

Sebas
Неуловимый Джо
Неуловимый Джо
Аватара пользователя
 
Сообщения: 3626
Зарегистрирован: 12.02.2002 (Вт) 17:25
Откуда: столько наглости такие вопросы задавать

Сообщение Sebas » 24.01.2005 (Пн) 15:33

AppForm - это что?
- Я никогда не понимал, почему они приходят ко мне чтобы умирать?

sebas<-@->mail.ru

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 24.01.2005 (Пн) 15:43

Sebas писал(а):AppForm - это что?

AppForm - это объявленный в проге тип. А какая разница? проблема с SetWindowLong
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 25.01.2005 (Вт) 8:11

мегачелы, не могу я с этой проблемой разобраться. И писать дополнительную dll, чтобы ставить hook - не хочу (тем более - переписывать всё на C, в компоненте уже с три короба всего наваяно).
Спасите-помогите. Хочется, по крайности, понять, преодолима ли проблема, в моем она коде или в чужой проге. если не преодолима - ну, буду переписывать под хук.. Но оччень не хочется.
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 25.01.2005 (Вт) 9:21

Может там быть какая-то защита от перезаписи атрибутов?
Есть ли у меня вопрос? У меня всегда есть вопрос

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

Сообщение tyomitch » 25.01.2005 (Вт) 12:18

Нет никакой защиты. Всё должно бы работать...

А может это у тебя Native DLL?
Изображение

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 25.01.2005 (Вт) 14:09

tyomitch писал(а):Нет никакой защиты. Всё должно бы работать...

А может это у тебя Native DLL?

Где? Я вообще не знаю, как они делаются на VB. по-моему, можно только расковырять ActiveX DLL вручную :)
А если это о приложении - оно загружает целую кучу native dll, но какая разница? Окно-то окном...
Есть ли у меня вопрос? У меня всегда есть вопрос

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

Сообщение GSerg » 25.01.2005 (Вт) 14:39

А это случаем не apartment-threading компонент, который там юзает всякие межпроцессные переходнички, в результате чего возникают всякие проблемы с адресным пространством?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 25.01.2005 (Вт) 14:49

GSerg писал(а):А это случаем не apartment-threading компонент, который там юзает всякие межпроцессные переходнички, в результате чего возникают всякие проблемы с адресным пространством?

Нет, это single-threaded
Я в моделях памяти не секу - не умею применять эти apartment-threaded. Только-только начал заново разбираться. Не пробовал все эти CreateThread and so on
Последний раз редактировалось Eugenio 25.01.2005 (Вт) 17:08, всего редактировалось 1 раз.
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 25.01.2005 (Вт) 15:09

Самое интересное, я уже стряпал плагины (с разными, конечно, технологиями подключения), которые вот подобным образом чужими окнами управляли - в плагине для excel это сработало (SetWindowLong и проч.), для word - сработало, а тут..
Последний раз редактировалось Eugenio 25.01.2005 (Вт) 20:17, всего редактировалось 1 раз.
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 25.01.2005 (Вт) 20:17

Люди, не будет больше мнений?

:( Пойду повешусь. Всё переписывать на C и по другому!...
Есть ли у меня вопрос? У меня всегда есть вопрос

SergeySV2
Новичок
Новичок
 
Сообщения: 33
Зарегистрирован: 06.01.2005 (Чт) 22:06

Сообщение SergeySV2 » 25.01.2005 (Вт) 23:42

чей то в msdn нехорошее написано

http://msdn.microsoft.com/library/en-us ... owlong.asp

Windows 95/98/Me: The SetWindowLong function may fail if the window specified by the hWnd parameter does not belong to the same process as the calling thread.

А ты в какой винде работаешь?

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 26.01.2005 (Ср) 9:28

Работаю на Win2003 + XP на раб.станциях.
К тому же, это in-process компонент, его загружает сама эта чертова прога, окном которой я пытаюсь манипулировать. Компонент в одном из её thread'ов. GetActiveWindow, я ж писал, указывает на главное окно проги, а эта функция возвращает активное окно в том же thread'e (а не только процессе), что и вызывающий. Но я не слышал, чтобы были проблемы, когда вызов идет из другого потока - везде говорится только о невозможности работать с другим процессом. Типа того, что ты нашел и вот этого (про изменение адреса процедуры):
Windows NT/2000/XP: You cannot change this attribute if the window does not belong to the same process as the calling thread.
Есть ли у меня вопрос? У меня всегда есть вопрос

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

Сообщение GSerg » 26.01.2005 (Ср) 16:54

Ээээ, батенька, менят-то разрешается, но вот все thread-related issues нужно обрабатывать самому... Блокировки, одновременный доступ к памяти... Отладка многопоточного приложения - страшный гемор, с учётом того, что баг может появиться, а может не появиться, в зависисмости от того, в каком именно месте винда переключит потоки...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 26.01.2005 (Ср) 20:37

GSerg, то есть что получается: это прога запускает несколько потоков. И если в момент, когда я пытаюсь перезаписать что-нибудь в одном из потоков, а именно он в это время ожидает (прога переключилась на другой) - происходит та самая гадость? Так, грубо говоря?
Т.о., чтобы все сработало, нужно, типа, активизировать thread?
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 27.01.2005 (Чт) 9:33

Видимо, так оно всё и есть.
:?: Можно ли подступиться к конкретному потоку, причем так:
- получить как-то его handle по дескриптору окна
- активизировать
- выполнить операцию с окном
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 27.01.2005 (Чт) 20:18

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

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

Сообщение tyomitch » 28.01.2005 (Пт) 7:39

Чего-то топик превращается в монолог... Плохая примета :-)

Eugenio, зацени GetWindowThreadProcessId, SuspendThread/ResumeThread и сопутствующие функции...
Изображение

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 28.01.2005 (Пт) 12:00

tyomitch писал(а):Чего-то топик превращается в монолог... Плохая примета :-)

Ох, плохая!
tyomitch писал(а):зацени GetWindowThreadProcessId, SuspendThread/ResumeThread и сопутствующие функции...

Это правильные функции, да.
Можно
GetWindowThreadProcessId (получили идентификатор);
OpenThread (получили хэндл);
ResumeThread пока возвращаемая задержка > 0.

НО! Я думаю, это не поможет, потому что выполняемая функция dll-ки -всё равно в другом потоке, активный он или нет. Тут нужен какой-то обмен данными с тем потоком. А как это делается, непонятно
Есть ли у меня вопрос? У меня всегда есть вопрос


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

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

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

    TopList