Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C++ Builder
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.11.2013, 20:27   #1
timao
 
Регистрация: 22.11.2013
Сообщений: 8
По умолчанию Переопределение WndProc для динамических компонентов

Решил бороться с известным багом TDateTimePicker, когда MaxDate и Date в свойствах компонента совпадают (вылетает сообщение "Failed to set calendar date or time" при сворачивании окна выбора даты)
Нашёл в интернете код для игнорирования некоторых сообщений TDateTimePicker винде.

Переопределяю WndProc так:

Код:
TWndMethod OldWndProc;
...
OldWndProc = DateTimePicker1->WindowProc;
DateTimePicker1->WindowProc = DateTimePickerWndProc;
...
void __fastcall TMyForm::DateTimePickerWndProc(TMessage &Message)
{
    if (Message.Msg != CN_NOTIFY) {
        OldWndProc(Message);
        return;
    }
    try {
        OldWndProc(Message);
    }
    catch (const Exception &e) {
        TWMNotifyDT &Notif = reinterpret_cast<TWMNotifyDT&>(Message);
        switch (Notif.NMHdr->code)
        {
            case DTN_CLOSEUP:
                break;
            case DTN_DATETIMECHANGE:
               break;
        }
    }
}
Подскажите, как заменить конструкцию с сохранением указателя на дефолтный WndProc или другое решение для случая, когда компоненты вызываются динамически. Подумал про свой компонент-наследник, но может можно обойтись чем-то вроде TDateTimePicker::Dispatch(&Message) ; ?
timao вне форума Ответить с цитированием
Старый 22.11.2013, 21:03   #2
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Запоминать указатель в Tag, например...
FataLL вне форума Ответить с цитированием
Старый 22.11.2013, 23:32   #3
timao
 
Регистрация: 22.11.2013
Сообщений: 8
По умолчанию

Цитата:
Сообщение от FataLL Посмотреть сообщение
Запоминать указатель в Tag, например...
Да, можно, но на все кривые решения стандартных проблем полей Tag не хватит, хотелось бы всё-таки более эстетичное решение
timao вне форума Ответить с цитированием
Старый 23.11.2013, 11:15   #4
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Тогда субклассируй.
Код:
// Перед классом формы:
namespace MyDateTimePicker
{
    class TMyDateTimePicker : public TDateTimePicker
    {
    protected:
        TWndMethod OldWndProc;
    public:
        __fastcall virtual TMyDateTimePicker( Classes::TComponent* AOwner )
            : TDateTimePicker(AOwner)
        {
            ... // манипуляции по изменению виндовой функции
        }
    };
}
#define TDateTimePicker MyDateTimePicker::TMyDateTimePicker
 
class TForm1 : public TForm
// ...
Не претендую на правильность кода, билдера под рукой нет, но принцип должен быть ясен...
FataLL вне форума Ответить с цитированием
Старый 25.11.2013, 00:52   #5
timao
 
Регистрация: 22.11.2013
Сообщений: 8
По умолчанию

Спасибо, проблема решена через наследование. Решил попробовать через Tag тоже и возникло несколько вопросов:

1) В первом методе через Tag как-то можно получить указатель на компонент, вызывающий WndProc?
Подумал, что можно узнать хендл (как?), а по нему получить указатель перебором компонентов через FindControl

2) Объясните, пожалуйста, для чего нужно пространство имён MyDateTimePicker? Наследовал класс без него, всё работает

Последний раз редактировалось timao; 25.11.2013 в 11:18.
timao вне форума Ответить с цитированием
Старый 25.11.2013, 14:45   #6
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

1) Действительно, засада.
2) На всякий случай
FataLL вне форума Ответить с цитированием
Старый 26.11.2013, 02:21   #7
Avazart
Форумчанин
 
Аватар для Avazart
 
Регистрация: 13.08.2011
Сообщений: 184
По умолчанию

Цитата:
2) Объясните, пожалуйста, для чего нужно пространство имён MyDateTimePicker? Наследовал класс без него, всё работает
Для того что бы не инсталить новосозданный компонент с целью поддержки дизайнтайма.
Avazart вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
События для динамических объектов fezilk25 Общие вопросы Delphi 3 05.10.2011 18:13
Переопределение метода для каждого экземпляря класса vsrmis Общие вопросы Delphi 6 01.08.2011 15:21
Переопределение оператора умножения для класса. Умножение числа на класс. capta1n Общие вопросы C/C++ 2 06.03.2010 16:50
чтение из ini динамических компонентов varelik Общие вопросы Delphi 2 03.09.2009 17:35
Смена WndProc в рантайме VVVadim Win Api 1 28.04.2009 18:16