baldr
|
|
« : 13-04-2005 09:28 » |
|
MSVS6.0. MFC. Есть класс от CDialog'а. На нем накиданы всякие контролы как-то CTreeCtrl, CComboBox и т.п. Если на контроле нажмешь Enter - форма закрывается как по OnOK(). Как ей запретить это делать?? То же самое по Esc.
|
|
« Последнее редактирование: 19-12-2007 19:56 от Алексей1153++ »
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #1 : 13-04-2005 09:52 » |
|
IDOK и IDCANCEL просто обработай по своему или переопредели функции их обрабатывающие если уж в мфц они спрятаны.
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #2 : 13-04-2005 10:28 » |
|
Обычно при нажатии на Enter в диалоге отрабатывается дефолтная кнопка. Можно сделать невидимую дефолтную кнопку.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
CyberMan
Гость
|
|
« Ответ #3 : 13-04-2005 11:06 » |
|
В редакторе ресурсов кликаешь дважды на кнопки OK И CANCEL создается обработчик и оттуда удаляешь вызовы СDialog::OnOK() ил CDialog::OnCancel(). Кстати Джон сказал что при нажатии на ентер обрабатывается дефолтная кнопка то какая кнопка обрабатывается при нажатии ескейп.
|
|
|
Записан
|
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #4 : 13-04-2005 12:23 » |
|
повторюсь еще раз . при нажатии на ентер обрабатывается по умолчанию команда IDOK, при нажатии на эскейп IDCANCEL. вот выдержка из файла winuser.h /* * Dialog Box Command IDs */ #define IDOK 1 #define IDCANCEL 2 #define IDABORT 3 #define IDRETRY 4 #define IDIGNORE 5 #define IDYES 6 #define IDNO 7
я представляю себе что в карте сообщений нужно вручную прописать обработку этих ID. При этом будут выполняться ваши функции. У меня это выглядит так. class dlg { BEGIN_MSG_MAP(dlg) COMMAND_HANDLER(IDOK, BN_CLICKED, OnBnClickedOk) COMMAND_HANDLER(IDCANCEL, BN_CLICKED, OnBnClickedCancel) END_MSG_MAP() LRESULT OnBnClickedOk(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled) { //EndDialog(IDOK); return 0; } LRESULT OnBnClickedCancel(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled) { //EndDialog(IDCANCEL); return 0; } };
|
|
« Последнее редактирование: 14-04-2005 06:38 от Pu »
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #5 : 13-04-2005 14:10 » |
|
Так, парни. Спокойно. А то получится медвежья помощь. CyberMan, а это случаем не опасно? Удалить обработчики? А как потом диалог закрыть? Опаньки. Поэтому мееееедленно разбираемся. 1. Нажатие кнопки Enter Pu, повторюсь ещё раз - при нажатии на Enter отрабатывает именно дефолтная кнопка! При создании диалога в редакотре ресурсов таковой является кнопка IDOK. Если переназначить дефолтную кнопку (например добавить ещё одну), то можно уснуть на Enter - диалог не закроется. Тк будет вызыватся обработчик ЭТОЙ (дефолтной) кнопки. Причем обработчик IDOK остаётся без изменений и даёт нам возможность всегда "положительно" завершить диалог с кодом возврата ID_OK. Обычно в таких случаях эту кнопку делают ещё и невидимой. Чтоб не маячила. 2. Нажатие кнопки Esc Здесь халявы не будет. Те нет кнопки отрабатывающей по Esc. Проблемма заключается в том, что OnCancel() - виртуальная ф-я вызываемая не только при нажатии на Esc, но и при нажатии комбинации Alt+F4 и других стандартных способов закрытия окна (системное меню, кликание на Х и тд и тп) Поэтому напрочь убирать обработчик CDialog::OnCancel() не стоит. Для затыкания Esc лучше воспользоваться обработчиком PreTranslateMessage (к сожаления диалговые окна не обрабатывают WM_KEYDOWN) BOOL CMyDlg::PreTranslateMessage(MSG* pMsg) { if((pMsg->message==WM_KEYDOWN) && (pMsg->wParam==VK_ESCAPE)) { return TRUE; } return CDialog::PreTranslateMessage(pMsg); }
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
esgal
Гость
|
|
« Ответ #6 : 13-04-2005 16:05 » |
|
Поэтапно: 1. С помощью классвизард выбираем IDOK, щёлкаем по BN_CLICKED. 2. Изменяем идентификатор кнопки IDOK на что то типа IDC_OK и отменяем в свойствах default button. 3. С помощью классвизард создаём ф-ию член OnClickedOk и редактируем её void CDlgExample::OnClickedOk() { CDialog::OnOk(); }
4. Редактируем исходную ф-ию OnOk void CDlgExample::OnOk() { //Вроде как заглушка }
С OnCancel аналогично. Мне думается так проще, чем делать кныпки невидимыми. Если где нагнал, поправте.
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #7 : 13-04-2005 17:59 » |
|
Все правильно - меняем обработчики... А закрыть окошко надо по WM_DESTROY это полный идиотизм от мелкомягких так закрывать...
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #8 : 13-04-2005 22:31 » |
|
Народ, вы чего? А? Чем вам Ok не нравится? А как-же диалог закрыть, и спросить его возвращённое значение? ну типа if(dlg.DoModal()==ID_OK) ... ? если вы всё позатыкаете, то нафига он тогда вообще нужен? Прочитайте вопрос внимательно. Речь идёт о нажатии на клаве Enter!!!! А не о затыкании кнопки Ок, на которую например можно мышкой кликнуть. Горе пользователю такого диалога, бедняга поседеет кликая на Ок пытаясь подтвердить введённую инфу. esgal, опять 25 , а как ты диалог закрывать собираешься? если OnCancel заткнёшь? Попробуй и напиши о результатах. Гром, те ты предлагаешь вставить кнопку, в обработчике которой посылать самому себе WM_DESTROY? А если эта кнопка будет дефолтная? То тогда при каждом Enter кранты окошку? Или кто должен WM_DESTROY посылать? А если диалог модальный? "Чёт я вас ребята не пойму, "Муму" Тургенев написал, а памятник вы Пушкину ставите." зы Если это продолжение первоапрельской темы, то тогда сорри. С юмором у меня в последнее время напряжёнка.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
esgal
Гость
|
|
« Ответ #9 : 14-04-2005 03:48 » |
|
Пробовал и не один раз. Закрывается по щелчку на кныпку. Если не веришь, попробуй сам, всё работает на отлично. Метод кстати стандартный. Просто не стоит на мух с молотом охотиться, когда есть мухобойка. Ведь мы же убрали только обработчик производного от класса. CDialog::OnOk() никуда не делся. Получаем, что у нас нормально закрывается диалог и больше не мешают клавиши эскап и ентер.
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #10 : 14-04-2005 04:51 » |
|
Джон - ты не понял. Есть несколько вариантов использования контрола диалога. 1. Обычный когда ты возврат смотришь. 2. Когда тебе не нужен возрат. росто тебе нужно окошко. 3. Как основное окно апликации. В первом случае все ясно. Во втором есть несколько типов контролов типа едит бокса в котором можно выставить Enter needed тогда по enter-у закрываться не будет если активным является он, но в остальных случаях закрытие по ентереу нежелательным оказувается. В третьем вообще бред сивой кобылы. Я обычно кнопочки Ок и Ентере когда они мне не нужны убиваю на корню. Учти что дефолтная кнопка в таком случае остается ентереом, и не поменять уже. Отсюда и проблема с ОнОк. Беру изначально ставлю обработчики и убираю все что надо, и не закрывается. А WM_DESTROY ставить на кнопку глупо. Я обычно менюшку делаю или выход по х в правом верхнем углу оставляю. Теперь немного из теории. Нажатие на ESC и Enter у мелкомягких в диалоге априори стоит и изавиться полностью трудно. Я бы сказал, что в случаях когда вот такой выход не нужен ставить не модальный диалог, а немодальный с помощью Create ShowWindow. Тогда все в твоих лапах
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Hooter
|
|
« Ответ #11 : 14-04-2005 15:33 » |
|
Если OK и Cancel в диалоге не нужны (это происходит чаще всего, когда диалоговое окно является главным окном приложения ), то действительно, проще всего - убить обработчики. А вот, когда их нужно оставить, имхо, самый правильный способ - фильтровать команды в PreTranslateMessage. Реализация этого способа тут уже проскакивала.
|
|
|
Записан
|
|
|
|
CyberMan
Гость
|
|
« Ответ #12 : 15-04-2005 10:22 » |
|
Гы-гы-гы тут идея такая пришла. Когда пользователь нажимает на кнопку ентер диалогу посылается сообщение диалог обрабатывает это сообщение и вызывает фукцию OnOk() так давай те перепишем эти функции в нашем производном классе(ескейп соответственно) после удалим дефолтные кнопки создадим новые с идентификаторами ID_MYOK создадим методы для их обработки и вызовем в ний функции CDialog::OnOk() (ескейп соответственно) геморойно получилось но должно работать и теоретически все выглядит ништяк никто не придередся DоModal возвратит IDOK/IDCANCEL ГЫ-ГЫ-ГЫ
|
|
|
Записан
|
|
|
|
baldr
|
|
« Ответ #13 : 15-04-2005 15:05 » |
|
Циберман, я так и сделал. Но это не метод. Фишка в том, что нажатие Enter на самом диалоге я отловил, а на контроле - нет. Esc вообще везде работает... Еще не пробовал совет Джона и Pu... Счас попробуем..
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
baldr
|
|
« Ответ #14 : 15-04-2005 15:07 » |
|
Вернее, я переопределил OnOK - но это глупо, потому что проще было убрать его из карты сообщений... Вообще говоря, идея переопределить DoModal мне в голову не приходила...
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
|