Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.07.2017, 09:28   #1
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию Не устанавливается фокус на компоненте в программно создаваемом окне

Здравствуйте.
Создаю программно модальную форму с двумя кнопками и эдитом. Хочу, чтобы фокус устанавливался в эдит, но он остаётся на первой создаваемой кнопке. Не пойму как переделать код, чтобы фокус устанавливался на Эдит.
Код:
function ShowCompare(TextStr, LenStr: string): string;
Var
  FormCompare: TForm;
  NoEd: TEdit;
begin
  Result:='';
  FormCompare:=TForm.Create(Application);
  try
    FormCompare.Width:=275;
    FormCompare.Height:=100;
    FormCompare.Caption:='Расхождение в тексте';
    FormCompare.Position:=poScreenCenter;
    with Tbutton.Create(FormCompare) do
    begin
      ModalResult:=mrYes;
      Top:=30;
      Left:=10;
      Width:= 45;
      Height:= 25;
      Name:='BtYes';
      Caption:='Да';
      Parent:=FormCompare;
    end;
    with TLabel.Create(FormCompare) do
    begin
      Top:=10;
      Left:=10;
      Height:= 25;
      Color := clWhite;
      Name:='LbInfo';
      Caption:='Соответствует ли текст "'+TextStr+'" длине "'+LenStr+'"?';
      Parent:=FormCompare;
    end;
    with Tbutton.Create(FormCompare) do
    begin
      ModalResult:=mrNo;
      Top:=30;
      Left:=FormCompare.ClientWidth-45-10;
      Width:= 45;
      Height:= 25;
      Name:='BtNo';
      Caption:='Нет';
      Parent:=FormCompare;
    end;
    NoEd:=TEdit.Create(FormCompare);
    with NoEd do
    begin
      Top:=30;
      Left:=10 + 45+ 10;
      Width:= FormCompare.ClientWidth - 45 - 30 - 45 - 10;
      Text:='';
      Parent:=FormCompare;
    end;
    if FormCompare.ShowModal = mrNo then
    begin
      FormCompare.SetFocus;
      NoEd.SetFocus;
      Result:=NoEd.Text;
    end;
  finally
    FormCompare.Free;
  end;
end;

Последний раз редактировалось Ship_1; 07.07.2017 в 09:30.
Ship_1 вне форума Ответить с цитированием
Старый 07.07.2017, 10:06   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

Цитата:
Создаю программно модальную форму с двумя кнопками и эдитом.
Весь фокус в том что код после ShowModal будет работать только ПОСЛЕ показа и после закрытия.

Вар1. написать и задать обработчик события OnCreate|OnShow не знаю где корректно отработает SetFocus.
Код:
formcompare.OnCreate:=.... ;
НО.... для этого будет нужен объект(класс) которому сможет принадлежать данный метод.
пока у нас такого класса не наблюдается (у нас приведена простая процедура).

Вар2.
Код:
FormCompare.Show; // показать форму НЕмодально
noed.SetFocus; // установить фокус
FormCompare.Hide; // снова ее скрыть
FormCompare.ShowModal ; // и показать ЕЕ модально
Вар3. поиграть с порядком переходов.
noed.TabOrder:=0;
и/или
порядка создания элементов (создавать noED первым из контролов).
фокус формы "автоматом" устанавливается на первый из подходящих дочерних элементов.
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 07.07.2017 в 10:12.
evg_m на форуме Ответить с цитированием
Старый 07.07.2017, 10:35   #3
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Самым удобным кажется вариант 3, самым привлекательным для меня - вариант 1. Но с обработчиками событий для классов я пока не сталкивался и не понимаю:
1. Можно ли запихнуть класс в функцию (тип можно - уже запихивал)?
2. Как это в данном случае реализовать?
Пока реализовал третьим способом, сработало, но хотелось бы узнать как реализовать первым в рамках одной функции.

Последний раз редактировалось Ship_1; 07.07.2017 в 10:58.
Ship_1 вне форума Ответить с цитированием
Старый 07.07.2017, 10:55   #4
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

Код:
type 
  TmyExtClass =class 
  public
     procedure FormShowExt(Sender: TObject); //данный метод(-процедуру) будет ПОТОМ задавать как обработчик события 
  public
     MyFocusComponent: TEdit; //а это нам пригодится чтобы помнить куда же мы хотим установить фокус
  end;

function ........
var
  extobj: TmyExtClass;
  fomcomapre: TForm;
  noed: TEdit; //теперь этот компонент мы будем запоминать "внутри" переменной(объекта) extobj (см. MyFocusComponent)
begin
  formcomapre:=Tform.Create();
  extobj:=TMyExtClass.Create; 
  formcompare.OnShow:=extobj.FormshowWxt; // это НЕ ВЫЗОВ процедуры! это задание обработчика события OnShow
  ...
  noed extobj.myfocuscomponent:=TEdit.Create;
  ...
  formcompare.ShowModal;
.....
  formcompare.Free;
  extobj.Free;
end;

procedure TmyExtClass.FormshowExt(Sender: TObject);
begin
   MyFocusComponent.SetFocus;
end;
P.S. при желании можно практически ВЕСЬ код твоей процедуры убрать в этот класс оставив только создание объекта данного класса ну и объявление соотв. переменной.
хотя бы так....
Код:
begin
  extobj:=TmyExtclass.Create; //форма может быть создана там внутри 
  extobj.AddControl(Tlabel.Create, false); // контрол не получает фокуса при показе 
  extobj.AddControl(TEdit.Create, true); //  контрол должен получить фокус при показе
  extobj.run; // выполнить показ в модальном режиме
  extobj.Free; //КОНЕЦ!!!!
end;
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 07.07.2017 в 11:04.
evg_m на форуме Ответить с цитированием
Старый 07.07.2017, 11:17   #5
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Но внутрь функции, похоже, это не удастся запихнуть?... Компилятор ругается, если я на public, я его поместил внутри функции...


Цитата:
форма может быть создана там внутри
Но сам класс же при этом не форма, как мне тогда назначать родителем и "следящей за уничтожением" ту "внутреннюю" форму при
Цитата:
Код:
extobj.AddControl(Tlabel.Create, false);
?

Последний раз редактировалось Ship_1; 07.07.2017 в 11:29.
Ship_1 вне форума Ответить с цитированием
Старый 07.07.2017, 11:57   #6
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

не знаю ответил ли я на ваши вопросы, но вот ваш код переделанный на работу классом.
Код:
type
  TAutoForm =class
  private
    Fautoform: TForm;
    FFocusControl: TWinControl;
  public
    procedure AddControl(r: TControl; needsetfocus: boolean =false);
    function RunModalform: string;
    procedure AfterConstruction; override; 
    procedure BeforeDestruction; override;
  protected
    procedure OnshowForm(Sender: TObject);
  end;
  
procedure TAutoform.OnShowForm(sender: TObject);
begin
  if FFocusControl<>nil then FFocusControl.SeFocus;
end;  

procedure TAutoform.AfterConstruction;
var
  r: Tcontrol;
begin
  inherited; 
  
  FAutoform:=TForm.Create(Application);
  Fautoform.Width:=275;
  Fautoform.Height:=100;
  Fautoform.Caption:='Расхождение в тексте';
  Fautoform.Position:=poScreenCenter;
  Fautoform.OnShow:=self.OnShowForm;

  r:=TBuitton.Create(FautoForm);
  width r as TButton do
  begin
    ModalResult:=mrYes;
    Top:=30;
    Left:=10;
    Width:= 45;
    Height:= 25;
    Name:='BtYes';
    Caption:='Да';
    Parent:=FormCompare;
  end;
  AddControl(r, false);
  
  r:=TLabel.Create(Fautoform);
  with r as TLabel do
  begin
    Top:=10;
    Left:=10;
    Height:= 25;
    Color := clWhite;
    Name:='LbInfo';
    Caption:='Соответствует ли текст "'+TextStr+'" длине "'+LenStr+'"?';
  end;
  AddControl(r, false);
  
  r:=Tbutton.Create(Fautoform);
  with r as TButon do
  begin
    ModalResult:=mrNo;
    Top:=30;
    Left:=FAutoForm.ClientWidth-45-10;
    Width:= 45;
    Height:= 25;
    Name:='BtNo';
    Caption:='Нет';
  end;
  autorun.AddControl(r, false);
  
  r:=TEdit.Create(fautoform);
  with r as TEdit do
  begin
    Top:=30;
    Left:=10 + 45+ 10;
    Width:= Fautoform.ClientWidth - 45 - 30 - 45 - 10;
    Text:='';
  end;
  autorun.AddControl(r, true);
end;

procedure Tautoform.BeforeDestruction;
begin
  self.Fautoform.Free;
  inherited;
end;

procedure Tautoform.AddControl(r: TControl; needsetfocus: boolean =false);
begin
  r.Parent:=self.fautoFrom;
  if neeedfocus then self.ffocuscontrol:=r;
end;

function TAutoform.runcompare: string;
begin
  case self.fautoform.showmodal of
  mryes: result:='yes';
  mrno:  result:='no';
  else   result:='---';
  end;
end;
Код:
function ShowCompare(TextStr, LenStr: string): string;
var
  autorun: TAutoForm;
begin
  autorun:=TAutoForm.Create;
  try
  result:=autorun.runmodalform;
  finally
    autorun.Free;
  end;
end;
P.S. а вдогонку и еще использование class function (вспомнилась другая ваша тема)
просто "прячем" нашу "главную"(из-за которой весь сыр-бор) функцию ShowCompare туда же где у нас и все остальное.
Код:
type
  TautoForm =class
  ... // все как и было
  public 
    class function ShowCompare(...): string; //слово класс означает что для ВЫЗОВА данной функции нам НЕ НУЖЕН сам объект (См. пример ниже)
 end;

var
 s: string;
begin
 s:=TautoForm.Showcomapre(...);  //мы не делаем Create!!!! а просто ВЫЗЫВАЕМ функцию!!! и получаем ответ
 showMessage(s);
end;

function ShowCompare(....): string;
class function TAutoForm.showCompare(...): string;
var
  autorun: TAutoform;
begin
  autorun:=TautoForm.Create; //а уже здесь создаем нужный нам объект
  ..... // работаем с ним 
  autorun.Free; // и тут же удаляем его (если он нам конечно не нужен зачем-то еще)
  end;
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 07.07.2017 в 12:00.
evg_m на форуме Ответить с цитированием
Старый 07.07.2017, 12:19   #7
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Спасибо огромное, в Ваших ответах много полезного и нового для меня и я возьму это за основу продолжения проб работы с классами!
Но один вопрос всё же остался без ответа, и в данном случае он для меня достаточно важен:
Цитата:
Сообщение от Ship_1 Посмотреть сообщение
1. Можно ли запихнуть класс в функцию (тип можно - уже запихивал)?
Цитата:
Сообщение от Ship_1 Посмотреть сообщение
Но внутрь функции, похоже, это не удастся запихнуть?... Компилятор ругается, если я на public, я его поместил внутри функции...
Дело в том, что форма используется только при одном типе запросов (сравнение двух текстов), ни с чем "внешним" больше не работает, поэтому хочется локализовать абсолютно всё внутри этой функции. Как понимаю, с классом это не пройдёт?
Ship_1 вне форума Ответить с цитированием
Старый 07.07.2017, 12:52   #8
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

Цитата:
Можно ли запихнуть класс в функцию
так что ли сделать?
Код:
function ShowComapre(.... ): string;

type
   Textclass =class
      ....
   end;

begin
  ....
end;
нет. негде писать реализацию методов, в объявлении класса могут быть только объявления методов и полей.
Да и если бы удалось, то код самой функции оказался бы совершенно нечитабелен для ЧЕЛОВЕКА. (к примеру описание параметров слишком далеко ушло бы от их использования).

если уж так хочется скрыть все нужное, то можно перенести все кроме объявления функции в "закрытый" блок implementaion
НО ... при этом придется следить за порядком написания размещения функций
Код:
unit
  
interface
  
  function ShowComapre(): string; // снаружи (из других модулей) будет видно только ЭТО.

implementation
  
здесь никто кроме функции ShowCompare про наш класс (и другие объявления) не узнает.

  type // объявим класс 
      TmyExtClass =class
      .....
      end;
// объявление класса должно быть ДО его первого использования (т.е. до реализации функции) 
function showComapre(...): string;
....
end;

// ну а уж реализация методов может быть и после нее.

procedure TmyExtClass....
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 07.07.2017 в 13:00.
evg_m на форуме Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как программно изменить цвет в компоненте cyPanel artemavd Компоненты Delphi 4 16.09.2014 10:45
Программно нажать кнопку в чужом окне Delphi7 AlexP_77 Win Api 1 03.05.2012 00:06
Как программно нажать кнопку в чужом Java-окне? vhawk Win Api 0 14.06.2011 17:05
RichTextBox программно потерять фокус. Casper-SC Общие вопросы .NET 0 02.04.2010 13:43
Почему строки в компоненте ListBox программно удаляются, а визуально нет? Velross Компоненты Delphi 7 10.12.2009 19:35