Как запретить выбор в активном CheckBox (не деактивируя его).
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.116] |
|
|
ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
| Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Как запретить выбор в активном CheckBox (не деактивируя его).
|
|
|
|
|
Собственно столкнулся с проблемой такого плана:
Есть ряд опциональных CheckBox, и они служат для показа опций и должны быть всегда Enable := True но при этом не должны менять своего статуса Checked, т.е. полный запрет на любое изменение пользователем как кликом мыши так и по нажатию пробела на клавиатуре. Какое сообщение нужно перехватить чтобы перекрыть его для всех CheckBox глобально. А может использовать что то другое вместо CheckBox? Какие варианты? |
|
Сообщ.
#2
,
|
|
|
|
Как то так можно глобально
![]() ![]() type TCheckBox = class(VCL.StdCtrls.TCheckBox) procedure CNCommand(var Message: TWMCommand); message CN_COMMAND; end; TForm1 = class(TForm) CheckBox1: TCheckBox; ..................... procedure TCheckBox.CNCommand(var Message: TWMCommand); begin if Owner = SomeOptionsForm then // SendMessage(Handle, BM_SETCHECK, 1, 0) else inherited; end; |
|
Сообщ.
#3
,
|
|
|
|
Эм.... как то не красиво выходит с перекрытием.
![]() ![]() type TCheckBoxX = class(TCheckBox) private { Private declarations } procedure CNCommand(var Message: TWMCommand); message CN_COMMAND; end; type TCheckBox = class(TCheckBoxX) end; ... procedure TCheckBoxX.CNCommand(var Message: TWMCommand); begin if Message.NotifyCode = BN_CLICKED then Exit; end; И получаетя при клике контрол маргает. Нужно чтобы вообще не получал фокус. |
|
Сообщ.
#4
,
|
|
|
|
Цитата User32 @ А может использовать что то другое вместо CheckBox? Image? И фокуса не будет и выключить нельзя будет. |
|
Сообщ.
#5
,
|
|
|
|
Цитата Lumen @ Цитата User32 @ А может использовать что то другое вместо CheckBox? Image? И фокуса не будет и выключить нельзя будет.Да не хотелось бы возится с отрисовкой двойных бордеров как у CheckBox чтобы придать объёмность а из битмапа грузить не правильно, т.к. если сменить стиль окон Windows то будут накладки. |
|
Сообщ.
#6
,
|
|
|
|
Цитата User32 @ А так не пойдет?Да не хотелось бы возится с отрисовкой двойных бордеров как у CheckBox ![]() ![]() DrawFrameControl(Canvas.Handle, Rect(10, 10, 24, 24), DFC_BUTTON, DFCS_CHECKED); |
|
Сообщ.
#7
,
|
|
|
|
Цитата User32 @ Да не хотелось бы возится с отрисовкой двойных бордеров как у CheckBox чтобы придать объёмность И не надо возиться, т.к. CheckBox рисуется стандартными средствами. Глянь, как рисуются чекбоксы в TCheckListBox.DrawCheck - несколько строчек при ThemesEnabled (через ThemeServices.DrawElement), иначе еще проще через DrawFrameControl |
|
Сообщ.
#8
,
|
|
|
|
Да, действительно, одним DrawFrameControl'ом не обойтись. Но если нужна поддержка тем, действительно почему бы не заглянуть в исходники VCL, и взять оттуда код отрисовки CheckBox. Как leo правильно уже заметил, взять можно из того же CheckListBox.
|
|
Сообщ.
#9
,
|
|
|
|
Упс, с DrawFrameControl уже опередили
|
|
Сообщ.
#10
,
|
|
|
|
Или так
![]() ![]() procedure TForm1.PaintBox1Paint(Sender: TObject) begin with TCheckBox.Create(Self) do try Left := -1000; Visible := True; Parent := Self; Checked := True; PaintTo(TPaintbox(Sender).Canvas.Handle, 0, 0); finally Free; end; Будет натуральная отрисовка с темами; |
|
Сообщ.
#11
,
|
|
|
|
Самое простое решение - положить чекбоксы на панель с выключенным бевелом. И панели назначить энайбл = фолсе.
|
|
Сообщ.
#12
,
|
|
|
|
Можно сабклассить чекбоксы и ловить WM_LBUTTONDOWN, WM_LBUTTONUP.
|
|
Сообщ.
#13
,
|
|
|
|
Цитата Fr0sT @ Можно сабклассить чекбоксы и ловить WM_LBUTTONDOWN, WM_LBUTTONUP. Да можно конечно же, но думаю результат будет аналогичен тому что я описал Добавлено Цитата Lumen @ Цитата User32 @ А так не пойдет?Да не хотелось бы возится с отрисовкой двойных бордеров как у CheckBox ![]() ![]() DrawFrameControl(Canvas.Handle, Rect(10, 10, 24, 24), DFC_BUTTON, DFCS_CHECKED); Гениально, я и не знал про волшебство WinAPI'шной DrawFrameControl Добавлено Цитата BugMeNot @ Или так ![]() ![]() procedure TForm1.PaintBox1Paint(Sender: TObject) begin with TCheckBox.Create(Self) do try Left := -1000; Visible := True; Parent := Self; Checked := True; PaintTo(TPaintbox(Sender).Canvas.Handle, 0, 0); finally Free; end; Будет натуральная отрисовка с темами; Не совсем удобно, точнее правильно я считаю создавать визуальные объекты за пределами родительского окна. Но как альтернатива или ещё один вариант вполне сносно. Добавлено Цитата northener @ Самое простое решение - положить чекбоксы на панель с выключенным бевелом. И панели назначить энайбл = фолсе. Да действительно это самое простое и оптимальное решение, без лишней головной боли. Совсем забыл про волшебное свойства панели. |
|
Сообщ.
#14
,
|
|
|
|
Цитата User32 @ Да можно конечно же, но думаю результат будет аналогичен тому что я описал Ну я попробовал, более-менее работает (не реагирует на нажатия). |
|
Сообщ.
#15
,
|
|
|
|
Как-то сложно все ...
Если чекбокс сам решает Checked он или не Checked то надо воспользоваться этим себе во благо ![]() Я пошел по такому пути: ![]() ![]() procedure TfrmMain.chk01Click(Sender: TObject); var ch: TCheckBox; begin ch := (Sender as TCheckBox); if ch.Checked then // Чекбокс хочет влючиться begin // Проверяем, а можно ли ему включаться? if НЕЛЬЗЯ then ch.Checked := False end; end; И все. т.е. выключение мы даже не прверяем. Работает стабильно, причем как видите с кучей чекбоксов |