Jump to content

Click not recognised via WM_NOTIFY


Der_Andi
 Share

Recommended Posts

Hi,

during runtime of a on-event function I use WM_NOTIFY to capture any click on a button. But the command, which determines the mouse action ...

DllStructGetData($tNMHDR, "code")

... does not return $NM_CLICK (-2), but a lot of $NM_CUSTOMDRAW (-12). It doesn't matter, if I click or just hover over this button. It's always -12.

Any idea, what this means or how I can detect the normal click?

Andi

PS:

I'll try to write a short example script, but I'm not sure if it will reproduce the problem.

Until then, I'll give you the real script, but it's quite long though.

Attention: This script probably will not run on your machine, as this program reads in some specific folder and expects a specific folder structure.

The interesting part:

At the beginning of the script, the main gui is built. There, a button $btnSync is linked to the function sync(). This functions creates the child gui and does some file operations. The child gui has the button $btnStopClose, which won't be linked to a function until file operations are completed. The problem does not occur because of the file operations, as they are taken care of a second script. So, the gui stays responsive.

In WM_NOTIFY() at the end of the script I try to capture a click on the button $btnStopClose. This doesn't work right. The line commented as "debug" prints "-12" 6 times, when I click that button once.

Tipp: the functions are sorted alphabetically.

#NoTrayIcon
Opt("GuiOnEventMode", 1)

#include <Constants.au3> ;loads $ICON_IMAGE for splash
#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <TreeViewConstants.au3>
#include <GuiTreeView.au3>
#include <ButtonConstants.au3>
#include <GuiListView.au3>
#include <GDIPlus.au3>
#include <ProgressConstants.au3>

#include <Array.au3>
#include <ArrayAdd2D.au3>
#include <ExtProp.au3>
#include <File.au3>
#include <WinAPI.au3>
#include <Icons.au3>
#include <Color.au3>

;Vars
$localSite = "C:\Users\Andreas\Music\"
$remoteDrive = ""
$remoteMusic = ""
$remoteVideo = ""
$remoteSite = ""
$extPath = @AutoItExe & ' ' & @ScriptDir & '\extCopy.au3 '

$loadText = "Musik-Sammlung wird geladen...  "
$formatInfotext = "Was soll gelöscht werden?"

;Internal vars
$fontSize = 9
$fontName = "Segoe UI"

Global $aLocalAlbums
Global $aRemoteAlbums
Global $playerStatus = False
Global $playerConnected = True
Global $playerDisconnected = False
Global $wmAlbumAdded = False
Global $wmAlbumRemoved = False
Global $flagNew = "new"
Global $flagRemoved = "delete"
Global $flagNull = ""
Global $colorNew = 0x00c000
Global $colorRemoved = 0xc00000
Global $ColorNull = 0x000000
Global $guiTracks
Global $lastClickedTree
Global $lastClickedAlbumsArray
Global $lstTitles
Global $prgLoad
Global $lblLoad
Global $guiSplash = 0
Global $guiFormat
Global $musicSize
Global $videoSize
Global $btnFormatClose
Global $btnFormatMusic
Global $btnFormatVideo
Global $lblMusicSize
Global $lblVideoSize
Global $lblInfo
Global $guiSync
Global $lblSync
Global $prgSync
Global $btnStopClose
Global $stopSync = False


$guiWidth = 920
$guiHeight = 720
$guiBottom = 40
$guiMain = GUICreate("mp3.Sync", $guiWidth, $guiHeight)
GUISetOnEvent($gui_event_close, "quit", $guiMain)
GUISetFont($fontSize, 400, 0, $fontName, $guiMain, 0)
GUISetIcon("walkman.ico", 0, $guiMain)

;Local tree
GUICtrlCreateLabel("Lokale Musik-Sammlung:", 10, 10, $guiWidth/2-10-5, 20, $ss_centerimage)
GUICtrlSetFont(-1, -1, 600)
GUICtrlSetColor(-1,0x0000ff)
$treeLocal = GUICtrlCreateTreeView(10, 30, $guiWidth/2-5-10, $guiHeight-$guiBottom-120-20, _
    BitOR($TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_FULLROWSELECT), _
    $ws_ex_clientedge)

;Remote tree
GUICtrlCreateLabel("Musik auf dem Walkman:", $guiWidth/2+5, 10, $guiWidth/2-5-10, 20, $ss_centerimage)
GUICtrlSetFont(-1, -1, 600)
GUICtrlSetColor(-1,0x0000ff)
$treeRemote = GUICtrlCreateTreeView($guiWidth/2+5, 30, $guiWidth/2-10-5, $guiHeight-$guiBottom-120-20, _
    BitOR($TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_FULLROWSELECT), _
    $ws_ex_clientedge)


;Album infos
GUICtrlCreateLabel("Infos zum Album:", 10, $guiHeight-$guiBottom-90, 150, 20, $ss_centerimage)
GUICtrlSetFont(-1, -1, 600)
GUICtrlSetColor(-1,0x0000ff)
GUICtrlCreateButton("Details", $guiWidth/2-5-60, $guiHeight-$guiBottom-94, 60, 20)
GUICtrlSetOnEvent(-1, "showAlbumTracks")

GUICtrlCreateLabel("", 10, $guiHeight-$guiBottom-70, $guiWidth/2-5-10, 2, $ss_sunken)

GUICtrlCreateLabel("Größe:", 10+20, $guiHeight-$guiBottom-60, 70, 20, $ss_centerimage)
GUICtrlSetFont(-1, -1, 600)
$lblAlbumSize = GUICtrlCreateLabel("", 10+110, $guiHeight-$guiBottom-60, $guiWidth/2-5-110, 20, $ss_centerimage)

GUICtrlCreateLabel("Titel:", 10+20, $guiHeight-$guiBottom-40, 70, 20, $ss_centerimage)
GUICtrlSetFont(-1, -1, 600)
$lblAlbumTitles = GUICtrlCreateLabel("", 10+110, $guiHeight-$guiBottom-40, $guiWidth/2-5-110, 20, $ss_centerimage)

GUICtrlCreateLabel("Laufzeit:", 10+20, $guiHeight-$guiBottom-20, 70, 20, $ss_centerimage)
GUICtrlSetFont(-1, -1, 600)
$lblAlbumRuntime = GUICtrlCreateLabel("", 10+110, $guiHeight-$guiBottom-20, $guiWidth/2-5-110, 20, $ss_centerimage)

;Player infos
GUICtrlCreateLabel("Infos zum Player:", $guiWidth/2+5, $guiHeight-$guiBottom-90, 150, 20, $ss_centerimage)
GUICtrlSetFont(-1, -1, 600)
GUICtrlSetColor(-1,0x0000ff)

GUICtrlCreateLabel("", $guiWidth/2+5, $guiHeight-$guiBottom-70, $guiWidth/2-5-10, 2, $ss_sunken)

GUICtrlCreateLabel("Speicher:", $guiWidth/2+5+20, $guiHeight-$guiBottom-60, 70, 20, $ss_centerimage)
GUICtrlSetFont(-1, -1, 600)
$lblPlayerMemory = GUICtrlCreateLabel("", $guiWidth/2+5+110, $guiHeight-$guiBottom-60, $guiWidth/2-5-10-110, 20, $ss_centerimage)

;Usage bar
GUICtrlCreateLabel("Belegung:", $guiWidth/2+5+20, $guiHeight-$guiBottom-40, 70, 20, $ss_centerimage)
GUICtrlSetFont(-1, $fontSize, 600)

GUICtrlCreateLabel("", $guiWidth/2+5+110, $guiHeight-$guiBottom-36, $guiWidth/2-5-10-110, 12, $ss_grayframe)
Dim $aUsagePos[2] = [$guiWidth/2+5+110 + 2, $guiHeight-$guiBottom-36 + 2]   ;left, top
$usageWidth = $guiWidth/2-5-10-110 - 4
$lblUsage = GUICtrlCreateLabel("", $aUsagePos[0], $aUsagePos[1], $usageWidth, 8)
GUICtrlSetBKColor(-1, $GUI_BKCOLOR_TRANSPARENT)

;Warning icon
$icoWarning = GUICtrlCreateIcon("shell32.dll", -78, $guiWidth/2+5, $guiHeight-$guiBottom-38, 16, 16)
GUICtrlSetState(-1, $gui_hide)

;Buttons
$btnSync = GUICtrlCreateButton("Sync", $guiWidth-10-80, $guiHeight-25-10, 80, 25)
GUICtrlSetFont(-1, $fontSize, 600)
GUICtrlSetOnEvent(-1, "sync")

$btnFormat = GUICtrlCreateButton("Formatieren", $guiWidth-10-80-10-80, $guiHeight-25-10, 80, 25)
GUICtrlSetOnEvent(-1, "showFormatGui")

$btnReset = GUICtrlCreateButton("Reset", $guiWidth-10-80-10-80-10-80, $guiHeight-25-10, 80, 25)
GUICtrlSetOnEvent(-1, "resetSelections")
GUICtrlSetState(-1, $gui_disable)




showSplashGui()
load($treeLocal, $localSite)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW, $guiMain)
While True
    Sleep(500)

    ;Check if status has changed
    checkPlayerStatus()

    ;Check for added or removed albums
    checkAlbumMovement()

WEnd


Func addAlbumToPlayer()
    ;Get index of selected album
    $id = GUICtrlRead($treeLocal)
    $index = _ArraySearch($aLocalAlbums, $id, 1, 0, 0, 0, 1, 4) ;col 4 holds album id
    If $index = -1 Then Return

    ;Check, if album already exists on remote site
    ;Search artist forward and if exist, search backward and then search album.
    ;If album exists with $flagRemoved, set to $flagNull; without this flag just exit.
    ;If album or artist does not exist at all, add album to remote site (outer else-part).
    $artist = $aLocalAlbums[$index][0]
    $album = $aLocalAlbums[$index][1]
    $fwd = _ArraySearch($aRemoteAlbums, $artist, 1, 0, 0, 0, 1, 0)  ;get index by forward search
    $bwd = _ArraySearch($aRemoteAlbums, $artist, 1, 0, 0, 0, 0, 0)  ;index by backward search
    If $fwd = -1 Then   ;artist not found. album search not relevant then.
        $result = -1
    Else
        $result = _ArraySearch($aRemoteAlbums, $album, $fwd, $bwd, 0, 0, 1, 1)  ;search album between
    EndIf

    If $result > -1 Then
        If $aRemoteAlbums[$result][5] = $flagRemoved Then   ;check flag
            $aRemoteAlbums[$result][5] = $flagNull  ;set default flag
        Else
            print("Album already on remote site.")
            ;TODO
            Return
        EndIf
    Else
        ;Get complete row from array at index
        $row = getArrayRow($aLocalAlbums, $index)

        ;Add to remote array, increase counter and set flag for added album (=last)
        _ArrayAdd2D($aRemoteAlbums, $row)
        $aRemoteAlbums[0][0] += 1
        $aRemoteAlbums[$aRemoteAlbums[0][0]][5] = $flagNew
        $aRemoteAlbums[$aRemoteAlbums[0][0]][6] = getAlbumSize($localSite & $artist & "\" & $album, 0)

        ;Sort albums by artist and by year
        _ArraySort($aRemoteAlbums, 0, 1)
        sortAlbumsByYear($aRemoteAlbums)

        ;Rebuild remote tree
        buildTree($aRemoteAlbums, $treeRemote)
    EndIf


EndFunc


Func buildTree(ByRef $aAlbums, $treeID)
    ;Builds the tree according to albums array, copy complete array to global variable
    ;and update all data

    Dim $aItems[1] = [0]
    _GUICtrlTreeView_DeleteAll($treeID)

    ;iterate through array and build tree
    $prev = ""
    For $i = 1 To $aAlbums[0][0]
        ;new artist? create artist item
        If $aAlbums[$i][0] <> $prev Then
            _ArrayAdd($aItems, GUICtrlCreateTreeViewItem($aAlbums[$i][0], $treeID))
            $aItems[0] += 1
            $prev = $aAlbums[$i][0] ;save current artist name
        EndIf
        $albumItem = GUICtrlCreateTreeViewItem($aAlbums[$i][1], $aItems[$aItems[0]])
        GUICtrlSetOnEvent($albumItem, "displayAlbumInfo")   ;register function

        ;Mark standard/new/deleted albums
        Switch $aAlbums[$i][5]
            Case $flagNew
                GUICtrlSetColor($albumItem, $colorNew)
            Case $flagRemoved
                GUICtrlSetColor($albumItem, $colorRemoved)
            Case Else
                GUICtrlSetColor($albumItem, $ColorNull)
        EndSwitch

        ;save ctrl-id's for later reference
        $aAlbums[$i][3] = $aItems[$aItems[0]]
        $aAlbums[$i][4] = $albumItem
    Next

    ;Allocate to the right array
    If $treeID = $treeLocal Then
        $aLocalAlbums = $aAlbums
    Else
        $aRemoteAlbums = $aAlbums
    EndIf

    ;Update player infos
    If $treeID = $treeRemote Then displayPlayerInfo()

    ;Make all artist items bold and expanded
    For $i = 1 To $aItems[0]
        GUICtrlSetState($aItems[$i], $gui_defbutton + $gui_expand)
    Next
    If $aAlbums[0][0] > 0 Then
        _GUICtrlTreeView_EnsureVisible($treeID, $aItems[1]) ;makes the treeview scroll up
    EndIf

    ;Check changed -> reset button
    For $i = 1 To $aAlbums[0][0]
        If $aAlbums[$i][5] <> $flagNull Then
            GUICtrlSetState($btnReset, $gui_enable)
            GUICtrlSetState($btnSync, $gui_enable)
            Return
        EndIf
    Next
    GUICtrlSetState($btnReset, $gui_disable)
    GUICtrlSetState($btnSync, $gui_disable)

EndFunc


Func checkAlbumMovement()
    ;Check flag, if album needs be added/removed
    ;$lastClickedTree will hold the right tree ID
    Select
        Case $wmAlbumAdded
            $wmAlbumAdded = False
            addAlbumToPlayer()
        Case $wmAlbumRemoved
            $wmAlbumRemoved = False
            removeOrLeaveAlbumOnPlayer()
    EndSelect
EndFunc


Func checkPlayerStatus()
    ;Check if player is connected/deconnected
    $status = getPlayerStatus()
    If $status() <> $playerStatus Then
        $playerStatus = $status
        load($treeRemote, $remoteSite)
    EndIf
EndFunc


Func closeFormatGui()
    ;close format  gui and reactivate main gui
    GUIDelete($guiFormat)
    GUISetState(@SW_ENABLE, $guiMain)
    GUISetState(@SW_RESTORE, $guiMain)
    GUISwitch($guiMain)
EndFunc


Func closeSplashGui()
    If $guiSplash = 0 Then Return

    GUIDelete($guiSplash)
    $guiSplash = 0
EndFunc


Func closeSyncGui()
    ;close sync gui and reactivate main gui
    GUIDelete($guiSync)
    GUISetState(@SW_ENABLE, $guiMain)
    GUISetState(@SW_RESTORE, $guiMain)
    GUISwitch($guiMain)
EndFunc


Func closeTracksGui()
    ;close title gui and reactivate main gui
    GUIDelete($guiTracks)
    GUISetState(@SW_ENABLE, $guiMain)
    GUISetState(@SW_RESTORE, $guiMain)
    GUISwitch($guiMain)
EndFunc


Func createAlbumsArray()
    ;Create the array for the albums.
    ;It holds: artist name, album name, release year, artist tvi ID, album tvi ID, new/delete flag
    Dim $album[1][7] = [[0]]
    Return $album
EndFunc


Func displayAlbumInfo()
    ;Display information about current selected album

    $id = GUICtrlRead($lastClickedTree)
    $index = _ArraySearch($lastClickedAlbumsArray, $id, 1, 0, 0, 0, 1, 4)   ;col 4 holds album id
    $artist = $lastClickedAlbumsArray[$index][0]
    $album = $lastClickedAlbumsArray[$index][1]

    ;Override to local albums array, if album is flagged as new
    If $lastClickedAlbumsArray[$index][5] = $flagNew Then
        $lastClickedAlbumsArray = $aLocalAlbums
    EndIf

    ;Update information about selected album
    If $index > -1 Then
        $albumSite = $lastClickedAlbumsArray[0][2] & $artist & "\" & $album & "\"
        $aInfo = getAlbumSize($albumSite, 1)    ;full array
        GUICtrlSetData($lblAlbumSize, Round($aInfo[0], 1) & " MB")
        GUICtrlSetData($lblAlbumTitles, $aInfo[1])
        GUICtrlSetData($lblAlbumRuntime, $aInfo[3] & " min")

    EndIf
EndFunc


Func displayPlayerInfo()


    If $playerStatus = $playerConnected Then
        ;Text info
        $total = getPlayerTotal()
        $free = getPlayerFree()
        $used = $total - $free
        $additions = getPlayerAdditions()

        $new_free = $free - $additions
        If $new_free < 0 Then
            $new_free = 0
        EndIf

        $stats = Round($total / 1024, 0)  & " GB / " & Round($new_free, 1) & " MB frei"
        GUICtrlSetData($lblPlayerMemory, $stats)

        ;Graphical info
        $new_used = $used + $additions
        $p = Round($new_used * 100 / $total, 0)
    Else
        GUICtrlSetData($lblPlayerMemory, "")
        $p = 0
    EndIf
    setPlayerUsage($p)
EndFunc


Func formatMedia($dir)
    ;Delete all content from the MUSIC folder

    ;Lock buttons
    GUICtrlSetState($btnFormatVideo, $gui_disable)
    GUICtrlSetState($btnFormatMusic, $gui_disable)
    GUICtrlSetState($btnFormatClose, $gui_disable)

    GUICtrlSetData($lblInfo, "Löschen...")
    GUICtrlSetStyle($lblInfo, $ss_center + $ss_centerimage)

    ;Delete
    $aFolders = _FileListToArray($dir, "*", 2)
    If @error = 0 Then
        For $i = 1 To $aFolders[0]
            DirRemove($dir & $aFolders[$i], 1)
        Next
    EndIf

    updateFormatGui()
    GUICtrlSetData($lblInfo, $formatInfotext)
    GUICtrlSetStyle($lblInfo, $ss_left + $ss_centerimage)
    GUICtrlSetState($btnFormatClose, $gui_enable)

    load($treeRemote, $remoteSite)
EndFunc


Func formatMusic()
    formatMedia($remoteDrive & $remoteMusic)
EndFunc


Func formatVideo()
    formatMedia($remoteDrive & $remoteVideo)
EndFunc


Func getAlbumRuntime($dir)
    ;Get total runtime of the album

    $aFiles = _FileListToArray($dir, "*.mp3", 1)    ;1 = files only
    If @error = 4 Then Return "n/a"

    $hour = 0
    $min = 0
    $sec = 0
    For $i = 1 To $aFiles[0]
        $time = _GetExtProperty($dir & $aFiles[$i], 27) ;27 is duration
        $parts = StringSplit($time, ":")
        $hour += $parts[1]
        $min += $parts[2]
        $sec += $parts[3]
    Next
    Return StringFormat("%02i:%02i", $hour * 60 + $min + Floor($sec / 60), Mod($sec, 60))
EndFunc


Func getAlbumsFromSite($site)
    ;Go through music folder and create an array with artits, albums and year
    Local $aThisAlbums

    ;Create an array for the albums
    $aThisAlbums = createAlbumsArray()

    ;Get artists
    $aArtists = _FileListToArray($site, "*", 2) ;folders
    If @error Then Dim $aArtists[1] = [0]   ;nothing found, skip next for-loop

    ;Iterate through artists
    For $i = 1 To $aArtists[0]
        ;Don't need number of artists/misc stuff
        If StringLeft($aArtists[$i], 1) = "_" Then ContinueLoop

        ;Update splash
        updateSplashGui($loadText & $aArtists[$i])

        ;Get albums of current artist
        $artistSite = $site & $aArtists[$i] & "\"
        $aAlbums = _FileListToArray($artistSite, "*", 2)
        If @error Then ContinueLoop

        ;Iterate through these albums
        For $k = 1 To $aAlbums[0]
            If StringLeft($aAlbums[$k], 1) = "_" Then ContinueLoop

            $albumSite = $artistSite & $aAlbums[$k] & "\"

            ;Check, if album folder is empty
            $aDir = DirGetSize($albumSite, 1)
            If $aDir[1] = 0 Then ContinueLoop

            $year = getAlbumYear($albumSite)
            _ArrayAdd2D($aThisAlbums, $aArtists[$i] & "|" & $aAlbums[$k] & "|" & $year)
            $aThisAlbums[0][0] += 1
        Next

        ;Update splash
        updateSplashGui("", Round($i * 100 / $aArtists[0], 0))
    Next

    ;Close splash
    closeSplashGui()

    ;Sort array by artist and then by year
    If UBound($aThisAlbums) > 1 Then
        _ArraySort($aThisAlbums, 0, 1)
        sortAlbumsByYear($aThisAlbums)
    EndIf
    Return $aThisAlbums
EndFunc


Func getAlbumSize($albumSite, $full=0)
    ;Returns the size of the specified album.
    ;$index refers to position in $aAlbums
    ;$full = 1 runs DirGetSize() in extended mode.

    $size = DirGetSize($albumSite, $full)
    If IsArray($size) Then
        $size[0] /= (1024*1024)
        _ArrayAdd($size, getAlbumRuntime($albumSite))
    Else
        $size /= (1024*1024)
    EndIf
    Return $size
EndFunc


Func getAlbumYear($albumSite)
    ;Determine the release year of the album.
    ;Will read the year of the first file

    $aFiles = _FileListToArray($albumSite, "*.mp3", 1)
    $year = _GetExtProperty($albumSite & $aFiles[1], 15)
    Return $year
EndFunc


Func getArrayRow($array, $index)
    ;Returns a complete row of an array as delimited string
    Local $row

    If Not IsArray($array) Then Return -1
    If $index > UBound($array) - 1 Then Return -1
    For $i = 0 To UBound($array, 2) - 1
        $row &= $array[$index][$i] & "|"
    Next
    Return StringTrimRight($row, 1)
EndFunc


Func getFilesToSync()
    ;Returns an array with the files to sync in the pattern artist\album\*.mp3
    Local $aFiles[1] = [0]
    For $i = 1 To $aRemoteAlbums[0][0]
        If $aRemoteAlbums[$i][5] <> $flagNew Then ContinueLoop

        $artist = $aRemoteAlbums[$i][0] & "\"
        $album = $aRemoteAlbums[$i][1] & "\"
        $albumSite = $localSite & $artist & $album
        $aMP3 = _FileListToArray($albumSite, "*.mp3", 1)
        For $k = 1 To $aMP3[0]
            _ArrayAdd($aFiles, $artist & $album & $aMP3[$k])
            $aFiles[0] += 1
        Next
    Next
    Return $aFiles
EndFunc


Func getPlayerAdditions()
    ;Calculates the amount of data. Size of new albums are added, removed ones will be subtracted
    Local $additions = 0
    For $i = 1 To $aRemoteAlbums[0][0]
        Switch $aRemoteAlbums[$i][5]
            Case $flagRemoved
                $additions -= $aRemoteAlbums[$i][6]
            Case $flagNew
                $additions += $aRemoteAlbums[$i][6]
        EndSwitch
    Next
    Return $additions
EndFunc


Func getPlayerFree()
    ;Returns the free space on player in MB
    Return DriveSpaceFree($remoteDrive)
EndFunc


Func getPlayerStatus()
    ;Find out, if player is connected
    $aDrives = DriveGetDrive("REMOVABLE")
    If Not IsArray($aDrives) Then Return False
    For $i = 1 To $aDrives[0]
        $dir = StringUpper($aDrives[$i]) & "\MUSIC\"
        If DriveStatus($aDrives[$i]) <> "READY" Then ContinueLoop
        If FileExists($dir) Then
            $remoteDrive = StringUpper($aDrives[$i]) & "\"
            $remoteMusic = "MUSIC\"
            $remoteVideo = "VIDEO\"
            $remoteSite = $dir
            Return True
        EndIf
    Next
    Return False
EndFunc


Func getPlayerTotal()
    ;Returns the total capacity of the player in MB
    Return DriveSpaceTotal($remoteDrive)
EndFunc


Func getProgressColor($p)
    ;Returns a color value according to percental usage of player.
    ;Color will change from green over yellow to red.
    ;Green will start changing into yellow at $p = 50.
    ;0 - $threshold represents the area between 0 - 510, because
    ;color changes earliest at $threshold (50), the percentage area
    ;must be shifted to 0-50, to get the calculation right
    ;The color is calculated by the rule of three (Dreisatz).

    Local $threshold = 50, $aRGB[3] = [0, 255, 0]   ;green as standard

    Select
        Case $p = 0
            Return $GUI_BKCOLOR_TRANSPARENT
        Case $p >= $threshold And $p < 100
            ;Calculate color value, if percentage is beyond threshold
            $colorWidth = 510       ;raise RED to 255, then lower GREEN to 0 ==> 510 in total

            ;divide colorWidth by threshold and multply by shifted percentage
            $targetValue = Round($colorWidth / $threshold * ($p - $threshold), 0)
            $aRGB[0] += $targetValue    ;raise RED -> will get yellow
            If $aRGB[0] > 255 Then      ;if RED exceeds 255...
                $aRGB[1] -= $aRGB[0] - 255      ;... remove it from GREEN --> will get red
                $aRGB[0] = 255      ;set RED to valid maximum
            EndIf
        Case $p >= 100
            $aRGB[0] = 96
            $aRGB[1] = 0
    EndSelect
    Return _ColorSetRGB($aRGB)  ;return hex value
EndFunc


Func getTextLengthInPixel($text, $font, $size = 9, $style = 0)
    ;Calculate actual width of the given text
    _GDIPlus_Startup()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($guiMain)
    $hFamily = _GDIPlus_FontFamilyCreate($font)
    $hGDIFont = _GDIPlus_FontCreate($hFamily, $size, $style)
    $hFormat = _GDIPlus_StringFormatCreate()
    $tLayout = _GDIPlus_RectFCreate(0, 0, @DesktopWidth, @DesktopHeight)

    $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $text, $hGDIFont, $tLayout, $hFormat)
    $width = Int(DllStructGetData($aInfo[0], 3)) * 1.05 + 10
    print($width)

    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_FontDispose($hGDIFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
    Return $width
EndFunc


Func load($treeID, $site)
    ;Make sure to load remote tree only, when player connected
;~  If $site = $remoteSite And $playerStatus = False Then
;~      _GUICtrlTreeView_DeleteAll($treeRemote)
;~      Return
;~  EndIf

    ;get array structure with albums
    $aAlbums = getAlbumsFromSite($site)

    ;save additional data in array
    $aAlbums[0][1] = $treeID
    $aAlbums[0][2] = $site

    ;build tree
    buildTree($aAlbums, $treeID)
EndFunc


Func removeOrLeaveAlbumOnPlayer()
    ;Get index of selected album
    $id = GUICtrlRead($treeRemote)
    $index = _ArraySearch($aRemoteAlbums, $id, 1, 0, 0, 0, 1, 4)    ;col 4 holds album id
    If $index = -1 Then Return

    ;Change flag adequately
    Switch $aRemoteAlbums[$index][5]
        Case $flagNew
            _ArrayDelete($aRemoteAlbums, $index)
            $aRemoteAlbums[0][0] -= 1
        Case $flagRemoved
            $aRemoteAlbums[$index][5] = $flagNull
        Case Else
            $aRemoteAlbums[$index][5] = $flagRemoved
            $albumSite = $remoteSite & $aRemoteAlbums[$index][0] & "\" & $aRemoteAlbums[$index][1]
            $aRemoteAlbums[$index][6] = getAlbumSize($albumSite, 0)
    EndSwitch

    ;Rebuild remote tree
    buildTree($aRemoteAlbums, $treeRemote)
EndFunc


Func resetSelections()
    ;Reset all changes made to remote site

    $i = 1
    While $i <= $aRemoteAlbums[0][0]
        ;Delete or remove flag according to current flag
        Switch $aRemoteAlbums[$i][5]
            Case $flagNew
                _ArrayDelete($aRemoteAlbums, $i)
                $aRemoteAlbums[0][0] -= 1
                $i -= 1 ;makes sure, the following album won't be skipped if it is changed, too.
            Case $flagRemoved
                $aRemoteAlbums[$i][5] = $flagNull
        EndSwitch
        $i += 1
    WEnd
    buildTree($aRemoteAlbums, $treeRemote)
EndFunc


Func setPlayerUsage($p)
    ;Set width of progress label and it's color, a marker and the warning icon

    $color = getProgressColor($p)
    If $p >= 100 Then
        $width = $usageWidth
        GUICtrlSetState($icoWarning, $gui_show)
        GUICtrlSetState($btnSync, $gui_disable)
    Else
        $width = $usageWidth / 100 * $p
        GUICtrlSetState($icoWarning, $gui_hide)
        GUICtrlSetState($btnSync, $gui_enable)
    EndIf
    GUICtrlSetPos($lblUsage, $aUsagePos[0], $aUsagePos[1], $width)
    GUICtrlSetBkColor($lblUsage, $color)
EndFunc


Func showAlbumTracks()
    ;Opens a new GUI and shows the tracks of the selected album

    $id = GUICtrlRead($lastClickedTree)
    $index = _ArraySearch($lastClickedAlbumsArray, $id, 1, 0, 0, 0, 1, 4)   ;col 4 holds album id
    If $index > -1 Then
        $albumDir = $localSite & $lastClickedAlbumsArray[$index][0] & "\" & $lastClickedAlbumsArray[$index][1] & "\"
        $aTracks = _FileListToArray($albumDir, "*.mp3", 1)
        _ArraySort($aTracks, 0, 1)
        showTracksGui($aTracks, $lastClickedAlbumsArray[$index][0], $lastClickedAlbumsArray[$index][1])
    EndIf
EndFunc


Func showFormatGui()
    $guiFWidth = 320
    $guiFHeight = 170
    $guiFormat = GUICreate("Formatieren", $guiFWidth, $guiFHeight, -1, -1, BitOr($WS_CAPTION, $WS_POPUP, $ds_modalframe), -1, $guiMain)
    GUISetFont($fontSize, 400, 0, $fontName, $guiFormat)

    GUICtrlCreateLabel("Speicherbelegung:", 10, 10, $guiFWidth-20, 20, $ss_centerimage)
    GUICtrlSetFont(-1, $fontSize, 600)
    GUICtrlSetColor(-1, 0x0000ff)
    GUICtrlCreateLabel("", 10, 30, $guiFWidth-20, 2, $ss_sunken)

    GUICtrlCreateLabel($remoteDrive & $remoteMusic, 10+20, 40, 80, 20, $ss_centerimage)
    GUICtrlSetFont(-1, $fontSize, 600)
    $lblMusicSize = GUICtrlCreateLabel("", 160, 40, 60, 20, $ss_right + $ss_centerimage)

    GUICtrlCreateLabel($remoteDrive & $remoteVideo, 10+20, 60, 80, 20, $ss_centerimage)
    GUICtrlSetFont(-1, $fontSize, 600)
    $lblVideoSize = GUICtrlCreateLabel("", 160, 60, 60, 20, $ss_right + $ss_centerimage)

    $lblInfo = GUICtrlCreateLabel($formatInfotext, 10, 90, $guiFWidth-20, 20, $ss_centerimage)

    $buttonWidth = ($guiFWidth - 4*10) / 3
    $btnFormatMusic = GUICtrlCreateButton("Musik", 10, $guiFHeight-10-25, $buttonWidth, 25, $bs_defpushbutton)
    GUICtrlSetOnEvent(-1, "formatMusic")
    $btnFormatVideo = GUICtrlCreateButton("Videos", $guiFWidth/2-$buttonWidth/2, $guiFHeight-10-25, $buttonWidth, 25)
    $btnFormatClose = GUICtrlCreateButton("Schließen", $guiFWidth-10-$buttonWidth, $guiFHeight-10-25, $buttonWidth, 25)
    GUICtrlSetOnEvent(-1, "closeFormatGui")

    updateFormatGui()

    ;Display the GUI
    GUISetState(@SW_SHOW, $guiFormat)
    GUISetState(@SW_DISABLE, $guiMain)
EndFunc


Func showSplashGui()

    $guiSplash = GUICreate("", 600, 400, -1, -1, $WS_POPUP, $WS_EX_TOOLWINDOW)
    GUISetFont($fontSize, 400, 0, $fontName)
    GUICtrlCreatePic("bg.jpg", 0, 0, 600, 400)
    GUICtrlSetState(-1, $gui_disable)

    ;load icon resource and load bitmap
    $iconSize = 192
    $hRunIcon = _WinAPI_LoadImage(_WinAPI_GetModuleHandle(0), "walkman.ico", $IMAGE_ICON, $iconSize, $iconSize, $LR_LOADFROMFILE)
    $hBitmap = _Icons_Bitmap_CreateFromIcon($hRunIcon)
    $StatusImage = GUICtrlCreatePic("", 100, 100, $iconSize, $iconSize)
    _SetHImage($StatusImage, $hBitmap)

    GUICtrlCreateLabel("mp3.Sync", 20, 310, 560, 30)
    GUICtrlSetColor(-1, 0xffffff)
    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
    GUICtrlSetFont(-1, 16, 600, 2)

    $lblLoad = GUICtrlCreateLabel("Laden...", 20, 350, 560, 20)
    GUICtrlSetColor(-1, 0xffffff)
    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)

    $prgLoad = GUICtrlCreateProgress(20, 370, 560, 10)

    GUISetState()

EndFunc


Func showSyncGui()
    $guiSWidth = 600
    $guiSHeight = 110
    $guiSync = GUICreate("Synchronisierung", $guiSWidth, $guiSHeight, -1, -1, BitOr($WS_CAPTION, $WS_POPUP, $ds_modalframe), -1, $guiMain)
    GUISetFont($fontSize, 400, 0, $fontName, $guiSync)

    GUICtrlCreateLabel("Synchronisierung:", 10, 10, $guiSWidth - 20, 20, $ss_centerimage)
    GUICtrlSetFont(-1, $fontSize, 600)
    GUICtrlSetColor(-1, 0x0000ff)
    GUICtrlCreateLabel("", 10, 10+20+4, $guiSWidth - 20, 2, $ss_sunken)

    $lblSync = GUICtrlCreateLabel("", 10+20, 50, $guiSWidth - 20, 20, $ss_centerimage)

    $prgSync = GUICtrlCreateProgress(10+20, 74, $guiSWidth-10-20-10-80-10, 16)
    $btnStopClose = GUICtrlCreateButton("Stop", $guiSWidth-10-80, 70, 80, 22)


    ;Display the GUI
    GUISetState(@SW_SHOW, $guiSync)
    GUISetState(@SW_DISABLE, $guiMain)
EndFunc


Func showTracksGui(ByRef $aTracks, $artist, $album)
    ;Displays a gui with a list of all tracks from the array.

    $guiTWidth = 480
    $guiTracks = GUICreate("Titel auf diesem Album", $guiTWidth, 600, -1, -1, BitOr($WS_CAPTION, $WS_POPUP, $ds_modalframe), -1, $guiMain)
    GUISetOnEvent($gui_event_close, "closeTracksGui", $guiTracks)
    GUISetFont($fontSize, 400, 0, $fontName, $guiTracks)

    $artistText = StringUpper($artist)
    $artistTextSize = 11
    $artistTextLen = getTextLengthInPixel($artistText, $fontName, $artistTextSize, 2)   ;2 = bold
    $lblArtist = GUICtrlCreateLabel($artistText, 10, 10, $artistTextLen, 20)
    GUICtrlSetFont(-1, $artistTextSize, 600)

    GUICtrlCreateLabel($album, 10 + $artistTextLen, 10+$artistTextSize-$fontSize+1, 300, 20)

    GUICtrlCreateLabel("", 10, 34, $guiTWidth-20, 2, $ss_sunken)

    $lstTracks = GUICtrlCreateListView(" | | | ", 10, 50, $guiTWidth-20, 500, _
        BitOR($GUI_SS_DEFAULT_LISTVIEW, $LVS_NOSORTHEADER), _
        BitOR($LVS_EX_CHECKBOXES, $ws_ex_clientedge))
    _GUICtrlListView_SetColumn($lstTracks, 0, " ", 20, 1)
    _GUICtrlListView_SetColumn($lstTracks, 1, "Nr.", 30, 1)
    _GUICtrlListView_SetColumn($lstTracks, 2, "Titel", $guiTWidth-20-50-30-10-10-30) ; col0, col1, col3, 2x border, scrollbar
    _GUICtrlListView_SetColumn($lstTracks, 3, "Länge", 50, 1)

    For $i = 1 To $aTracks[0]
        $name = StringTrimRight(StringTrimLeft($aTracks[$i], 3), 4)     ;number and extension removed
        $aLength = StringSplit(_GetExtProperty($localSite & $artist & "\" & $album & "\" & $aTracks[$i], 27), ":")
        GUICtrlCreateListViewItem("|" & $i & ".|" & $name & "|" & Int($aLength[2]) & ":" & $aLength[3], $lstTracks)
        GUICtrlSetState(-1, $gui_checked)
    Next

    $btnClose = GUICtrlCreateButton("OK", $guiTWidth/2-50, 565, 100, 22)
    GUICtrlSetOnEvent(-1, "closeTracksGui")  ;may later be saveTitleSelections

    ;Display the GUI
    GUISetState(@SW_SHOW, $guiTracks)
    GUISetState(@SW_DISABLE, $guiMain)

EndFunc


Func sortAlbumsByYear(ByRef $array)
    $a = 1
    $prev = $array[$a][0]       ;preload with first artist

    ;iterate through albums and sort
    For $i = 1 To $array[0][0]
        ;If new artist was found
        ;then sort the array at column 2, which is year.
        ;$i becomes new substart-index, currently found new artist is saved.
        If $array[$i][0] <> $prev Then
            ;If previous artist has more than 1 album (--> index diff. greater 0)
            If $i - 1 - $a > 0 Then
                _ArraySort($array, 0, $a, $i-1, 2)      ;2 is year
            EndIf
            $a = $i
            $prev = $array[$i][0]
        EndIf
    Next
    _ArraySort($array, 0, $a, $array[0][0], 2)
EndFunc


Func sync()

    ;Display sync gui and initialize stop indicator
    showSyncGui()
    $stopSync = False   ;must be set AFTER showSyncGui

    ;Delete removals
    For $i = 1 To $aRemoteAlbums[0][0]
        If $stopSync Then ExitLoop

        ;If current album is not flagged as removed, ignore it
        If $aRemoteAlbums[$i][5] <> $flagRemoved Then ContinueLoop

        ;Get relative album path on the player and update label
        $albumDir = $aRemoteAlbums[$i][0] & "\" & $aRemoteAlbums[$i][1]
        GUICtrlSetData($lblSync, "Löschen... " & $albumDir)

        ;Remove the album and the artist folder, if it's empty then
        DirRemove($remoteSite & $albumDir, 1)
        If DirGetSize($remoteSite & $aRemoteAlbums[$i][0]) = 0 Then
            DirRemove($remoteSite & $aRemoteAlbums[$i][0])
        EndIf
    Next


    ;Copy new albums

    $p = 0
    $aFiles = getFilesToSync()
    For $i = 1 To $aFiles[0]
        If $stopSync Then
            GUICtrlSetData($lblSync, "Abbrechen...")
            ExitLoop
        EndIf

        ;Update label with current file
        GUICtrlSetData($lblSync, $p & "%... " & $aFiles[$i])

        ;Run and wait for copy process by calling external copy script and passing source and destination as arguments
        RunWait($extPath & '"' & $localSite & $aFiles[$i] & '" "' & $remoteSite & $aFiles[$i] & '"')

        ;Calculate percentage and set progress bar
        $p = Round($i * 100 / $aFiles[0], 0)
        GUICtrlSetData($prgSync, $p)
    Next

    ;Update sync gui
    If $stopSync Then
        GUICtrlSetData($lblSync, "Abgebrochen.")
        GUICtrlSetData($prgSync, 0)
    Else
        GUICtrlSetData($lblSync, "Fertig.")
    EndIf
    GUICtrlSetData($btnStopClose, "Schließen")
    GUICtrlSetOnEvent($btnStopClose, "closeSyncGui")

    ;Load remote site
    load($treeRemote, $remoteSite)
EndFunc


Func updateFormatGui()
    ;Update size displays
    $musicSize = Round(DirGetSize($remoteDrive & $remoteMusic)/1024/1024, 1)
    $videoSize = Round(DirGetSize($remoteDrive & $remoteVideo)/1024/1024, 1)
    GUICtrlSetData($lblMusicSize, $musicSize & " MB")
    GUICtrlSetData($lblVideoSize, $videoSize & " MB")
    If $musicSize = 0 Then
        GUICtrlSetState($btnFormatMusic, $gui_disable)
    Else
        GUICtrlSetState($btnFormatMusic, $gui_enable)
    EndIf
    If $videoSize = 0 Then
        GUICtrlSetState($btnFormatVideo, $gui_disable)
    Else
        GUICtrlSetState($btnFormatVideo, $gui_enable)
    EndIf
EndFunc


Func updateSplashGui($text = "", $p = 0)
    ;Update the information shown in the splash gui

    If $guiSplash = 0 Then Return

    If $text <> "" Then
        GUICtrlSetData($lblLoad, $text)
    EndIf
    If $p > 0 Then
        GUICtrlSetData($prgLoad, $p+1)
        GUICtrlSetData($prgLoad, $p)
    EndIf
EndFunc


Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tagNMHDR = "int hwndFrom; int idFrom; int code"
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    If @error Then Return
    Local $iCode = DllStructGetData($tNMHDR, "code")

    Switch $wParam
        Case $treeLocal
            Switch $iCode
                Case $NM_CLICK
                    $lastClickedTree = $wParam
                    $lastClickedAlbumsArray = $aLocalAlbums
                Case $NM_DBLCLK
                    $wmAlbumAdded = True
            EndSwitch
        Case $treeRemote
            Switch $iCode
                Case $NM_CLICK
                    $lastClickedTree = $wParam
                    $lastClickedAlbumsArray = $aRemoteAlbums
                Case $NM_DBLCLK
                    $wmAlbumRemoved = True
            EndSwitch
        Case $btnStopClose
            print(@HOUR&":"&@MIN&":"&@SEC&" "&$iCode)   ;debug
            If $iCode = $NM_CLICK Then
                $stopSync = True
            EndIf
    EndSwitch
    $tNMHDR = 0
    Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_NOTIFY


Func print($s)
    ConsoleWrite($s & @CRLF)
EndFunc


Func quit()
    Exit
EndFunc
Edited by Der_Andi
Link to comment
Share on other sites

I just cut your WM_NOTIFY out and tried it in one of my scripts... didn't do a thing.

Aren't you supposed to check $hWndFrom to see which control triggered the event, rather than $iWParam?

All my WM_NOTIFY routines start out similar to this:

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
;    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")

    Switch $hWndFrom
        Case $hListView
            Switch $iCode
                Case $NM_CLICK

Edit: Glancing at your code you have a number of custom includes, you're not afriad of indexing (as many are), you have calls to GDI+ and WinAPI. So, I'm sure you know exactly what you're doing, and there's nothing wrong with what appears to me to be an odd version of WM_NOTIFY. I've never bothered to use eventmode and would guess that must affect the parameters of the WM_NOTIFY message?

Edited by Spiff59
Link to comment
Share on other sites

That sounds strange to me, because hWndFrom is the window handle. Using it to see which control sent the message causes my script to crash. This seems not to be right.

As far as I got it, the IDFrom value is the same as $wParam and according to the AutoIt help file, it is "the identifier of the control sending the message."

The WM_NOTIFY of mine worked all the time, except the $btnStopClose thing which was added today.

Link to comment
Share on other sites

Ah... ListViews must report as being their own window, and that's where I'm used to using WM_NOTIFY. You're, of course, correct, after commenting out some of your code and inserting a "ToolTip($wParam & " " & Binary($iCode))" after "Case $treelocal" and "$Case $treeremote" I see your WM_NOTIFY is working exactly as you described. Sorry for the distraction.

Link to comment
Share on other sites

Your posted script was way too long to work with, but:

A button control sends BN_CLICKED by a WM_COMMAND message. You are watching the wrong message:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>

Opt("GuiOnEventMode", 1)

Global $hGUI = GUICreate("Test", 300, 300)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")

Global $btnStopClose = GUICtrlCreateButton("Stop", 100, 250, 100, 30)
Global $hButton = ControlGetHandle($hGUI, "", $btnStopClose)
GUICtrlSetOnEvent($btnStopClose, "closeSyncGui")

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

GUISetState()

While 1
    Sleep(10)
WEnd

Func _Quit()
    Exit
EndFunc   ;==>_Quit

Func closeSyncGui()
    ConsoleWrite('Debug closeSyncGui():  You clicked "Stop"; ID = ' & @GUI_CtrlId & '; Hwnd = ' & @GUI_CtrlHandle & @LF)
EndFunc   ;==>closeSyncGui

Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $hFrom = HWnd($lParam)
    Local $idFrom = BitAND($wParam, 0x0000FFFF)
    Local $iCode = BitShift(BitAND($wParam, 0xFFFF0000), 16)
    ConsoleWrite("Debug WM_COMMAND:  $hFrom = " & $hFrom & "; $hButton = " & $hButton & @LF)
    Switch $hFrom
        Case $hButton
            If $iCode = $BN_CLICKED Then
                ConsoleWrite('Debug WM_COMMAND:  You clicked "Stop"; code = ' & $iCode & '; hwndFrom = ' & $hFrom & @LF)
            EndIf
    EndSwitch
    $tNMHDR = 0
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

When you click on the button in this demo, you see both GuiCtrlSetOnEvent() action and the WM_COMMAND action.

;)

P.S. A button might also send WM_NOTIFY messages, but they will not be for "clicked", rather gaining/losing focus and stuff like that.

:)

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

[...] you're not afriad of indexing (as many are), you have calls to GDI+ and WinAPI. So, I'm sure you know exactly what you're doing, and there's nothing wrong with what appears to me to be an odd version of WM_NOTIFY. I've never bothered to use eventmode and would guess that must affect the parameters of the WM_NOTIFY message?

Well, to be honest, I just copied some GDI code found here in the forum and modified it a little bit. It also was my first encounter with GDI, so I just hoped it would work. Same story for those WinAPI calls. ;-)

What is this "indexing" you mentioned above?

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...