Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   *Теория* | Классы C++ для представления winapi32 (http://forum.oszone.net/showthread.php?t=47272)

pva 28-03-2005 11:28 310657

*Теория* | Классы C++ для представления winapi32
 
Я мечтаю найти оптимальный способ переделки WinApi, который вообше-то на C рассчитан в C++. Главная задача: как связать дочернее окно и родительское. Есть несколько вариантов (реализованных в разных библиотеках).
1. Субклассится дочернее окно, все его сообщения ему же и перенаправляются. Дочернее окно обрабатывает свои же сообщения и запускает соответствующие методы родительского окна, на которые хранит указатели.
2. Родительское окно содержит таблицу расшифровки сообщений в указатели на методы и пользуется ей.
3. всё как в (1), только вместо указателя наметод (12 байт) используется номер метода (4 байта), а родительское окно имеет метод invoke(int method,...);

Хотелось бы услышать предложения умных людей или независимые (от меня) аргументы в пользу какого-либо варианта

hasherfrog 05-04-2005 11:30 312999

pva
Знаете, тут есть ещё случай из QT. Окно субклассится. Дочернее окно пользуется методами родительского класса. Но может их переопределить. А может сделать ещё хитрее - поставить фильтр на обработку события, например своего же собственного переопределённого-родительского метода.
Но это уже готовое решение в С++, со своей идеологией.

Я лично выбрал бы (для реализации своей собственной библиотеки - которую я никогда писать не буду, ибо незачем) вариант 1. Метод 2 исключает собственно дочерний класс из процесса, а метод 3 сильно напоминает callback'и из простого С. Хотя...... ;-|

pva 06-04-2005 10:58 313312

Вариант 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;
    }
}


pva 06-04-2005 11:04 313318

Я не ставлю главной задачей поиск нового решения. Скорее хочу состряпать оптимального Франкенштейна

hasherfrog 06-04-2005 20:16 313452

pva

>> >>пользуется методами родительского класса
>>Вот этого я не понял (откуда оно их знает). Можно пример?

>> >> поставить фильтр на обработку события
>> Во всех детально рассмотренных мной библиотеках (MFC, OWL, VCL, ATL) так и делается.

Эээ... батенька, это Вы очень глубоко копаете.
С точки зрения использующего QT программиста на С++ никаких callback'ов не существует. И никаких WM_чего-то-там, кстати, тоже.

Может, я как-то некорректно выражаюсь, ну извините. Я как аксакал, что вижу, то и пою. Доморощенный программист, что возмёшь...

Вот как это всё выглядит на Qt. Берёте базовый класс, например, QMAinWindow. Субклассите свой. Вы можете в любом месте использовать его методы и реакцию на события (слоты). Можете переопределить слоты основного окна (создать новые). Но есть ещё ситуации, когда надо сделать что-то "эдакое". Например, отследить движение мыши. У Вас есть решение - переписать всё, начиная с самого первого класса виджета - одуреть, согласны? И что же делать - ведь в базовом классе "основного окна" нет слота, отслеживающего мышь (они уже давно перекрыты протектед-приват слотами). Ан нет, на помощь приходит "хак" от самих же кьютишников - фильтр событий. Действительно смахивает на перехват событий в виде WM_всяко-разно. Но дело-то в том, что вам события предоставят в уже "разобранном виде" - как раз для С++ программиста, которому на фиг не нужны тонкости winApi. И что ещё интереснее - Вы можете "врезать" свой обработчик-фильтр в любое место даже для родительских окон из дочерних.

Я когда-то хотел даже картинку-карикатурку нарисовать: Qt в действительности. Там всё держится на этих самых фильтрах (у системных программистов, во всяком случае ;] )

Надеюсь, не слишком сумбурно объяснил.

pva 11-04-2005 11:28 314706

Почему вы боитесь слова "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)
т.е. можно сказать, что дочерние окна "врезаются" в очередь событий родительского окна.

Единственная трудность - Микрософт пишет программы, удобные для сервера, а не клиента. Вместо того, чтобы спрашивать у родителя, как дочернему окну оповещать о событии, родительские окна должны приспосабливаться к капризам дочерних. Все гуишные библиотеки первым делом пытаются исправить эту ситуацию. Вот я и думаю как бы это сделать как можно лучше.


Время: 08:34.

Время: 08:34.
© OSzone.net 2001-