На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> Как запретить выбор в активном CheckBox (не деактивируя его).
    Собственно столкнулся с проблемой такого плана:
    Есть ряд опциональных CheckBox, и они служат для показа опций и должны быть всегда Enable := True но при этом не должны менять своего статуса Checked, т.е. полный запрет на любое изменение пользователем как кликом мыши так и по нажатию пробела на клавиатуре. Какое сообщение нужно перехватить чтобы перекрыть его для всех CheckBox глобально. А может использовать что то другое вместо CheckBox?
    Какие варианты?
      Как то так можно глобально
      ExpandedWrap disabled
        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;
        Эм.... как то не красиво выходит с перекрытием.

        ExpandedWrap disabled
          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;

        И получаетя при клике контрол маргает.
        Нужно чтобы вообще не получал фокус.
          Цитата User32 @
          А может использовать что то другое вместо CheckBox?

          Image? :) И фокуса не будет и выключить нельзя будет.
            Цитата Lumen @
            Цитата User32 @
            А может использовать что то другое вместо CheckBox?

            Image? :) И фокуса не будет и выключить нельзя будет.

            Да не хотелось бы возится с отрисовкой двойных бордеров как у CheckBox чтобы придать объёмность а из битмапа грузить не правильно, т.к. если сменить стиль окон Windows то будут накладки.
              Цитата User32 @
              Да не хотелось бы возится с отрисовкой двойных бордеров как у CheckBox
              А так не пойдет?
              ExpandedWrap disabled
                DrawFrameControl(Canvas.Handle, Rect(10, 10, 24, 24), DFC_BUTTON, DFCS_CHECKED);
                Цитата User32 @
                Да не хотелось бы возится с отрисовкой двойных бордеров как у CheckBox чтобы придать объёмность

                И не надо возиться, т.к. CheckBox рисуется стандартными средствами. Глянь, как рисуются чекбоксы в TCheckListBox.DrawCheck - несколько строчек при ThemesEnabled (через ThemeServices.DrawElement), иначе еще проще через DrawFrameControl
                  Да, действительно, одним DrawFrameControl'ом не обойтись. Но если нужна поддержка тем, действительно почему бы не заглянуть в исходники VCL, и взять оттуда код отрисовки CheckBox. Как leo правильно уже заметил, взять можно из того же CheckListBox.
                    Упс, с DrawFrameControl уже опередили
                      Или так
                      ExpandedWrap disabled
                        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;

                      Будет натуральная отрисовка с темами;
                      Сообщение отредактировано: BugMeNot -
                        Самое простое решение - положить чекбоксы на панель с выключенным бевелом. И панели назначить энайбл = фолсе.
                          Можно сабклассить чекбоксы и ловить WM_LBUTTONDOWN, WM_LBUTTONUP.
                            Цитата Fr0sT @
                            Можно сабклассить чекбоксы и ловить WM_LBUTTONDOWN, WM_LBUTTONUP.

                            Да можно конечно же, но думаю результат будет аналогичен тому что я описал

                            Добавлено
                            Цитата Lumen @
                            Цитата User32 @
                            Да не хотелось бы возится с отрисовкой двойных бордеров как у CheckBox
                            А так не пойдет?
                            ExpandedWrap disabled
                              DrawFrameControl(Canvas.Handle, Rect(10, 10, 24, 24), DFC_BUTTON, DFCS_CHECKED);

                            Гениально, я и не знал про волшебство WinAPI'шной DrawFrameControl

                            Добавлено
                            Цитата BugMeNot @
                            Или так
                            ExpandedWrap disabled
                              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 @
                            Самое простое решение - положить чекбоксы на панель с выключенным бевелом. И панели назначить энайбл = фолсе.

                            Да действительно это самое простое и оптимальное решение, без лишней головной боли. Совсем забыл про волшебное свойства панели.
                            Сообщение отредактировано: User32 -
                              Цитата User32 @
                              Да можно конечно же, но думаю результат будет аналогичен тому что я описал

                              Ну я попробовал, более-менее работает (не реагирует на нажатия).
                                Как-то сложно все ...
                                Если чекбокс сам решает Checked он или не Checked то надо воспользоваться этим себе во благо :)
                                Я пошел по такому пути:
                                ExpandedWrap disabled
                                  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;


                                И все.
                                т.е. выключение мы даже не прверяем.
                                Работает стабильно, причем как видите с кучей чекбоксов
                                  А мне, извините, кажется порочной сама идея не давать меняться контролу. Т.е. именно для этого существует свойство Enabled. Если что-то не должно реагировать на нажатие - Enabled := false; И юзер не морщит моск какого хрена чек кликается, но не меняется.
                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                  0 пользователей:


                                  Рейтинг@Mail.ru
                                  [ Script execution time: 0.1031 ]   [ 16 queries used ]   [ Generated: 27.04.26, 09:53 GMT ]