Версия для печати
VCL.TRadioButton.Автовыбор при получении фокуса в момент показа формы
http://www.delphikingdom.com/asp/viewitem.asp?catalogID=1187Cepгей Poщин
дата публикации 26-12-2005 06:51
КАТЕГОРИЯ БИБЛИОТЕКА.VCL.TRadioButton.Автовыбор при получении фокуса в момент показа формы ПРОДУКТ Delphi ПЛАТФОРМА Windows При получении фокуса ввода контролом TRadioButton в момент отображения формы свойство Checked принимает значение True.
Проверено в Delphi 7 (SP1), Delphi 2005 (SP3), Windows 2000, Windows 98.
В приведенном примере в момент закрытия окна диалога все TRadioButton принимают ранее сохраненные значения поля Checked. Если изменить RadioButton.Checked, используя мышь, и кнопку "Отмена" тоже нажать мышью — форма закроется и при следующем открытии все TRadioButton будут находиться в нужном состоянии. Если нажать клавишу Esc, то при следующем открытии тот RadioButton, в котором находится фокус ввода — будет выбран, чего быть не должно.
Типовые решения
- При закрытии формы надо поменять фокус ввода, если он находится в RadioButton.
- При изменении свойства Checked изменять фокус ввода. Если новое значение True, то этот орган управления получает фокус ввода, в противном случае проверяется, есть ли хоть один RadioButton у которого Checked=true, и если таковых нет, то эмулируется потеря фокуса всеми RadioButton. Для этого следует исправить метод TRadioButton.SetChecked (см. модуль StdCtrls):
procedure TRadioButton.SetChecked(Value: Boolean); procedure TurnSiblingsOff; var I: Integer; Sibling: TControl; begin if Parent <> nil then with Parent do for I := 0 to ControlCount - 1 do begin Sibling := Controls[I]; if (Sibling <> Self) and (Sibling is TRadioButton) then with TRadioButton(Sibling) do begin if Assigned(Action) and (Action is TCustomAction) and TCustomAction(Action).AutoCheck then TCustomAction(Action).Checked := False; SetChecked(False); end; end; end; //Эта процедура устанавливает фокус ввода на выбраный переключатель procedure FocusChanged; var i:integer; Sibling: TControl; NoChecked:boolean; begin if Value then begin //Когда устанавливается свойство Checked if HandleAllocated then Windows.SetFocus(Handle); //Этот переключатель просто получает фокус ввода end else begin //Когда сбрасывается свойство Checked, несколько сложнее if (parent<>nil) then begin //Проверяем, есть ли хоть один TRadioButton у которого свойство Checked=true NoChecked:=true; for i:=0 to Parent.ControlCount - 1 do begin Sibling := Parent.Controls[I]; if (Sibling is TRadioButton) and Sibling.Visible and Sibling.Enabled and TRadioButton(Sibling).Checked then begin NoChecked:=false; break; end; end; //Если таких TRadioButton нет, то эмулируем для них потерю фокуса ввода if NoChecked then for i:=0 to Parent.ControlCount - 1 do begin Sibling := Parent.Controls[I]; if (Sibling is TRadioButton) and Sibling.Visible and Sibling.Enabled and TRadioButton(Sibling).HandleAllocated then begin //Чтобы TRadioButton потерял фокус ввода, делаем его //сначала неактивным, а потом активным //Возможно есть другие варианты TRadioButton(Sibling).Enabled:=false; TRadioButton(Sibling).Enabled:=true; end; end; end; end; end; begin if FChecked <> Value then begin FChecked := Value; TabStop := Value; if HandleAllocated then SendMessage(Handle, BM_SETCHECK, Integer(Checked), 0); if Value then begin TurnSiblingsOff; inherited Changed; if not ClicksDisabled then Click; end; FocusChanged; //Добавлено end; end;
Дополнительные ссылки и прилагаемые файлыВопрос на Круглом столе Королевства Delphi:
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=35572
Скачать пример:StoneTest_90.zip