-
Доброго времени, уважаемые господа дельфисты. Вроде не первый год с дельфи, а возникла проблема, которая, вроде, банальна, но как ее решить - не нашел. Итак, у меня динамически создается PageControl. На его TabSheet'ах также динамически создаются TMemo. Мне нужно в глобальную переменную CurMemo: TMemo положить найденный мемо-контрол на активной вкладке, чтобы обращаться к его методам и свойствам как CurMemo.Clear. var CurMemo: TMemo;
...
procedure TForm1.PageCtrlChange(Sender: TObject);
begin
CurMemo:=TMemo(PageCtrl.ActivePage.Controls[0]);
end;
...
procedure SomeProc;
begin
CurMemo.Clear; end; Но ничего не выходит - при вызове CurMemo.Clear получаем AV. Решил проще - как в учебниках, через AS. Но! С контролом можно работать только внутри функции/процедуры, где ты его получил. То есть код procedure SomeProc;
var CurMemo: TControl;
begin
CurMemo:=PageCtrl.ActivePage.Controls[0]; TMemo(CurMemo).Clear; end; работает без проблем, все очищается. Но стоит CurMemo: TControl вынести в глобальную и вызвать Clear из любой другой процедуры/функции как написано выше (без получения контрола), то получаем АВ. var CurMemo: TControl;
...
procedure TForm1.PageCtrlChange(Sender: TObject);
begin
CurMemo:=PageCtrl.ActivePage.Controls[0];
end;
...
procedure SomeProc;
begin
TMemo(CurMemo).Clear; end; Все тоже самое во FPC работает без проблем. А дельфя не соглашается так делать. В чем подвох?
-
> Вроде не первый год с дельфи
Знать все эти годы учебники не читались, а вместо чтения учебников использовался код с помоек.
-
SomeProc вызывается раньше PageCtrlChange
Ваш КО.
-
procedure SomeProc(const CurMemo: TMemo);
-
может, забыл создать CurMemo?
-
> Знать все эти годы учебники не читались, а вместо чтения учебников использовался код с помоек. Я не просил углубляться в историю кто, чего и где читал. Я просил совета. Я с подобным динамическим управлением сталкиваюсь впервые. С динамическими созданиями контролов и заполнениями проблем нет. Я много чего читал, но что-то улетучилось из-за неиспользования и за давностью лет.
> procedure SomeProc(const CurMemo: TMemo); > может, забыл создать CurMemo? Нет, КО выиграл. Действительно, я проверял на одной вкладке - ессно там OnChange еще не вызывался (хотя вновь создаваемая вкладка у меня автоматически делается активной и я посчитал, что это вызовет OnChange). Но стоило сделать две и переключиться на другую, как все заработало. Вот в который раз убеждаюсь, что нефига программить поздно вечером на ночь глядя - слона-то я и не заметил. Заработал метод с TMemo как с переменной - CurMemo:=TMemo(Memo1); и CurMemo.Clear;
-
Просто изначально неудачная идея делать подобную глобальную переменную и работать с нею из обычной функции. Да ещё и Assigned не проверять. Сделайте поле класса. Инициализируйте его значение при создании, меняйте при событии, и просто обращайтесь как к полю Self.
-
Да надо будет все облагородить - я ж просто для примера сделал, без каких-либо проверок. Как оказалось, делал-то все верно, но забыл, что переменная не проинициализирована. Отсюда АВ. Там много чего еще хранить надо будет, кроме мемо. Ессно придется все это как-то оборачивать для удобства.
-
Можно либо сделать наследников от PageControl и TTabSheet - создавать сразу с TMemo, создать поле CurMemo и поддерживать его актуальность. Ну либо бюджетный вариант:
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls;
type TForm1 = class(TForm) PageControl1: TPageControl; Button1: TButton; Button2: TButton; Button3: TButton; procedure FormCreate(Sender: TObject); procedure PageControl1Change(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private CurrentMemo: TMemo; procedure TabAdd(P: TPageControl; const Activate: Boolean = False); procedure TabDeleteActive(P: TPageControl); procedure TabDeleteIndex(P: TPageControl; const Index: Integer); public // end;
var Form1: TForm1;
implementation
{$R *.dfm}
const NEW_TAB_TITLE = 'New Tab'; TAB_MEMO_NAME = 'TabMemo';
procedure TForm1.FormCreate(Sender: TObject); begin CurrentMemo:=nil; end;
procedure TForm1.TabAdd(P: TPageControl; const Activate: Boolean = False); var T: TTabSheet; M: TMemo; begin if not Assigned(P) then Exit; T:=TTabSheet.Create(P); T.Caption:=NEW_TAB_TITLE; M:=TMemo.Create(T); M.Name:=TAB_MEMO_NAME; M.Text:='#'+IntToHex(GetTickCount(), 8); M.Align:=alClient; M.ScrollBars:=ssBoth; M.Parent:=T; T.PageControl:=P; if Activate then P.ActivePage:=T; P.OnChange(P); end;
procedure TForm1.TabDeleteActive(P: TPageControl); begin if not Assigned(P) then Exit; if (P.PageCount>0) then begin P.ActivePage.Free(); P.OnChange(P); end; end;
procedure TForm1.TabDeleteIndex(P: TPageControl; const Index: Integer); begin if not Assigned(P) then Exit; if (P.PageCount>0) and (Index>=0) and (Index<P.PageCount) then begin P.Pages[Index].Free(); P.OnChange(P); end; end;
procedure TForm1.PageControl1Change(Sender: TObject); var M: TComponent; begin CurrentMemo:=nil; with TPageControl(Sender) do if (PageCount>0) then begin M:=ActivePage.FindComponent(TAB_MEMO_NAME); if (M is TMemo) then CurrentMemo:=TMemo(M); end; end;
procedure TForm1.Button1Click(Sender: TObject); begin TabAdd(PageControl1, True); end;
procedure TForm1.Button2Click(Sender: TObject); begin if Assigned(CurrentMemo) then ShowMessage(CurrentMemo.Text); end;
procedure TForm1.Button3Click(Sender: TObject); begin TabDeleteActive(PageControl1); end;
end.
-
>> Можно либо сделать наследников от PageControl и TTabSheet - создавать сразу с TMemo Я уже думал сделать наследника PageControl с внутренним управлением CurMemo, без внешних вмешательств.
>> M:=ActivePage.FindComponent(TAB_MEMO_NAME); TabSheet возвращает ComponentCount=0 при динамическом размещении контролов на нем, поэтому пришлось через Controls/ControlCount.
-
>> ComponentCount=0 Тьфу, если при создании указывать родителя, то <>0. Я указывал Create(nil).
-
Причём тут ComponentCount? Представленный в [8] код рабочий и в нём такого нету. :) Родитель == nil это с одной стороны допустимо, но тут лучше так не делать, родитель Меме - вкладка.
|