*Теория* | Классы C++ для представления winapi32

Ответить
Аватара пользователя
pva

*Теория* | Классы C++ для представления winapi32

Сообщение pva »

Я мечтаю найти оптимальный способ переделки WinApi, который вообше-то на C рассчитан в C++. Главная задача: как связать дочернее окно и родительское. Есть несколько вариантов (реализованных в разных библиотеках).

1. Субклассится дочернее окно, все его сообщения ему же и перенаправляются. Дочернее окно обрабатывает свои же сообщения и запускает соответствующие методы родительского окна, на которые хранит указатели.

2. Родительское окно содержит таблицу расшифровки сообщений в указатели на методы и пользуется ей.

3. всё как в (1), только вместо указателя наметод (12 байт) используется номер метода (4 байта), а родительское окно имеет метод invoke(int method,...);



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

Re: *Теория* | Классы C++ для представления winapi32

Сообщение hasherfrog »

pva

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

Но это уже готовое решение в С++, со своей идеологией.



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

Re: *Теория* | Классы C++ для представления winapi32

Сообщение pva »

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

Re: *Теория* | Классы C++ для представления winapi32

Сообщение pva »

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

Re: *Теория* | Классы C++ для представления winapi32

Сообщение hasherfrog »

pva



>> >>пользуется методами родительского класса

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



>> >> поставить фильтр на обработку события

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



Эээ... батенька, это Вы очень глубоко копаете.

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



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



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



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



Надеюсь, не слишком сумбурно объяснил.
Аватара пользователя
pva

Re: *Теория* | Классы C++ для представления winapi32

Сообщение pva »

Почему вы боитесь слова "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)

т.е. можно сказать, что дочерние окна "врезаются" в очередь событий родительского окна.



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

Вернуться в «Программирование и базы данных»