Avatar billede morten_s Nybegynder
24. september 2001 - 12:18 Der er 43 kommentarer og
3 løsninger

Undgå selvmord ?

Jeg har en form hvorpå der under runtime placeres nogle speedbutton, når der trykkes på en af SpeedButtons (OnClick), skal de slettes.

Mit problem er at jeg af og til får en Exceptionfejl, formentlig fordi at alt koden i \"den slettede\" knap endnu ikke er afviklet, måske OnMouseUp event osv.

Jeg har prøvet at slette kanppen på OnMouseUp istedet for OnClick, det gør ingen forskel



Avatar billede unclebug Nybegynder
24. september 2001 - 12:20 #1
Lav en PostMessage til din mainform, og slet dem der
Avatar billede borrisholt Novice
24. september 2001 - 12:21 #2
kan du ikke bare sætte OnMouseup til nil inden du sletter den ?

Jens B
Avatar billede morten_s Nybegynder
24. september 2001 - 12:21 #3
Og hvordan gør jeg det ?
Avatar billede morten_s Nybegynder
24. september 2001 - 12:22 #4
Jens B> Prøver lige
Avatar billede morten_s Nybegynder
24. september 2001 - 12:23 #5
Jens B> nej så går det galt hvergang
Avatar billede morten_s Nybegynder
24. september 2001 - 12:24 #6
unclebug>> Hvordan gøres det ?
Avatar billede borrisholt Novice
24. september 2001 - 12:26 #7
Mystisk .. Send lige mig koden .. SÅ skal jeg hacke den på plads ...

Jens B
Avatar billede morten_s Nybegynder
24. september 2001 - 12:29 #8
Jeg har en Array med Buttons (TLinksButton er en TSpeedButton jom jeg har tilføjet lidt mere)

Links : array[0..(MaxNoLinks-1)] of TLinkButton;


Og jeg sletter på følgende måde:


for i := 0 to MaxNoLinks-1 do
      if (Links[i] <> nil) then
      begin
        Links[i] := nil;
        Links[i].Destroy;
      end;
    NoLinks := 0;
Avatar billede martinlind Nybegynder
24. september 2001 - 12:30 #9
Lav et Flag på din form som du sætter når du er færdig, og lav en procedure som kører i en løkke og checker på det flag.

OkToSlet : Boolean;
DoSlet( Sender : TObject );




procedure KnapOnClick();
begin
  OkToSlet := FALSE;
  ...
  ...
  DoSlet(Sender);
  OkToSlet := TRUE;
end;

procedure DoSlet( Sender : TObject );
begin
  while not OkToSlet do Application.ProccesMessages;
  // Slet Knap;
end;

Noget i denne stil kan du prøve
Avatar billede pellelil Nybegynder
24. september 2001 - 12:31 #10
morten_s> kan du ikke bare sætte \"Visible\" (og måske \"Enabled\") for dine speedbuttons to False ?
Avatar billede morten_s Nybegynder
24. september 2001 - 12:33 #11
Martin> Jeg har jo mere end en knap....

procedure KnapOnClick();
begin
  OkToSlet := FALSE;
  ...
  ...
  DoSlet(Sender);
  OkToSlet := TRUE;
end;


Skal denne procedure bygges ind i kanppen ?

Avatar billede morten_s Nybegynder
24. september 2001 - 12:35 #12
pelleli> Kunne godt lade sig gøre, men jeg fylder jo min arrray op igen med nye kanpper... så skal man over i noget pointer noget, og på et tidspunkt skal de jo slettes....
Avatar billede morten_s Nybegynder
24. september 2001 - 12:39 #13
Martin>> Hvilken unit ligger Application.ProccesMessages  i ?
 
Avatar billede martinlind Nybegynder
24. september 2001 - 12:40 #14
Form unit\'en.

Er det det ikke den samme OnClick event du har på alle knaper ?
Avatar billede pellelil Nybegynder
24. september 2001 - 12:42 #15
morten_s> Nu kender jeg ikke dit program, men kunne du ikke blot beholde anvende de samme knapper så blot deler samme OnClick, og så lade denne holde styr på hvad de enkelte knapper skal \"betyde\" - så slipper du for at \"spilde tid\" med at create/dispose knapper hele tiden
Avatar billede morten_s Nybegynder
24. september 2001 - 12:43 #16
Det er en frame jeg proggramere i, jeg får Undeclared identifire.

Avatar billede borrisholt Novice
24. september 2001 - 12:44 #17
Så kom de (gamle) cirkus heste frem af deres skjul .... :-)

Nå tak for hjælpen den anden dag Pelle...

Jens B
Avatar billede morten_s Nybegynder
24. september 2001 - 12:46 #18
pellelil... jeg har ikke lige mange knapper hvergang...har selv overvejet ideen
Avatar billede martinlind Nybegynder
24. september 2001 - 12:49 #19
Ellers må du maile koden så kigger jeg på det *S*
Avatar billede unclebug Nybegynder
24. september 2001 - 12:50 #20
const UM_REMOVEBUTTONS = WM_USER + 1
...declaration:
procedure Um_RemoveButtons(var Message: TMessage); Message UM_REMOVEBUTTONS;

...Implementation:
procedure TDinForm.Um_RemoveButtons(var Message: TMessage);
begin
  // Slet knapper
end;

...Usage (i knappens on_click):
PostMessage(Handle, UM_REMOVEBUTTONS, 0, 0);


Avatar billede pellelil Nybegynder
24. september 2001 - 12:50 #21
borrisholt> Det var det så lidt - glad for at jeg kunne returnere tjenesten
Avatar billede unclebug Nybegynder
24. september 2001 - 12:52 #22
for i := 0 to MaxNoLinks-1 do
      if (Links[i] <> nil) then
      begin
        Links[i] := nil;
        Links[i].Destroy;
  end;

Ehhmmm, er det kun mig der kan se noget forkert her? :o)

   
Avatar billede morten_s Nybegynder
24. september 2001 - 12:53 #23
Martin>> har fundet funktionen, men den bliver \"Hængende\" her

while not OkToSlet do Application.ProccesMessages;
 
Avatar billede borrisholt Novice
24. september 2001 - 12:55 #24
morten_s >> Du bliver nok nød til at sure i det bide æble og sende koden enten til ham der pjækkede fra eksperten eventet (lead os ikke nævne navne Martin)  eller undertegnede (jens@Borrisholt.com)

Jens B
Avatar billede morten_s Nybegynder
24. september 2001 - 12:57 #25
Jens B> Jeg kan af kommerciellegrunde ikke så godt sende mit program ud af huset selv om det er fristende nok..
Avatar billede pellelil Nybegynder
24. september 2001 - 12:58 #26
Borrisholt> Er der planer om en ny event hvor de der pjækkede og de der åbentbart ikke havde fulgt ordenligt med også kan deltage !?
Avatar billede martinlind Nybegynder
24. september 2001 - 12:58 #27
Ellers så prøv lige unclebug\'s foreslag det ser fornuftigt ud

JB >> har i fået hentet DDG4 cd filen ??
Avatar billede morten_s Nybegynder
24. september 2001 - 12:59 #28
UncleBug> Jeg kan ikke se hvad der er galt i :

for i := 0 to MaxNoLinks-1 do
      if (Links[i] <> nil) then
      begin
        Links[i] := nil;
        Links[i].Destroy;
  end;

Måske du ku give et tip...


Har kigget lidt på din kode...den er desværre lidt for langhåret til mig...hvor skal jeg sætte koden ind ?
Avatar billede borrisholt Novice
24. september 2001 - 12:59 #29
Pelle >>Ja der er tale om en Julefrokost (hik)

Morten >> Så lav en skygge projekt der kun kan det med knapperne og send DET.

Jens b
Avatar billede borrisholt Novice
24. september 2001 - 13:00 #30
martinlind >> Ja tak ...

Jens B
Avatar billede unclebug Nybegynder
24. september 2001 - 13:02 #31
Links[i] := nil;
Links[i].Destroy;

Først sættes den til nil, derefter kaldes .Destroy. Dette vil altid give en exception :O)

Gør det i omvendt rækkefølge, eller brug FreeAndNil(Links[i].Destroy)

 
Avatar billede morten_s Nybegynder
24. september 2001 - 13:14 #32
unclebug> det var JB\'s forslag at det skulle gøres i omvendt rækkefølge......


FreeAndNil(Links[i]); giver også Exception

Kan du ikke ligehjælpe mig lidt på vej med hvor jeg skal placere din kode... jeg har følgende kode i min Frame:

unit frOnline;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls, Buttons;

const UM_REMOVEBUTTONS = WM_USER + 1;

type
  TFrameOnline = class(TFrame)
    PanelOnline: TPanel;
    ImageBg: TImage;
  private
    { Private declarations }
  public
    { Public declarations }
    procedure OnShow(Sender: TObject);
    procedure SaveChange(Sender: TObject);
    procedure LinkClick(Sender: TObject);
    procedure SletObjekter;
    procedure Um_RemoveButtons(var Message: TMessage); Message UM_REMOVEBUTTONS;
  end;

implementation

uses DataManger, uFalcoVars, uFalcoMain, LinkButton;

var
  OkToDelete : Boolean = True;

{$R *.dfm}

{ TFrameOnline }

procedure TFrameOnline.LinkClick(Sender: TObject);
var
  ClickBut : TLinkButton;
  OldIdSelectedInt : Integer;
begin
  if EditMode then
    exit;
  If not (Sender is TLinkButton) then
    exit;
  OldIdSelectedInt := IdSelectedInt;
  ClickBut := (Sender as TLinkButton);
  IdSelectedInt :=  ClickBut.LnkToID;
// ShowMessage(IntToStr(IdSelectedInt));
  if  DM.DataSourceInt.DataSet.Locate(\'Id\', IdSelectedInt, []) then
  begin
//    OkToDelete := False;
//    OnShow(Sender);
//    OkToDelete := True;
    PostMessage(Handle, UM_REMOVEBUTTONS, 0, 0);
    OnShow(Sender);
.
.
.
end;

procedure TFrameOnline.SletObjekter;
      var
    i : Integer;
  begin
    for i := 0 to MaxNoLinks-1 do
      if (Links[i] <> nil) then
      begin
        FreeAndNil(Links[i]);
      end;
    NoLinks := 0;
  end;


procedure TFrameOnline.Um_RemoveButtons(var Message: TMessage);
begin
  SletObjekter;
end;

Er koden placeret rigtigt ???

PostMessage(Handle, UM_REMOVEBUTTONS, 0, 0);

Denne linie giver not enough actual parameters
Avatar billede morten_s Nybegynder
24. september 2001 - 13:14 #33
Og da det ser ud til at være ved at blive svært hæver jeg lige til 60 point
Avatar billede unclebug Nybegynder
24. september 2001 - 13:25 #34
unclebug> det var JB\'s forslag at det skulle gøres i omvendt rækkefølge......

Den forstår jeg ikke helt. Hvem er JB, og hvor? Er jeg bare blind? Men ja, FreeAndNil giver også exception, for du kan ikke free en komponent i en af dens events (efter eventen returnerer den nemlig til komponentens kode, der ikke længere eksisterer). Men det kan PostMessage så løse.

Prøv lige at skrive windows.PostMessage(....). Den fejl (not enough parameters) må skyldes at der er en funktion i en anden unit der også hedder PostMessage.
Avatar billede morten_s Nybegynder
24. september 2001 - 13:30 #35
Min kode ser sådan her ud
windows.PostMessage(Handle, UM_REMOVEBUTTONS, 0, 0);


ved comp. får jeg
windows.PostMessage(Handle, UM_REMOVEBUTTONS, <- Cursoren stiller sig her ved compilering

med meddelelsen not enough actual parameters



Avatar billede martinlind Nybegynder
24. september 2001 - 13:34 #36
unclebug > Jens Borrisholt = JB
Avatar billede unclebug Nybegynder
24. september 2001 - 13:34 #37
Oops, sorry. My mistake.

Funktionen hedder det samme som konstanten. Kald den UMRemoveButtons istedet (bare fjern underscore).

procedure UmRemoveButtons(var Message: TMessage); Message UM_REMOVEBUTTONS;
 

Avatar billede morten_s Nybegynder
24. september 2001 - 14:09 #38
UncleBug>> nu går det ikke ned længere, men mine knapper bliver heller ikke slettet ?

Hvis jeg debugger på slettekoden altså denne

for i := 0 to MaxNoLinks-1 do
      if (Links[i] <> nil) then
      begin
        Links[i].Destroy;
        Links[i] := nil;
      end;
    NoLinks := 0;

Så kan jeg se at alle knapper er nil når jeg går ud af koden, men de forsvinder ikke fra formen...hvad går galt
Avatar billede unclebug Nybegynder
24. september 2001 - 14:46 #39
Jeg har lige prøvet at lave et eksempel hvor jeg laver 10 TSpeedButton\'s, og sletter dem på den angivne måde, og det virkede. Jeg kan jo ikke se hele din kode, men måske creater du dem igen efter de er slettet? Jeg har ikke flere forslag lige p.t., men det kode jeg kan se er korrekt og virker.


Avatar billede morten_s Nybegynder
24. september 2001 - 14:49 #40
Har jeg ret i at din kode \"udsætte\" sletningen ?

For jeg gentegner jo samtidigt billedet med de nye kanpper og allokkere til den samme variabel Links[i],  det betyder vel at hvis knapperne endnu ikke er slettet har jeg ikke længere fat i dem ??
Avatar billede unclebug Nybegynder
24. september 2001 - 14:56 #41
Ja, metoden udsætter lige præcis sletningen. Den smider en message i messagekøen, og sletningen bliver så udført når den message når frem til programmet. Du må først allokere de nye knapper efter at du har kaldt Destroy. Jeg kan ikke rigtig se ud fra det du skriver, om det er det du gør. Men hvis du ikke gør det, så vil det forklare hvorfor de ikke forsvinder, for du har pludselig to sæt knapper, og får kun slettet dem Links[i] refererer til. De andre er ganske rigtigt tabt (selv om du kan finde dem ved hjælp af formens ControlCount og Controls (hvis du har angivet formen i constructoren da du createde)).

Kort og godt: Allokér først de nye EFTER Destroy.
Avatar billede cms Nybegynder
24. september 2001 - 17:08 #42
hmm.. Kunne man løse problemet ved at kalde

RemoveComponent(Links[i])

i stedet for

Links[i].Free

??
Avatar billede unclebug Nybegynder
24. september 2001 - 17:19 #43
>RemoveComponent(Links[i])
Det tror jeg ikke. Den bruger ikke PostMessage, og der returneres derfor stadig til en destroyed komponent efter eventen. Jeg lavede lige en test hvor en TButton removede sig selv i OnClick. Knappen forsvandt ikke, og ved andet click fik jeg en AV (fordi det første click destroyede den).

Ellers interessant forslag!

Avatar billede morten_s Nybegynder
25. september 2001 - 12:52 #44
UncleBug>> Det virker perfekt, lig et svar så  du kan få dine point
Avatar billede unclebug Nybegynder
25. september 2001 - 12:56 #45
Godt nok :o)
Avatar billede morten_s Nybegynder
25. september 2001 - 13:59 #46
Hov de røg vist til Martin allesammen, det var et uheld ;-(((((((

Havde tænkt mig 40 til UncelB
10 til Martin og 10 til JB
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