Перейти к содержанию
Fire Monkey от А до Я
  • 0

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


x11

Вопрос

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

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

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

 

 

 

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

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

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

что конкретно у вас не получается? после выполнения диалога программа придет туда, где у вас 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)

 

Ссылка на комментарий

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

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

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

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

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

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

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

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

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

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