Newsgroup: it.comp.lang.pascal
Titolo: wait

salve,
per essere breve vi descrivo cosa cerco di realizzare e non a cosa possa
servire.
Mi serve una procedure che non riceva e non dia parametri, ma che
finisca di
essere eseguita quando l'utente preme un tasto o fa un click da mouse.
Tale procedura non deve avere cicli interni infiniti.
Accetto consigli o pure i lcodice se vi capita.
Preferibilmante per pascal(dos) o meglio ancaora per FreePascal
DOS(Go32V2) /Win32
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 Accetto consigli o pure i lcodice se vi capita.
questo è quello che mi viene in mente
    procedure waitkey();
    begin
         repeat
         until keypressed;
    end;
Se hai una funzione mouseHIT che ti indica se è stato premuto un tasto la
metti nel ciclo
Ciao RDC
www.pascallike.too.it


Sicuro? Mmm... Vediamo un pò...
i:=1;
while i>0
   begin
        i:=0;
    end;
Secondo me questa va solo una volta... O no?
Skerzo...
Ciao!!!
--
----------------------------------------
Carlo Camarda
chiamac...@tiscalinet.it
]@#[ Anna I Love You ]#@[


Ti piace questo?
Provalo!!!
Program Test;
Uses Crt,Dos;
Var i:longint;
Begin
  ClrScr;
  i:=0;
  While (Not (KeyPressed)) Do
  Begin
    Inc(i);
  End;
  Write('La i vale: ',i);
  Readln;
  Readln;
End.
Dimmi se è quello che volevi...


Assolutamente no! apprezzo l'aiuto ma non corrisponde a quello
 che chiedevo, anzi all'esatto contrario.
Mi spiego meglio:
sono stati usati i cicli negli esempi proposti , che e' cosa che non
 volevo. 
perche'? 
perche' l'interrogazione software (del ciclo che usa il keypressed o
mousePressed)
puo' far uso troppo eccessivo del processore, riducendo eventualmente le
 prestazioni del multitasking.
E' il ciclo che mi porta fastidio!
Acctto ancora consigli. 
 grazie!


Scusa ma questa procedura cosa deve fare ???
deve esegue qualcosa ?
Un idea c'è l'ho ma nn so se ti può essere utile senza sapere la struttura
della procedura che deve essere eseguita.
Ciao RDC

[Cut]
Mi serve una procedure che non riceva e non dia parametri, ma che
finisca di
essere eseguita quando l'utente preme un tasto o fa un click da mouse.
Tale procedura non deve avere cicli interni infiniti
Scusa ma non riesco a capire una cosa questa procedura deve aspettare che
venga premuto un tasto da tastiera o dal mouse il che significa che deve
ciclare in qualche modo altrimenti quando la chiami viene eseguita e finisce
[Cut]
perche' l'interrogazione software (del ciclo che usa il keypressed o
mousePressed)
puo' far uso troppo eccessivo del processore, riducendo eventualmente le
 prestazioni del multitasking.
Ma su questo non sono tanto sicuro...

beh quello che chiedi non so' se e' possibile: in un pc le cose
avvengono normalmente per 2 motivi
a) normale flusso di programma (salti compresi)
b) interrupt (anche software: tipo callback)
[ forse ce ne sono altri, ma esulano dal 'normalmente' :-) ]
Tu vuoi che il programma si fermi, ed attenda un evento, e questo
corrisponderebbe al modello `interrupt', ma ad un interrupt puoi
agganciare una procedura, il resto del programma che fa ?
cicla. e se esci cicla il prompt lampeggiando in attesa...
e se chiudi la finestra ? ciclano ancora gli altri programmi... e se
chiudi tutto c'e' una simpatica funzioncina finale idle( ) del
sistema operativo che fa'   " while true do; " in attesa che lo
scheduler sia invocato da un'interruzione...
In pratica non puoi `fermare' un programma in attesa di un evento
perche' ci sara' sempre qualcuno che aspetta attivamente... senza
far nulla... non so' come siano implementate readkey/read e le
chiamate bloccanti, ma la cosa migliore sarebbe affidarsi ad esse.
Cmq un programma che cicla inutilmente non consumera' piu'
processore di uno che cicla calcolando arcoseni iperbolici inversi:
[ a meno di chiamate di I/O: queste avrebbero un peso diverso !! ]
la frazione di tempo concessa dallo scheduler e' sempre uguale.
Se vuoi provare la via degli interrupt, nell'help del tp, sotto Keep
c'e' un esempio di `hook' sull'interrupt della tastiera: puoi mettere
una tua proc in attesa, che appena chiamata rimette a posto il
vettore delle interr. e faccia quel che deve... ma ricorda che e'
una proc di interrupt, non farle fare troppo ! :-)
E cmq il resto del programma deve.. attendere, non puo' fermarsi
Resta cmq piu' comodo tenersi un ciclo... la keypressed non e'
una violenta procedura, ma una lettura di una porta ed un paio
di if... niente chiamate di I/O che potrebbero appesantire il programma
idem per il mouse... il driver tanto e' li che lavora... :-)
--
Dreadnaut
(Life would be easier if I had the source code)

 servire.
...........
etc etc....
a mio avviso dovresti usare un linguaggio più tecnico.... non è facile
intuire ciò che intendi dire... usando un linguaggio cosi approssimato, a
ogni modo per quanto possa aver capito io, quello che cerchi dovrebbe
corrispondere alla funzione:   readkey (il risultato lo si ignora...) oppura
a keypressed,   abbinato a un repeat... until (quindi sempre un ciclo)... ma
visto che lo scarti a priori... rimarrebbe  il readkey...
Poi parli di multitasking.... beh... io uso TP7 e li di multitasking ce ne
ben poco se non nulla... essendo per dos... ma cmq il multitasking anche nel
caso di linux... non viene gestito da PASCAL ma dal sistema operativo
stesso... quindi non capisco cosa ti preoccupa...
Cmq ciao, Cooper.

Tale procedura non deve avere cicli interni infiniti.
Praticamente una procedura che non serve a nulla :-)
ROTFL.
-- 
http://web.tiscali.it/mbsoftware
--------------------------------
Ma... facendo scandisk non e' che rovino le idee del pc ?!?

non pensavo di scuotere cosi' tanto le acque.....
Riguardo al multitasking e' ovvio che lo deve gestire l'OS e non
 il Programma in pascal :-)
Il problema a cui mi riferivo non e' sempre ben visibile a tutti,
specialmente se il computer e' abbastanza moderno.....
(un buon programma deve essere testato pure su macchine + scadenti,
 ma umanamente accettabili)
Riguardo alla storiella degli interrupt ci avevo gia' pensato.
Ma visto che nessuno mi sa dire oltre a quello che mi avete scritto
 e a quel che so, come risolvere il problemino... 
(SENZA OFFESE PER NESSUNO)
Dunque, ho pensato di rompere un po' la testa al TEAM del FreePascal 
.Appena posso riformulero' la questione in lingua inglese :-)
e sperando che PIERRE MULLER non mi uccida e che mi risponda
(e sperando che esista una soluzione: non avevo ancora considerato
questo fatto)
vi daro' la possibile risposta (eventaulmente in italiano )
Grazie a tutti per la collaborazione!


  e a quel che so, come risolvere il problemino...
ehehhe in realta' lo sappiamo, ma nella nostra radicata malvagita'
non te lo vogliamo dire... muhahahha :-)


DOS(Go32V2) /Win32
ora rifacendomi ad un altro messagio tu hai parlato di MultiTasking...
apparte una unit trovata poki giorni fa su intenet (l'ho scaricata?
boh non mi ricordo) il pascal non ha il suporto multitasking (volevo
fare una unit io ma poi gli impegni e una cosa chiamata FFX mi hanno
distolto dal intento) indi anche il programma + stupido
Program CiaoMondo;
Begin
   WriteLn('Hello World');
   ReadLn;
End.
occupa il 100% della CPU  (come qualunque programma dos)
io il FreePascal non lo conosco indi non so se altri doti ma cmq è
cosi... 
ora ritornado a noi... secondo me te la dovresti fregare della CPU
(intnato non puoi farci niente) e fare un bel
Procedure WaitMouseClickOrKeyPressed; { bel nome eh? }
Begin
  Repeat Until KeyPressed OR MouseClick;
End;
La MouseClick... dove stara? ma si la rifaccio cosi sul momento
Indi aprimo la Ralf Brown's Int List e mettimoci al lavoro:
il mouse è l'int $33 (o 33h o 0x33 se preferite) e guardate che vi
trovate:
NT 33 0003 - MS MOUSE v1.0+ - RETURN POSITION AND BUTTON STATUS
Category: M - mouse/pointing device
Inp.:
	AX = 0003h
Return: BX = button status (see #03168)
	CX = column
	DX = row
Note:	in text modes, all coordinates are specified as multiples of
the cell
	  size, typically 8x8 pixels
SeeAlso: AX=0004h,AX=000Bh,INT 2F/AX=D000h"ZWmous"
INT 33
Copied from Ralf Brown's Interrupt List
ora qui rimanda a una tabella (#03168)
che io non copio ma in pratica dice che il primo bit è 1 se il primo
pusante e premuto e cosi via... indi...
prima di tutto prepariamoci una funzione del tipo:
Function MouseButtons : Word; Assembler;
Asm
  Mov Ax, 0003h
  int 33h
  Mov Ax, Bx
End;
(Il ritorno delle funzioni è associato al valore di AX per le funzioni
Word, Al per quelle Byte; Tanto per sapere ma per le Integer e LongInt
qualcuno sa come si ritorna?)
ora che abbiamo un funzione che ci dice quale pusante e cliccato direi
di fare una che ci dice se o meno ne è cliccato uno... facile abbiamo
detto che se 1 punsante e cliccato allora 1 bit da qualke pizzo c'è
allora basta una cosa del genere
Function MouseCliked : Boolean;
Begin
  MouseClicked := MouseButtons <> 0;
End;
Ora questo se tu voi fare come tutti e te ne freghi altamente della
CPU di eventuali Crash (tra l'altro con la KeyPressed a meno che la
tastiera non si rompa quel ciclo puo essare interotto con un dito
spingendo una tasto) ma facciamo finta che tu preso dalla pazia +
totale voglia fare di testa tua e non usare Repeat allora sarebbe un
po + problematico... 
dovresti usare gli INT scriverti una piccola procedura da mettere a
posto del INT del timer di sistema (che richiama la vecchia INT, se no
addio sistema, non puoi neache imaginare quanti programmi fanno
affidamento sul INT del clock... perfino il MultiTasking di alcuni (se
non tutti) sistemi operativi) cmq dentro questa procedura (sarebbe
meglio in ASM) devi controlare (o fare affidamento su degli int ma è
brutto) lo stato della tastiera e del mouse...
una volta che scopri che il mouse e clicato beh puoi rimetere a posto
le cose (riassegnare INT originario a quello che hai toccato) e
lanciare una procedura callback (che pero' non deve essere per forsa
una INT come ha detto qualkuno dopo che hai messo a posto le cose con
un call puoi chiamare qualcune procedura che tu vuoi... se sei
abbastanza bravo gli puoi passare anche dei parametri.. ma per me è
troppo...
non posso darti del codice perche per me è troppo... forse qualcuno +
legato al asm (tipo Albe) puo aiutarti con del codice...
e cmq ti cosiglio di legerti Help di Keep e dintorni....
be ora basta  se no mi tocca emtere [LUNGO] nel Sub..
Il Razziatore,
The Only Good Windows in an uninstalled Windows
-----------------------------------------------
E-MAILs : IlRazziat...@NOSPAMnetscape.net
WEB     : 
http://www.razziatore.dns2go.com/
ICQ     : 67552596

Per utilizzare gli interrupt dovresti utilizzare delle procedure del pascal
che ti permettono di prelevare il vettore degli interrupt e settarlo a tuo
piacimento, (getinterruptvector dovrebbe chiamarsi cosě), il problema
fondamentale che se il programma gira in puro dos allora funziona, ma se
gira sotto windows allora i tuoi programmi girano i protect mode e non puoi
modificare la tabella degli interrupt...
Ciao RDC

 ora me... hai creato un bel po di scompiglo....
Io direi:
"ma lo sai che hai mosso i vertici del NG? RdC, Dreadnaut e ora me..."
"Inoltre hai mosso pure lo smanettone di Carletto..."
Eheh...
Cmq concordo con la tua soluzione...
Ciao


 ora me... hai creato un bel po di scompiglo....
Razz, tu non sei uno dei vertici del ng :-p  e io al massimo sono un
angolo ottuso :-) Ma alle 01:32 non hai altro da fare ??? hehehehhe
ciao



mmh, beh, non č del tutto vero...cioč, la IDT certamente non la puoi
modificare, ma la tabella degli interrupt della V86 sě....

 (SENZA OFFESE PER NESSUNO)
la "storiella" degli interrupt? ahahah!! lol ;)
A quanto ho capito, nella tua routine tu non vuoi il polling. Però guarda
che non ci sono molte soluzioni: se non implementi una gestione dell'I/O
attraverso il polling, la implementi attraverso gli interrupt...non ci sono
molte altre soluzioni.
Comunque, per quanto riguarda il mouse, mi pare che di solito venga usato
proprio il polling (cioè, il test ad ogni ciclo), perchè interrogare il
mouse non "spreca" tanti cicli di CPU (e anche perchè non mi pare che il
mouse, nei PC, generi degli interrupt hardware...).
Per quanto riguarda la tastiera, di solito si usano gli interrupt...ma cmq
come ti ha già detto Dreadnaut, i cicli ci sono di mezzo sempre...cioè, per
farti un esempio, hai presente com'è fatta una qualsiasi applicazione win32?
E' un ciclo continuo che attende messaggi dall'OS...
Io in questo caso userei il polling per entrambi i device (mouse e
tastiera), che, stai tranquillo, non tolgono molto...però, se tu vuoi fare
in modo diverso, puoi scriverti il tuo interrupt della tastiera (in genere è
l'interrupt 08h, cmq in generale è l'IRQ 0). Un interrupt del genere viene
invocato ogni volta che è stato premuto un tasto...ma non può fare molto di
più di modificare qualche flag e mettere il tasto letto in un buffer: in
ogni caso, quindi, nella tua Repeat/Until, dovrai mettere un check sui flag
e sul buffer modificati dal tuo interrupt (e questi sono i check che compie
anche la corrispondente routine in pascal!).
Un'ultima cosa (io sto ipotizzando, visto che non ho capito bene il tuo
problema): forse tu vuoi che la tua routine venga interrotta nel momento
*esatto* in cui un tasto è premuto (senza attendere il check,
insomma)...allora, in questo caso, ti basta mettere, all'interno del tuo
interrupt 08h, un salto alla parte di programma che vuoi che venga eseguita
all'uscita della Repeat/Until. Mi spiego: se tu hai il tuo programma fatto
così:
repeat
{ operazioni }
until ... ;
potresti inserire, all'interno del tuo int 08h, un salto diretto
all'istruzione successiva alla "until". In questo modo, appena premi un
tasto, ti esce dalla repeat/until senza aver bisogno del check. Purtroppo in
pascal non lo so fare...e cmq questo sistema funzionerebbe solo per la
tastiera, ma non per il mouse.
bye
Albe

D'accordo sul principio, ma col Tp7 (e penso anche col 6) al posto di
chiamarsi manualmente l'int 33 basta usare la unit driver, anche se è della
Trurbo Vision non c'è bisogno di rendere a finestre il programma; basta
chiamare InitEvents all'inizio, creare un TEvent e passarlo a un
GetMouseEvent, leggendone i campi, e alla fine un bel HideMouse; per
disattivare il mouse. Tutto per voi da USES Drivers, abbastanza garantito(ho
preso tutto da un mio programma funzionante); getmouseevent mi pare aveva
qualche bug ma non darà problemi sul tuo programma.
Lascia stare il ciclo infinito, Windows dà bassa priorità ai tuoi programmi,
si può fare, come t'hanno spiegato gli altri, ma se non sai assembler meglio
lasci stare, rischi di creare bug, e poi non guadagni niente, meglio
abbassare la priorità dalle proprietà del PIF.
Ciao
--
Paolo Giarrusso
Per rispondere togliere solo "TOGLIMI" dall'indirizzo, non _spam.

 chiamarsi manualmente l'int 33 basta usare la unit driver
beh e' una questione di fiducia... non so' cosa ci sia dentro drivers,
ma se so' che mi bastano 4 righe per fare la stessa cosa, per sicurezza
ci metto quelle :-)
