Перейти к содержанию
  • 0
x11

InputQuery работает только на Windows

Вопросы

Пока всё было внутри модуля формы и внутри локальной процедуры, то запись добавлялась в таблицу.

Решил сделать обёртку и перенёс код в общий модуль, чтобы использовать в других местах.

На винде, всё норм, а на смартфоне ошибок нет, но запись не добавляется.

 

 

 

type
 TInputQueryResult = record
   Res: TModalResult;
   OutV: string;
 end;
...
...
...


function myInputQuery(const Caption, Text, AVal: String): TInputQueryResult;
Var
  val: array of string;
  r: TInputQueryResult;
begin
  SetLength(val, 1);
  val[0] := AVal;

  TDialogService.InputQuery(Caption, [Text], Val,
      procedure(const AResult: TModalResult; const AValues: array of string)
        begin
          case AResult of
            mrOk:
              begin
                R.Res := mrOk;
                R.OutV:= AValues[0];
              end;

            mrCancel:
              begin
                R.Res := mrCancel;
                R.OutV:= '';
              end;
          end;
        end
  );

  result := r;
end;

 

Использование

 

procedure TfmReference.actInsertExecute(Sender: TObject);
Var
  sTableName, cap: string;
  res: TInputQueryResult;
begin
  cap := comboRefType.Items[comboRefType.ItemIndex];

  res := myInputQuery(cap, 'Добавить: ', '');
  if res.Res = mrOk then
  begin
    if not res.OutV.IsEmpty then
    begin
      sTableName := GetTableName;
      sqlInsert.sql.Text := Format('Insert into %s (name) values(' + QuotedStr(res.OutV) + ')', [sTableName]);
      sqlInsert.Execute;
      if sqlInsert.Transaction.Active then sqlInsert.Transaction.Commit;
      actRefreshExecute(nil);
    end;
  end;
end;

 

Отредактировал x11

Поделиться сообщением


Ссылка на сообщение

Рекомендуемые сообщения

  • 0

Решил проблему так:

 

добавил пару строк

  while r.Res = mrNone do // wait for modal result
    Application.ProcessMessages;

 

и получилось:

function myInputQuery(const Caption, Text, AVal: String): TInputQueryResult;
Var
  val: array of string;
  r: TInputQueryResult;
begin
  SetLength(val, 1);
  val[0] := AVal;

  TDialogService.InputQuery(Caption, [Text], Val,
      procedure(const AResult: TModalResult; const AValues: array of string)
        begin
          case AResult of
            mrOk:
              begin
                R.Res := mrOk;
                R.OutV:= AValues[0];
              end;

            mrCancel:
              begin
                R.Res := mrCancel;
                R.OutV:= '';
              end;
          end;
        end
  );

  while r.Res = mrNone do // wait for modal result
    Application.ProcessMessages;

  result := r;
end;

 

 

Я надеюсь, это нормально или это плохо?

Отредактировал x11

Поделиться сообщением


Ссылка на сообщение
  • 0
6 часов назад, x11 сказал:

На винде, всё норм, а на смартфоне ошибок нет, но запись не добавляется.

вам знакомо non-blocking dialogs? курим мануальчик

Поделиться сообщением


Ссылка на сообщение
  • 0

Да, я уже понял, что в этом дело.

Тут уже в другом вопрос: то, что я добавил

while r.Res = mrNone do Application.ProcessMessages;

это нормально или нельзя так?

Поделиться сообщением


Ссылка на сообщение
  • 0

т.е. придётся лепить тот старый овнокод в каждой процедуре :(

Поделиться сообщением


Ссылка на сообщение
  • 0

Неужели никак нельзя придумать "обёртку" TDialogService.InputQuery?

Поделиться сообщением


Ссылка на сообщение
  • 0

то, что вы не хотите принять принцип работы операционной системы, которая справедливо лишает "программеров" возможности одним окном убить всё вокруг, никак не повод помогать делать то, что не нужно делать

на мобильных ОС нет модальных диалогов таких как на десктопе.

что конкретно у вас не получается? после выполнения диалога программа придет туда, где у вас Case AResult of

там и размещайте код, который должен выполниться при возврате из диалога

можете заменить 

TDialogService.InputQuery(Caption, [Text], Val,
      procedure(const AResult: TModalResult; const AValues: array of string)
        begin
          ...
        end
  );

на 

procedure TForm1.InputDialogHandler(const AResult: TModalResult; const AValues: array of string);
begin
  case AResult of
  ...
end;

...
TDialogService.InputQuery(Caption, [Text], Val, InputDialogHandler);

в чем проблема-то?

Поделиться сообщением


Ссылка на сообщение
  • 0

Да я всё понимаю и не против отсутствия модульных окон.

4 минуты назад, krapotkin сказал:

procedure TForm1.InputDialogHandler(const AResult: TModalResult; const AValues: array of string); begin case AResult of ... end;

 

Получается, что в каждой форме нужно лепить <TForm>.InputDialogHandler"? Просто это противоречит принципу ООП: один раз написал, много раз используй.

Отредактировал x11

Поделиться сообщением


Ссылка на сообщение
  • 0

Мало того, в каждой форме и на каждый чих нужно создавать свой

TForm1.InputDialogHandler

?

 

Например, процедуры добавление, удаление и редактирование.

Нужно создавать три разных InputDialogHandler.

 

Это и так три разных процедуры, а получается, что нужно создать ещё по одной.

 

Поделиться сообщением


Ссылка на сообщение
  • 0

ничего не понятно

раньше вы писали
if inputQuery then  SomeProcedure
сейчас надо писать
inputQuery(SomeProcedure) 
procedure SomeProcedure;
if Result=mrOK then
собственно вся разница
Одну строку добавили. Где if AResult

Поделиться сообщением


Ссылка на сообщение
  • 0

В общем теперь так:

procedure TfmReference.InputDialogHandlerInsert(const AResult: TModalResult; const AValues: array of string);
begin
//запрос на добавление

  case AResult of
    mrOk:
      if not AValues[0].IsEmpty then
      begin
        sqlInsert.sql.Text := Format('Insert into %s (name) values(' + QuotedStr(AValues[0]) + ')', [GetTableName]);
        sqlInsert.Execute;
        if sqlInsert.Transaction.Active then sqlInsert.Transaction.Commit;
        actRefreshExecute(nil);
      end;//
  end;// case
end;

procedure TfmReference.InputDialogHandlerEdit(const AResult: TModalResult; const AValues: array of string);
Var
 id: integer;
begin
//запрос на редактирование

  case AResult of
    mrOk:
      if not AValues[0].IsEmpty then
        begin
          id := StrToIntDef(ListView1.Items[ListView1.Selected.Index].Objects.FindObjectT<TListItemText>('id').Text, -1);
          sqlInsert.sql.Text := Format('update %s set name = ' + QuotedStr(AValues[0]) + 'where id = ' + IntToStr(ID), [GetTableName]);
          sqlInsert.Execute;
          actRefreshExecute(nil);
        end;
  end;// case
end;


procedure TfmReference.MyInputCloseDialogProc(const AResult: TModalResult);
Var
 id: integer;
begin
// запрос на удаление
  if AResult = mrYes then
  begin
    id := StrToIntDef(ListView1.Items[ListView1.Selected.Index].Objects.FindObjectT<TListItemText>('id').Text, -1);
    sqlInsert.sql.Text := Format('delete from %s where id = ' + IntToStr(ID), [GetTableName]);
    try
      sqlInsert.Execute;
      actRefreshExecute(nil);
    except
      on e:exception do
      begin
        ShowMessage('Ошибка удаления. ' + e.Message + sLineBreak + sqlInsert.sql.Text);
      end;// on e:exception do

    end;// try
  end
end;

 

 

 

пример использования:

procedure TfmReference.actInsertExecute(Sender: TObject);
Var
  val: array of string;
  cap: string;
begin
// добавляем запись

  SetLength(val, 1);
  val[0] := '';
  cap    := comboRefType.Items[comboRefType.ItemIndex];

  TDialogService.InputQuery(cap, ['Добавить: '], Val, InputDialogHandlerInsert);
end;

procedure TfmReference.actEditExecute(Sender: TObject);
Var
  val: array of string;
  cap: string;
begin
// редактируем запись

  if not Assigned(ListView1.Selected) then
  begin
    ShowMessage('Выберите строку');
    exit;
  end;

  SetLength(val, 1);
  val[0] := ListView1.Items[ListView1.Selected.Index].Objects.FindObjectT<TListItemText>('name').Text;
  cap    := comboRefType.Items[comboRefType.ItemIndex];

  TDialogService.InputQuery(cap, ['Изменить: '], Val, InputDialogHandlerEdit);
end;
    

procedure TfmReference.actDeleteExecute(Sender: TObject);
Var
  id: integer;
begin
// удаляем запись
    
  if not Assigned(ListView1.Selected) then
  begin
    ShowMessage('Выберите строку');
    exit;
  end;

//  resDel := False;
  TDialogService.MessageDialog('Удалить выбранную строку?', TMsgDlgType.mtConfirmation, mbYesNo, TMsgDlgBtn.mbYes, 0,
    MyInputCloseDialogProc);
end;

 

 

 

Т.е., как видите, получается 6 процедур вместо трёх.

Отредактировал x11

Поделиться сообщением


Ссылка на сообщение
  • 0

вы не очень внимательно читаете

best practice - это писать

ActInsert...
 if Inputquery() then ProcInsert()
ActEdit...
 if Inputquery() then ProcEdit()
ActDelete...
 if Inputquery() then ProcDelete()

и мы получаем ровно то же количество процедур

если же писать "простыней" в старом варианте

ActInsert...
If InputQuery() then
begin
  ...
end;


то это в точности соответствует

InputQuery(..., procedure (...)begin 
  if AResult=mrOk then
  begin
  end;
end)

 

Поделиться сообщением


Ссылка на сообщение
  • 0

но всё равно, в каждой форме, где планируется использовать InputDialog, нужно создавать свой InputDialogHandler.

Поделиться сообщением


Ссылка на сообщение

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...