how to make the continuous sound once some thing happen?

 

I want to achieve this purpose: when the EA was attached into some pair's chart, and some case happened, then a message box or relative thins will be showed, and a certain sound, such as "alert.wav", will play again and continuous until I click the OK button on the message box.

does it can be achieved?

 
vx0532: does it can be achieved?

No because once you put up the message box the EA has stopped. You probably don't want to anyway.

  1. Just create a custom wav (of say 5 minutes long) and use that.
  2. Alternatively shell a command such as a SCHTASKS to play the wav once per minute and after message box shell it to cancel the task.
    rem TERMINAL\experts\files\contSound.bat
    set sound="%~dp0\..\..\Sounds\wait.wav"
    if "%1" == "on"  ( schtasks /create /tn mysound /SC minute /it /tr %sound%
    ) else (           schtasks /delete /tn mysound /F
                       TaskKill.exe /IM WMPlayer.exe
    )
  3. This will play the sound once per minute (at the top of the minute) until task is deleted.
  4. Alternatively shell a command to put up the a message box and set a file on press. Have the EA sound and check for the file continuously.
 
vx0532:

I want to achieve this purpose: when the EA was attached into some pair's chart, and some case happened, then a message box or relative thins will be showed, and a certain sound, such as "alert.wav", will play again and continuous until I click the OK button on the message box.

does it can be achieved?


You can do it using the Win32 PlaySound() call rather than MT4's own built-in PlaySound():

#import "winmm.dll"
   int PlaySoundA(string, int, int);
   int PlaySoundW(int , int, int);
#import

void start()
{
   PlaySoundA(StringConcatenate(TerminalPath(), "\\sounds\\alert.wav"), 0, 9); /* 9 = SND_ASYNC | SND_LOOP */
   MessageBox("This is very annoying...");
   PlaySoundW(0, 0, 0);
}

(This A and W imports are because the sound has to be stopped by passing a null pointer, not a blank string. This can't easily be done with a single DLL import, but the easy work-around is to use the Ansi and Unicode calls as a way of calling the function with different parameter types.)

N.B. This code will need modification if compiled with build 574 of MT4, for two reasons. Firstly, sounds will may no longer be stored in the <mt4>\sounds directory. Secondly, an EA compiled with v574 uses Unicode string parameters in DLL calls rather than Ansi parameters. Therefore, the use of PlaySoundA versus PlaySoundW would need to be swapped round.

 
WHRoeder:

No because once you put up the message box the EA has stopped. You probably don't want to anyway.

  1. Just create a custom wav (of say 5 minutes long) and use that.
  2. Alternatively shell a command such as a SCHTASKS to play the wav once per minute and after message box shell it to cancel the task.
  3. This will play the sound once per minute (at the top of the minute) until task is deleted.
  4. Alternatively shell a command to put up the a message box and set a file on press. Have the EA sound and check for the file continuously.



Thank you, WHRoeder

I think the practical and simple method is 1.

 
gchrmt4:


You can do it using the Win32 PlaySound() call rather than MT4's own built-in PlaySound():

(This A and W imports are because the sound has to be stopped by passing a null pointer, not a blank string. This can't easily be done with a single DLL import, but the easy work-around is to use the Ansi and Unicode calls as a way of calling the function with different parameter types.)

N.B. This code will need modification if compiled with build 574 of MT4, for two reasons. Firstly, sounds will may no longer be stored in the <mt4>\sounds directory. Secondly, an EA compiled with v574 uses Unicode string parameters in DLL calls rather than Ansi parameters. Therefore, the use of PlaySoundA versus PlaySoundW would need to be swapped round.



Thank you, gchrmt4

I have modify it a little (control when the sound should be stop) as below and so it can fit my request perfect; thank you very much.

#include <WinUser32.mqh >
#import "winmm.dll"
   int PlaySoundA(string, int, int);
   int PlaySoundW(int , int, int);
#import
int x=0;

 
void start()
{
   if(x==IDOK) return;
   PlaySoundA(StringConcatenate(TerminalPath(), "\\sounds\\alert.wav"), 0, 9); /* 9 = SND_ASYNC | SND_LOOP */
   x=MessageBox("This is very annoying...",NULL,MB_OK|MB_ICONQUESTION);
   PlaySoundW(0, 0, 0);
}


in addition, shall I know how to know more information about PlaySoundA/PlaySoundW and related function?

 
thank you all. the materials are quite valuable to me. How to make the sound louder?
 
vx0532:

In addition, shall I know how to know more information about PlaySoundA/PlaySoundW and related function?

See http://msdn.microsoft.com/en-us/library/windows/desktop/dd743680(v=vs.85).aspx
 
tzm:
[...] How to make the sound louder?

Turn up your speakers! Or edit the .wav file.

 


Thank you. so PlaySound() here is Win's function not MT4.

I think you set PlaySound() as PlaySoundA(), just wanting it not to recognized by by MQL, but I can't understand how winmm.dll can recognize it when you change its name?

 
vx0532:


Thank you. so PlaySound() here is Win's function not MT4.

I think you set PlaySound() as PlaySoundA(), just wanting it not to recognized by by MQL, but I can't understand how winmm.dll can recognize it when you change its name?

Unicode and ANSI names

PlaySoundW (Unicode) and PlaySoundA (ANSI)


 
vx0532:


Thank you. so PlaySound() here is Win's function not MT4.

I think you set PlaySound() as PlaySoundA(), just wanting it not to recognized by by MQL, but I can't understand how winmm.dll can recognize it when you change its name?



[Some simplifications in the following; it is not 100% literally true]

There are two ways of representing a string in the computer's memory. A) Ansi. One byte per character, therefore limited to 255 different characters and unable to represent characters from writing systems such as Kanji or Arabic. W) Unicode. Two bytes per character, and therefore able to represent a much larger range of characters. (The W stands for "wide".)

All Windows API functions which accept string parameters come in two versions, A and W, e.g. PlaySoundA and PlaySoundW, or ShellExecuteA and ShellExecuteW, or CreateFileA and CreateFileW. If your code uses Ansi strings then you use the A version. If your code uses Unicode strings, then you use the W version.

Apart from the different parameter types, the A and W functions are identical. Therefore, the Microsoft documentation contains a single entry for PlaySound(), not separate entries for PlaySoundA() and PlaySoundW().

When writing code in a language such as C, header files and compiler settings will automatically translate the use of e.g. PlaySound() to either PlaySoundA() or PlaySoundW() as appropriate. In other words, you would normally write code using references to PlaySound() rather than PlaySoundA() or PlaySoundW(), and the compiler would quietly convert this to either PlaySoundA() or PlaySoundW().

In languages such as MQL4, there is no such automatic conversion and mapping of functions names. You have to use declare and use the underlying functions exported by the Windows API. Therefore, MQL4 code must explicitly import and use PlaySoundA() or PlaySoundW(), rather than referring to PlaySound(). This is also convenient because there would otherwise be a conflict between MQL4’s built-in PlaySound() function and an attempt to import the Windows function. (The same applies to the Win32 MessageBox function versus the built-in MQL4 MessageBox.)

The additional trick in the above code is that you cancel a repeating sound by passing a null pointer to PlaySound() instead of a string. MQL4 has no (easy) way of doing this with a single function import. However, the existence of separate A and W functions means that it is possible to import the same function twice in MQL4, with different parameter lists, so that PlaySoundW() can be used as a way of passing a null string parameter.

Finally: when compiling with build 574 of MT4, MQL4 code uses Unicode strings rather than Ansi strings. Therefore, all references (including the imports) in the above code to PlaySoundA() would need to be changed to PlaySoundW(), and vice versa.

Reason: