Показать полную графическую версию : *Теория* | Классы C++ для представления winapi32
Я мечтаю найти оптимальный способ переделки WinApi, который вообше-то на C рассчитан в C++. Главная задача: как связать дочернее окно и родительское. Есть несколько вариантов (реализованных в разных библиотеках).
1. Субклассится дочернее окно, все его сообщения ему же и перенаправляются. Дочернее окно обрабатывает свои же сообщения и запускает соответствующие методы родительского окна, на которые хранит указатели.
2. Родительское окно содержит таблицу расшифровки сообщений в указатели на методы и пользуется ей.
3. всё как в (1), только вместо указателя наметод (12 байт) используется номер метода (4 байта), а родительское окно имеет метод invoke(int method,...);
Хотелось бы услышать предложения умных людей или независимые (от меня) аргументы в пользу какого-либо варианта
hasherfrog
05-04-2005, 11:30
pva
Знаете, тут есть ещё случай из QT. Окно субклассится. Дочернее окно пользуется методами родительского класса. Но может их переопределить. А может сделать ещё хитрее - поставить фильтр на обработку события, например своего же собственного переопределённого-родительского метода.
Но это уже готовое решение в С++, со своей идеологией.
Я лично выбрал бы (для реализации своей собственной библиотеки - которую я никогда писать не буду, ибо незачем) вариант 1. Метод 2 исключает собственно дочерний класс из процесса, а метод 3 сильно напоминает callback'и из простого С. Хотя...... ;-|
Вариант 3 навеян исходниками (функция invoke()), которые даёт moc от QT3 для windows. Меня вполне устраивает QT3, и прежде всего подкупает красотой идеи и современной реализацией, но отпугивает ценой QT3 под windows. Вполне согласен с которую я никогда писать не буду, ибо незачем, но хочется доступную библиотеку под windows, рассчитанную на wide char, так чтобы компилятор пригодный для такой библиотеки поддерживал C++ 3.xx и STL.
1. MFC хорошая штука, надо только пересобрать для wide char
2. VCL слишком много памяти использует понапрасну, работает только с bcb, который глючит на STL
3. QT3 rulez!!! но бесплатная версия - только под линухи.
пользуется методами родительского класса Вот этого я не понял (откуда оно их знает). Можно пример?
поставить фильтр на обработку события Во всех детально рассмотренных мной библиотеках (MFC, OWL, VCL, ATL) так и делается. Если допускать динамическое создание контролов, по-другому и не сделать... или можно?
TControl::perform(...)
{
// условно, т.к. VCL на паскале написана
switch (message) {
...
case WM_COMMAND :
...
TControl* ctl = ControlByHandle(HWND(lparam));
ctl->perform(message + CM_BASE, wparam, lparam);
break;
}
}
Я не ставлю главной задачей поиск нового решения. Скорее хочу состряпать оптимального Франкенштейна
hasherfrog
06-04-2005, 20:16
pva
>> >>пользуется методами родительского класса
>>Вот этого я не понял (откуда оно их знает). Можно пример?
>> >> поставить фильтр на обработку события
>> Во всех детально рассмотренных мной библиотеках (MFC, OWL, VCL, ATL) так и делается.
Эээ... батенька, это Вы очень глубоко копаете.
С точки зрения использующего QT программиста на С++ никаких callback'ов не существует. И никаких WM_чего-то-там, кстати, тоже.
Может, я как-то некорректно выражаюсь, ну извините. Я как аксакал, что вижу, то и пою. Доморощенный программист, что возмёшь...
Вот как это всё выглядит на Qt. Берёте базовый класс, например, QMAinWindow. Субклассите свой. Вы можете в любом месте использовать его методы и реакцию на события (слоты). Можете переопределить слоты основного окна (создать новые). Но есть ещё ситуации, когда надо сделать что-то "эдакое". Например, отследить движение мыши. У Вас есть решение - переписать всё, начиная с самого первого класса виджета - одуреть, согласны? И что же делать - ведь в базовом классе "основного окна" нет слота, отслеживающего мышь (они уже давно перекрыты протектед-приват слотами). Ан нет, на помощь приходит "хак" от самих же кьютишников - фильтр событий. Действительно смахивает на перехват событий в виде WM_всяко-разно. Но дело-то в том, что вам события предоставят в уже "разобранном виде" - как раз для С++ программиста, которому на фиг не нужны тонкости winApi. И что ещё интереснее - Вы можете "врезать" свой обработчик-фильтр в любое место даже для родительских окон из дочерних.
Я когда-то хотел даже картинку-карикатурку нарисовать: Qt в действительности. Там всё держится на этих самых фильтрах (у системных программистов, во всяком случае ;] )
Надеюсь, не слишком сумбурно объяснил.
Почему вы боитесь слова "callback"?
С точки зрения использующего QT программиста на С++ никаких callback'ов не существует WTF emit()?
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 {
...
virtual void event(QEvent*);
virtual void onCommand(int);
virtual void onSize(int,int);
};
...
switch (message) {
...
case WM_COMMAND :
onCommand(event->wparam & 0xffff);
break;
case WM_SIZE :
onSize(event->lparam & 0xffff, event->lparam >> 16);
break;
}
на фиг не нужны тонкости winApi На то QT и intercompiler & interplatform GUI library
А насчёт установки фильтров на сообщения я подумаю... Хотя, грубо говоря так в винде и делается:
1. Снимается сообщение
2. Диалог отсеивает tab, shift+tab, стрелки, F6 и др. (IsDialogMessage)
3. Диалог отсеивает аккселераторы (TranslateAccelerator)
4. Диалог переводит нажатия клавиш в ввод символов (TranslateMessage)
5. Окна обрабатывают сообщения, если они ещё не обработаны (DispatchMessage)
т.е. можно сказать, что дочерние окна "врезаются" в очередь событий родительского окна.
Единственная трудность - Микрософт пишет программы, удобные для сервера, а не клиента. Вместо того, чтобы спрашивать у родителя, как дочернему окну оповещать о событии, родительские окна должны приспосабливаться к капризам дочерних. Все гуишные библиотеки первым делом пытаются исправить эту ситуацию. Вот я и думаю как бы это сделать как можно лучше.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.