Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Отключить привязку к событиям в рантайм 
V
    Опции темы
17dufa
Дата 30.9.2009, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Добрый день.
Имеется у меня дочерняя форма, а на ней куча полей, которые заполняются пользователем. Формочка по KILLFOCUS проверяет корректность заполнения, если заполнено с ошибкой - мессаджбокс и возврат фокуса в окно. Проблема вылезает если ввести что-нить неправильное и попытаться закрыть формочку. Формочка закрывается и начинают сыпаться мессаджбоксы об ошибке ввода, после штук 3-5 сообщений приложение закрывается целиком. Соответственно есть мысля: по закрытию формочки отрубить обработку KILLFOCUS'ов. Как это сделать в рантайме?
PM MAIL   Вверх
SenkraD
Дата 30.9.2009, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



17dufa,  ну можно поймать WM_CLOSE и выставить там какой-то флаг,
а в обработчике WM_KILLFOCUS проверять флаг и далее работать по результатам
проверки


--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
17dufa
Дата 30.9.2009, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



SenkraD, этих самых обработчиков WM_KILLFOCUS до чертиков. в каждом из них плодить:
Код

if (m_Closing)
   return;

как-то некрасиво. проще в WM_CLOSE отрубить все эти обработчики.
PM MAIL   Вверх
Earnest
Дата 30.9.2009, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



Если все-таки хочешь обрубить обработчики, то можно сделать так: перекрsть OnCmdMsg на диалоге; в ней если пришла команда и код уведомления KILLFocus и стоит флаг закрытия, не вызывать базовый обработчик а просто возвращать true.
Но есть подозрение, что фишка не пройдет: ты ведб закрываешь форму, нажимая какую-нибудь кнопку, а это скорее всего сначала вызовет killfocus, прежде чем ты флаг выставишь.

Вообще-то проверка на KillFocus - плохая идея - ты уже хлебнул. Нужно выбрать сначала концепуию: 
1) каждое поле в любой момент содержит валидные данные 
ИЛИ
2) валидные данные должны быть в конце, при нажатии OK или эквивалента.  
Очевидно, 1 вариант поддерживать сложнее, и нужно бороться с кил-фокусами. Кстати, тогда нечего возмущаться, что по Cancel форма не закрывается, а требует исправления (всегда так всегда)
2-й вариант более человечный: проверяй все поля только при выходе с подтверждением.




--------------------
...
PM   Вверх
17dufa
Дата 30.9.2009, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Earnest, к сожалению, второй вариант не катит. По поведению KillFocus я и не возмущаюсь, я его прекрасно понимаю и полностью с ним согласен в рамках существующего кода, но так как такое поведение пользователя не устроит, то код надо править. попробую завтра поиграться с OnCmdMsg, по результатам отпишусь.
PM MAIL   Вверх
Earnest
Дата 1.10.2009, 06:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



Ясно, но имей в виду, что более чем возможно, что KillFocus придет раньше, чем команда Cancel (и ты выставишь флаг). Тогда попробуй перехватить событие, которое должно привести к выходу с отменой, например LBUTTONDOWN на кнопке Cancel. Выставь флаг и вызови стандартный обработчик. Это должно помочь. Удобнее всего сделать это в PreTranslateMessage диалога, т.к. там можно обработать всевозможные варианты выхода. А что касается OnCmdMsg, так это железно получится, если флаг вовремя выставишь.


--------------------
...
PM   Вверх
17dufa
Дата 1.10.2009, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



значит так. вот работающие решение по отрубанию обработчиков KILLFOCUS по закрытию формы кнопочкой "выход"(IDCANCEL) или крестиком:
Код

class CForm : CDialog
{
BOOL m_Exit;
....
};

CForm::CForm(...):m_Exit(FALSE)....

BOOL CMT103Form::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) 
{
    const MSG &lastSentMsg = AfxGetThreadState()->m_lastSentMsg;

    if (m_bExit && nCode != CN_UPDATE_COMMAND_UI && !pHandlerInfo) 
    {
        int nMsg = HIWORD(nCode);
        nCode = LOWORD(nCode);
    if (!nMsg) nMsg = WM_COMMAND;
        if (nMsg == WM_COMMAND && ((nCode == EN_KILLFOCUS)
             || (nCode == CBN_KILLFOCUS)
             || (nCode == LBN_KILLFOCUS)
             || (nMsg == WM_NOTIFY && nCode == LOWORD(NM_KILLFOCUS)))) 
    {
            return TRUE;
    }
    return CDialogScr::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}

void СForm::OnCancel() 
{
    m_Exit = TRUE;
    
    CDialogScr::OnCancel();
}

BOOL CMT103Form::PreTranslateMessage(MSG* pMsg) 
{
    if (pMsg->message == WM_LBUTTONDOWN)
    {
        if (GetDlgItem(IDCANCEL)->GetSafeHwnd() == pMsg->hwnd)
            m_Exit = TRUE;
    }
}


Благодарю Earnest за помощь.

Это сообщение отредактировал(а) 17dufa - 2.10.2009, 14:17
PM MAIL   Вверх
Earnest
Дата 1.10.2009, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



Проверять классы - это лишнее, уведомления уникальны, можно проверять только их. А вот чего у тебя нет - это отсечения апдейтов, которые тоже идут через OnCmdMsg. И, кстати, флажок лучше проверить в самом начале:
Код

   if (m_bExit && nCode != CN_UPDATE_COMMAND_UI && !pHandlerInfo)
   {
       nMsg = HIWORD(nCode);
       nCode = LOWORD(nCode);
       if (nMsg == 0) nMsg = WM_COMMAND;
       if ((nMsg == WM_COMMAND && (nCode == EN_KILLFOCUS || nCOde == ...)) || (nMsg == WM_NOTIFY && nCode ==   NM_KILLFOCUS) return TRUE;
   }




--------------------
...
PM   Вверх
17dufa
Дата 2.10.2009, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Earnest, ща поправлю
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




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


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

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