#delphi #modal-dialog
#delphi #модальный диалог
Вопрос:
У меня есть modaldialog с OK и Cancel кнопкой. Для OK я установил Default
для свойства значение True, а для Cancel кнопки — Cancel
свойство. ModalResult имеет значение mrOK
и mrCancel
соответственно.
Однако ни нажатие Enter, ни Esc клавиша на моей клавиатуре не закрывают диалоговое окно. Что я здесь пропустил?
Редактировать
Я разместил на своем сайте небольшое тестовое приложение, использующее подозрительный диалог. IDE — это RAD Studio XE3.
Комментарии:
1. Вы установили для свойств ModalResult значение mrOk / mrCancel?
2. @lurd — Да, я сделал (иначе кнопки тоже не работали бы). Я добавлю информацию к своему вопросу. Спасибо за ответ.
3. Вызываете ли вы модальный диалог с помощью
ShowModal
метода? Просто чтобы убедиться. В противном случае я предлагаю вам создать небольшой компилируемый пример, чтобы продемонстрировать вашу проблему.4. @lurd — Да, я вызываю
ShowModal
. Я разместил тестовое приложение на своем сайте .5. Похоже, это как-то связано с TSpinEdit; Если вы добавляете TEdit в форму, то Enter и Esc работают правильно, когда TEdit сфокусирован, но не когда сфокусирован TSpinEdit.
Ответ №1:
Из вашего опубликованного примера вы можете видеть, что TSpinEdit
элемент управления сфокусирован и фиксирует ключи.
Чтобы закрыть модальную форму во всех случаях, установите form KeyPreview
в true и вставьте это в OnKeyPress
событие:
procedure TSelectDlg.FormKeyPress(Sender: TObject; var Key: Char);
begin
if (Key = Char(vk_escape)) then // #27
CancelBtn.Click
else
if (Key = Char(vk_return)) then // #13
OkBtn.Click;
end;
Комментарии:
1. Хотя я согласен, что это решает проблему (спасибо за это), остается новый вопрос: какая польза от свойств
Cancel
иDefault
, если нам приходится самим писать код для эмуляции нажатий клавиш? Кроме того, этот код также требуется, если у меня нетsetfocus
строки.2. Если вы нажмете клавишу OK, чтобы сфокусироваться, вы можете выйти с помощью клавиши return без этого дополнительного кода. Это поведение Windows по умолчанию. Свойства cancel и default обрабатываются, когда нет другого сфокусированного элемента управления, захватывающего ключи.
3. Понял. Похоже, я ожидал слишком многого от свойств
Cancel
иDefault
:-). (Прошло некоторое время с тех пор, как я использовал Delphi в последний раз)4. Это не проблема delphi, это стандартное поведение платформы
5. @DavidHeffernan Это isue Delphi. Перейдите и проверьте реализацию TSpinEdit, и вы увидите, почему. Методы, которые вы хотите проверить, — это TSpinEdit. Нажатие клавиши и запуск TSpinEdit. Является validchar.
Ответ №2:
Для справки, это должно сработать. Однако, похоже, что в TSpinEdit есть ошибка. Поскольку TSpinEdit является образцом (Vcl.Samples.Spin.pas, обратите внимание на «Образцы»), вы можете исправить это самостоятельно.
Для TSpinEdit добавьте следующее объявление метода сразу после WMCut:
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
Завершите класс (Shift Ctrl C) и добавьте следующий код в WMGetDlgCode:
procedure TSpinEdit.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
inherited;
Message.Result := Message.Result and not DLGC_WANTALLKEYS;
end;
Это сообщит VCL, что элемент управления редактированием не хочет обрабатывать клавиши Enter и Escape (VK_ENTER, VK_ESCAPE). Поскольку он не обрабатывает клавиши, они будут перенаправлены на кнопки, которые затем будут вызваны на основе их настроек (по умолчанию и отмена).
Не стесняйтесь сообщать об этом в Центр качества
Комментарии:
1. Возможно, пришло время рассмотреть возможность замены этого «образца» на реальный
up-down control
.2. Нравится компонент TUpDown? Существует уже некоторое время, например, с Delphi 2 или 3.
3. Сообщается как QC125891, TSpinEdit захватывает ключи vk_return и vk_escape .
4. @LURD Не могли бы вы отредактировать контроль качества, пожалуйста. Эта проблема существует со времен Delphi 7, если не даже более старых версий Delphi. В Delphi 7 установлена версия компилятора 15, но вы ввели 20, что равно для Delphi 2009.
5. @SilverWarior, 20 — это Delphi-XE6. Я не уверен, но я думаю, что предполагается добавить последнюю версию, в которой обнаруживается ошибка. В любом случае, я добавил примечание о том, что это присутствует, по крайней мере, с D7.