На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Обязательно выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Этот раздел предназначен для вопросов, посвященных разработке компонентов, а также для тестирования собственных бесплатных компонентов с открытым исходным кодом.

Здесь запрещается:
1. Размещать ссылки на какие-либо коммерческие компоненты, реализующие требуемую функциональность.
2. Обсуждать и тестировать коммерческие компоненты или компоненты с закрытым кодом.
3. Давать ссылки на сайты с исходным кодом компонентов. Все тестируемые исходные коды должы быть размещены на сайте ИСХОДНИКИ.RU.
Модераторы: Rouse_, DimaBr
  
> Обработчик событий в динамически созданном объекте, Добавление CheckBox в InputQuery и событие OnClick...
    Друзья, нужна помощь в укращении InputQuery.
    Решил немного переписать диалоговое окно InputQuery из Dialogs.pas, добавив CheckBox.
    И тут встала проблема обработки события OnClick у CheckBox...
    Собственно как это сделать внутри функции?

    Крод:
    ExpandedWrap disabled
      function TMainForm.MyInputQuery(const ACaption, APrompt, AButtonOk, AButtonCancel: string;
        var Value: string): Boolean;
      var
        Form: TForm;
        Prompt: TLabel;
        Edit: TEdit;
        CheckBox: TCheckBox;
        DialogUnits: TPoint;
        ButtonTop, ButtonWidth, ButtonHeight: Integer;
       
      function GetAveCharSize(Canvas: TCanvas): TPoint;
      var
        I: Integer;
        Buffer: array[0..51] of Char;
      begin
        for I := 0 to 25 do Buffer[I] := Chr(I + Ord('A'));
        for I := 0 to 25 do Buffer[I + 26] := Chr(I + Ord('a'));
        GetTextExtentPoint(Canvas.Handle, Buffer, 52, TSize(Result));
        Result.X := Result.X div 52;
      end;
       
      procedure MyOnClick(Sender: TObject);
      begin
       if(CheckBox.Checked) then
        Edit.PasswordChar := #42
       else
        Edit.PasswordChar := #0;
      end;
       
      begin
        Result := False;
        Form := TForm.Create(Application);
        with Form do
          try
            Canvas.Font := Font;
            DialogUnits := GetAveCharSize(Canvas);
            BorderStyle := bsDialog;
            Caption := ACaption;
            ClientWidth := MulDiv(180, DialogUnits.X, 4);
            Position := poScreenCenter;
            Prompt := TLabel.Create(Form);
            with Prompt do
            begin
              Parent := Form;
              Caption := APrompt;
              Left := MulDiv(8, DialogUnits.X, 4);
              Top := MulDiv(8, DialogUnits.Y, 8);
              Constraints.MaxWidth := MulDiv(164, DialogUnits.X, 4);
              WordWrap := True;
            end;
            Edit := TEdit.Create(Form);
            with Edit do
            begin
              Parent := Form;
              Left := Prompt.Left;
              Top := Prompt.Top + Prompt.Height + 5;
              Width := MulDiv(164, DialogUnits.X, 4);
              MaxLength := 255;
              PasswordChar := '*';
              Text := Value;
              SelectAll;
            end;
            CheckBox := TCheckBox.Create(Form);
            with CheckBox do
            begin
              Parent := Form;
              Left := Prompt.Left;
              Top := Edit.Top + Edit.Height + 6;//15;
              Width := MulDiv(113, DialogUnits.X, 4);
              Caption := 'Скрыть пароль';
              Checked := True;
              State := cbChecked;
              OnClick := MyOnClick; //проблема тут!!!
            end;
            ButtonTop := Edit.Top + Edit.Height + 25;//15;
            ButtonWidth := MulDiv(50, DialogUnits.X, 4);
            ButtonHeight := MulDiv(14, DialogUnits.Y, 8);
            with TButton.Create(Form) do
            begin
              Parent := Form;
              Caption := AButtonOk;
              ModalResult := mrOk;
              Default := True;
              SetBounds(MulDiv(38, DialogUnits.X, 4), ButtonTop, ButtonWidth,
                ButtonHeight);
            end;
            with TButton.Create(Form) do
            begin
              Parent := Form;
              Caption := AButtonCancel;
              ModalResult := mrCancel;
              Cancel := True;
              SetBounds(MulDiv(92, DialogUnits.X, 4), ButtonTop, //Edit.Top + Edit.Height + 15,
                ButtonWidth, ButtonHeight);
              Form.ClientHeight := Top + Height + 13;
            end;
            if ShowModal = mrOk then
            begin
              Value := Edit.Text;
              Result := True;
            end;
          finally
            Form.Free;
          end;
      end;

    Прикреплённый файлПрикреплённый файл____________________.png (3,71 Кбайт, скачиваний: 56)

    Причина такого подхода заключается в довольно частом и универсальном использовании InputQuery.
    Сообщение отредактировано: User32 -
    Незнание некоторых фактов сполна компенсируется знанием некоторых принципов...
      Обработчик события (procedure MyOnClick) должен быть методом объекта, а не регулярной процедурой и тем более не вложенной.

      Как видно по TMainForm - объект имеется, вот его методом и сделать MyOnClick
      Сообщение отредактировано: MBo -
        Цитата MBo @
        Обработчик события (procedure MyOnClick) должен быть методом объекта, а не регулярной процедурой
        ...
        Как видно по TMainForm - объект имеется, вот его методом и сделать MyOnClick

        Можно присобачить динамически к чекбоксу.
        Цитата User32 @
        Собственно как это сделать внутри функции?

        Внутри никак, снаружи - элементарно
        ExpandedWrap disabled
          procedure cbxClick(Sender: TObject);
          begin
            if (Sender as TCheckBox).Checked then showmessage('+') else showmessage('-');
          end;
           
          function TMainForm.MyInputQuery(const ACaption, APrompt, AButtonOk, AButtonCancel: string;
            var Value: string;EventCBX:Pointer=nil): Boolean;
          var
          ...
            NE:TNotifyEvent;
          begin
          ...
                CheckBox := TCheckBox.Create(Form);
                with CheckBox do
                begin
                  Parent := Form;
                  Left := Prompt.Left;
                  Top := Edit.Top + Edit.Height + 6;//15;
                  Width := MulDiv(113, DialogUnits.X, 4);
                  Caption := 'Скрыть пароль';
                  Checked := True;
                  State := cbChecked;
                  if EventCBX<>nil then begin
                    with TMethod(NE) do
                    begin
                      Code:=EventCBX;
                      Data:=Pointer(CheckBox);
                    end;
                    OnClick:=NE;
                  end;
                end;
          ...
          end;
           
           
          ....
          MyInputQuery(ACaption, APrompt, AButtonOk, AButtonCancel, Value, @cbxClick);


        Добавлено
        Цитата User32 @
        Причина такого подхода заключается в довольно частом и универсальном использовании InputQuery.

        У дураков мысли сходятся, у мну такая же функция есть )))
        Сообщение отредактировано: Gonarh -
          В теории можно самому реализовать ShowModal, крутя выборку сообщений, ловить соответствующий click и обрабатывать его. Но это маразм. Я бы посоветовал не жадиться и выделить этот диалог в самостоятельный класс со всеми приличествующими атрибутами. Потому что через месяц ты захочешь прикрутить, к примеру, показ баллуна и дизейбл кнопки при вводе некорректного символа, и цикл повторится.

          Добавлено
          Также можно подменить WindowProc, но тут тоже всё внутри процедуры не упакуешь.
          Codero ergo sum
          // Программирую — значит, существую
          1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script Execution time: 0,0885 ]   [ 16 queries used ]   [ Generated: 15.11.18, 08:25 GMT ]