Avatar billede Slettet bruger
18. oktober 2009 - 22:51 Der er 2 kommentarer og
2 løsninger

Free TTabSheet med TFrame fra TFrame.

Jeg opretter et nyt TTabSheet, hvor på jeg opretter en TFrame.

procedure TMainForm.ButtonOpenClick(Sender: TObject);
Var
  TabSheet:TTabSheet;
  Kort: TFrameArbejdskort;
begin
  TabSheet:= TTabSheet.Create(MainPageControl);
  TabSheet.PageControl:= MainPageControl;
  TabSheet.Caption:= 'BilagsNr.: ' + MSQuery.FieldByName('BilagsNr').AsString;
  Kort:= TFrameArbejdskort.Create(TabSheet);
  Kort.Parent:= TabSheet;
  Kort.Connection:= MSConnection;
  Kort.Init(MSQuery.FieldByName('BilagsNr').AsInteger);
  MainPageControl.ActivePage:= TabSheet;
end;

Jeg kan slette det igen, fra min MainForm.

procedure TMainForm.ButtonCloseClick(Sender: TObject);
begin
  If MainPageControl.ActivePageIndex > 0 Then
    MainPageControl.ActivePage.Free;
end;

Hvordan sletter jeg mit TTabSheet med TFrame, ved klik på en TButton der er på TFrame'n ?

:-)
Avatar billede martinlind Nybegynder
18. oktober 2009 - 23:15 #1
det er en knap på dit kort du vil slette kort fra ikke ?
Du kan jo prove med self.free; i din onclick event.
Ellers kan du lægge en ref til kort i tag på tabsheet eller du kan lave en nedarvet tabsheet med dit kort på... eller noget helt 3´de

Spørg hvis du vil vide mere :-)
Avatar billede Slettet bruger
18. oktober 2009 - 23:39 #2
Ja.

Self.free er jo kun min TFrame, jeg skal også have TTabSheet med. Self.Free giver Access violation.

Jeg havde håbet på en testet Code.
:-)
Avatar billede Slettet bruger
19. oktober 2009 - 12:04 #3
Jeg fandt dette på nettet:

"In article <3ca52414_2@dnews>, Rafael wrote:
> Hello People....my problem is as to close my FRAME...

> // I create my Frame in this way...
> // CadClientes = My FRAME

> procedure TContatos.Button9Click(Sender: TObject);
> var CadClientes : TCadClientes;
> begin
>    CadClientes := TCadClientes.Create(Contatos);
>    CadClientes.Parent := Contatos;
> end;

Change that to
  CadClientes := TCadClientes.Create(self);
  CadClientes.Parent := self;

You should never refer to the forms variable from inside the forms
methods. Not only is that not necessary, since you can use Self to get
the forms reference, it is also dangerous if you do it during the forms
creation (e.g. in the OnCreate or OnShow event), where the forms
variable may not yet have a valid value. And of course the form variable
created by the IDE is completely useless if you have more than one
instance of a form class around.

> // I want to close the frame....not Work :-((((((((((((

You should really do something about this multiple chin problem <g>.

> procedure TCadClientes.SpeedButton5Click(Sender: TObject);
> begin
>        free;
>        destroy;

Well, you destroy the frame twice here, and that alone is a cause for
the AVs. But just doing a Free will still AV, and the reason is that you
cannot destroy a component safely from within an event of this component
(or a nested component in this case). Doing so is like sawing off the
branch you are sitting on, code executed after your Free call may well
still try to refer to the component you just murdered in cold blood <g>.

I usually solve this dilemma by asking a third party to destroy the
component, by posting a custom message to it. For you define a custom
message and a message record for it. The declaration should go into
separate unit (without a form in it) that collects types and constants
that need to be used by more than one other unit in the project. If you
don't yet have such a "globals" unit, create one (File->New->Unit).

Unit ProjectGlobals;
Interface
Uses Messages, Windows;
Const
  UM_BASE            = WM_USER + 666; // just a start value
  UM_DELETEOBJECT    = UM_BASE;
  // other project messages would use UM_BASE+1 and so on
Type
  {: Message record for the UM_DELETEOBJECT message }
  TUMDeleteObject = packed Record
    message: Cardinal;
    unused : WPARAM;
    obj    : TObject;
    result : Longint;
  End; { TUMDeleteObject }
Implementation
End.

Add this unit to the Uses clause of both frame and main form.

OK, your button click to destroy the frame now does this:

procedure TCadClientes.SpeedButton5Click(Sender: TObject);
begin
  PostMessage (
    Application.Mainform.Handle,
    UM_DELETEOBJECT,
    0,
    LPARAM(self));
end;

The main form gets a handler for this message:

  private
    Procedure UMDeleteObject( var msg: TUMDeleteObject );
      message UM_DELETEOBJECT;

which is implemented as     

Procedure TForm1.UMDeleteObject( var msg: TUMDeleteObject );
Begin
  msg.obj.Free
End; 

You can use this method to safely destroy frames and other components
from their event handlers, even if the components are not on the main
form. Posting (as opposed to sending) a message delays the action long
enough that any code executing in the component after the event handler
returns has finished. This trick is useful in other cases as well, like
forcing focus to a control from an OnEnter or OnExit handler.

--
Peter Below (TeamB)"

Det løste mit problem.

:-)
Avatar billede martinlind Nybegynder
19. oktober 2009 - 12:24 #4
Super, en msg havde også været mit næste bud, har ikke haft min delphi kørende de sidste par mdr. :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester