/ Forside / Teknologi / Udvikling / Delphi/Pascal / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Delphi/Pascal
#NavnPoint
oldwiking 603
jrossing 525
rpje 520
EXTERMINA.. 500
gandalf 460
gubi 270
DJ_Puden 250
PARKENSS 230
technet 210
10  jdjespers.. 200
Kørsel uden brugerindgreb
Fra : Mik


Dato : 18-01-04 12:28

Jeg har et lille Delphi7 program som sender nogle regnskabsdata til en anden
maskine (email).
Programmet virker fint, men jeg vil gerne, at programmet viser en meddelelse
på skærmen, sender filen og derefter afslutter - uden brugerindgreb.
Bruger jeg Event OnActivate på min Form virker det fint - bortset fra at
meddelelsen (Label) aldrig vises på skærmen.
Hvordan får jeg startet afsendelsen - efter meddelelsen vises på skærmen?

Med venlig hilsen
Lars



 
 
Klaus Petersen (18-01-2004)
Kommentar
Fra : Klaus Petersen


Dato : 18-01-04 12:36


> Programmet virker fint, men jeg vil gerne, at programmet viser en
meddelelse
> på skærmen, sender filen og derefter afslutter - uden brugerindgreb.
> Bruger jeg Event OnActivate på min Form virker det fint - bortset fra at
> meddelelsen (Label) aldrig vises på skærmen.

Det er nok ikke så godt at bruge OnActivate, da den event udløses hver gang
vinduet bliver aktiveret - dvs. skifter du til et andet program og tilbage
igen køres eventhandleren een gang til.

Een måde at lave det på er at have en Timer komponent på formen. Timeren
skal disabled på formen.

På formens OnShow kan du enable timeren - og på timeren's event kan du
starte afsendelsen.

> Hvordan får jeg startet afsendelsen - efter meddelelsen vises på skærmen?

Meddelsen bliver ikke vist, fordi hændelsen (OnActivate) indetræffer før den
når at vise den.

Det skyldes sikkert også, at du ikke afvikler meddelser (her snakker jeg om
windows' egne messages) mens du afvikler afsendelsen.

Det har samme effekt som når et program ikke svarer i windows.

Løsningen er som regel simpel - du skal bare indsætte følgende linje:

application.ProcessMessages;

.... i løkker (repeat .. until ... do ... while ... ) i din afsendelses
rutine.

mvh.
Klaus.



Mik (18-01-2004)
Kommentar
Fra : Mik


Dato : 18-01-04 14:54

>"Klaus Petersen skrev:
>
> Løsningen er som regel simpel - du skal bare indsætte følgende linje:
>
> application.ProcessMessages;
>
> mvh.
> Klaus.

Tak - ovenstående løste problemet.

mvh. Lars



Ove Kjeldgaard (18-01-2004)
Kommentar
Fra : Ove Kjeldgaard


Dato : 18-01-04 21:37

"Klaus Petersen" <spectual2@getTOnet.dk> wrote:

>Løsningen er som regel simpel - du skal bare indsætte følgende linje:
>
>application.ProcessMessages;
>
>... i løkker (repeat .. until ... do ... while ... ) i din afsendelses
>rutine.

Det er egentlig en god ting altid at indsætte ProcessMessages i løkker, det er
noget nemmere hvis man får lavet en uendelig løkke

Det er kun få dage siden jeg havde en While, hvor jeg igen glemte både at
incremente en variabel og ProcessMessages linien...


--
Med venlig hilsen, Ove Kjeldgaard, nospam AT privat DOT dk
Natur og Friluftsliv: <http://hiker.dk>

Nicolai Hansen (19-01-2004)
Kommentar
Fra : Nicolai Hansen


Dato : 19-01-04 09:03

Ove Kjeldgaard <ReadMyEmail@The.Signature> wrote in message news:<d7rl00l59ajf8fnugrrv90aa1odf4bcbra@4ax.com>...
> "Klaus Petersen" <spectual2@getTOnet.dk> wrote:
>
> >Løsningen er som regel simpel - du skal bare indsætte følgende linje:
> >
> >application.ProcessMessages;
> >
> >... i løkker (repeat .. until ... do ... while ... ) i din afsendelses
> >rutine.
>
> Det er egentlig en god ting altid at indsætte ProcessMessages i løkker, det er
> noget nemmere hvis man får lavet en uendelig løkke
>
> Det er kun få dage siden jeg havde en While, hvor jeg igen glemte både at
> incremente en variabel og ProcessMessages linien...

Maaaan skal passe på her. Man roder sig ud i noget asynkron
programmering ;)

Hvis man indsætter en Application.ProcessMessages; i en handler for
f.eks. et tryk på en knap (hvor man har en laaaaang løkke i), vil man
kunne starte løkken inden i løkken, inden i løkken, inden i ... indtil
der kommer et stack overflow, bang, crash, forfra

Hvis man bare vil ha en label tegnet på skærmen, vil jeg foreslå
label.caption:='hej'; label.update;
istedet.

Mik (19-01-2004)
Kommentar
Fra : Mik


Dato : 19-01-04 12:50

"Nicolai Hansen" <nic@aub.dk> skrev i en meddelelse
news:d96764ff.0401190003.2ed51517@posting.google.com...

> Hvis man bare vil ha en label tegnet på skærmen, vil jeg foreslå
> label.caption:='hej'; label.update;
> istedet.

Fuldt tilstrækkeligt i mit tilfælde - tak

mvh. Mik



Klaus Petersen (21-01-2004)
Kommentar
Fra : Klaus Petersen


Dato : 21-01-04 00:00

> Hvis man bare vil ha en label tegnet på skærmen, vil jeg foreslå
> label.caption:='hej'; label.update;
> istedet.

Med fare for at tage fejl ... opdatering af en label foregår vel som alle
grafiske opdateringer af vinduer foregår i windows ... ved at sende en
WM_PAINT til vinduet, som så tegner sig selv.

Men hvis du ikke afvikler meddelser, så når du aldrig at få meddelsen før
den afvikler meddelser igen - dvs. efter løkken er afsluttet.

Hvis man vi undgå, at løkken bliver startet 2 gange er der mange muligheder.
Den nemeste er vist at disable knappen - den sikreste at sætte et flag, som
den tjekker inden den går ind i løkken.




Nicolai Hansen (21-01-2004)
Kommentar
Fra : Nicolai Hansen


Dato : 21-01-04 14:16

"Klaus Petersen" <spectual2@getTOnet.dk> wrote in message news:<SpiPb.361$ia2.1@news.get2net.dk>...
> > Hvis man bare vil ha en label tegnet på skærmen, vil jeg foreslå
> > label.caption:='hej'; label.update;
> > istedet.
>
> Med fare for at tage fejl ... opdatering af en label foregår vel som alle
> grafiske opdateringer af vinduer foregår i windows ... ved at sende en
> WM_PAINT til vinduet, som så tegner sig selv.

Sådan KAN det foregå. TControl.Update gennemtvinger en optegning uden
om Windows message pumpen.

Fra (VCL) TControl.Update hjælpen i Delphi 6:

procedure Update; virtual;

Description

Call Update to force the control to be repainted before any more,
possibly time-consuming, processing takes place. Use Update to provide
immediate feedback to the user that cannot wait for the Windows paint
message to arrive.

Update does not invalidate the control, but simply forces a repaint of
any regions that have already been invalidated. Call Repaint instead
to invalidate the control as well.

> Men hvis du ikke afvikler meddelser, så når du aldrig at få meddelsen før
> den afvikler meddelser igen - dvs. efter løkken er afsluttet.

..Update sender ikke en besked - den tegner direkte og med det samme.
Hvis du vil sende en besked er der også en metode til det -
PostMessage eller noget i den dur - som lægger en besked i køen.

> Hvis man vi undgå, at løkken bliver startet 2 gange er der mange muligheder.
> Den nemeste er vist at disable knappen - den sikreste at sætte et flag, som
> den tjekker inden den går ind i løkken.

Det kommer skam an på hvor asynkront man har lyst til at programmere.
Det man skal være klar over er at hvis man starter løkke A, og
midtvejs i denne starter løkke B - så kører den løkke B færdig før den
genoptager sit arbejde med løkke A.
Så hvis man -inde fra løkke A- kalder ProcessMessages() eller
HandleMessage() skal man være 101% sikker på at løkke A er HELT
adskilt fra resten af programmet, da man vil have en uspecificeret
tilstand af denne løkke i måske flere sekunder.
Det svarer lidt til at programmere i tråde; det er fint så længe de
ikke skal dele variable.

Prøv følgende lille program ...

Lav en form med to knapper, Button1 (caption="count") og Button2
(caption="reset") og en editbox (Edit1). Lav en privat variabel
"count: Integer;".

Skriv følgende OnClick handlers:

Button1Click:

begin
Count:=0;
repeat
inc(count);
Edit1.Text:=IntToStr(count);
Application.ProcessMessages;
until count>1000000;
ShowMessage('finito!');
end;

Button2Click:

begin
Count:=0;
end;

prøv at starte med at trykke på knap 1 - og så trykke på knap to af og
til. Counteren startes forfra hver gang.

Prøv så at fjerne Application.ProcessMessages og erstat linien med
"Edit1.Update". Så kører programmet som det skal (knap 1 tæller og
knap 2 resetter).

Klaus Petersen (21-01-2004)
Kommentar
Fra : Klaus Petersen


Dato : 21-01-04 17:47

> Sådan KAN det foregå. TControl.Update gennemtvinger en optegning uden
> om Windows message pumpen.

Det var så den "fare" jeg snakkede om :-]



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408924
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste