API de controle de volume do Windows

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

API de controle de volume do Windows

Mensagem por cjp »

Pessoal, alguém saberia como faço para controlar o volume do som do computador com Windows 10 Pro de dentro de um programa feito em Harbour console?
Pesquisei API do Windows, achei essa: EndpointVolumeChanger. Mas não consegui usar.
Se der para apenas ligar e desligar o som, já está ótimo.
Inacio de Carvalho Neto
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

API de controle de volume do Windows

Mensagem por cjp »

Alguém me ajuda?
Inacio de Carvalho Neto
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

API de controle de volume do Windows

Mensagem por clodoaldomonteiro »

Olá.

Acho que vc poderia tentar usando Virtual Key, em C.

Código: Selecionar todos

#pragma BEGINDUMP
   /////////////////////////////////////////////////////////////////////////////
   //Pressionar a tecla alt
   //https://docs.microsoft.com/pt-br/windows/win32/inputdev/virtual-key-codes
HB_FUNC( _VKALT )
   {
   keybd_event (VK_MENU, 0, 0, 0 );
   keybd_event (VK_MENU, 0, KEYEVENTF_KEYUP, 0);
   }

   /////////////////////////////////////////////////////////////////
   //Pressionar qualquer tecla
HB_FUNC( _VKLETRA )
   {
   keybd_event (hb_parnl(1), 0, 0, 0 );
   keybd_event (hb_parnl(1), 0, KEYEVENTF_KEYUP, 0);
   }

   /////////////////////////////////////////////////////////////////
   //Pressionar seta baixo
HB_FUNC( _VKSETABAI )
   {
   int n; //= 1;
   for(n = 1; n <= hb_parni(1); n++) {
      keybd_event (VK_DOWN, 0, 0, 0 );
      keybd_event (VK_DOWN, 0, KEYEVENTF_KEYUP, 0);
      }
   }

#pragma ENDDUMP

Código: Selecionar todos

   ...
   ...
   Case nMenuEvent == 101
      Mnu()
      CBC1(.T.)
      _VKAlt()
      _VKLetra(0x54) 

   ...
   ...

At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
carlaoonline
Usuário Nível 3
Usuário Nível 3
Mensagens: 190
Registrado em: 24 Ago 2014 22:38
Localização: Porto Alegre-RS

API de controle de volume do Windows

Mensagem por carlaoonline »

Bom dia!

Pode também tentar usar o nircmd.exe com o comando Hb_run() ou EXECUTE FILE

https://nircmd.nirsoft.net

Se não me engano para baixar o volume usa o parâmetro changesysvolume com o decremento/incremento:

Código: Selecionar todos

nircmd.exe changesysvolume -5000

E para quem tem o MiniGui Extend instalado, tem um exemplo na pasta:
C:\MiniGUI\SAMPLES\Advanced\NirCmdDll

Vou deixar o codigo MiniGui do exemplo aqui para estudar a parte da execução:

Código: Selecionar todos

/*
 * MiniGUI DLL Demo
 *
 * Sample for using NirCmd DLL
 * For more information about NirCmd:
 * http://www.nirsoft.net/utils/nircmd.html
 *
 * (c) 2010-2016 Grigory Filatov <gfilatov@inbox.ru>
*/

#include "minigui.ch"
#include "hbdyn.ch"

Procedure Main
  
	SET HELPFILE TO 'NirCmd.chm'

	SET FONT TO _GetSysFont(), 9

	DEFINE WINDOW Form_1 ;
		AT 0,0 ;
		WIDTH 400 ;
		HEIGHT 230 + iif(IsWinXPorLater(), GetBorderHeight(), 0) ;
		TITLE 'NirCmd DLL Test' ;
		ICON 'NirCmd.ico' ;
		MAIN ;
		ON INTERACTIVECLOSE MsgYesNo ( 'Are You Sure ?', 'Exit' )

		DEFINE BUTTON Button_1
			ROW	10
			COL	10
			WIDTH	170
			CAPTION 'Open CD-ROM Door'
			ACTION OpenCDRom_Click()
		END BUTTON

		DEFINE BUTTON Button_2
			ROW	40
			COL	10
			WIDTH	170
			CAPTION 'Close CD-ROM Door'
			ACTION CloseCDRom_Click()
		END BUTTON

		DEFINE BUTTON Button_3
			ROW	70
			COL	10
			WIDTH	170
			CAPTION 'Mute System Volume'
			ACTION MuteVolume_Click()
		END BUTTON

		DEFINE BUTTON Button_4
			ROW	100
			COL	10
			WIDTH	170
			CAPTION 'Unmute System Volume'
			ACTION UnmuteVolume_Click()
		END BUTTON

		DEFINE BUTTON Button_5
			ROW	130
			COL	10
			WIDTH	170
			IF IsWinXPorLater()
				CAPTION 'Show the task manager'
				ACTION TaskManager_Click()
			ELSE
				CAPTION 'Turn Monitor Off'
				ACTION MonitorOff_Click()
			ENDIF
		END BUTTON

		DEFINE BUTTON Button_5a
			ROW	160
			COL	10
			WIDTH	170
			CAPTION 'Save screenshot in clipboard'
			ACTION savescreenshot_Click()
		END BUTTON

		DEFINE BUTTON Button_6
			ROW	10
			COL	200
			WIDTH	150
			CAPTION 'Start the screen saver'
			ACTION StartSS_Click()
		END BUTTON

		DEFINE BUTTON Button_7
			ROW	40
			COL	200
			WIDTH	150
			CAPTION 'Disable the screen saver'
			ACTION DisableSS_Click()
		END BUTTON

		DEFINE BUTTON Button_8
			ROW	70
			COL	200
			WIDTH	150
			CAPTION 'Enable the screen saver'
			ACTION EnableSS_Click()
		END BUTTON

		DEFINE BUTTON Button_9
			ROW	100
			COL	200
			WIDTH	150
			CAPTION 'Clear the clipboard'
			ACTION ClearClipboard_Click()
		END BUTTON

		DEFINE BUTTON Button_10
			ROW	130
			COL	200
			WIDTH	150
			CAPTION 'Display a tray balloon'
			ACTION TrayBalloon_Click()
		END BUTTON

		DEFINE BUTTON Button_10a
			ROW	160
			COL	200
			WIDTH	150
			IF IsWinXPorLater()
				CAPTION 'Flash this window'
				ACTION FlashWin_Click()
			ELSE
				CAPTION 'Cancel'
				ACTION ThisWindow.Release()
			ENDIF
		END BUTTON

		ON KEY F1 ACTION DISPLAY HELP MAIN
		ON KEY ESCAPE ACTION ThisWindow.Release()

	END WINDOW

	CENTER WINDOW Form_1
	ACTIVATE WINDOW Form_1

Return


Procedure OpenCDRom_Click()
    DoNirCmd( "cdrom open" )
Return


Procedure CloseCDRom_Click()
    DoNirCmd( "cdrom close" )
Return


Procedure MuteVolume_Click()
    DoNirCmd( "mutesysvolume 1" )
Return


Procedure UnmuteVolume_Click()
    DoNirCmd( "mutesysvolume 0" )
Return


Procedure MonitorOff_Click()
    MsgAlert('Monitor will be off for 10 seconds!', 'Warning')
    DoNirCmd( "monitor off" )
    inkey(10)
    DoNirCmd( "monitor on" )
Return


Procedure StartSS_Click()
    DoNirCmd( "screensaver" )
Return


Procedure EnableSS_Click()
    DoNirCmd( [regsetval sz "HKCU\control panel\desktop" "ScreenSaveActive" 1] )
Return


Procedure DisableSS_Click()
    DoNirCmd( [regsetval sz "HKCU\control panel\desktop" "ScreenSaveActive" 0] )
Return


Procedure ClearClipboard_Click()
    DoNirCmd( "clipboard clear" )
Return


Procedure TrayBalloon_Click()
    EXECUTE FILE "nircmd.exe" PARAMETERS [trayballoon "Hello" "This is the text that will be appear inside the balloon!" "shell32.dll,-154" 10000]
Return


Procedure TaskManager_Click()
    EXECUTE FILE "nircmd.exe" PARAMETERS "sendkeypress ctrl+shift+esc"
Return


Procedure savescreenshot_Click()
    Form_1.Minimize
    EXECUTE FILE "nircmd.exe" PARAMETERS "savescreenshot *clipboard*"
    Form_1.Restore
Return


Procedure FlashWin_Click()
    EXECUTE FILE "nircmd.exe" PARAMETERS [win flash title 'NirCmd DLL Test']
Return


// BOOL WINAPI DoNirCmd(LPSTR lpszCommand)
Function DoNirCmd( cCommand )
Return HMG_CallDLL( "NIRCMD.DLL", HB_DYN_CTYPE_BOOL, "DoNirCmd", cCommand )

cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

API de controle de volume do Windows

Mensagem por cjp »

Muito obrigado a todos que responderam.
Resolvi provisoriamente a questão com a nircmd.
Mas ainda precisarei melhorar essa questão, pois, pelo que vi, a nircmd aumenta ou abaixa o volume, mas não verifica quanto está o volume.
Minha ideia seria apenas desmutar, se estiver no mudo, mas isso não achei lá.
De qualquer forma, já está ótimo.
Obrigado.
Inacio de Carvalho Neto
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

API de controle de volume do Windows

Mensagem por clodoaldomonteiro »

Boa tarde.

Um cara q ajuda muito nesses problemas é o ChatGPT, veja a resposta dele:

Código: Selecionar todos

#include <stdio.h>
#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>

BOOL IsMuted() {
    BOOL bMuted = FALSE;
    CoInitialize(NULL);
    IMMDeviceEnumerator *deviceEnumerator = NULL;
    HRESULT hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (LPVOID *)&deviceEnumerator);

    if (SUCCEEDED(hr)) {
        IMMDevice *defaultDevice = NULL;
        hr = deviceEnumerator->lpVtbl->GetDefaultAudioEndpoint(deviceEnumerator, eRender, eConsole, &defaultDevice);
        if (SUCCEEDED(hr)) {
            IAudioEndpointVolume *endpointVolume = NULL;
            hr = defaultDevice->lpVtbl->Activate(defaultDevice, &IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
            if (SUCCEEDED(hr)) {
                hr = endpointVolume->lpVtbl->GetMute(endpointVolume, &bMuted);
                endpointVolume->lpVtbl->Release(endpointVolume);
            }
            defaultDevice->lpVtbl->Release(defaultDevice);
        }
        deviceEnumerator->lpVtbl->Release(deviceEnumerator);
    }
    CoUninitialize();
    return bMuted;
}

int main() {
    if (IsMuted()) {
        printf("O volume do PC está mudo.\n");
    } else {
        printf("O volume do PC não está mudo.\n");
    }
    return 0;
}
int main() {
    if (IsMuted()) {
        printf("O volume do PC está mudo.\n");
    } else {
        printf("O volume do PC não está mudo.\n");
    }
    return 0;
}
Abraços.
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

API de controle de volume do Windows

Mensagem por cjp »

Desculpe aí, não sabia que os códigos feitos pelo ChatGPT eram confiáveis.
Este código é em C++, correto?
Tentei colocar no meu sistema, com #pragma BEGINDUMP, não deu certo. Tá dando erro na compilação (imagem anexa). Fiz algo errado?
Também não sei bem como chamar programa em C++. Pode me ajudar?
Anexos
tela.png
Inacio de Carvalho Neto
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

API de controle de volume do Windows

Mensagem por clodoaldomonteiro »

Para incluir rotinas em C, não é C++, no seu sistema, inicie com:

Código: Selecionar todos

#pragma BEGINDUMP

   #include <"Includes arquivos em C">

   HB_FUNC( NOME_SUA_FUNCAO )
   {
      //programação em C
       return;
    }

#pragma ENDDUMP
No Chat-GPT, pergunte o q quer e vá testando, se não der certo, vá refinando a pergunta.

Abraços.
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

API de controle de volume do Windows

Mensagem por cjp »

Não sei se entendi bem.

Fiz assim:

Código: Selecionar todos

#pragma BEGINDUMP

#include <stdio.h>
#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>

hb_func("som")

BOOL IsMuted() {
    BOOL bMuted = FALSE;
    CoInitialize(NULL);
    IMMDeviceEnumerator *deviceEnumerator = NULL;
    HRESULT hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (LPVOID *)&deviceEnumerator);

    if (SUCCEEDED(hr)) {
        IMMDevice *defaultDevice = NULL;
        hr = deviceEnumerator->lpVtbl->GetDefaultAudioEndpoint(deviceEnumerator, eRender, eConsole, &defaultDevice);
        if (SUCCEEDED(hr)) {
            IAudioEndpointVolume *endpointVolume = NULL;
            hr = defaultDevice->lpVtbl->Activate(defaultDevice, &IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
            if (SUCCEEDED(hr)) {
                hr = endpointVolume->lpVtbl->GetMute(endpointVolume, &bMuted);
                endpointVolume->lpVtbl->Release(endpointVolume);
            }
            defaultDevice->lpVtbl->Release(defaultDevice);
        }
        deviceEnumerator->lpVtbl->Release(deviceEnumerator);
    }
    CoUninitialize();
    return bMuted;
}

int som() {
    if (IsMuted()) {
        printf("O volume do PC está mudo.\n");
    } else {
        printf("O volume do PC não está mudo.\n");
    }
    return 0;
}
#pragma ENDDUMP
Deu erro na compilação (imagem anexa).

O que estou fazendo errado?
Anexos
tela.png
Inacio de Carvalho Neto
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

API de controle de volume do Windows

Mensagem por alxsts »

Olá!

Use a busca do fórum... procure por hb_func. Vai encontrar vários exemplos. Compare a sintaxe do que encontrar com a sintaxe que você escreveu. Certamente encontrará diferenças. Corrija o teu código e compile...
[]´s
Alexandre Santos (AlxSts)
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

API de controle de volume do Windows

Mensagem por cjp »

Achei os seguintes tópicos (entre outros) no fórum:
viewtopic.php?f=4&t=27059&p=161240&hilit=hb_func#p161240
viewtopic.php?f=4&t=9619&p=161433&hilit=hb_func#p161433

Mudei assim:

Código: Selecionar todos

#pragma BEGINDUMP

#include <stdio.h>
#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>

hb_func(_som) {

BOOL IsMuted() {
    BOOL bMuted = FALSE;
    CoInitialize(NULL);
    IMMDeviceEnumerator *deviceEnumerator = NULL;
    HRESULT hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (LPVOID *)&deviceEnumerator);

    if (SUCCEEDED(hr)) {
        IMMDevice *defaultDevice = NULL;
        hr = deviceEnumerator->lpVtbl->GetDefaultAudioEndpoint(deviceEnumerator, eRender, eConsole, &defaultDevice);
        if (SUCCEEDED(hr)) {
            IAudioEndpointVolume *endpointVolume = NULL;
            hr = defaultDevice->lpVtbl->Activate(defaultDevice, &IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
            if (SUCCEEDED(hr)) {
                hr = endpointVolume->lpVtbl->GetMute(endpointVolume, &bMuted);
                endpointVolume->lpVtbl->Release(endpointVolume);
            }
            defaultDevice->lpVtbl->Release(defaultDevice);
        }
        deviceEnumerator->lpVtbl->Release(deviceEnumerator);
    }
    CoUninitialize();
    return bMuted;
}

int _som() {
    if (IsMuted()) {
        printf("O volume do PC está mudo.\n");
    } else {
        printf("O volume do PC não está mudo.\n");
    }
    return 0;
}
}
#pragma ENDDUMP
Mas continua dando erro na compilação (vide anexo).

Testei também sem o "_" antes de "som", mas também não funcionou.

Ainda não consegui entender como fazer isto.
Anexos
tela.png
Inacio de Carvalho Neto
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

API de controle de volume do Windows

Mensagem por clodoaldomonteiro »

Boa noite, Inacio.

Peguei esse exemplo com o GPT, que ele me passou na primeira questão, e geralmente vc vai ter q ir refinando a questão, informando as funções e erros q aconteceram, daí, pode ser, pode ser mesmo, que ele lhe dê uma respostas sem que vc tenha q fazer algum ajuste.

Não sou bom em C, e quando tenho alguma dúvida, saio pela internet pesquisando até me cansar, hehe.

A verdade é que nada vem fácil, só com muito estudo e persistência.

Abraços.
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

API de controle de volume do Windows

Mensagem por clodoaldomonteiro »

Não testei em um PC, pois tenho um MacBook com Máquina Virtual.

Código: Selecionar todos

Function Main()

   wait 'Pressione qq tecla para desligar o som.'
   _VKPresTecla(0xAE)

   wait 'Pressione qq tecla para ligar o som.'
   _VKPresTecla(0xAD)

   wait 'Terminou...'

   Return

////////////////////////////////////////////////////////////////////////////////
//Funções em C
//https://learn.microsoft.com/pt-br/windows/win32/inputdev/virtual-key-codes
//https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
////////////////////////////////////////////////////////////////////////////////

#include "common.ch"    // para poder redefinir a fun‡Æo type() para ischaracter() e outras
#include "winuser.ch"

   /////////////////////////////////////////////////////////////////////////////
#pragma BEGINDUMP
   #pragma comment( lib, "shell32.lib" )

   #define _WIN32_WINNT   0x0400
   #define HB_OS_WIN_32_USED

   //Coloquei todos, pois nào lembro quais necessitam para Virtual Key
   #include <windows.h> //arquivos C
   #include <winsock.h>
   #include <windows.h>
   #include "winbase.h"
   #include "winuser.h"
   #include <stdio.h>
   #include <stdlib.h>
   #include <Iphlpapi.h>
   #include <Assert.h>
   #include "hbapi.h"
   #include "hbapiitm.h"
   #include "item.api"
	#include <commdlg.h>
	//#include <shlobj.h>
	#include <commctrl.h>

   /////////////////////////////////////////////////////////////////
   //Pressionar qualquer tecla
HB_FUNC( _VKPRESTECLA )
   {
   keybd_event (hb_parnl(1), 0, 0, 0 );               //Pressiona a tecla
   keybd_event (hb_parnl(1), 0, KEYEVENTF_KEYUP, 0);  //Solta a tecla pressionada
   }

#pragma ENDDUMP
Daí vc vai testando, modificando, pesquisando, e ando..., ando, hehe

Abraços
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

API de controle de volume do Windows

Mensagem por clodoaldomonteiro »

Fiz uma consulta para o GPT novamente e retornou um que compilou, veja abaixo:

Código: Selecionar todos

#include <windows.h>
#include <mmsystem.h>
#include "hbapi.h"

HB_FUNC( ISMUTED )
{
   DWORD dwVolume;
   MMRESULT result = waveOutGetVolume(NULL, &dwVolume);

   if (result == MMSYSERR_NOERROR)
   {
      if (LOWORD(dwVolume) == 0 && HIWORD(dwVolume) == 0)
         hb_retl( HB_TRUE );  // Retorna verdadeiro
      else
         hb_retl( HB_FALSE ); // Retorna falso
   }
   else
   {
      hb_retl( HB_FALSE );
   }
}
Compile o código usando o Harbour:
Copy code
harbour IsMuted.c -lwinmm
O argumento -lwinmm é usado para linkar com a biblioteca winmm.lib.

Depois de compilar, você terá o arquivo IsMuted.obj. Para finalizar, você precisa linkar este arquivo .obj ao seu programa Harbour principal.
Agora você pode chamar a função IsMuted() no seu código Harbour. Por exemplo:

harbour
Copy code
IF IsMuted()
? "O volume do PC esta mudo."
ELSE
? "O volume do PC nao esta mudo."
ENDIF
Espero que isso ajude! Se você encontrar algum problema, certifique-se de verificar todas as etapas e assegurar-se de que a biblioteca winmm.lib (ou mmsystem.lib) está acessível para o Harbour.

Té mais...
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

API de controle de volume do Windows

Mensagem por cjp »

Funcionou. Muito obrigado.
Apenas para constar (pra eventuais outros interessados): no teu exemplo, está invertido, o de desligar, está ligando, o de ligar, está desligando o som.
Inacio de Carvalho Neto
Responder