Newsgroup: it.comp.lang.visual-basic
Titolo: playsound e risorse

riposto per maggiore visibilità.
da quello che ho capito, per far suonare un file contenuto in un file res
allegato a un progetto vb bisogna usare la funzione playsound.
questa funzione, al secondo argomento (hModule), richiede (quando si tratta
di file risorse) "A handle to the application module containing the sound
resource the play". ma una volta allegato il file res al progetto, come mi
ottengo questo handle?
MarioH

 wrote in message
97od38$q0i92$1...@ID-70152.news.dfncis.de...


 Te l' ho detto tre volte!
allora... ::))))))) l'esempio ATM l'ho visto, ma ho visto anche su MSDN che
dice che sndPlaySound è vecchia, e che PlaySound ci mette una riga di codice
dove l'altra ce ne mette un paccotto... inoltre MSDN dice che è
consigliabile usare playsound, per motivi di "portabilità" su altri pc.
cmq ho risolto. anzi, ho risolto a metà.
carico il suono wav in memoria usando loadresdata e dopo lo "sputo" fuori
(cioe lo suono) con play sound.
non sono riuscito a leggere "direttamente" con playsound nel file res
allegato al progetto vb. l'unica cosa che NON va è il secondo parametro
(hModule), non riesco a ottenerne uno giusto da oggi pomeriggio... che
rabbia... in pratica mi tocca fare un passaggio in piu, usando loadresdata,
cosa che in teoria potrei tranquillamete vitare.
quindi, se qualcuno sa come usare PlaySound (non l'altra, sndPlaySound) con
il flag SND_RESOURCE, me lo dica... grazie...
MarioH

ps: dimenticavo... per quel problemino che fa quando dichiaro una variabile
nella DLL come Picture? io non l'ho ancora risollto... e qui l'esempio ATM
non è di enorme aiuto...
in pratica ci vorrebbe una funzione dichiarata all'interno della DLL (dll
che a sua volta contiene il file RES) che "ritorni" un'immagine. io avevo
pensato di dichiararla come image o come object, che ne pensi?
MarioH

qualche chiarimento sul parametro hModule... anzi, sulla funzione
PlaySound in genere: PlaySound suona qualsiasi cosa. Non necessariamente
dei wav, può anche "suonare" un evento, come una finestra di dialogo di
conferma. In questi casi, il parametro hModule deve essere uguale a NULL
(in VB, ByVal 0&). Se decidi di caricare il wav da un file risorse, le
cose cambiano. hModule deve essere l'handle al modulo (exe o dll) che
contiene la risorsa da suonare. L'handle si ottiene con GetModuleHandle
(se il modulo con la risorsa è l'exe stesso, passagli una stringa
vuota). Piccolo problema: la dichiarazione va cambiata da così:
Function PlaySound(ByVal pszSound As String, ByVal hmod as Long, ByVal 
fdwSound as Long) as Boolean
a così:
... ByVal pszSound As Long...
dal momento che VB tratta le stringhe come dati e non come puntatori a
dati, come invece fanno C, C++ e Pascal. Mentre i dati sono degli array
di lunghezza variabile, i puntatori sulle nostre macchine a 32 bit sono,
appunto, variabili a 32 bit, quindi 4 byte, quindi un Long.
Perchè questo trucco? perchè per caricare una risorsa dovrai usare:
- FindResource per controllare che la risorsa esista realmente, e se
  esiste ottenere un handle
- LoadResource per caricare la risorsa corrispondente all'handle
  ricavato con FindResource
- LockResource per bloccare la risorsa in memoria e convertire l'handle
  in un puntatore (ossia il Long di cui parlavo più sopra - che, notare,
  è effettivamente un puntatore ad una stringa, quindi in un linguaggio
  "di questo mondo" sarebbe compatibile al 100% con il parametro
  pszSound. Non in VB, ahimè)
- PlaySound con il puntatore di cui sopra come parametro pszSound (se
  vuoi passargli una comune stringa, ti basterà passargli
  StrPtr(stringa), che converte una stringa nel suo puntatore - cose
  dell'altro mondo, tutti gli altri linguaggi hanno funzioni che fanno
  l'esatto opposto...). Ricorda di settare il parametro fdwSound a
  SND_MEMORY)
Ora che ci penso... in realtà puoi tranquillamente saltare tutto quanto,
passare la stringa con l'ID della risorsa a PlaySound, che si occuperà
al posto tuo dei primi tre passi della procedura... beh, però imparare
come trattare con le risorse non ti fa certo male :)
che altro? breve spiegazione dei parametri extra di PlaySound:
SND_APPLICATION - ne ignoro totalmente il significato
SND_ALIAS - il suono è un evento di sistema (vedi
            HKCU:\AppEvents\EventLabels per la lista completa)
SND_ALIAS_ID - ignoro completamente la funzione di questo parametro.
               Credo sia qualcosa di simile a SND_ALIAS
SND_ASYNC - comincia a suonare e ritorna immediatamente. Per
            interrompere il suono chiama una seconda volta la funzione
            specificando una stringa vuota come suono
SND_FILENAME - carica il suono da un file wav
SND_LOOP - da usare assieme a SND_ASYNC. Ripete in continuazione un
           suono finchè non viene interrotto.
SND_MEMORY - specifica questo se la stringa contiene non il nome del
             file, ma il file vero e proprio. E' l'esempio che ti ho
             fatto più sopra del caricamento da file risorse.
SND_NODEFAULT - se il suono non viene trovato, normalmente PlaySound
                suona il suono predefinito di sistema. Aggiungi questa
                flag per impedirlo
SND_NOSTOP - se stai cercando di suonare un suono mentre ne stai già
             suonando uno, PlaySound cercherà di interrompere il wav
             che sta già suonando. Aggiungi questa flag per impedirlo.
SND_NOWAIT - se la scheda audio è occupata, ritorna immediatamente e
             segnala l'errore.
SND_PURGE - blocca tutti i suoni con lo stesso nome di quello che stai
            suonando. Se come nome dai una stringa vuota, ferma tutti i
            suoni avviati dal tuo programma. Per fermare suoni da
            risorse devi specificare anche hmod.
SND_RESOURCE - se la stringa è un identificatore di risorsa.
SND_SYNC - se il tuo programma deve rimanere bloccato in attesa che il
           suono sia completato.
-- 
Posted from 62.149.155.30 by way of 
smtp1.libero.it
 [193.70.192.51] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 wrote in message
G9LSSQ$IppOarLIaZjdHwumZEvV...@libero.it...


oooooooooooooops
scusa ho letto male... devo lasciare il primo parametro come long e
passargli strptr... grazie mille, mi era sfuggito, ora provo...
MarioH

NOOOOOOOOO non funziona...
ho provato nei seguenti due modi.
ho cambiato nome alla funzione (come sggerito su vbapi) e ho messo long al
primo parametro
nella sezioen CUSTOM ci sono diversi suoni
retval = PlaySound_Res(ByVal StrPtr("102"), ByVal GetModuleHandle(""),
SND_ASYNC Or SND_MEMORY Or SND_NODEFAULT)
oppure
retval = PlaySound_Res(ByVal StrPtr("102"), ByVal GetModuleHandle(""),
SND_ASYNC Or SND_RESOURCE Or SND_NODEFAULT)
non funziona in nessuno dei due modi, e retval esce sempre uguale a 0.
che devo fare adesso??????
MarioH

 GetModuleHandle("") giusto?
E' meglio GetModuleHandle(vbNullString), comunque puoi utilizzare
App.hInstance.
Ciao.

 App.hInstance.
non funziona nè con l'uno ne con l'altro... orami ho perso ogni speranza...

 ha

Non ho mai utilizzato la PlaySound e non volevo avere la pretesa di
risolverti il problema, la mia era solo una precisazione: e' sempre
meglio utilizzare vbNullString in luogo di "".
Ciao.


credo che il problema sia che non riesce ad individuare l'ID della stringa,
io gli passo strptr("101") e lui se e frega...
cmq ripeto, ci sono arrivato da un'altra parte, e cioe caricando il WAV in
una variabile con loadresdata, e poi chimando playsound passandogli il
varptr della variabile. e funziona. solo che appunto devo fare questo
passaggio in piu che volevo evitare... tutto qui...
MarioH

SND_ASYNC Or SND_MEMORY Or SND_NODEFAULT)
molto semplice: le costanti non hanno puntatore. Non sono oggetti in
memoria, sono valori e basta. Devi salvare l'ID in una variabile:
Dim id As String
id="102"
retval = PlaySound_Res(ByVal StrPtr(id), ByVal GetModuleHandle(""),
SND_ASYNC Or SND_MEMORY Or SND_NODEFAULT)
non garantisco assolutamente sul funzionamento. Il fallimento della
chiamata _dovrebbe_ dipendere dal fatto che stai cercando di ottenere
il puntatore ad una costante (prova Debug.Print StrPtr("102"), così,
tanto per fugare qualsiasi dubbio. Se ti da' zero, allora è come dico
io)
Altrimenti dichiare le due forme come funzioni distinte:
Declare Function PlaySoundStr(ByVal pszSound as String, ...
Declare Function PlaySoundLong(ByVal pszSound as Long, ...
lasciando intatto l'alias ("PlaySoundA", se non erro)
<nota>qui avrebbe fatto comodo l'overloading della funzione</nota>
PS:
vedo che ti mancano delle fondamentali basi di programmazione :)
senza offesa, è che cominciando con VB è difficile acquisirle. Se avessi
cominciato con il Pascal o con il C saresti un programmatore migliore
(ma una persona terribilmente meschina ;) specie se avessi iniziato con
il Pascal ;)
PPS:
Ah, se vuoi usare le risorse (FindResource, LoadResource, LockResource),
ricordati di fare pulizia (UnlockResource, FreeResource) appena non ti
servono più. Ecco la differenza tra usare le runtime e gestirtela da te:
le runtime fanno pulizia ("garbage collection") solo quando il programma
viene terminato, e solo se viene terminato con (relativa) "dolcezza", ad
esempio con Exit. NON con Stop. (aaah, come mi mancherebbero i try...
catch... finally, se rimettessi mano a VB...)
-- 
Posted from 62.149.155.106 by way of 
smtp3.libero.it
 [193.70.192.53] 


servono piů.
aspetta, devo usare freeresource anche se uso loadresdata + playsound (da
memoria) ? credo di no. mi sembrava di aver capito che lockresource,
loadresource, freeresource andassero usate solo se uno non usava la funzione
VCB loadresdata... giusto?

 ad individuare l'ID della stringa,
Controlla l'errore che ti restituisce la funzione con Err.LastDLLError
Ciao.

 catch... finally, se rimettessi mano a VB...)
VB.NET
 introduce pure la gestione delle eccezioni
(Try...Catch...Finally).
Ciao.


non ci crederai, ma è 0...