Jump to content
Sign in to follow this  
Armand

WM_NOTIFY Event issue... with listview in TAB. [AU3 BUG ?!]

Recommended Posts

Armand

hey guys,

>> I have a listview obj, created using the built-in inside a TAB at the 2nd TAB.

>> the items are inserted using a _UDF someone has donated in the forum...

>> it is being monitored by WM_Notify [just like in the help file].

>> when i click on entry #3, Row #4 of the listview, the TAB always switches to it's first TAB item.

Now i'm asking myself and you guys.... WTF ?!

why would this specific function be called after i click a specific entry in the listview [4 row, $i 3] no matter what is stored in it it always calls that same function after.... and only for that entry.

if that listview has less then 4 rows then you can click all day and nothing will happen....

EDIT:: complete reproduction a bit lower...

Edited by Armand

[u]My Au3 Scripts:[/u]____________(E)Lephant, A Share download manager (RS/MU etc)Http1.1 Console, The Ez Way!Internet Reconnection Automation Suite & A Macro Recording Tool.SK's Alarm Clock, Playing '.MP3 & .Wav' Files._________________Is GOD a mistake of the Humanity Or the Humanity is a mistake of GOD ?!

Share this post


Link to post
Share on other sites
Armand

Yeeppzzzz... i've managed...

Here is a reproduction of the issue... just click on entry #3 [row n4]

P.S > Latest beta.

#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)

;$Debug_LV = False ; Check ClassName being passed to ListView functions, set to True and use a handle to another control to see it work

Global $hListView

_Main()

Func _Main()

    Local $GUI, $hImage
    $GUI = GUICreate("(UDF Created) ListView Create", 500, 400)
    GUISetOnEvent($GUI_EVENT_CLOSE, "ExitProg")
    $TAB = GUICtrlCreateTab(0, 0, 498, 398)
    ;GUICtrlSetOnEvent(-1, "TabsChanger")  ; UNTICK ME IF U WANT TO SEE THE MSG.
    $Tab0 = GUICtrlCreateTabItem("ItemNumber0")
    GUICtrlSetOnEvent(-1, "TabsChanger")
    $Tab1 = GUICtrlCreateTabItem("ItemNumber1")
    GUICtrlSetOnEvent(-1, "TabsChanger")
    
    $hListView = GUICtrlCreateListView("#|A|B|C|D|E|F|G|H|I|J|K|L|M", 2, 22, 394, 268)
    ;$hListView = _GUICtrlListView_Create($GUI, "#|A|B|C|D|E|F|G|H|I|J|K|L|M", 2, 2, 394, 268)
    ;;;>> Doesn't create the listview on the tab required but for entire $GUI.
    _GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES))
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

    ; Load items
    For $i = 0 To 20
        MyGUICtrlCreateListViewItem($i&"|BLAA|ASDA|ASDASD|ASDASD|ASDASD|ASDASD", $hListView)
        ;;; USING THIS FUNCTION >>
        ;;;                         because of _UDF lack of ability to support unicode properly.
        ;;;                         because of built-in flickering property, [it just flashes like a milion times during the updates].
    Next
    
    
    $Tab2 = GUICtrlCreateTabItem("ItemNumber2")
    GUICtrlSetOnEvent(-1, "TabsChanger")
    GUICtrlCreateTabItem("")
    GUISetState()

    ; Loop until user exits
    While 1
    WEnd
EndFunc   ;==>_Main

Func ExitProg()
    Exit
EndFunc


Func TabsChanger()
    MsgBox(0, "IF I AM HERE??", "HERE IS THE BUG")
EndFunc

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
;~  Local $tBuffer
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndListView
            Switch $iCode
                Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
                    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                    _DebugPrint("$NM_CLICK" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode & @LF & _
                            "-->Index:" & @TAB & DllStructGetData($tInfo, "Index") & @LF & _
                            "-->SubItem:" & @TAB & DllStructGetData($tInfo, "SubItem") & @LF & _
                            "-->NewState:" & @TAB & DllStructGetData($tInfo, "NewState") & @LF & _
                            "-->OldState:" & @TAB & DllStructGetData($tInfo, "OldState") & @LF & _
                            "-->Changed:" & @TAB & DllStructGetData($tInfo, "Changed") & @LF & _
                            "-->ActionX:" & @TAB & DllStructGetData($tInfo, "ActionX") & @LF & _
                            "-->ActionY:" & @TAB & DllStructGetData($tInfo, "ActionY") & @LF & _
                            "-->lParam:" & @TAB & DllStructGetData($tInfo, "lParam") & @LF & _
                            "-->KeyFlags:" & @TAB & DllStructGetData($tInfo, "KeyFlags"))
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _DebugPrint($s_text, $line = @ScriptLineNumber)
    ConsoleWrite( _
            "!===========================================================" & @LF & _
            "+======================================================" & @LF & _
            "-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_text & @LF & _
            "+======================================================" & @LF)
EndFunc   ;==>_DebugPrint
        
; #FUNCTION# ====================================================================================================================
; Name...........: MyGUICtrlCreateListViewItem
; Description ...: Create and insert items directly into the listview, Unicode supported!
; Syntax.........: MyGUICtrlCreateListViewItem($sText, $nCtrlID[, $nIndex = -1])
; Parameters ....: $sText       - Text of the item and subitems seperated by seperation char. [Default "|"]
;                  $nCtrlID     - Listview control ID.
;                  $nIndex      - Item's index. [Default -1, will add at last location]
; Return values .: Nothing.
; Author ........: Unknown, Supplied by: ChrisL @ http://www.autoitscript.com/forum/index.php?showtopic=70227&view=findpost&p=515453
; Modified.......: Armand.
; ===============================================================================================================================
Func MyGUICtrlCreateListViewItem($sText, $nCtrlID, $nIndex = -1)
    Local $stLvItem = DllStructCreate("uint;int;int;uint;uint;ptr;int;int;int;int;")
    Local $stText = DllStructCreate("wchar[260]")
    Local $arText = StringSplit($sText, "|")

    If $nIndex = -1 Then $nIndex = GUICtrlSendMsg($nCtrlID, $LVM_GETITEMCOUNT, 0, 0)

    DllStructSetData($stText, 1, $arText[1]); Save the item text in the struct

    DllStructSetData($stLvItem, 1, BitOR($LVIF_TEXT, $LVIF_PARAM))
    DllStructSetData($stLvItem, 2, $nIndex)
    DllStructSetData($stLvItem, 6, DllStructGetPtr($stText))
    ; Set the lParam of the struct to the line index - unique within the listview
    DllStructSetData($stLvItem, 9, $nIndex)

    $nIndex = GUICtrlSendMsg($nCtrlID, $LVM_INSERTITEMW, 0, DllStructGetPtr($stLvItem))

    If $nIndex > -1 Then
        ; Insert now the rest of the column text
        For $i = 2 To $arText[0]
            DllStructSetData($stText, 1, $arText[$i])
            DllStructSetData($stLvItem, 3, $i - 1); Store the subitem index

            GUICtrlSendMsg($nCtrlID, $LVM_SETITEMTEXTW, $nIndex, DllStructGetPtr($stLvItem))
        Next
    EndIf

    $stText = 0
    $stLvItem = 0

EndFunc   ;==>MyGUICtrlCreateListViewItem
Edited by Armand

[u]My Au3 Scripts:[/u]____________(E)Lephant, A Share download manager (RS/MU etc)Http1.1 Console, The Ez Way!Internet Reconnection Automation Suite & A Macro Recording Tool.SK's Alarm Clock, Playing '.MP3 & .Wav' Files._________________Is GOD a mistake of the Humanity Or the Humanity is a mistake of GOD ?!

Share this post


Link to post
Share on other sites
Siao

Remove this bit:

; Set the lParam of the struct to the line index - unique within the listview
    DllStructSetData($stLvItem, 9, $nIndex)

For LV items made with GUICtrlCreateListViewItem, lParam stores the "controlID" of the item. Your function stores item index. Which throws off internal event handler I guess: clicking item3 (which has lParam = 3) activates event for GUI control whose controlID is 3, which happens to be Tab.


"be smart, drink your wine"

Share this post


Link to post
Share on other sites
v3rt1g0

Remove this bit:

; Set the lParam of the struct to the line index - unique within the listview
    DllStructSetData($stLvItem, 9, $nIndex)

For LV items made with GUICtrlCreateListViewItem, lParam stores the "controlID" of the item. Your function stores item index. Which throws off internal event handler I guess: clicking item3 (which has lParam = 3) activates event for GUI control whose controlID is 3, which happens to be Tab.

I think I'm seeing this same type of issue, though I'm not sure how to fix my issue from what you said there.

When I click certain ListView elements, my functions are triggered.

Here's the code:

; ==================================
; Vars
; ==================================

;Includes
#include <Array.au3>
#include <File.au3>
#Include <GuiListView.au3>
#include <Date.au3>
#include <GUIConstants.au3>

;Vars
global $aName, $aStat, $aOS, $aLang, $aIdle, $aApp, $aWeb, $aOSYS, $aAge, $aHide, $aPHP, $aMOT, $aAssi, $aReso, $aIP
global $mArray, $iArray, $i, $in, $sFile, $oFile, $iFile, $list, $fileage, $now, $xlist
global $gui, $refresh_butt, $status, $properties_butt, $filter_butt, $langdrop, $langdropop

;Options
Opt("GUIOnEventMode", 1)

; ==================================
; Main
; ==================================

;Startup
GUISetOnEvent($GUI_EVENT_CLOSE, "ExitApp")
GUIStart()
UpdateStatusData()
RefreshList()

;Idle Loop
While 1
    Sleep(500)
WEnd

;Exit
Func ExitApp()
    StatusUpdate("Bye ...")
    Exit
EndFunc


; =========================================================================================================================================================================================
; Functions
; =========================================================================================================================================================================================
Func GUIStart()
    $gui = GUICreate("Machine Status", 750, 800)
    $status = GUICtrlCreateLabel("", 10, 10, 730, 13)
    $xlist = GUICtrlCreateListView("", 10, 33, 730, 580)
    $list = GUICtrlGetHandle($xlist)
    _GUICtrlListView_SetExtendedListViewStyle($list, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_CHECKBOXES, $LVS_EX_HEADERDRAGDROP, $LVS_EX_GRIDLINES))
    _GUICtrlListView_InsertColumn($list, 0, "Machine", 91) ;var, index, header, width
    _GUICtrlListView_InsertColumn($list, 1, "Status", 80)
    _GUICtrlListView_InsertColumn($list, 2, "OS", 40)
    _GUICtrlListView_InsertColumn($list, 3, "Language", 75)
    _GUICtrlListView_InsertColumn($list, 4, "Idle", 50)
    _GUICtrlListView_InsertColumn($list, 5, "Running", 70)
    _GUICtrlListView_InsertColumn($list, 6, "Client", 70)
    _GUICtrlListView_InsertColumn($list, 7, "Web", 40)
    _GUICtrlListView_InsertColumn($list, 8, "PHP", 40)
    _GUICtrlListView_InsertColumn($list, 9, "MOT", 50)
    _GUICtrlListView_InsertColumn($list, 10, "Assignee", 60)
    _GUICtrlListView_InsertColumn($list, 11, "Data Age", 60)
    $refresh_butt = GUICtrlCreateButton("Refresh", 10, 623, 120, 25)
    GUICtrlSetOnEvent($refresh_butt, "UpdateStatusData")
    $properties_butt = GUICtrlCreateButton("Properties", 620, 623, 120, 25)
    GUICtrlSetOnEvent($properties_butt, "Properties")
    $filter_butt = GUICtrlCreateButton("Filter", 310, 623, 120, 25)
    GUICtrlSetOnEvent($filter_butt, "Filter")
    ;$langdrop = _GUICtrlComboBox_Create ($gui, "", 310, 643, 120, 296)
    ;$langdropop = _GUICtrlComboBox_Create ($gui, "", 310, 663, 396, 296)
    GUISetState(@SW_SHOW)
EndFunc


Func UpdateStatusData()
    If Not FileExists("\\server\dat\") Then MsgBox(0, "Error", "Can't find \\server\dat\")
    StatusUpdate("Reading machine data from server ...")
    $mArray = _FileListToArray("\\server\dat\", "*.dat", 1)
    If @error = 1 or @error = 4 Then MsgBox(0, "Error", "Path not found or no files found in \\server\dat\")
    global $aName[$mArray[0]+1]=[$mArray[0]], $aStat[$mArray[0]+1]=[$mArray[0]], $aOS[$mArray[0]+1]=[$mArray[0]], $aLang[$mArray[0]+1]=[$mArray[0]], $aIdle[$mArray[0]+1]=[$mArray[0]]
    global $aApp[$mArray[0]+1]=[$mArray[0]], $aWeb[$mArray[0]+1]=[$mArray[0]], $aOSYS[$mArray[0]+1]=[$mArray[0]], $aAge[$mArray[0]+1]=[$mArray[0]], $aHide[$mArray[0]+1]=[$mArray[0]]
    global $aPHP[$mArray[0]+1]=[$mArray[0]], $aMOT[$mArray[0]+1]=[$mArray[0]], $aAssi[$mArray[0]+1]=[$mArray[0]]
    StatusUpdate("Populating Arrays ...")
    For $i = 1 to $mArray[0] ;populate arrays from data files
        $aHide[$i] = 0
        $sFile = $mArray[$i]
        $oFile = FileOpen("\\server\dat\"&$sFile, 0)
        $aName[$i] = FileReadLine($oFile, 1) ;Machine name
        $aStat[$i] = FileReadLine($oFile, 2) ;Ready/Running/Dead/etc
          $aOS[$i] = FileReadLine($oFile, 3) ;Which OS installed?
        $aLang[$i] = FileReadLine($oFile, 4) ;which lang OS installed?
        $aIdle[$i] = FileReadLine($oFile, 5) ;how many minutes idle? checks mouse x axis for changes
         $aApp[$i] = FileReadLine($oFile, 6) ;are any known apps running?
        $aWeb[$i] = FileReadLine($oFile, 7) ;is web installed?
        $aOSYS[$i] = FileReadLine($oFile, 8) ;is Client idle or running? StringInStr(WinGetTitle("Client"), Available)
         $aPHP[$i] = FileReadLine($oFile, 9) ;Is PHP folder present? %progfiles%\PHP
       $aMOT[$i] = FileReadLine($oFile, 10) ;Is MOT folder present? @HomeDrive\MOT
        $aAssi[$i] = FileReadLine($oFile, 11) ;Assigned to who? c:\assigned.dat
        FileClose($sFile)
        $fileage = FileGetTime("\\server\dat\"&$sFile)
        $now = _Date_Time_GetLocalTime()
        $now = _Date_Time_SystemTimeToArray($now)
        Select ;how old is the data file
            Case $now[2] > $fileage[0] ;year
                $aAge[$i] = $now[2] - $fileage[0] & " yr *"
            Case $now[0] > $fileage[1] ;month
                $aAge[$i] = $now[0] - $fileage[1] & " mth *"
            Case $now[1] > $fileage[2] ;day
                $aAge[$i] = $now[1] - $fileage[2] & " day *"
            Case $now[3] > $fileage[3] ;hour
                If $now[3] - $fileage[3] = 1 and $fileage[4] > $now[4] Then ;if one hr diff, and if file minutes higher than current minutes, eg 1:53 vs 2:04
                    $aAge[$i] = 60 - $fileage[4] + $now[4] & " min" ;((60-53)=7)+4 = 11 mins old, not an hour old
                Else
                    $aAge[$i] = $now[3] - $fileage[3] & " hr *"
                EndIf
            Case $now[4] > $fileage[4] ;minute
                If $now[4] - $fileage[4] = 1 and $fileage[5] > $now[5] Then ;if one min diff, and if file seconds higher than current seconds, eg 1:53:45 vs 2:04:07
                    $aAge[$i] = 60 - $fileage[5] + $now[5] & " sec" ;((60-45)=15)+7 = 22 secs old, not a minute old
                Else
                    $aAge[$i] = $now[4] - $fileage[4] & " min"
                EndIf
            Case $now[5] >= $fileage[5] ;second
                $aAge[$i] = $now[5] - $fileage[5] & " sec"
        EndSelect
    Next
    RefreshList()
EndFunc

Func RefreshList()
    StatusUpdate("Refreshing List ...")
    _GUICtrlListView_DeleteAllItems($list)
    $in = 0 ;index
    For $i = 1 to $mArray[0]
        If $aHide[$i] = 0 Then ;filter
            _GUICtrlListView_AddItem($list, $aName[$i])
            _GUICtrlListView_AddSubItem($list, $in, $aStat[$i], 1)
            _GUICtrlListView_AddSubItem($list, $in, $aOS[$i], 2)
            _GUICtrlListView_AddSubItem($list, $in, $aLang[$i], 3)
            _GUICtrlListView_AddSubItem($list, $in, $aIdle[$i], 4)
            _GUICtrlListView_AddSubItem($list, $in, $aApp[$i], 5)
            _GUICtrlListView_AddSubItem($list, $in, $aOSYS[$i], 6)
            _GUICtrlListView_AddSubItem($list, $in, $aWeb[$i], 7)
            _GUICtrlListView_AddSubItem($list, $in, $aPHP[$i], 8)
            _GUICtrlListView_AddSubItem($list, $in, $aMOT[$i], 9)
            _GUICtrlListView_AddSubItem($list, $in, $aAssi[$i], 10)
            _GUICtrlListView_AddSubItem($list, $in, $aAge[$i], 11)
        EndIf
        If $aHide[$i] = 1 Then $in -= 1 ;reduce index
        $in += 1 ;index
    Next
    StatusUpdate("Ready ...")
EndFunc


Func Properties()
    StatusUpdate("Retrieving extended machine data ...")
    If Not FileExists("\\server\dat\") Then MsgBox(0, "Error", "Can't find \\server\dat\")
    $iFile = _GUICtrlListView_GetSelectedIndices($list, False) ;selected index
    $sFile = $aName[$iFile + 1]
    $oFile = FileOpen("\\server\dat\"&$sFile&".dat", 0)
    $aReso = FileReadLine($oFile, 12)
    $aIP = FileReadLine($oFile, 13)
    FileClose($oFile)
    MsgBox(0, $sFile & " Properties", "Display Resolution:"&@CRLF&$aReso&"bit"&@CRLF&@CRLF&"IP Addresses:"&@CRLF&$aIP)
    StatusUpdate("Ready ...")
EndFunc


Func Filter()
    StatusUpdate("Filtering ...")
    For $i = 1 to $mArray[0]
        $aHide[$i] = 0
        ;Select
        ;   Case GUICtrlRead($langdropop) = "Is"
        ;       If $aLang[$i] = GUICtrlRead($langdrop) Then $aHide[$i] = 1
        ;   Case GUICtrlRead($langdropop) = "Not"
        ;       If $aLang[$i] <> GUICtrlRead($langdrop) Then $aHide[$i] = 1
        ;EndSelect
        ;MsgBox(0, "Langs", "$i is " & $i & ".. $aLang[$i] is " & $aLang[$i] & "$aHide[$i] is " & $aHide[$i])
    Next
    RefreshList()
EndFunc


;===========================================================================
; Status Update Flasher
;===========================================================================
Func StatusUpdate($statusdata)
    GUICtrlSetData($status, $statusdata)
    Sleep(15)
    GUICtrlSetBkColor($status,0x000000)
    GUICtrlSetColor($status,0xffffff)
    Sleep(15)
    GUICtrlSetBkColor($status,$GUI_BKCOLOR_TRANSPARENT)
    GUICtrlSetColor($status,0x000000)
    Sleep(15)
    GUICtrlSetBkColor($status,0x000000)
    GUICtrlSetColor($status,0xffffff)
    Sleep(15)
    GUICtrlSetBkColor($status,$GUI_BKCOLOR_TRANSPARENT)
    GUICtrlSetColor($status,0x000000)
EndFunc

Share this post


Link to post
Share on other sites
v3rt1g0

Bump.

Is this really not a bug? How do I prevent the ListView item indexes from somehow being mapped to the ControlIDs of the buttons?

Share this post


Link to post
Share on other sites
Siao

I think this should not be an issue with the latest version of AutoIt, so are you sure you are using that?


"be smart, drink your wine"

Share this post


Link to post
Share on other sites
GaryFrost

I think this should not be an issue with the latest version of AutoIt, so are you sure you are using that?

I would say not, been fixed for a while in the beta and now in the latest release.


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites
v3rt1g0

I would say not, been fixed for a while in the beta and now in the latest release.

Latest release, 3.2.12, fixes this issue.

Share this post


Link to post
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
Sign in to follow this  

×