Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Свой класс Dialog 
:(
    Опции темы
Leksey
Дата 22.4.2005, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 332
Регистрация: 12.12.2004

Репутация: 1
Всего: 1



Решил реализовать класс диалог ,чтобы на его основе создавать другие диалоги:
Код

#ifndef _DIA_LOG_
#define _DIA_LOG_

#include<windows.h>

class Dialog
{
public:
Dialog(HINSTANCE hInst,LPCTSTR lpTName,HWND hWndP=0,LPARAM dwInPar=0)
{
    DialogBoxParam(hInst,lpTName,hWndP,DialogProc,dwInPar);
}
virtual ProcessMessage(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)=0;
virtual ~Dialog() {}
private:
INT_PTR CALLBACK DialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{ProcessMessage(hwndDlg,uMsg,wParam,lParam);return 0;}

};
#endif

Но в static методе класса нельзя вызывать не static методы, тем более virtual.
Подскажите как это можно реализовать.
PM MAIL   Вверх
zhgutov
Дата 27.4.2005, 01:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 14.12.2004

Репутация: 1
Всего: 2



Можно, например, хранить множество пар (дескриптор окна; объект*), а DialogProc будет осуществлять вызов соответствующей виртуальной функции. Хотя это несколько криво, но работать будет. Так или иначе, вряд ли в программе одновременно будет открыто много диалоговых окон, поэтому будет быстро. А еще надо придумать механизм для добавления непредусмотренных обработчиков сообщений. МФЦ для этого использует т.н. «карты сообщений», но это не очень удобно (имхо). В свою очередь, реализация всех возможных обработчиков слишком накладна.

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

Если чего еще придумаю — напишу...

Это сообщение отредактировал(а) zhgutov - 27.4.2005, 01:26
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
maxim1000
Дата 27.4.2005, 01:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 2
Всего: 110



Цитата
Но в static методе класса нельзя вызывать не static методы, тем более virtual.
Подскажите как это можно реализовать

для этого нужно действительно построить соответствие "окно-объект"
только можно не заводить массив пар
у каждого окна есть дополнительная информация (4 байта)
она передается с сообщением WM_CREATE и потом может быть прочитана с помощью "не помню какой функции" smile (но в MSDN найти можно)
правда, я не уверен, что в случае с диалогами эта информация может быть все так же свободно использована
есть еще один механизм - свойства окна: функции GetProp/SetProp
с помощью них у каждого окна поддерживается массив пар (строка,указатель)
можно при обработке первого сообщения писать SetProp("OBJECT",PointerToObject),а при обработке остальных PointerToObject=GetProp("OBJECT");
ну и потом, соответственно, PointerToObject->ProcessMessage...

только есть еще одна проблема с наследованием:
предположим, унаследовали мы от такого диалога свой класс
пишем свой специализированный конструктор, который, конечно же, должен вызвать конструктор предка
и тут появляется беда:
конструктор предка вызывает функцию DialogBoxParam
эта функция создает окно диалога и посылает ему сообщение WM_CREATE
и ЖДЕТ, пока оно обработается
что здесь плохого:
на момент создания окна объект не полностью создан
создан только объект-предок, и в виртуальной таблице находится адрес старой виртуальной функции (соответствующей предку), а значит, чтобы мы ни переопределяли в обработчике сообщений, для WM_CREATE все равно вызовется старая версия (что довольно-таки печально, т.к. немало специфическихдействий производится именно при создании)...

Добавлено @ 02:02
Цитата
Можно, например, хранить множество пар (дескриптор окна; объект*)

а кто его заполнять будет ;)
дело в том, что функция DialogBoxParam не вернет дескриптор окна, пока не обработается WM_CREATE, а значит, будет непонятно, какой объект должен его обрабатывать
если же заполнять его в WM_CREATE, то все равно надо передавать адрес объекта как-то с помощью DialogBoxParam (например, в последнем аргументе)
Цитата
Еще можно наследовать класс от класса, добавляя свою специфическую функцию-обработчик, и вызывая для остальных сообщений предусмотренную базовым классом. Но это тоже криво

а почему криво?
вполне нормальный подход (ИМХОsmile)
для API-шных приложений в MSDN тоже рекомендуется в обработчике обрабатывать те сообщения, которые интересны, а потом вызывать DefWindowProc
да и вообще это - способ наследования классов (subclassing) окон в WinAPI...


--------------------
qqq
PM WWW   Вверх
En_t_end
Дата 27.4.2005, 04:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: нет
Всего: 20



А в MFC лень глянуть, а ведь там это нормально реализованно smile
PM MAIL ICQ Skype GTalk Jabber   Вверх
zhgutov
Дата 27.4.2005, 07:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 14.12.2004

Репутация: 1
Всего: 2



Цитата
а кто его заполнять будет ;)

Заполнять при обработке WM_INITDIALOG.
З.Ы. Согласен, можно обойтись без «мапы».

Цитата
а почему криво?

Без применения какой-либо элегантной методы — криво, так как все-равно придется писать функцию обработчик.

Цитата
на момент создания окна объект не полностью создан

Создание окна лучше выполнять не в конструкторе, а в чем-нить типа virtual create () — тогда объект будет правильно сконструирован.

Это сообщение отредактировал(а) zhgutov - 27.4.2005, 07:34
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0520 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.