Autor |
Beitrag |
LittleBen
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Fr 22.04.11 19:41
Hallo,
habe mal wieder ein kleines Problemchen. Es geht um das erzeugen, aber viel wichtiger, um das löschen von Pages auf einem Pager. Dazu verwende ich Komponenten der TMS-Bibliothek(TAdvOfficePage bzw. TAdvOfficePager).
Eine Page zu erzeugen ist kein Problem, doch eine zu löschen schon...
Der Vorgang:
Ich habe eine Procedure die RefreshTab heißt. Diese löscht zuerst alle Tabs(auser den Ersten), und erzeugt dann wieder so viele Tabs, wie die StringList Items hat. Doch wenn ich mich gerade in einem Tab(nicht im Ersten) aufhalte und dann diese Procedure aufrufe, dann tritt ein Fehler(meist Zugriffsverletzung) auf. Doch das komische ist, dass dieser Fehler nur manchmal auftritt, auch wenn ich immer das selbe mache.
Wenn ich mich im ersten Tab aufhalte funktioniert alles.
Schaut es euch einfach mal an:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
| procedure TF_Essen.RefreshTab; var aPage: TAdvOfficePage; aButton: TButton; i: integer; sl: TStringlist; begin sl:= TStringlist.Create; for i:= oReg1.AdvPageCount-1 downto 1 do begin oReg1.AdvPages[i].free; end; sl.Add('TEST'+inttostr(1)); sl.Add('TEST'+inttostr(2)); sl.Add('TEST'+inttostr(3)); sl.Add('TEST'+inttostr(4)); sl.Add('TEST'+inttostr(5)); for i:= 0 to sl.count-1 do begin aPage:= TAdvOfficePage.Create(self); aPage.AdvOfficePager:= oReg1; aPage.Caption:= sl.Strings[i]; aPage.Name:= 'Page'+inttostr(i+2); aPage.Tag:= i+2; aButton:= TButton.Create(Self); aButton.Parent:= oReg1.AdvPages[oReg1.AdvPageCount-1]; aButton.Caption:= 'Refresh '+IntToStr(i+1); aButton.Name:= 'b_refresh'+IntToStr(i+2); aButton.SetBounds(100,12+i*(aButton.Height+4),aButton.Width,aButton.Height); aButton.Tag:=i+2; aButton.OnClick:= b_refresh1Click; end; sl.Free; end; |
Habe mich dann ein bisschen schöau gemacht und den Tipp gelesen, dass man mit die Pages mit Postmessage freigeben soll.
Also habe ich das getan. Hat sich dadurch auch deutlich verbessert!!
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| const PM_FREEPAGE = CM_Base+1; ... procedure TF_Essen.RefreshTab; var ... begin ... for i:= oReg1.AdvPageCount-1 downto 1 do begin PostMessage(Handle,PM_FREEPAGE,i,0); Application.ProcessMessages; end; ... end; |
Delphi-Quelltext 1: 2: 3: 4:
| procedure TF_Essen.PMFREEPAGE(var Message: TMessage); begin oReg1.AdvPages[Message.WParam].Free; end; |
Nun kommen nur abwechselnd irgendwelche Exceptions, etc...
Doch ich mach immer genau das Selbe:
Wechseln zu Page3-->Button drücken-->Wechseln zu Page3-->Button drücken-->Wechseln zu Page3-->Button drücken-->...
Und irgendwann kommt dann mal ein Fehler!
Warum?
Ich hoffe, dass ich mein Problem gut genug geschildert habe, sodass ihr mir auch helfen könnt
Freu mich schon auf eure Ideen!
Danke&Grüße
Benny
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 22.04.11 20:40
Ich kenne die Komponente eigentlich nicht, habe sie aber einmal kurz installiert. Da fällt mir sofort RemoveAdvPage beim Pager ins Auge. Hast du das einmal damit versucht statt die Seite einfach freizugeben?
Bei mir funktioniert das damit problemlos, ohne irgendwelche Messages oder irgendetwas Besonderes. 
|
|
LittleBen 
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Fr 22.04.11 21:44
Also wenn ich es so mache:
Delphi-Quelltext 1: 2:
| for i:= 2 to oReg1.AdvPageCount do oReg1.RemoveAdvPage(TAdvOfficePage(FindComponent('Page'+inttostr(i)))); |
und dann wieder meine Pages erstelle, kommt sofort der Fehler, dass Page2 schon vorhanden ist.
Ich denke dass RemoveAdvPage die Page nicht wirklich Destroyed.
Grüße
Benny
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 22.04.11 21:47
Na gut, das hatte ich jetzt natürlich nicht getestet. Und wie sieht es mit einer Kombination aus beidem aus? Erst entfernen, dann freigeben? 
|
|
LittleBen 
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Fr 22.04.11 21:52
Das funktioniert dann, wenn ich mich im ersten Tab aufhalte.
Wenn nicht, dass gibt es wieder, aber nur Manchmal, eine Zugriffsverletzung...
Delphi-Quelltext 1: 2: 3: 4: 5:
| for i:= oReg1.AdvPageCount-1 downto 1 do begin oReg1.RemoveAdvPage(TAdvOfficePage(FindComponent('Page'+inttostr(i+1)))); TAdvOfficePage(FindComponent('Page'+inttostr(i+1))).Free; end; |
Als ich nach dem Problem gegooglet hatte, bin ich ja auf den Tipp mit Postmessage gekommen.
Hier die Erklärung dafür:
Zitat: | PostMessage wird hier verwendet, weil PostMessage ans Ende der Botschafts-
warteschlange gestellt wird und deshalb erst abgearbeitet wird wenn alle
anderen Botschaft, wie z.B. die Click Botschaft an den Button abgearbeitet
wurde |
EDIT: Zurzeit kommen auch Fehlermeldungen wie "Priviligierte Anweisung" oder "Abstrakter Fehler"
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 22.04.11 22:25
Ja, wenn du auch die Seite freigeben willst, auf der der Button ist, so dass der mit freigegeben wird...
Dann musst du das eben alles kombinieren, Message schicken, dort Seiten entfernen und freigeben.
|
|
LittleBen 
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Fr 22.04.11 22:27
Wie meinen?
Edit: Also meinst du, dass ich den Button auch(manuell) freigeben muss?
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 22.04.11 22:48
Ok, ich habe es ausprobiert. Und dabei dann ClearAdvPages gesehen. So klappt es bei mir absolut problemlos: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57:
| const WM_TEST = WM_USER + 3290;
type TForm746 = class(TForm) TestPager: TAdvOfficePager; procedure FormCreate(Sender: TObject); private procedure RecreatePagesClick(Sender: TObject); protected procedure WmTest(var Msg: TMessage); message WM_TEST; public end;
var Form746: TForm746;
implementation
{$R *.dfm}
procedure TForm746.RecreatePagesClick(Sender: TObject); begin PostMessage(Handle, WM_TEST, 0, 0); end;
procedure TForm746.FormCreate(Sender: TObject); begin RecreatePagesClick(Sender); end;
procedure TForm746.WmTest(var Msg: TMessage); var i: Integer; NewPage: TAdvOfficePage; NewButton: TButton; begin TestPager.ClearAdvPages;
for i := 0 to Random(10) + 1 do begin NewPage := TAdvOfficePage.Create(Self); NewPage.AdvOfficePager := TestPager; NewPage.Caption := 'Page ' + IntToStr(i); NewPage.Name := 'Page' + IntToStr(i);
NewButton := TButton.Create(Self); NewButton.Parent := NewPage; NewButton.Caption := 'Refresh ' + inttostr(i + 1); NewButton.Name := 'b_refresh' + inttostr(i + 2); NewButton.SetBounds(100, 12 + i * (NewButton.Height + 4), NewButton.Width, NewButton.Height); NewButton.Tag := i + 2; NewButton.OnClick := RecreatePagesClick; end; end; |
|
|
LittleBen 
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Fr 22.04.11 22:56
Vielen,vielen Dank!
Vorallem dass du dir die Mühe gemacht hast!
Doch ich musste erschreckend feststellen, dass ich diese Funktion nicht habe
Könntest du sie vielleicht posten?
Vielen Danke!
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 22.04.11 23:07
Ich habe nur die Trial, also keine Quelltexte.
Aber dann eben ohne diese Funktion, so funktioniert es ebenfalls problemlos: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72:
| uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, AdvOfficePager, StdCtrls, Generics.Collections;
const WM_TEST = WM_USER + 3290;
type TForm746 = class(TForm) TestPager: TAdvOfficePager; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private FPageList: TObjectList<TAdvOfficePage>; procedure RecreatePagesClick(Sender: TObject); protected procedure WmTest(var Msg: TMessage); message WM_TEST; public end;
var Form746: TForm746;
implementation
{$R *.dfm}
procedure TForm746.FormDestroy(Sender: TObject); begin FPageList.Free; end;
procedure TForm746.RecreatePagesClick(Sender: TObject); begin PostMessage(Handle, WM_TEST, 0, 0); end;
procedure TForm746.FormCreate(Sender: TObject); begin FPageList := TObjectList<TAdvOfficePage>.Create(True); RecreatePagesClick(Sender); end;
procedure TForm746.WmTest(var Msg: TMessage); var i: Integer; NewPage, CurrentPage: TAdvOfficePage; NewButton: TButton; begin for CurrentPage in FPageList do TestPager.RemoveAdvPage(CurrentPage); FPageList.Clear;
for i := 0 to Random(10) do begin NewPage := TAdvOfficePage.Create(nil); NewPage.AdvOfficePager := TestPager; NewPage.Caption := 'Page ' + IntToStr(i); NewPage.Name := 'Page' + IntToStr(i); FPageList.Add(NewPage);
NewButton := TButton.Create(Self); NewButton.Parent := NewPage; NewButton.Caption := 'Refresh ' + inttostr(i + 1); NewButton.Name := 'b_refresh' + inttostr(i + 2); NewButton.SetBounds(100, 12 + i * (NewButton.Height + 4), NewButton.Width, NewButton.Height); NewButton.Tag := i + 2; NewButton.OnClick := RecreatePagesClick; end; end; | // EDIT:
Ich sehe gerade, dass du nur Delphi 5 und 7 hast? Dann musst du eine normale TObjectList nehmen und statt for..in eine normale for-Schleife. 
|
|
LittleBen 
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Fr 22.04.11 23:18
Genau, habe nur Delphi 5 und 7. Wie meinst du das mit der for-schleife? Bekomme ich irgendwie nicht hin
Trotzdem nochmal viiiiielen Dank 
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 22.04.11 23:33
Naja, so halt: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72:
| uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, AdvOfficePager, StdCtrls, Contnrs;
const WM_TEST = WM_USER + 3290;
type TForm746 = class(TForm) TestPager: TAdvOfficePager; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private FPageList: TObjectList; procedure RecreatePagesClick(Sender: TObject); protected procedure WmTest(var Msg: TMessage); message WM_TEST; public end;
var Form746: TForm746;
implementation
{$R *.dfm}
procedure TForm746.FormDestroy(Sender: TObject); begin FPageList.Free; end;
procedure TForm746.RecreatePagesClick(Sender: TObject); begin PostMessage(Handle, WM_TEST, 0, 0); end;
procedure TForm746.FormCreate(Sender: TObject); begin FPageList := TObjectList.Create(True); RecreatePagesClick(Sender); end;
procedure TForm746.WmTest(var Msg: TMessage); var i: Integer; NewPage: TAdvOfficePage; NewButton: TButton; begin for i := 0 to FPageList.Count - 1 do TestPager.RemoveAdvPage(FPageList[i] as TAdvOfficePage); FPageList.Clear;
for i := 0 to Random(10) do begin NewPage := TAdvOfficePage.Create(nil); NewPage.AdvOfficePager := TestPager; NewPage.Caption := 'Page ' + IntToStr(i); NewPage.Name := 'Page' + IntToStr(i); FPageList.Add(NewPage);
NewButton := TButton.Create(Self); NewButton.Parent := NewPage; NewButton.Caption := 'Refresh ' + inttostr(i + 1); NewButton.Name := 'b_refresh' + inttostr(i + 2); NewButton.SetBounds(100, 12 + i * (NewButton.Height + 4), NewButton.Width, NewButton.Height); NewButton.Tag := i + 2; NewButton.OnClick := RecreatePagesClick; end; end; |
Für diesen Beitrag haben gedankt: LittleBen
|
|
LittleBen 
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Fr 22.04.11 23:39
ES FUNKTIONIERT!!
Vielen Dank für alles!!!!
Bin nun so erlöst
Nochmals Danke und eine gute Nacht!
Grüße,
Benny
|
|
|