Ошибка при фокусировки на TabSheet [РЕШЕНО]

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Аватара пользователя
vada
энтузиаст
Сообщения: 691
Зарегистрирован: 14.02.2006 12:43:17

Ошибка при фокусировки на TabSheet [РЕШЕНО]

Сообщение vada »

Вот такая проблема: что-то в программе считаю, а потом юзверю надо показать результаты. Для этого делаю TabSheet видимым и активным, и фокусирую PageControl на нем.

Код: Выделить всё

TabSheet6.Enabled := true;
TabSheet6.TabVisible := true;
PageControl1.ActivePageIndex := 4; // У TabSheet6 индекс именно 4
Sleep(200);  // Добюавил Sleep ибо без него выпадение ошибки 50% с ним около 10%
PageControl1.Invalidate;
// Назначаем стартовую ячейку грида.
Sel := KGrid6.Selection;
Sel.Col1 := 1;
Sel.Col2 := 1;
Sel.Row1 := 1;
Sel.Row2 := 1;
KGrid6.Selection := Sel;


В результате получаю ошибку (картинка во вложении)

Причем, ошибка выскакивает не всегда. Как левая нога у компьютера брыкнет. Игрался параметром Sleep. Не сильно помогает. Даже если его задать настолько большим что чуствуется задержка, все равно, иногда выскакивает ошибка.
Что делать? Что я делаю не так?
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Последний раз редактировалось vada 11.05.2011 15:00:24, всего редактировалось 3 раза.
Maxizar
постоялец
Сообщения: 385
Зарегистрирован: 20.03.2010 18:48:14

Re: Ошибка при фокусировки на TabSheet

Сообщение Maxizar »

Я делаю например так, увсе вроде работает:

Код: Выделить всё

unit Unit1; 

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ComCtrls, Grids;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    PageControl1: TPageControl;
    StringGrid1: TStringGrid;
    StringGrid2: TStringGrid;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button2Click(Sender: TObject);
begin
  PageControl1.ActivePageIndex:=0;
  StringGrid1.SetFocus;
  StringGrid1.Row:=2;
  StringGrid1.Col:=4;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 TabSheet2.TabVisible:=True;
 TabSheet2.Visible:=True;
 PageControl1.PageIndex:=1; //РјРѕР¶РЅРѕ Рё так PageControl1.PageIndex:=TabSheet2.PageIndex;
 StringGrid2.SetFocus;
 StringGrid2.Row:=1;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
 TabSheet2.TabVisible:=False;
 TabSheet2.Visible:=False;
end;

procedure TForm1.Button1Click(Sender: TObject);
var NewTab:TTabSheet;
    SG    :TStringGrid;
begin
    NewTab:=TTabSheet.Create(Nil);
    NewTab.PageControl:=PageControl1;
    NewTab.Caption:='NewTab';

    SG:=TStringGrid.Create(NewTab);
    SG.Align:=alClient;
    SG.Parent:=NewTab;
    SG.Visible:=True;

    NewTab.Visible:=True;

    PageControl1.PageIndex:=NewTab.PageIndex;
    SG.SetFocus;
    SG.Row:=2;
    SG.Col:=3;
end;

end.



Lazarus 0.9.30 For Win
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
vada
энтузиаст
Сообщения: 691
Зарегистрирован: 14.02.2006 12:43:17

Re: Ошибка при фокусировки на TabSheet

Сообщение vada »

В тестовой форме у меня тоже все работает.
В рабочей программе нет. :(
Аватара пользователя
dunin
энтузиаст
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и
Контактная информация:

Re: Ошибка при фокусировки на TabSheet

Сообщение dunin »

Sel - это что такое?
Код полностью можно?
Аватара пользователя
vada
энтузиаст
Сообщения: 691
Зарегистрирован: 14.02.2006 12:43:17

Re: Ошибка при фокусировки на TabSheet

Сообщение vada »

Полностью кода очень много.

Код: Выделить всё

var
  Sel: TKGridRect;

Но это место не принципиально. У меня в нескольких местах после каких-то действий открываются вкладки. Вкладки разной насыщеностью. Пофиг веники. Во всех попытках открыть спрятанные вкладки иногда получаю такую ошибку.
И вот тут.

Код: Выделить всё

  Report.CreateReport;

  if (FormProgress.Showing) then FormProgress.Close;

  TabSheet7.Enabled := true;
  TabSheet7.TabVisible := true;

  // Открываем файл отчета
  OpenHtmlFile(UTF8Encode(HtmlReportFileName));
  PageControl1.ActivePageIndex := 6;
  IpHtmlPanel1.SetFocus;

  MenuItemSpeedButtonList.SetEnable(true, [fmiReportOpenHtmlBrowse, fmiReportOpenHtmlMsWord]);

У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
dunin
энтузиаст
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и
Контактная информация:

Re: Ошибка при фокусировки на TabSheet

Сообщение dunin »

Вместо

Код: Выделить всё

PageControl1.ActivePageIndex := 6;

Попробуйте

Код: Выделить всё

PageControl1.tabIndex := 6;


Добавлено спустя 4 минуты 57 секунд:
Не знаю. не удалось повторить ошибку
Аватара пользователя
vada
энтузиаст
Сообщения: 691
Зарегистрирован: 14.02.2006 12:43:17

Re: Ошибка при фокусировки на TabSheet

Сообщение vada »

Код: Выделить всё

  Report.CreateReport;

  if (FormProgress.Showing) then FormProgress.Close;

  TabSheet7.Enabled := true;
  TabSheet7.TabVisible := true;

  // Открываем файл отчета
  OpenHtmlFile(UTF8Encode(HtmlReportFileName));
  //PageControl1.ActivePageIndex := 6;
  PageControl1.tabIndex := 6;
  IpHtmlPanel1.SetFocus;

  MenuItemSpeedButtonList.SetEnable(true, [fmiReportOpenHtmlBrowse, fmiReportOpenHtmlMsWord]);



Добавлено спустя 4 минуты 24 секунды:
Убрал

Код: Выделить всё

IpHtmlPanel1.SetFocus;


Ошибка не выскакивает!
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
dunin
энтузиаст
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и
Контактная информация:

Re: Ошибка при фокусировки на TabSheet

Сообщение dunin »

PageControl1.ActivePageIndex := 6; а на картинке ActivePageIndex := 5
Не в этом дело?

Не... в последнем сообщении картинка правильная...

Добавлено спустя 2 минуты 18 секунд:
vada писал(а):...
Убрал

Код: Выделить всё

IpHtmlPanel1.SetFocus;


Ошибка не выскакивает!

Ну так надо понимать, что IpHtmlPanel1.Enabled в этот момент в False стоит. не?
Аватара пользователя
vada
энтузиаст
Сообщения: 691
Зарегистрирован: 14.02.2006 12:43:17

Re: Ошибка при фокусировки на TabSheet

Сообщение vada »

Нет не в этом дело. Если бы я указал 5, открылась бы другая вкладка. Тут все правильно.

Добавлено спустя 3 минуты 45 секунд:
Ну так надо понимать, что IpHtmlPanel1.Enabled в этот момент в False стоит. не?

А кто ее знает! :) Какие пипки юзверь понажимал, те и в фейсе.
В общем, похоже, работает. Мне не важно на что фокус в форме будет. Выбросил везде фокусировку, заработало нормально.

Спасибо за помощь!

Добавлено спустя 8 минут 7 секунд:
Костыль конечно, но пусть пока так... Программу сдавать надо :)
Аватара пользователя
vada
энтузиаст
Сообщения: 691
Зарегистрирован: 14.02.2006 12:43:17

Re: Ошибка при фокусировки на TabSheet

Сообщение vada »

Оказалось что костыль не помог. Сообщение все равно появляется. Покопался отладчиком и вот что получается. Есть такой метод в файле customform.inc

Код: Выделить всё

procedure TCustomForm.SetActiveControl(AWinControl: TWinControl);
begin
  if FActiveControl <> AWinControl then
  begin
    if (AWinControl<>nil) then
    begin
      if (AWinControl = Self) or
         (GetParentForm(AWinControl) <> Self) or
         not ((csLoading in ComponentState) or AWinControl.CanFocus) then
      begin
        DebugLn('TCustomForm.SetActiveControl ',DbgSName(Self),' AWinControl=',DbgSName(AWinControl),' GetParentForm(AWinControl)=',
                DbgSName(GetParentForm(AWinControl)),' csLoading=',dbgs(csLoading in ComponentState),' AWinControl.CanFocus=',
                dbgs((AWinControl<>nil) and AWinControl.CanFocus),' IsControlVisible=',dbgs((AWinControl<>nil) and AWinControl.IsControlVisible),
                ' Enabled=',dbgs((AWinControl<>nil) and AWinControl.Enabled));
        {$IFDEF VerboseFocus}
        RaiseGDBException(SCannotFocus);
        {$ELSE}
        raise EInvalidOperation.Create(SCannotFocus);
        {$ENDIF}
      end;
    end;

    {$IFDEF VerboseFocus}
    DbgOut('TCustomForm.SetActiveControl ',Name,':',ClassName,' FActive=',DbgS(FActive));
    if FActiveControl<>nil then
      DebugLn(' OldActiveControl=',DbgSName(FActiveControl))
    else
      DebugLn(' OldActiveControl=nil');
    if AWinControl<>nil then
      DebugLn(' NewActiveControl=',DbgSName(AWinControl))
    else
      DebugLn(' NewActiveControl=nil');
    {$ENDIF}

    FActiveControl := AWinControl;
    if ([csLoading, csDestroying] * ComponentState = []) then
    begin
      if FActive then
        SetWindowFocus;
      ActiveChanged;
    end;
  end;
end;

в нем и формируется мое злополучное ругательство.

Код: Выделить всё

raise EInvalidOperation.Create(SCannotFocus);

Замечено следующее поведение:
После того как я сделал

Код: Выделить всё

PageControl1.ActivePageIndex := 0;

В приведенный выше метод приходит параметр AWinControl имеющий правильное значение, т.е. контрол на которой должны фокусироваться на вкладке PageIndex = 0. Ну, типа, зашибись! Активный контрол становится именно тот что нам нужно, вкладка та что нужно!... Но это не все! Дальше этот метод вызывается еще несколько раз, и один из них с параметром который указывает на контрол, который был активен до

Код: Выделить всё

PageControl1.ActivePageIndex := 0;

Ну и получаем нафиг не нужный нам Exception. Т.к. активное окно уже другое и на нем этого контрола нет. :(

Люди добрые! ПОМОГИТЕ! Как правильно переключиться на другую вкладку???? Я уже столько костылей перепрбовал - не помогает.
alexmai
постоялец
Сообщения: 106
Зарегистрирован: 02.02.2009 13:58:42

Re: Ошибка при фокусировки на TabSheet

Сообщение alexmai »

Люди добрые! ПОМОГИТЕ! Как правильно переключиться на другую вкладку???? Я уже столько костылей перепрбовал - не помогает.

[/quote]
А чем не нравиться метод PageControl1.PageIndex:=6;
и поставить заглушки чтобы не тявкала когда пытаюсь установить фокус

Код: Выделить всё

procedure TForm1.PageControl1Enter(Sender: TObject);
begin
 ifPageControl1.PageIndex=0 then
 begin
 edv1.SetFocus ;
 btnnext.Enabled :=false;
 end;
 if PageControl1.PageIndex=1 then
 ed11.SetFocus ; 
end;
Аватара пользователя
vada
энтузиаст
Сообщения: 691
Зарегистрирован: 14.02.2006 12:43:17

Re: Ошибка при фокусировки на TabSheet

Сообщение vada »

Что

Код: Выделить всё

PageControl1.PageIndex:=6;

что

Код: Выделить всё

PageControl1.ActivePageIndex := 6;

без разницы. Поведение системы одинаковое.
Подпер жутким костылем. Сначала прикрываю все вкладки, кроме первой.(ВСЕ закрывать нельзя. Потом все вкривь вкось) Кстати, если фокусировка была на контрол с этой вкладки, проблема остается. Единственно, редко на ней фокус остается. :?
Потом открываю нужные вкладки. Добравшись до "фокусной" делаю

Код: Выделить всё

PageControl1.ActivePageIndex := N;
, открываю остальные нужные вкладки.
УЖАС!!!!!!!! Неужели нельзя как-то попроще! Да и проблема осталась не решенной.
Maxizar
постоялец
Сообщения: 385
Зарегистрирован: 20.03.2010 18:48:14

Re: Ошибка при фокусировки на TabSheet

Сообщение Maxizar »

vada У Вас уже 99 сообщений, значит, вы не в первый раз читаете этот форум. Так значит, я вас не удивлю, сказав, что Вам уже писал и я и другие, что проблему не удалось воспроизвести. Значит: у Вас что то есть специфическое, и скорее всего не во вкладках дело. А попытаться воспроизвести проблему, и т.п. Это никому не нужно. У Вас достаточно сложная форма или приложение (код нам не нужен, может там и правда военная тайна) но вот сидеть тратить 30-50 минут на то чтобы нарисовать что то подобное, да и еще попытаться представить как именно вы это сделали трудно да и зачем оно нам???.. Правильно? Да правильно конечно.

Тогда как Вы не новичок, скажу Вам прямо: Наверное пока Вы не сделаете тестовое приложение (пустое, только форма + окна бла бла бла и без лишнего кода, особенно кода вашего приложения) Это все только усложнить поиск проблемы. При этом тест, должен именно воспроизводить вашу ошибку и представлять собой именно те окна и тому подобное которое вы используете. Вот тогда, у кого будет желание и свободное время сможет скачать и реально потестить… и возможно ответить на вашу проблему.

Просто подумайте когда вопрос чисто синтаксический или проблема в понимании логики работы одной функции, тестов то и не нужно привел код, получил ответ. Но у вас то проблема другого плана… И где кошка зарыта, не совсем понятно, возможно, зарыта она прям под носом а возможно и нет.... Но это можно будет сказать, только имея тест перед глазами. :wink:
Аватара пользователя
vada
энтузиаст
Сообщения: 691
Зарегистрирован: 14.02.2006 12:43:17

Re: Ошибка при фокусировки на TabSheet

Сообщение vada »

Удалось добиться повторяемости ошибки в тестовом примере.
Ошибку подкидывает компонент TKGrid http://www.tkweb.eu/en/delphicomp
Причем, только в случае когда грид в фокусе. В примере реакция на выбранную ячейку в пятой строке.
Тестовый проект во вложении.
В общем, похоже, косяк у автора TKGrid. :(

Написал автору письмо. Всем спасибо кто потратил свое драгоценное время.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Maxizar
постоялец
Сообщения: 385
Зарегистрирован: 20.03.2010 18:48:14

Re: Ошибка при фокусировки на TabSheet

Сообщение Maxizar »

Ну вот другое дело...
Проблема именно в TKGrid, а именно в посылке или очереде сообщений на выделение. Focus. Копать нужно в этом напровлении. Почему именно в этом, видно, что указатель и т.п при фокусировки не отробатывают до конца... (ну как бы не до конца) всмысле. мы в процедуре, которая отрабатывает выделение (KGrid1SelectCell) уходим от родного компонента (на котором лежит таблица)... возможно из за этой потери фокуса, в классе происходят траблы.. ведь если убрать переход на Таб, все просто гуд...
Решение: Грабли от меня :oops:
Выключать Таблицу, и лишь потом переходить на другую вкладку. благодоря этому, мы не доходим до того момента когда отрабатывается смена фокуса, так как таблица выключена.
Из за чего необходимо таблицу Включать, при переходе на нужную вкладку... Ну короче в архиве ваше приложение, с моими граблями вроде все ок...
При этом я уж сильно не увлекался, мол при клике на табе включать таблицу :oops: , код включения только на кнопках.. ну если грабли устроят вас то можно и на табы переписать... :wink:
Если захотите исправить баг, можно наверное посмотреть, реализацию передачи фокуса и т.п в Таблице лазаруса...

PS. Надеюсь я чем то помог Вам.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Ответить