Страница: 1 |
Страница: 1 |
Вопрос: Опять сабклассинг
Добавлено: 21.02.05 09:56
Автор вопроса: LamerOnLine | ICQ: 334781088
Сабж: пишу свой набор контролов, но вот такая проблемка - окошки создаются через CreateWindowEx, процедура обработки задается сабклассингом. Однако, эта процедура находится в модуле, который не может генерировать события для клиента. Нужен способ хотя бы передать сообщение в класс, откуда и выкинуть Event. Но сложность состоит в нахождении нужного контрола по hWnd. Нет никакого оптимального решения кроме перебора в цикле? Ведь для этого надо бы еще и хранить их hWnd в модуле, т.е. делать их Public. Либо пытаться работать с коллекциями. В общем, морока. Примерчики такого есть?
P.S. В проекте несколько ctl и один bas.
Ответы
Всего ответов: 8
Номер ответа: 1
Автор ответа:
sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #1
Добавлено: 21.02.05 11:28
Смотри примеры...
1. ApiListBox - по твоему сделан
2. AoiListView - сделан несколько по иному...
Номер ответа: 2
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #2
Добавлено: 21.02.05 12:40
Да, с асмовыми вставками - оно, конечно, круто, но для исходников - не то...
Номер ответа: 3
Автор ответа:
cresta
Вопросов: 117
Ответов: 1538
Профиль | | #3
Добавлено: 21.02.05 13:05
Вроде тебе всё равно придется хранить что-то: либо hWnd, либо ID, ведь не бросишь же бесхозным контрол.
Наверное слышал о таких вещах, как GWL_ID, GWL_USERDATA - тут можно хранить кое-какую информацию.
Я всего один контрол делал, и тот на асме, поэтому много чего не подскажу. Делал кнопку. У каждой определена своя структура
crBUTTONSTATE STRUCT
hWnd dd ?
hInst dd ?
hParent dd ?
ctlID dd ?
szCaption db 64 dup (?)
hIcon dd ?
и т.д.
crBUTTONSTATE ends
Массив таких структур в либе. Тоже цикл, пока не найден нужный hWnd. Это при обработке сообщений для неё.
Сам из программы с кнопкой общаюсь только по её ID. Кнопка родителю посылает стандартный WM_COMMAND, из wParam'a ясно, какая кнопка послала его, если вдруг понадобится в программе её hWnd - он в lParam'e.
О генерации событий: при инициализации контрола можно указать ему AddressOf некоторой процедуры в модуле, которая должна выполняться на определенные события, пусть он её и вызывает, а сам напишешь там что угодно. AddressOf можно хранить как один из элементов структуры.
Номер ответа: 4
Автор ответа:
sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #4
Добавлено: 22.02.05 00:45
2LOL
Дык первый пример без асьмовых вставок, там контрол состоит из модуля и класса, в модуле - процедура сабклассинга... множественного...
По тому же принципу создан ApiCalendar & ApiImageComboBox... Пример RichEdit'a мой ана этом сайте тоже без асьмовой вставки лежит... Хотя есть уже и переделанный
Номер ответа: 5
Автор ответа:
sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #5
Добавлено: 22.02.05 00:48
2LOL
Дык первый пример без асьмовых вставок, там контрол состоит из модуля и класса, в модуле - процедура сабклассинга... множественного...
По тому же принципу создан ApiCalendar & ApiImageComboBox... Пример RichEdit'a мой ана этом сайте тоже без асьмовой вставки лежит... Хотя есть уже и переделанный
Номер ответа: 6
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #6
Добавлено: 25.02.05 12:21
Тут вот такая трилема. Либо хранить, как наиболее распространено, массив структур, описывающих экземпляры, либо создать коллекцию, в которой hWnd будет Key'ем, либо через GWL_USERDATA заносить ObjPtr экземпляра, переписывать оттуда адрес vtbl в новый экземпляр и вызывать через него. Опытные в этом люди - подскажите как эффективнее...
Номер ответа: 7
Автор ответа:
cresta
Вопросов: 117
Ответов: 1538
Профиль | | #7
Добавлено: 25.02.05 12:59
Какой способ выбрать зависит наверное в первую очередь от скорости получения указателя на конкретный элемент. Что быстрее - GetWindowLong + преобразование к привычному виду при помощи CopyMemory или цикл по массиву структур?
На асме однозначно быстрее цикл. На VB возможно тоже, но не факт, надо проверять.
Dim StructArray() As CtlStruct
For i = 0 to Ubound
If StructArray(i).hWnd = MyWnd Then Exit For
Next i
If i<= Ubound Then
'нашли
Else
'элемента нет
End If
Номер ответа: 8
Автор ответа:
sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #8
Добавлено: 26.02.05 12:58
Я выбрал цикл по массиву структур...