![]() |
*Теория* | Классы C++ для представления winapi32
Я мечтаю найти оптимальный способ переделки WinApi, который вообше-то на C рассчитан в C++. Главная задача: как связать дочернее окно и родительское. Есть несколько вариантов (реализованных в разных библиотеках).
1. Субклассится дочернее окно, все его сообщения ему же и перенаправляются. Дочернее окно обрабатывает свои же сообщения и запускает соответствующие методы родительского окна, на которые хранит указатели. 2. Родительское окно содержит таблицу расшифровки сообщений в указатели на методы и пользуется ей. 3. всё как в (1), только вместо указателя наметод (12 байт) используется номер метода (4 байта), а родительское окно имеет метод invoke(int method,...); Хотелось бы услышать предложения умных людей или независимые (от меня) аргументы в пользу какого-либо варианта |
pva
Знаете, тут есть ещё случай из QT. Окно субклассится. Дочернее окно пользуется методами родительского класса. Но может их переопределить. А может сделать ещё хитрее - поставить фильтр на обработку события, например своего же собственного переопределённого-родительского метода. Но это уже готовое решение в С++, со своей идеологией. Я лично выбрал бы (для реализации своей собственной библиотеки - которую я никогда писать не буду, ибо незачем) вариант 1. Метод 2 исключает собственно дочерний класс из процесса, а метод 3 сильно напоминает callback'и из простого С. Хотя...... ;-| |
Вариант 3 навеян исходниками (функция invoke()), которые даёт moc от QT3 для windows. Меня вполне устраивает QT3, и прежде всего подкупает красотой идеи и современной реализацией, но отпугивает ценой QT3 под windows. Вполне согласен с
Цитата:
1. MFC хорошая штука, надо только пересобрать для wide char 2. VCL слишком много памяти использует понапрасну, работает только с bcb, который глючит на STL 3. QT3 rulez!!! но бесплатная версия - только под линухи. Цитата:
Цитата:
Код:
TControl::perform(...) |
Я не ставлю главной задачей поиск нового решения. Скорее хочу состряпать оптимального Франкенштейна
|
pva
>> >>пользуется методами родительского класса >>Вот этого я не понял (откуда оно их знает). Можно пример? >> >> поставить фильтр на обработку события >> Во всех детально рассмотренных мной библиотеках (MFC, OWL, VCL, ATL) так и делается. Эээ... батенька, это Вы очень глубоко копаете. С точки зрения использующего QT программиста на С++ никаких callback'ов не существует. И никаких WM_чего-то-там, кстати, тоже. Может, я как-то некорректно выражаюсь, ну извините. Я как аксакал, что вижу, то и пою. Доморощенный программист, что возмёшь... Вот как это всё выглядит на Qt. Берёте базовый класс, например, QMAinWindow. Субклассите свой. Вы можете в любом месте использовать его методы и реакцию на события (слоты). Можете переопределить слоты основного окна (создать новые). Но есть ещё ситуации, когда надо сделать что-то "эдакое". Например, отследить движение мыши. У Вас есть решение - переписать всё, начиная с самого первого класса виджета - одуреть, согласны? И что же делать - ведь в базовом классе "основного окна" нет слота, отслеживающего мышь (они уже давно перекрыты протектед-приват слотами). Ан нет, на помощь приходит "хак" от самих же кьютишников - фильтр событий. Действительно смахивает на перехват событий в виде WM_всяко-разно. Но дело-то в том, что вам события предоставят в уже "разобранном виде" - как раз для С++ программиста, которому на фиг не нужны тонкости winApi. И что ещё интереснее - Вы можете "врезать" свой обработчик-фильтр в любое место даже для родительских окон из дочерних. Я когда-то хотел даже картинку-карикатурку нарисовать: Qt в действительности. Там всё держится на этих самых фильтрах (у системных программистов, во всяком случае ;] ) Надеюсь, не слишком сумбурно объяснил. |
Почему вы боитесь слова "callback"?
Цитата:
1. Вы пишете метод, который называете "слотом" void reflectSomeway(); 2. Подсоединяете его к "сигналу" connect(SIGNAL(doingSomething()), SLOT(reflectSomeway())) 3. При вызове хозяина слота функции emit(SIGNAL(doingSomething())) вызывается (и в том числе) ваша reflectSomeway(). 4. Другим способом reflectSomeway() не вызывается. Разве это не callback? Мне кажется, что фразу "no more callbacks" из хелпа следует воспринимать как "no more type-unsafe callbacks". Цитата:
Цитата:
Код:
TControl { Цитата:
А насчёт установки фильтров на сообщения я подумаю... Хотя, грубо говоря так в винде и делается: 1. Снимается сообщение 2. Диалог отсеивает tab, shift+tab, стрелки, F6 и др. (IsDialogMessage) 3. Диалог отсеивает аккселераторы (TranslateAccelerator) 4. Диалог переводит нажатия клавиш в ввод символов (TranslateMessage) 5. Окна обрабатывают сообщения, если они ещё не обработаны (DispatchMessage) т.е. можно сказать, что дочерние окна "врезаются" в очередь событий родительского окна. Единственная трудность - Микрософт пишет программы, удобные для сервера, а не клиента. Вместо того, чтобы спрашивать у родителя, как дочернему окну оповещать о событии, родительские окна должны приспосабливаться к капризам дочерних. Все гуишные библиотеки первым делом пытаются исправить эту ситуацию. Вот я и думаю как бы это сделать как можно лучше. |
Время: 08:34. |
Время: 08:34.
© OSzone.net 2001-