Jump to content

Need help using WM_CopyData to pass values


timmy2
 Share

Recommended Posts

The following is a script from Eukalyptus that plays an audio file and displays an FFT Visualization. Let's call it the "Child".

My goal is to be able to close it AND to send volume-level change commands from a Parent program (script farther below). I'm trying to use WM_CopyData for IPC but it's not working for me. Part of my problem is I'm unsure about what's needed to initialize WM_CopyData in the Parent program -- if this is even necessary.  I realize I could use the MailSlot UDF for this but would like to give WM_CopyData a go first, based on Guinness's recommendation. Once I get WM_CopyData working I might even try to use it to close the Child program.

Other issues I'm unsure about are:

1. can I send decimal values via WM_CopyData_Send() ?  (BASS_SetVolume() needs values between 0 and 1)

2. at the receiving end in the Child am I using the proper variable type and format for BASS_SetVolume()?

 

"Child" (must be compiled and named "FFT-Viz-WM_CopyData" so Parent can run it)

#AutoIt3Wrapper_UseX64=n

#include "Bass.au3"
#include "BassExt.au3"
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include 'WM_COPYDATA.au3'

Opt("MustDeclareVars", 1)

_WM_COPYDATA_SetID('MyUniqueID')  ; set ID for WM_CopyData


Global $sFile = FileOpenDialog("Open...", "..\audiofiles", "playable formats (*.MP3;*.MP2;*.MP1;*.OGG;*.WAV;*.AIFF;*.AIF)")
If @error Or Not FileExists($sFile) Then Exit

Global $iWidth = 522
Global $iHeight = 170

Global $hGui = GUICreate("FFT", $iWidth, $iHeight, -1, -1, BitOR($WS_SYSMENU, $WS_POPUP))
GUISetOnEvent($GUI_EVENT_CLOSE, "_EXIT")
_GDIPlus_Startup()
Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
Global $hBmp_Buffer = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
Global $hGfx_Buffer = _GDIPlus_ImageGetGraphicsContext($hBmp_Buffer)
_GDIPlus_GraphicsSetSmoothingMode($hGfx_Buffer, 2)

Global $hBrush = _CreateFFTBrush(5, 5, $iWidth - 10, $iHeight - 10)

GUIRegisterMsg($WM_PAINT, "WM_PAINT")
GUISetState()

_BASS_Startup()
_BASS_EXT_Startup()
_BASS_Init(0, -1, 44100, 0, "")

Global $hStream = _BASS_StreamCreateFile(False, $sFile, 0, 0, $BASS_SAMPLE_FLOAT)
Global $aFFT = _BASS_EXT_CreateFFT(128, 5, 5, $iWidth - 10, $iHeight - 10, 1, True)

_BASS_ChannelPlay($hStream, True)

Local $iControlID = _WM_COPYDATA_Start($hGui) ; Start the communication process.
Global $iTimer = TimerInit()
While _BASS_ChannelIsActive($hStream)
    If TimerDiff($iTimer) > 20 Then

        Switch GuiGetMsg()
            Case -3    ; allows Parent program to use WinClose to close this program.
                ExitLoop
            Case $iControlID   ; if the Parent program sends a volume change value via WM_CopyData
                Local $volumelevel = _WM_COPYDATA_GetData()
                _BASS_SetVolume($volumelevel)
                Beep(1000, 100)  ; for testing purposes to see if this Case ever gets triggered
        EndSwitch

        $iTimer = TimerInit()
        _GDIPlus_GraphicsClear($hGfx_Buffer, 0xFF110022)

        _BASS_EXT_ChannelGetFFT($hStream, $aFFT, 2)
        If Not @error Then DllCall($ghGDIPDll, "int", "GdipFillPolygon", "handle", $hGfx_Buffer, "handle", $hBrush, "ptr", $aFFT[0], "int", $aFFT[1], "int", "FillModeAlternate")

        _GDIPlus_GraphicsDrawImage($hGraphics, $hBmp_Buffer, 0, 0)
    EndIf
WEnd
_Exit()



Func _CreateFFTBrush($iX, $iY, $iWidth, $iHeight)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
    Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)

    Local $hBrush_FFT = _GDIPlus_LineBrushCreate(0, 0, 0, $iHeight, 0, 0, 3)
    Local $aColors[5][2] = [[4]]
    $aColors[1][0] = 0xFFFF0000
    $aColors[1][1] = 0
    $aColors[2][0] = 0xFFFFAA00
    $aColors[2][1] = 0.25
    $aColors[3][0] = 0xFF00AAFF
    $aColors[3][1] = 0.5
    $aColors[4][0] = 0xFF00AAFF
    $aColors[4][1] = 1
    _GDIPlus_LineBrushSetPresetBlend($hBrush_FFT, $aColors)

    Local $hBrush_LED = _GDIPlus_LineBrushCreate(0, 0, 0, 4, 0xAA000000, 0x00000000, 0)

    _GDIPlus_GraphicsFillRect($hContext, 0, 0, $iWidth, $iHeight, $hBrush_FFT)
    _GDIPlus_GraphicsFillRect($hContext, 0, 0, $iWidth, $iHeight, $hBrush_LED)
    _GDIPlus_BrushDispose($hBrush_LED)
    _GDIPlus_BrushDispose($hBrush_FFT)
    _GDIPlus_GraphicsDispose($hContext)

    Local $hBrush = _GDIPlus_TextureCreate($hBitmap)
    _GDIPlus_BitmapDispose($hBitmap)

    DllCall($ghGDIPDll, "uint", "GdipTranslateTextureTransform", "hwnd", $hBrush, "float", $iX, "float", $iY, "int", 0)

    Return $hBrush
EndFunc   ;==>_CreateFFTBrush



Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmp_Buffer, 0, 0)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_PAINT

; #FUNCTION# ====================================================================================================================
; Author ........: Authenticity
; Modified.......: UEZ
; ===============================================================================================================================
Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iPixelFormat = $GDIP_PXF32ARGB, $iStride = 0, $pScan0 = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0


; #FUNCTION# ====================================================================================================================
; Author ........: Authenticity
; Modified.......: UEZ
; ===============================================================================================================================
Func _GDIPlus_LineBrushCreate($nX1, $nY1, $nX2, $nY2, $iARGBClr1, $iARGBClr2, $iWrapMode = 0)
    Local $tPointF1, $tPointF2, $aResult
    $tPointF1 = DllStructCreate("float;float")
    $tPointF2 = DllStructCreate("float;float")
    DllStructSetData($tPointF1, 1, $nX1)
    DllStructSetData($tPointF1, 2, $nY1)
    DllStructSetData($tPointF2, 1, $nX2)
    DllStructSetData($tPointF2, 2, $nY2)
    $aResult = DllCall($ghGDIPDll, "int", "GdipCreateLineBrush", "struct*", $tPointF1, "struct*", $tPointF2, "uint", $iARGBClr1, "uint", $iARGBClr2, "int", $iWrapMode, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[6]
EndFunc   ;==>_GDIPlus_LineBrushCreate


; #FUNCTION# ====================================================================================================================
; Author ........: Authenticity
; Modified.......: UEZ
; ===============================================================================================================================
Func _GDIPlus_LineBrushSetPresetBlend($hLineGradientBrush, $aInterpolations)
    Local $iI, $iCount, $tColors, $tPositions, $aResult
    $iCount = $aInterpolations[0][0]
    $tColors = DllStructCreate("uint[" & $iCount & "]")
    $tPositions = DllStructCreate("float[" & $iCount & "]")
    For $iI = 1 To $iCount
        DllStructSetData($tColors, 1, $aInterpolations[$iI][0], $iI)
        DllStructSetData($tPositions, 1, $aInterpolations[$iI][1], $iI)
    Next
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetLinePresetBlend", "handle", $hLineGradientBrush, "struct*", $tColors, "struct*", $tPositions, "int", $iCount)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_LineBrushSetPresetBlend


; #FUNCTION# ====================================================================================================================
; Author ........: Authenticity
; Modified.......: UEZ
; ===============================================================================================================================
Func _GDIPlus_TextureCreate($hImage, $iWrapMode = 0)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateTexture", "handle", $hImage, "int", $iWrapMode, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[3]
EndFunc   ;==>_GDIPlus_TextureCreate



Func _Exit()
    _BASS_StreamFree($hStream)
    _BASS_Free()

    _WM_COPYDATA_Shutdown()

    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGfx_Buffer)
    _GDIPlus_BitmapDispose($hBmp_Buffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>_Exit

And here's the Parent program, which you can run from SciTE.

#include "ExtMsgBox.au3"
#Include <WinAPIEx.au3>
#include 'WM_COPYDATA.au3'

;_WM_COPYDATA_SetID('MyUniqueIDC')  ; NOT SURE IF I NEED THIS

;Local $iControlID = _WM_COPYDATA_Start(Default) ; Start the communication process. NOT SURE IF I NEED THIS

$wPID = run ("FFT-Viz-WM_CopyData.exe")

sleep(2000)

_ExtMsgBox(0,0,"","press enter to reduce volume",0,1,1)
_WM_COPYDATA_Send(.2)  ;can WM_CopyData send values like this or must they be strings?


_ExtMsgBox(0,0,"","press enter to raise volume",0,1,1)
_WM_COPYDATA_Send(1)

_ExtMsgBox(0,0,"","press enter to exit",0,1,1)

$aData = _WinAPI_EnumProcessWindows ($wPID)
ConsoleWrite($aData[1][0] & @LF)
Sleep(2000)
$result = WinClose($aData[1][0])
ConsoleWrite ("winclose issued! Result = " & $result & @LF)
sleep (2000)

;_WM_COPYDATA_Shutdown()  ;NOT SURE IF I NEED THIS

Exit
Link to comment
Share on other sites

Can you try this:

 

Main.au3

#AutoIt3Wrapper_UseX64=n
#include "ExtMsgBox.au3"
#include <WindowsConstants.au3>

GUIRegisterMsg($WM_COPYDATA, '_WM_COPYDATA')
$TITLE_RECEIVER = 'FFT_Child_Window'
$wPID = Run("Child.exe")

Sleep(2000)

_ExtMsgBox(0, 0, "", "press enter to reduce volume", 0, 1, 1)
_SendData(WinGetHandle($TITLE_RECEIVER), 0.1)

_ExtMsgBox(0, 0, "", "press enter to raise volume", 0, 1, 1)
_SendData(WinGetHandle($TITLE_RECEIVER), 0.5)

_ExtMsgBox(0, 0, "", "press enter to exit", 0, 1, 1)

_SendData(WinGetHandle($TITLE_RECEIVER), -1)

Sleep(2000)

Exit

Func _SendData($hWnd, $sData)
    Local $tCOPYDATA, $tMsg

    $tMsg = DllStructCreate('char[' & StringLen($sData) + 1 & ']')
    DllStructSetData($tMsg, 1, $sData)
    $tCOPYDATA = DllStructCreate('dword;dword;ptr')
    DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
    $Ret = DllCall('user32.dll', 'lparam', 'SendMessage', 'hwnd', $hWnd, 'int', $WM_COPYDATA, 'wparam', 0, 'lparam', DllStructGetPtr($tCOPYDATA))
    If (@error) Or ($Ret[0] = -1) Then
        Return 0
    EndIf
    Return 1
EndFunc   ;==>_SendData

Func _WM_COPYDATA($hWnd, $msgID, $wParam, $lParam)

    Local $tCOPYDATA = DllStructCreate('dword;dword;ptr', $lParam)
    Local $tMsg = DllStructCreate('char[' & DllStructGetData($tCOPYDATA, 2) & ']', DllStructGetData($tCOPYDATA, 3))

    Return 0
EndFunc   ;==>_WM_COPYDATA

Child.au3

#AutoIt3Wrapper_UseX64=n

#include "Bass.au3"
#include "BassExt.au3"
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("MustDeclareVars", 1)


Global $sFile = FileOpenDialog("Open...", "", "playable formats (*.MP3;*.MP2;*.MP1;*.OGG;*.WAV;*.AIFF;*.AIF)", 3)
If @error Or Not FileExists($sFile) Then Exit

Global $iWidth = 522
Global $iHeight = 170

_GDIPlus_Startup()
Global $hGui = GUICreate("FFT_Child_Window", $iWidth, $iHeight, -1, -1, BitOR($WS_SYSMENU, $WS_POPUP))
GUISetState()

Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
Global $hBmp_Buffer = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
Global $hGfx_Buffer = _GDIPlus_ImageGetGraphicsContext($hBmp_Buffer)
_GDIPlus_GraphicsSetSmoothingMode($hGfx_Buffer, 2)

Global $hBrush = _CreateFFTBrush(5, 5, $iWidth - 10, $iHeight - 10)

Global $sMsg

_BASS_Startup()
_BASS_EXT_Startup()
_BASS_Init(0, -1, 44100, 0, "")

Global $hStream = _BASS_StreamCreateFile(False, String($sFile), 0, 0, $BASS_SAMPLE_FLOAT)
If Not $hStream Then _Exit()
Global $aFFT = _BASS_EXT_CreateFFT(128, 5, 5, $iWidth - 10, $iHeight - 10, 1, True)

_BASS_ChannelPlay($hStream, True)

Global $dummy = GUICtrlCreateDummy()

GUIRegisterMsg($WM_PAINT, "WM_PAINT")
GUIRegisterMsg($WM_COPYDATA, '_WM_COPYDATA')

While _BASS_ChannelIsActive($hStream)
    Switch GUIGetMsg()
        Case -3, $dummy ; allows Parent program to use WinClose to close this program.
            ExitLoop
    EndSwitch

    _GDIPlus_GraphicsClear($hGfx_Buffer, 0xFF110022)

    _BASS_EXT_ChannelGetFFT($hStream, $aFFT, 2)
    If Not @error Then DllCall($ghGDIPDll, "int", "GdipFillPolygon", "handle", $hGfx_Buffer, "handle", $hBrush, "ptr", $aFFT[0], "int", $aFFT[1], "int", "FillModeAlternate")

    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmp_Buffer, 0, 0)
WEnd

_Exit()

Func _WM_COPYDATA($hWnd, $msgID, $wParam, $lParam)
    Local $tCOPYDATA = DllStructCreate('dword;dword;ptr', $lParam)
    Local $tMsg = DllStructCreate('char[' & DllStructGetData($tCOPYDATA, 2) & ']', DllStructGetData($tCOPYDATA, 3))

    $sMsg = DllStructGetData($tMsg, 1)
    Switch $sMsg
        Case 0.0 To 1.0
            _BASS_SetVolume($sMsg)
        Case -1
            GUICtrlSendToDummy($Dummy)
    EndSwitch
    Return 0
EndFunc   ;==>_WM_COPYDATA

Func _CreateFFTBrush($iX, $iY, $iWidth, $iHeight)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
    Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)

    Local $hBrush_FFT = _GDIPlus_LineBrushCreate(0, 0, 0, $iHeight, 0, 0, 3)
    Local $aColors[5][2] = [[4]]
    $aColors[1][0] = 0xFFFF0000
    $aColors[1][1] = 0
    $aColors[2][0] = 0xFFFFAA00
    $aColors[2][1] = 0.25
    $aColors[3][0] = 0xFF00AAFF
    $aColors[3][1] = 0.5
    $aColors[4][0] = 0xFF00AAFF
    $aColors[4][1] = 1
    _GDIPlus_LineBrushSetPresetBlend($hBrush_FFT, $aColors)

    Local $hBrush_LED = _GDIPlus_LineBrushCreate(0, 0, 0, 4, 0xAA000000, 0x00000000, 0)

    _GDIPlus_GraphicsFillRect($hContext, 0, 0, $iWidth, $iHeight, $hBrush_FFT)
    _GDIPlus_GraphicsFillRect($hContext, 0, 0, $iWidth, $iHeight, $hBrush_LED)
    _GDIPlus_BrushDispose($hBrush_LED)
    _GDIPlus_BrushDispose($hBrush_FFT)
    _GDIPlus_GraphicsDispose($hContext)

    Local $hBrush = _GDIPlus_TextureCreate($hBitmap)
    _GDIPlus_BitmapDispose($hBitmap)

    DllCall($ghGDIPDll, "uint", "GdipTranslateTextureTransform", "hwnd", $hBrush, "float", $iX, "float", $iY, "int", 0)

    Return $hBrush
EndFunc   ;==>_CreateFFTBrush

Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmp_Buffer, 0, 0)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_PAINT

; #FUNCTION# ====================================================================================================================
; Author ........: Authenticity
; Modified.......: UEZ
; ===============================================================================================================================
Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iPixelFormat = $GDIP_PXF32ARGB, $iStride = 0, $pScan0 = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0


; #FUNCTION# ====================================================================================================================
; Author ........: Authenticity
; Modified.......: UEZ
; ===============================================================================================================================
Func _GDIPlus_LineBrushCreate($nX1, $nY1, $nX2, $nY2, $iARGBClr1, $iARGBClr2, $iWrapMode = 0)
    Local $tPointF1, $tPointF2, $aResult
    $tPointF1 = DllStructCreate("float;float")
    $tPointF2 = DllStructCreate("float;float")
    DllStructSetData($tPointF1, 1, $nX1)
    DllStructSetData($tPointF1, 2, $nY1)
    DllStructSetData($tPointF2, 1, $nX2)
    DllStructSetData($tPointF2, 2, $nY2)
    $aResult = DllCall($ghGDIPDll, "int", "GdipCreateLineBrush", "struct*", $tPointF1, "struct*", $tPointF2, "uint", $iARGBClr1, "uint", $iARGBClr2, "int", $iWrapMode, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[6]
EndFunc   ;==>_GDIPlus_LineBrushCreate


; #FUNCTION# ====================================================================================================================
; Author ........: Authenticity
; Modified.......: UEZ
; ===============================================================================================================================
Func _GDIPlus_LineBrushSetPresetBlend($hLineGradientBrush, $aInterpolations)
    Local $iI, $iCount, $tColors, $tPositions, $aResult
    $iCount = $aInterpolations[0][0]
    $tColors = DllStructCreate("uint[" & $iCount & "]")
    $tPositions = DllStructCreate("float[" & $iCount & "]")
    For $iI = 1 To $iCount
        DllStructSetData($tColors, 1, $aInterpolations[$iI][0], $iI)
        DllStructSetData($tPositions, 1, $aInterpolations[$iI][1], $iI)
    Next
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetLinePresetBlend", "handle", $hLineGradientBrush, "struct*", $tColors, "struct*", $tPositions, "int", $iCount)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_LineBrushSetPresetBlend


; #FUNCTION# ====================================================================================================================
; Author ........: Authenticity
; Modified.......: UEZ
; ===============================================================================================================================
Func _GDIPlus_TextureCreate($hImage, $iWrapMode = 0)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateTexture", "handle", $hImage, "int", $iWrapMode, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[3]
EndFunc   ;==>_GDIPlus_TextureCreate

Func _Exit()
    _BASS_StreamFree($hStream)
    _BASS_Free()

    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGfx_Buffer)
    _GDIPlus_BitmapDispose($hBmp_Buffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>_Exit

Compile Child.au3 and start Main.au3. Both scripts must be compiled as x86 because of Bass.dll and WM_COPYDATA code.

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

You should mention UEZ that your version will only work in AutoIt 32-bit.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

I did provide a version of WM_COPYDATA that works compiled as x86 and x64 in the form of a manageable UDF. The OP PM'd me earlier today in which I offered help, but they decided to seek advice from the Forum instead.

It seems you have completed the task. Thanks.

Edited by guinness

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

I saw your UDF but I've choosen Yashied's WM_COPYDATA example because it was faster for me to implement it for the code in post #1.

timmy2 can change it to your UDF if he wants but bass.dll is not working as x64 code.

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

I see that UEZ and Guinness have replied to my post but I've been offline working on a noob-compatible demonstration of the WM_CopyData function, to test my rudimentary understanding of it and to share it. Requires Guinness' WM_CopyData UDF (also provided below). Now that I understand it to this extent I hope I can get it to work with my FFT Visualizer and its test Parent.  :sweating:

"WM_Child.exe"

;"WM_Child" script to demonstrate WM_CopyData function by Guinness
;compile as WM_Child.exe so WM_Parent can run it

#include <Constants.au3>
#include 'WM_COPYDATA.au3'

_WM_COPYDATA_SetID('MyProgUniqueID') ; Create a unique ID.
Local $iWM_COPYDATA = _WM_COPYDATA_Start(Default) ; Start the _WM_COPYDATA message. The first parameter can be your GUI, otherwise it will create a hidden one.
Local $sWM_COPYDATA = ''

HotKeySet("{ESC}","_Exit")

Local $sText = "WM_Child is ready and waiting for a message." & @LF & @LF & "IPC Message: "
SplashTextOn ("WM_Child",$sText,300,200, 0,0,4)

While 1
    Switch GUIGetMsg()
        Case $iWM_COPYDATA ; If the message from the WM_Parent is picked up.
            $sWM_COPYDATA = _WM_COPYDATA_GetData()  ; Get message from WM_Parent
            Switch $sWM_COPYDATA
                Case "Quit"  ; received if user clicked Cancel button
                    _Exit()
                Case "xxx"  ; received if user enterd nothing
                    $sWM_COPYDATA = "(nothing entered)"
            EndSwitch

            ControlSetText ("WM_Child","","Static1", $sText & $sWM_COPYDATA)
    EndSwitch
WEnd

Func _Exit()
    _WM_COPYDATA_Shutdown()  ; shutdown WM_COPYDATA
    SplashOff()
    Exit
EndFunc

WM_Parent

;"WM_Parent" script to demonstrate WM_CopyData function by Guinness
;requires WM_Child.exe present in same folder

#include <Constants.au3>
#include 'WM_COPYDATA.au3'

If FileExists ("WM_Child.exe") then
    Run("WM_Child.exe")
Else
    Beep(300,200)
    SplashTextOn("ERROR","WM_Child.exe not found!",300,75)
    Sleep(2000)
    _Exit()
EndIf

WinWait ("WM_Child")

_WM_COPYDATA_SetID('MyProgUniqueID') ; Create a unique ID.
_WM_COPYDATA_Start(Default) ; Start the _WM_COPYDATA message for the parent script as well. This will grab details about the Child script if it's already running.

While 1

    $sMessage = InputBox("WM_Parent", "Enter value to send to Child: " & @LF & @LF & "(or Cancel to close all)")
    If @Error Then _Exit()
    If $sMessage = "" then $sMessage = "xxx"  ; if user just presses Enter still send something
    _WM_COPYDATA_Send($sMessage) ; Send IPC message

WEnd


Func _Exit()
    _WM_COPYDATA_Send("Quit") ; Send IPC message
    _WM_COPYDATA_Shutdown()  ; Close process
    Exit
EndFunc

Get WM_COPYDATA.au3 UDF >here.

Edited by timmy2
Link to comment
Share on other sites

93fb.jpg Ack!

Thank you, UEZ, these scripts work great!  I have specific questions about your code because you didn't use Guinness' WM_CopyData UDF so I'm back in uncharted territory. I sure hope you'll answer them, because your working scripts (versus my non-working scripts) are quite tempting.  However, I would like to fully understand them, not simply use them.

First, though, If I inadvertently used code intended for 64-bit that was pure keyboard monkey behavior. I don't have the 64b AutoIt installed nor do I want to create any 64b scripts yet. As far as I know my previous post is 32-bit so the few elements of Guinness' UDF that I used must be 32-bit compatible. My impression about BASS is that it is also 32-bit, which must be what you mean by, "bass.dll is not working as x64 code."


Your Parent Script

The most noticeable aspect of your IPC solution, besides not using an external UDF, is there's no ID established before the Parent can send messages addressed to the Child. I assume you accomplish the same thing in the following two lines of code. Please explain in simple, almost-layman terms what each line does, because the Help file explanation of GUIRegisterMsg relies on understanding "Windows Message ID's", which is not in the average AutoIt Beginners lexicon. (Any time a definition relies on understanding the definition of something else equally as advanced, pushes my stack one level too deep.)

GUIRegisterMsg($WM_COPYDATA, '_WM_COPYDATA')$sTITLE_RECEIVER = 'FFT_Child_Window'

Maybe I even understand why you don't need an ID: you already know the Child's Window Title so a simple WinGetHandle provides Child's handle to your own _SendData() function. I assume Yashied's WM_CopyData implementation doesn't need a _Start or _Shutdown, either. Nice, I guess... (I doubt Guinness included them for grins -- he must've had a reason).

I understand why you ditched my use of the WinAPIEx UDF, _WinAPI_EnumProcessWindows, and WinClose: because the Parent is able to close the Child at the end using IPC.


Your Child script.

I started with a very recent post by Eukalyptus of his FFT Visualizer for the Autoit 3.3.8.1, so I'm very curious about any changes you made to it besides changing IPC-related commands.

As in the Parent, you use no ID, _Start or _Shutdown commands.

I'm curious about the line you added just after starting up BASS. (Does it cause an exit if the sound file reaches the end?)

If Not $hStream Then _Exit()  ;  WHAT DOES THIS ACCOMPLISH?

You also added the following line:

Global $dummy = GUICtrlCreateDummy()

... which creates a Dummy control you use later in the pivotal "_WM_COPYDATA function. I've never used this before but maybe the Help file Example will demonstrate its usefulness.


Where it really gets interesting to me (and therefore needs your explanation) is in Eukalyptus' main While/WEnd loop, which I believe displays the FFT visualization. In his latest implementation he added...

Global $iTimer = TimerInit()While _BASS_ChannelIsActive($hStream)    If TimerDiff($iTimer) > 20 Then...    $iTimer = TimerInit()EndIf

which did not exist in his original demonstration script. You removed his new timer-related code. Why?


Also, you left in my code for using WinClose in the parent to close the Child program, but you no longer use WinClose in your Parent script.

Switch GUIGetMsg()        Case -3, $dummy ; allows Parent program to use WinClose to close this program.            ExitLoop    EndSwitch

Can this Switch statement be removed from the Parent script?


Even more significant to me is I thought I would need to look for IPC messages (_WM_COPYDATA_GetData()) inside the main While/WEnd loop, but you don't do it. In fact -- and this is really what puzzles me -- you make volume level changes in a new _WM_COPYDATA function that I don't see referred to anywhere else in your Child script? Being the noob that I am, this qualifies as magic.

Please, UEZ, explain how volume control messages are received and handled.

Also, how does a value of -1 sent via IPC from the Parent interrupt the Child's While/WEnd loop, and then use GUICtrlSendToDummy() to go to the _Exit function? Try to keep your explanation in near-layman terminology so I can really understand what's going on here.

Edited by timmy2
Link to comment
Share on other sites

Your post with my UDF demonstrates you understanding of how the UDF works. So I see you now have to implement this into your application, which only you can do really.

Edited by guinness

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

I don't have the 64b AutoIt installed

That's not true. If have AutoIt installed then automatically the x64 files are installed, too. Just look in the AutoIt dir and look for *_x64.* files.

 

 

My impression about BASS is that it is also 32-bit, which must be what you mean by, "bass.dll is not working as x64 code."

When you compile your code as x64 executable and call the bass.dll then probably you code will crash because bass.dll is not x64 compatible. When you start Child.au3 you will have noticed the output:

!Bass.dll is for 32bit only!
Run/compile Script at 32bit

 

 

Your Parent Script

GUIRegisterMsg($WM_COPYDATA, '_WM_COPYDATA')

$sTITLE_RECEIVER = 'FFT_Child_Window'

Using GUIRegisterMsg is a technique to initiate a callback to your function. That means whenever a trigger from the operating system is sent regarding the WM_*  message id you can check it in your function. Here it is done in _WM_COPYDATA function.

As you can see in the variable name the function _SendData uses the GUI name 'FFT_Child_Window' to send information. It would make sense to use here a more unique name rather than a standard name. I didn't test what will happen when more than 1 GUI exits with the same name.

guinness' UDF is based on Yashied's original code but completely redesigned to use it as an UDF.

 

I understand why you ditched my use of the WinAPIEx UDF, _WinAPI_EnumProcessWindows, and WinClose: because the Parent is able to close the Child at the end using IPC.

Because it is not needed anymore. The closure of the child process is also done using WM_COPYDATA.

 

 

If Not $hStream Then _Exit()  ;  WHAT DOES THIS ACCOMPLISH?

This is only a check whether _BASS_StreamCreateFile returns an handle otherwise something went wrong loading the audio file, e.g. corrupted, etc.

 

 

 

I used this function to send the exit trigger to GUIGetMsg(). There is no need in Main.au3 to close the GUI.

 

Switch GUIGetMsg()        

Case -3, $dummy ; allows Parent program to use WinClose to close this program.            

ExitLoop    

EndSwitch

 

-3 is needed only when you want to close the child GUI using the ESC key or by WinClose function. But the GUIGetMsg check is needed for GUICtrlSendToDummy($Dummy)!

 

 

Global $iTimer = TimerInit()While _BASS_ChannelIsActive($hStream)    If TimerDiff($iTimer) > 20 Then...    $iTimer = TimerInit()EndIf

 

Using this timer function causes high CPU load and I cannot see any purpose to use a timer in this loop.

 

 

Please, UEZ, explain how volume control messages are received and handled.

 

The main script sends its first "command" to the child process using this command:

_SendData(WinGetHandle($TITLE_RECEIVER), 0.1)

That means the child process will receive the value 0.1 _WM_COPYDATA function. There, if the sent value is a proper one, it will decide what to do.

$sMsg = DllStructGetData($tMsg, 1)
    Switch $sMsg
        Case 0.0 To 1.0
            _BASS_SetVolume($sMsg)
        Case -1
            GUICtrlSendToDummy($Dummy)
    EndSwitch

We assume that values from 0 to 1 are related to the sound volume. If the child process receives a -1 then the closure of the child process will be initiated by sending the dummy trigger. This will cause the GUIGetMsg to recive the $dummy value which will exit the loop and thus call the _Exit function.

 

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Just as an FYI, BASS is available as a set of 64bit dlls .

http://www.un4seen.com/bass.html

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Right BrewManNH, I forgot to mention it that also x64 DLL are available.

Thx,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...