Вопрос: Нужен Hook! | Добавлено: 22.05.04 15:45 |
Автор вопроса: ![]() |
Парни, нужен качественный субклассировщик, позволяющий ставить hook на несколько окон одновременно. Может у кого-нибудь есть? |
Ответы | Всего ответов: 16 |
Номер ответа: 1 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() Разработчик Offline Client ICQ: 233286456 Вопросов: 34 Ответов: 5445 |
Web-сайт: Профиль | Цитата | #1 | Добавлено: 22.05.04 19:40 |
Дык это не на VB прийдется писать... |
Номер ответа: 2 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #2 | Добавлено: 24.05.04 23:05 |
Может у кого уже готовый есть.. Я нашел один-отличный! Но работает только с одним окном. При постановке hooka на второе окно, в первом начинаются глюки. |
Номер ответа: 3 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #3 | Добавлено: 24.05.04 23:07 |
Может у кого уже готовый есть.. Я нашел один-отличный!(позволяет отлавливать событие как до,так и после его наступления.. также есть возможность замены сообщения своим.) Но работает только с одним окном. При постановке hooka на второе окно, в первом начинаются глюки. |
Номер ответа: 4 Автор ответа: ![]() ![]() ![]() ![]() ![]() ICQ: 554200 Вопросов: 101 Ответов: 343 |
Профиль | Цитата | #4 | Добавлено: 24.05.04 23:08 |
hgfhgfh |
Номер ответа: 5 Автор ответа: ![]() ![]() ![]() ![]() ![]() ICQ: 554200 Вопросов: 101 Ответов: 343 |
Профиль | Цитата | #5 | Добавлено: 24.05.04 23:09 |
Хукна что тебе нужен? На клаву, на мышь? или на что? И какой должна быть функция установки хука? Какие параметры? |
Номер ответа: 6 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ICQ: 204447456 Вопросов: 28 Ответов: 664 |
Web-сайт: Профиль | Цитата | #6 | Добавлено: 25.05.04 00:06 |
У меня в одной процедуре принимал сообщения от 3-х контролов и формы. Вроде глюков не наблюдал.
В конце концов можно на каждый приёмник сообщений выделить по одной процедуре. |
Номер ответа: 7 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() Разработчик Offline Client ICQ: 233286456 Вопросов: 34 Ответов: 5445 |
Web-сайт: Профиль | Цитата | #7 | Добавлено: 25.05.04 01:05 |
- если хочется ставить хук не на свои окошки, то это не на ВБ - если на свои окошки, то это легче легкого ![]() |
Номер ответа: 8 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #8 | Добавлено: 26.05.04 00:58 |
Парни, спасибо всем откликнувшимся! Видимо я неточно выразился.. Уточняю требования: -Сообщения должны отлавливаться в СВОИХ окошках (VB6). .. кнопки,текстовые поля и combo,listboxы и т.д. Короче говоря хук должен ставиться на любое окно в своем приложении. -В событии должно передаваться само сообщение со всеми параметрами(lParam, wParam и т.д.включая hWnd окна которое получило данное сообщение),причем ByRef - чтобы можно было при необходимости заменить мессагу или параметр своими данными. -Желательно наличие свойства,которое определяло бы когда информировать? After, Before того как окно обработает полученное сообщение(по-умолчанию Before) -Субклассировщик должен работать не с одним окном, а с несколькими одновременно!Количество заранее не известно. В принципе,всё вышесказанное я сделал.. НО! я не могу добиться,чтобы он работал с несколькими окнами... Поскульку используемая AdressOf функция ОБЯЗАНА распологаться в стандартном модуле, то данные по новому окну затирают предыдущие данные.. Другими словами я не могу добиться разделения переменных!!!Всю голову уже сломал!! ВЫРУЧАЙТЕ!! И потом,если кому-то удастся сделать все вышеперечисленное (тому респект).. То я думаю,его надо будет обязательно выложить на сайте.Многие спасибо скажут!!!. Я облазил все известные мне VB-сайты.. Но НИ ОДНОГО приличного субклассировщика там нет!!!(я тестировал их 16 штук) А у нас будет! Насколько я понимаю, на VB6 сделать это вполне реально.. Еще раз
|
Номер ответа: 9 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() Разработчик Offline Client ICQ: 233286456 Вопросов: 34 Ответов: 5445 |
Web-сайт: Профиль | Цитата | #9 | Добавлено: 26.05.04 11:37 |
Тогда тебе нужно отодрать код из одного из этих примеров:
ApiListBox, ImageComboBox, RichEdit, WndReceiver Там именно этим и занимаюсь, что работаю с несколькими окошками... |
Номер ответа: 10 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ICQ: 204447456 Вопросов: 28 Ответов: 664 |
Web-сайт: Профиль | Цитата | #10 | Добавлено: 27.05.04 04:49 |
По порядку.
1. Запоминаем адрес старой CallBack функции. Public OldCBFunc_Form1 as Long, OldCBFunc_Command1 as long OldCBFunc_Form1=SetWindowLong(Form1.hwnd, GWL_WNDPROC, AddressOf CommonCallback) OldCBFunc_Command1=SetWindowLong(Command1.hwnd, GWL_WNDPROC, AddressOf CommonCallback) 2. В самой CallBack функции работаем только с тем окном, чьё hWnd поступило. Function CommonCallback(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Select Case hWnd Case Form1.hWnd 'Поступило сообщение в Form1 Case Command1.hwnd 'Поступило сообщение в Command1 End Select 3. Вызываем родную CallBack функцию для текущего окна. В принципе, если необходимо чтобы сообщение не поступило, то просто обнуляем его (uMsg=0) Select Case hWnd Case Form1.hWnd CommonCallback=CallWindowProc(OldCBFunc_Form1, hwnd, uMsg, wParam, lParam) Case Command1.hwnd CommonCallback=CallWindowProc(OldCBFunc_Command1, hwnd, uMsg, wParam, lParam) End Select End Function |
Номер ответа: 11 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ICQ: 204447456 Вопросов: 28 Ответов: 664 |
Web-сайт: Профиль | Цитата | #11 | Добавлено: 27.05.04 05:29 |
Т.е. в самом окне(форме или кнопке) хранится адрес функции, которая будет принимать сообщения для окна. Когда окну посылается сообщение, она вызывает функцию по этому адресу. Что то наподобие CALL FuncName. Только, в отличие от VB, функция вызывается не по имени, а по адресу (типа CALL DWORD в Power Basic). Вот ты этот адрес и подменяешь.
А т.к. все CallBack функции одинаковы, то и подменить можно функцию для любого окна. В Power Basic например, если ты не указываешь CallBack функцию для контрола, то по умолчанию все сообщения передаются родителю. И это верно не только для PB, а для любого языка, совместимого с ОС (независимового от внутреннего интерпретатора). Вот посмотри что получится на самом деле. Посылаем сообщение окну SendMessage Command1.hWnd,WM_LBUTTONCLICK,wParam,lParam Кнопка в свою очередь вызывает функцию, обрабатывающую сообщения Что то типа: - Сложить все параметры в стёке: PUSH lParam PUSH wParam PUSH WM_LBUTTONCLICK PUSH Command1.hWnd - Вызвать функцию по известному адресу: CALL GWL_WNDPROC Функция сама вынет параметры из стёка. На этом её самостоятельность и заканчивается. Всё остальное ты должен запрограммировать сам. А определить какое окно её вызвало можно по парамерту hWnd. === Усёк? ![]() |
Номер ответа: 12 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #12 | Добавлено: 27.05.04 20:05 |
To CyRAX: С сабклассингом я разобрался.На данный момент у меня проблема заключается немного в другом. Возможно ли из ехе-шника вызвать функцию расположенную в длл, а длл в свою очередь вызывает функцию расположенную в ехе.. Сейчас попробую объяснить.. Для начала должен сказать, что весь сабклассинг я пранирую засунуть в длл(кроме одной ф-и), иначе отладка в пошаговом режиме превращается в кошмар... вот кусок твоей CallBack функции: Select Case hWnd Вот тут необходимо вызвать функцию расположенную в ехе,для того чтобы при необходимости можно было заменить uMsg, wParam, lParam!!! ,чтобы каждый раз длл не перекомпилировать. А вот как это сделать? ума не приложу!!!
|
Номер ответа: 13 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() Разработчик Offline Client ICQ: 233286456 Вопросов: 34 Ответов: 5445 |
Web-сайт: Профиль | Цитата | #13 | Добавлено: 27.05.04 23:37 |
Вообще из дллки можно вызывать функцию ехе, если в качестве параметра передать адрес функции (AddressOf ProcName) |
Номер ответа: 14 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ICQ: 204447456 Вопросов: 28 Ответов: 664 |
Web-сайт: Профиль | Цитата | #14 | Добавлено: 28.05.04 13:03 |
Для того чтобы вызвать функцию из внешнего модуля, она должна быть экспортной - т.е. её адрес должен быть прописан в секции экспорта EXE или DLL. А в вызывающем модуле она должна быть объявлена (DECLARE SUB ProcName LIB "MODULE!!!" Arguments).
--- >вызвать функцию расположенную в ехе - В принципе наверное такое можно сделать, но только не в VB. Тебе нужно сложить все параметры в стёке, а потом CALL ProcAddr. Если второе сделать легко с помощью AddressOf, то для первого ЯВУ должен поддерживать АСМ. === заменить uMsg, wParam, lParam можно прямо в функции CommonCallback просто пишешь uMsg=Value потом CommonCallback=CallWindowProc(OldCBFunc_Form1, hwnd, uMsg, wParam, lParam) это вызывает родную Callback функцию для формы (ту, которая генерирует события: типа Form_Click, Form_Size и т.д.). А так как сообщение изменено, то в форму поступает не родное uMsg, а значение Value. === Я вообщето делал по другому. Ложил на форму контрол, а из внешнего модуля слал туда сообщения или менял какое либо из его свойств. И в них уже обрабатывал то, что хочет внешний модуль. Пример DLL Sub DLL_SUB (byval hWnd_Text1 as long) SetWindowText hWnd_Text1, NewText$ End Sub Пример EXE Private Sub Text1_Change() If len(Text1)>0 then Call AnotherProc End Sub |
Номер ответа: 15 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ICQ: 204447456 Вопросов: 28 Ответов: 664 |
Web-сайт: Профиль | Цитата | #15 | Добавлено: 28.05.04 13:03 |
>т.е. её адрес должен быть прописан в секции экспорта EXE или DLL
- Вернее её имя |
|