Jump to content

how to change bgcolor of a control belonging to another window?


Gianni
 Share

Recommended Posts

  • Moderators

LarsJ,

No idea - and until we get some more information on exactly what is the link between the external processes and the labels I would argue that we cannot sensibly test which is better. I was intending to run some tests on the 3 basic ideas with largish number of labels later this week (today and tomorrow are already reserved for golf) so that we could at least see if they were feasible at a larger scale - and how they compared in terms of speed.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

How will these ideas perform with 1000 colored labels?

Even in own process perform with 1000 labels would be excessive.

Saludos

Link to comment
Share on other sites

It's not that bad.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Example()

Func Example()
  Local $hProgram2 = GUICreate("Program 2", 810, 330)
  GUISetBkColor("0x9A9A9A", $hProgram2)
  Local $aLabels = _GUICtrlsMatrix_Create(5, 5, 50, 20, 15, 15)
  GUISetState( @SW_SHOW, $hProgram2 )

  Local $hProgram1 = GUICreate( "Program 1", 200, 100, 100, 100 )
  Local $idColors = GUICtrlCreateButton( "Set colors", 50, 30, 100, 40 )
  GUISetState( @SW_SHOW, $hProgram1 )

  Local $j = 0
  While 1
    Switch GUIGetMsg()
      Case $idColors
        While $j < 25
          For $i = 0 To 999
            GUICtrlSetBkColor( $aLabels[$i], Random(0,255,1)+256*Random(0,255,1)+256*256*Random(0,255,1) )
          Next
          $j += 1
        WEnd
        $j = 0
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  GUIDelete( $hProgram2 )
  GUIDelete( $hProgram1 )
EndFunc

Func _GUICtrlsMatrix_Create($xPanelPos, $yPanelPos, $nrPerLine, $nrOfLines, $Width, $Height, $xSpace = 1, $ySpace = 1)
  Local $aGuiControls[1000], $j = 0
  For $i = 1 To $nrPerLine * $nrOfLines
    $row = Int($i / $nrPerLine) + Not(Not(Mod($i, $nrPerLine)))
    $col = $i - ($row * $nrPerLine - $nrPerLine)
    $left = $xPanelPos + (($Width + $xSpace) * $col) - ($Width + $xSpace)
    $top = $yPanelPos + (($Height + $ySpace) * $row) - ($Height + $ySpace)
    $aGuiControls[$j] = GUICtrlCreateLabel("", $left, $top, $Width, $Height)
    GUICtrlSetBkColor(-1, "0xFFFFFF")
    $j += 1
  Next
  Return $aGuiControls
EndFunc

 

Link to comment
Share on other sites

In computers fast as yours. I'm mine one it takes about 2 seconds to change all colors lol :S

 

Saludos

Link to comment
Share on other sites

  • Moderators

Hi,

I won the golf match very comfortably this morning, so I have been playing around with this little problem this afternoon. Here is a working set of scripts using Dany's ControlClick method:

Label_Master:

#include <GUIConstantsEx.au3>

; Array to hold data - ControlIDs of inputs, labels and current colours
Global $aData[101][3]

; Set start time - this allows all child processes to be created before colour changes are started
$iBaseMin = @MIN
If $iBaseMin = 59 Then $iBaseMin = -1

SplashTextOn("Label test", "Creating child processes!")

; Launch 100 child processes - each will change the colour of one label
For $i = 1 To 100
    ; Randomize the Random seed for each child or we get the same colour for each!
    $iSeed = Random(1, 2^10, 1)
    ; Pass parameters to the child process
    ShellExecute("Label_Child.exe", $i & " " & $iBaseMin & " " & $iSeed)
Next

SplashOff()

; Create GUI
$hGUI = GUICreate("Label_Master", 510, 510)

; Create labels and hidden inputs
For $i = 0 To 9
    For $j = 0 To 9
        $iIndex = $j + ($i * 10) + 1
        $aData[$iIndex][1] = GUICtrlCreateLabel("", 10 + ($j * 50), 10 + ($i * 50), 40, 40)
        GUICtrlSetBkColor(-1, 0xC4C4C4)
        GUICtrlSetFont(-1, 18)
        $aData[$iIndex][0] = GUICtrlCreateInput("", 10 + ($j * 50), 600 + ($i * 50), 40, 40)
    Next
Next
; Create hidden button
$cButton = GUICtrlCreateButton("", 10, 1200, 80, 30)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $cButton

            ; For each input
            For $i = 1 To 100
                ; Read content
                $iColour = Number(GUICtrlRead($aData[$i][0]))
                ; If colour has changed
                If $iColour <> $aData[$i][2] Then
                    ; Recolour label
                    GUICtrlSetBkColor($aData[$i][1], $iColour)
                    ; Store new colour
                    $aData[$i][2] = $iColour

                    ; Increase count - just to cshow that each label change get honoured
                    GUICtrlSetData($aData[$i][1], GUICtrlRead($aData[$i][1]) + 1)
                EndIf

            Next
    EndSwitch



WEnd

Label_Child:

If $CmdLine[0] = 0 Then Exit

; Read parameters
$iIndex = $CmdLine[1]
$iBaseMin = $CmdLine[2]
$iSeed = $CmdLine[3]

; Randomize the random process
SRandom($iSeed)

; Sleep to allow all child processes to be created
Do
    Sleep(10)
Until @MIN >= $iBaseMin + 1

; 5 cycles
For $i = 1 To 5
    ; Stagger the requests
    Sleep(Random(1, 5, 1) * 1000)
    ; Generate colour
    $iColour = Dec(Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2))
    ; Tell master
    ControlSetText("Label_Master", "", "Edit" & $iIndex, $iColour)
    ; Fire the button
    ControlClick("Label_Master", "", "Button1")

Next

It seems to work quite nicely - now to work on the other methods.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

And now using LarsJ's method:

Label_Master:

#include <GUIConstantsEx.au3>

; Array to hold ControlIDs of labels
Global $aData[101]

; Create GUI
$hGUI = GUICreate("Label_Master", 510, 510)

; Create labels
For $i = 0 To 9
    For $j = 0 To 9
        $iIndex = $j + ($i * 10) + 1
        $aData[$iIndex] = GUICtrlCreateLabel("", 10 + ($j * 50), 10 + ($i * 50), 40, 40)
        GUICtrlSetBkColor(-1, 0xC4C4C4)
    Next
Next

GUISetState()

SplashTextOn("Label test", "Creating child processes!", Default, Default, 0, 0)

; Set start time - this allows all child processes to be created before colour changes are started
$iBaseMin = @MIN
If $iBaseMin = 59 Then $iBaseMin = -1

; Launch 100 child processes - each will change the colour of one label
For $i = 1 To 100
    ; Randomize the Random seed for each child or we get the same colour for each!
    $iSeed = Random(1, 2^10, 1)
    ; Get handle for the associated label
    $hHandle = GUICtrlGetHandle($aData[$i])
    ; Pass parameters to the child process
    ShellExecute("Label_Child.exe", $i & " " & $iBaseMin & " " & $iSeed & " " & $hHandle)
Next

SplashOff()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch



WEnd

Label_Child:

#include <WinAPI.au3>

If $CmdLine[0] = 0 Then Exit

; Read parameters
$iIndex = $CmdLine[1]
$iBaseMin = $CmdLine[2]
$iSeed = $CmdLine[3]
$hHandle = Hwnd($CmdLine[4])

; Randomize the random process
SRandom($iSeed)

Local $tRECT = DllStructCreate($tagRECT)
DllStructSetData($tRECT, 'Left', 1)
DllStructSetData($tRECT, 'Top', 1)
DllStructSetData($tRECT, 'Right', 40)
DllStructSetData($tRECT, 'Bottom', 40)
Local $pRECT = DllStructGetPtr($tRECT)

; Sleep to allow all child processes to be created
Do
    Sleep(10)
Until @MIN >= $iBaseMin + 1

; 5 cycles
For $i = 1 To 5
    ; Stagger the requests
    Sleep(Random(1, 5, 1) * 1000)
    ; Generate colour
    $iColour = Dec(Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2))
    Local $hDC = _WinAPI_GetDC($hHandle)
    Local $hBrush = _WinAPI_CreateSolidBrush($iColour)
    _WinAPI_FillRect($hDC, $pRECT, $hBrush)
    _WinAPI_SetBkColor($hDC, $iColour)
    _WinAPI_ReleaseDC($hHandle, $hDC)
    _WinAPI_DeleteObject($hBrush)
Next

And now for my MailSlot method......

M23

Edited by Melba23
Typo

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

And last, but not least, my MailSlot method (courtesy of trancexx's UDF):

Label_Master:

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

#include "MailSlot.au3"

; Array to hold ControlIDs of labels
Global $aData[101]

; Create the Mailslot

$sRandomMailSlotname = _RandomStr()
$sMailSlotName = "\\.\mailslot\" & $sRandomMailSlotname

$hMailSlot = _MailSlotCreate($sMailSlotName)
If @error Then
    MsgBox(48, "MailSlot for Label_Master", "Failed to create account!")
    Exit
EndIf



SplashTextOn("Label test", "Creating child processes!")

; Set start time - this allows all child processes to be created before colour changes are started
$iBaseMin = @MIN
If $iBaseMin = 59 Then $iBaseMin = -1

; Launch 100 child processes - each will change the colour of one label
For $i = 1 To 100
    ; Randomize the Random seed for each child or we get the same colour for each!
    $iSeed = Random(1, 2^10, 1)
    ; Pass parameters to the child process
    ShellExecute("Label_Child.exe", $i & " " & $iBaseMin & " " & $iSeed & " " & $sMailSlotName)
Next

SplashOff()

; Create GUI
$hGUI = GUICreate("Label_Master", 510, 510)

; Create labels
For $i = 0 To 9
    For $j = 0 To 9
        $iIndex = $j + ($i * 10) + 1
        $aData[$iIndex] = GUICtrlCreateLabel("", 10 + ($j * 50), 10 + ($i * 50), 40, 40)
        GUICtrlSetBkColor(-1, 0xC4C4C4)
        GUICtrlSetFont(-1, 18)
    Next
Next

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch



    ; Is there a message?
    Local $iSize = _MailSlotCheckForNextMessage($hMailSlot)
    If $iSize Then
        ; If so then read it
        $sMessage = _MailSlotRead($hMailSlot, $iSize, 1)
        ; Split into sections
        $aSplit = StringSplit($sMessage, ":")
        $iIndex = Number($aSplit[1])
        $iColour = Number($aSplit[2])
        ; Colour label
        GUICtrlSetBkColor($aData[$iIndex], $iColour)
        ; Increase count - just to show that each label change get honoured
        GUICtrlSetData($aData[$iIndex], GUICtrlRead($aData[$iInDex]) + 1)

    EndIf





WEnd



Func _RandomStr()
    Local $sString



    For $i = 1 To 13
        $sString &= Chr(Random(97, 122, 1))
    Next
    Return $sString



EndFunc   ;==>__RandomStr

Label_Child:

#include "MailSlot.au3"

If $CmdLine[0] = 0 Then Exit

; Read parameters
$iIndex = $CmdLine[1]
$iBaseMin = $CmdLine[2]
$iSeed = $CmdLine[3]
$sMailSlotName = $CmdLine[4]

; Randomize the random process
SRandom($iSeed)

; Sleep to allow all child processes to be created
Do
    Sleep(10)
Until @MIN >= $iBaseMin + 1

; 5 cycles
For $i = 1 To 5
    ; Stagger the requests
    Sleep(Random(1, 5, 1) * 1000)
    ; Generate colour
    $iColour = Dec(Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2))
    ; Send colour to MailSlot

    _MailSlotWrite($sMailSlotName, String($iIndex) & ":" & String($iColour))
Next

Well that was a fun way to pass a few hours. What do others think about the 3 different methods? Which seems best suited to the task?

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Hi all, thanks a lot for interesting answers :)


taking into account the "results" that I would get, as from my previous post #9, I tried these different ways to get the color change of the controls by another process,
I report again here in summary the "constraints" that I would prefer not break, (or rather, to which I would like to approach)
1) on the "main" process, there are "many" label controls involved (say from about 100 to 1000 or so)
2) I have to pawn a number of separate running Processes and each of them need to change the color of one or even more of the Label controls on the Gui of the Main program.
3) The many running processes should "update" the colours of the labels autonomously, without involving (or better involving as less as possible) the main script.

@Danyfirex way, needs to create a second control to be used as data broker. It's a nice solution to pass data from a process to the other (even if for this case, where there are many Labels involved, it's a bit  cumbersome to have to double all controls...). Also, the main script is anyway not free, since has to worry to check all the controls containing color data and implement by himself the changing on the labels accordingly. (criticalities on above point 3)

here how I've used your way:

save this as main1.au3 (and also save next script as child1.au3 before running main1.au3)

#include <GUIConstantsEx.au3>
HotKeySet("{ESC}", "_Bye")
; Array to hold data - ControlIDs of inputs, labels and current colours
Global $aData[101][2]

; Create GUI
$hGUI = GUICreate("Label_Master", 510, 510)

; Create labels and hidden inputs
For $i = 0 To 9
    For $j = 0 To 9
        $iIndex = $j + ($i * 10) + 1
        $aData[$iIndex][1] = GUICtrlCreateLabel("100", 10 + ($j * 50), 10 + ($i * 50), 40, 40)
        GUICtrlSetBkColor(-1, 0xC4C4C4)
        GUICtrlSetFont(-1, 18)
        $aData[$iIndex][0] = GUICtrlCreateInput("", 10 + ($j * 50), 600 + ($i * 50), 40, 40)
    Next
Next
GUISetState()

; Launch 100 child processes - each will change the colour of one label
For $x = 1 To 100
    ; Pass parameters to the child process
    Run(@AutoItExe & " .\Child1.au3 " & $x & " " & $hGUI)
    GUICtrlSetBkColor($aData[$x][1], Random(0, 16777215, 1))
Next
Local $iIncrease = False
Do
    If $iIncrease Then
        $x += 1
    Else
        $x -= 1
    EndIf
    ; For each input
    For $i = 1 To 100
        ; Read content
        $iColour = Number(GUICtrlRead($aData[$i][0]))
        GUICtrlSetBkColor($aData[$i][1], $iColour)

        ; Cange count - just to cshow that each label change get honoured
        GUICtrlSetData($aData[$i][1], $x)
    Next
    If $x < 1 Then $iIncrease = True
    If $x > 99 Then $iIncrease = False
Until GUIGetMsg() = $GUI_EVENT_CLOSE
Func _Bye()
    Exit
EndFunc   ;==>_Bye

child1.au3

If $CmdLine[0] = 0 Then Exit

; Read parameters
$iIndex = $CmdLine[1] ; nr. of the control to bind to
$hParent = $CmdLine[2] ; parent window

; Randomize the random process
SRandom(@MSEC)  ; Randomize the Random seed for each child or we get the same colour for each!

; endless cycle
While WinExists(HWnd($hParent)) ; when parent window will close this process will also close itself
    $iColour =  Random(0, 16777215, 1) ; Dec(Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2))
    ; Tell master
    ControlSetText("Label_Master", "", "Edit" & $iIndex, $iColour)
    ; ControlSetText("Label_Master", "", "Static"& $iIndex, @LF& $iColour) ;  , Chr(Random(64, 127, 1))) ; & $iIndex
    Sleep(50)
WEnd

 

@LarsJ way, is the most close to what I would like to achieve, even if it's more a workaround than a solution because it doesn't act directly on the color of the control, but it seems to me that it overlaps a "layer of paint" on the control itself. The final effect is really nice. Also, all the job is done by the separate task, leaving the main script completly  free concerning the update of the label controls. it would be perfect if only it could change the own color of the label instead of painting on it. (criticalities on above point 2)

here how I've used your way:

save this as main2.au3 (and also save next script as child2.au3 before running main2.au3)

#include <GUIConstantsEx.au3>
; Array to hold ControlIDs
Global $aData[101]

; Create GUI
$hGUI = GUICreate("Label_Master", 510, 510)

; Create labels
For $i = 0 To 9
    For $j = 0 To 9
        $iIndex = $j + ($i * 10) + 1
        $aData[$iIndex] = GUICtrlCreateLabel("", 10 + ($j * 50), 10 + ($i * 50), 40, 40)
        GUICtrlSetBkColor(-1, 0xC4C4C4)
    Next
Next
GUISetState()
; Launch 100 child processes - each will change the colour of one label
For $x = 1 To 100
    ; Pass parameters to the child process
    Run(@AutoItExe & " .\Child2.au3 " & ControlGetHandle("", "", $aData[$x]) & " " & $hGUI)
    Sleep(10)
Next
MsgBox(0, "Info", "Main script is in pause" & @LF & "100 separate processes are running," & @LF & "each of them paints on each label autonomously." & @LF & "Click OK to exit")

child2.au3

#include <WinAPI.au3>
If $CmdLine[0] = 0 Then Exit

; Read parameters
$iIndex = $CmdLine[1] ; nr. of the control to bind to
$hParent = HWnd($CmdLine[2]) ; parent window

; Randomize the random process
SRandom(@MSEC) ; Randomize the Random seed for each child or we get the same colour for each!

; Local $aPos = WinGetPos($iIndex)
Local $tRECT = DllStructCreate($tagRECT)
DllStructSetData($tRECT, 'Left', 1)
DllStructSetData($tRECT, 'Top', 1)
DllStructSetData($tRECT, 'Right', 39) ; $aPos[2] - 1)
DllStructSetData($tRECT, 'Bottom', 39) ; $aPos[3] - 1)
Local $pRECT = DllStructGetPtr($tRECT)
$hDC = _WinAPI_GetDC($iIndex)
Local $hBrush, $iColor

; endless cycle
While WinExists(HWnd($hParent)) ; when parent window will close this process will also close itself
    ; Tell master
    $iColor = "0x" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2)
    $hBrush = DllCall("gdi32.dll", "handle", "CreateSolidBrush", "INT", $iColor) ; "0x" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2))
    DllCall("user32.dll", "int", "FillRect", "handle", $hDC, "struct*", $pRECT, "handle", $hBrush[0])
    DllCall("gdi32.dll", "bool", "DeleteObject", "handle", $hBrush[0])
    Sleep(20)
WEnd
_WinAPI_ReleaseDC($iIndex, $hDC)
_WinAPI_DeleteObject($hBrush)

 

@Melba way, Very interesting the use of mailslot, it's perfect to pass parameters between different processes, but, it's necessary to poll incoming messages by the script itself. Indeed you have continuously check for incoming messages in a loop (instead of as in LarsJ's mode). (criticalities on above point 3)

here how I've modified a little your example above:

save this as main3.au3 (and also save next script as child3.au3 before running main3.au3)

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

#include "MailSlot.au3"

; Array to hold ControlIDs of labels
Global $aData[101]

; Create the Mailslot

$sRandomMailSlotname = _RandomStr()
$sMailSlotName = "\\.\mailslot\" & $sRandomMailSlotname

$hMailSlot = _MailSlotCreate($sMailSlotName)
If @error Then
    MsgBox(48, "MailSlot for Label_Master", "Failed to create account!")
    Exit
EndIf

; Create GUI
$hGUI = GUICreate("Label_Master", 510, 510)

; Create labels
For $i = 0 To 9
    For $j = 0 To 9
        $iIndex = $j + ($i * 10) + 1
        $aData[$iIndex] = GUICtrlCreateLabel("", 10 + ($j * 50), 10 + ($i * 50), 40, 40)
        GUICtrlSetBkColor(-1, 0xC4C4C4)
        GUICtrlSetFont(-1, 18)
    Next
Next

GUISetState()

; Launch 100 child processes - each will change the colour of one label
For $i = 1 To 100
    ; Pass parameters to the child process
    Run(@AutoItExe & " child3.au3 " & $i & " " & $hGUI & " " & $sMailSlotName)
    Sleep(50)
    GUICtrlSetBkColor($aData[$i], Random(0, 16777215, 1))
Next
Do
    ; Is there a message?
    Local $iSize = _MailSlotCheckForNextMessage($hMailSlot)
    If $iSize Then
        ; If so then read it
        $sMessage = _MailSlotRead($hMailSlot, $iSize, 1)
        ; Split into sections
        $aSplit = StringSplit($sMessage, ":")
        $iIndex = Number($aSplit[1])
        $iColour = Number($aSplit[2])
        ; Colour label
        GUICtrlSetBkColor($aData[$iIndex], $iColour)
        ; Increase count - just to show that each label change get honoured
        GUICtrlSetData($aData[$iIndex], GUICtrlRead($aData[$iIndex]) + 1)
    EndIf
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func _RandomStr()
    Local $sString
    For $i = 1 To 13
        $sString &= Chr(Random(97, 122, 1))
    Next
    Return $sString
EndFunc   ;==>_RandomStr

child3.au3

#include "MailSlot.au3"

If $CmdLine[0] = 0 Then Exit

; Read parameters
$iIndex = $CmdLine[1]
$hParent = $CmdLine[2]
$sMailSlotName = $CmdLine[3]

; Randomize the random process
SRandom(@MSEC ) ; Randomize the Random seed for each child or we get the same colour for each!

; endless cycle
While WinExists(HWnd($hParent)) ; when parent window will close this process will also close itself
    ; Stagger the requests
    Sleep(Random(1, 5, 1) * 100)
    ; Generate random colour
    $iColour = Random(0, 16777215, 1)
    ; Send colour to MailSlot
    _MailSlotWrite($sMailSlotName, String($iIndex) & ":" & String($iColour))
WEnd

Thanks a lot to all for again for your nice ideas

p.s
I'm testing a new way that make use of the "_WM_CTLCOLORSTATIC" message, I will post it in short

... to be continued ...

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • Moderators

Chimp,

As I have stated before in the thread, giving us an idea of what you are trying to achieve rather than a whole list of constraints on how you want to do it might allow us to offer you yet another, better way.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Sorry melba, you are right, I completely forget to tell my final goal.


In very short:

What I want (I would) to write is a main script, say I will call it "Mega Ping", that will spawn many processes.

Each of those many separate processes will perform a range of Ping on a range of computers. So, if I spawn 100 processes, and each of those 100 processes will perform say (100)  10 ping in turn, I should run 1000 ping against 1000 computers (this is only a theoretical example untested ...)
Now, all those separate processes should report results of those ping managed by themselves back to the main script, showing the results by colors on a matrix of labels located on the main script. (say responding device with a green label and not responding devices with a red label)
That's all... (for now)

edit:

I'm been inspired on this other post: https://www.autoitscript.com/forum/topic/156395-versatile-multi-ping/?do=findComment&comment=1275681

Edited by Chimp
added infos

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • Moderators

Chimp,

I am afraid that sounds a lot like something we would not want to support. Why do you want to ping 10000 computers?

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

just 1000, not 10000
I meant 100 processes that spawns 10 pings each...
Anyway should be a powerful pinger for network administrators, so to allow with just a quick lookout on the visual  matrix if some monitored host is offline.

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • Moderators

Chimp,

Quite frankly I do not see why you need to spawn umpteen child processes rather than ping these machines within the main script itself, How often are you intending to ping each of them anyway? I cannot believe that networks which would use an AutoIt script for such a purpose would ever be that time critical - if they were, they would use something much faster.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Regardless of the number of how many hosts can be monitored, I really don't see how this kind of tool could be a problem. Also considering that pinging hosts is a really harmless activity. Even more harmless if considering that pings are all performed against different hosts and not all against a single host. (maybe in this last case it could be argued a possible d.o.s. attack against some host?  .....maybe not dangerous even in this case I think)
I've really no bad intention, indeed... I'm quite sure this tool could be very useful.
About why I  need to spawn umpteen child processes rather than ping these machines within the main script itself, well is because I'm trying to get all ping results as quick as possible. Is not at all a "time critical" problem, but only a way to reach the best possible improvements on performances. As quickly as I can see a "red label" on the matrix, as quickly as I can go into the matter of the problem.
A way to manage all those pings, within the same script, is an already ready script as from the udf and relative examples in this thread, but I think that there are possible and good margins for improvements.

Now, about my problem in first post, I have found another way to change the color of the labels from another script, but it gives some little issues. .... can I go ahead here and post what I've so far, so to have yours opinions, or I have to give up?

Thanks

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • Moderators

Chimp,

By all means go ahead - but I really do think you are overcomplicating the whole thing.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thank You,

well, in this new way I try to rely on the WM_CTLCOLORSTATIC message like this:
1) The child script writes something in the label control of the main script
2) the writing of point 1 fires the WM_CTLCOLORSTATIC message on the main script, that is catched by theGUIRegisterMsg($WM_CTLCOLORSTATIC, '_WM_CTLCOLORSTATIC') function.
3) within the _WM_CTLCOLORSTATIC() function I'm trying to perform the update of the color on the Label, and it seems to work well if I spawn only few external processes.

if I try to spawn all the 100 processes, the loop that runs the processes slow down while processes are spawned and does not reaches the goal of running all processes.

Also, I'm not quite sure on how to manage things within the  _WM_CTLCOLORSTATIC function. I've botched here something found elsewhere, (exactly here), but with a not great result..

Within the  _WM_CTLCOLORSTATIC function I would like to change the color of the background of the label and also the text color as well.

Also another strange issue is that if I drag the main window outside the screen, and then I drag it again in the middle of the screen, also some more labels are mysteriously painted. (?)

suggestions are welcome

Thank you

This is the main.au3

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

; Array to hold data
Global $aData[101]

; Create GUI
Global $hGUI = GUICreate("Label_Master", 510, 510)
Global $hDelay ,$iDelay = 10

; Create labels
For $i = 0 To 9
    For $j = 0 To 9
        $iIndex = $j + ($i * 10) + 1
        $aData[$iIndex] = GUICtrlCreateLabel("", 10 + ($j * 50), 10 + ($i * 50), 40, 40)
        GUICtrlSetBkColor(-1, 0xC4C4C4)
    Next
Next
GUISetState()

; ----- with 10 processes things are OK, but if I try 100 processes things doesn't go.  <---- issue is here?
For $x = 1 To 10 ; 100
    ; Pass parameters to the child process
    Run(@AutoItExe & " .\Child_WM_CTLCOLORSTATIC.au3 " & $x & " " & $hGUI)
    Sleep(100)
Next
GUIRegisterMsg($WM_CTLCOLORSTATIC, '_WM_CTLCOLORSTATIC')

; sleep(5000)
MsgBox(0,"Pause", "Main script is in pause"&@CRLF&"Click Ok to exit")

GUIDelete()
Exit

Func _WM_CTLCOLORSTATIC($hwnd, $iMsg, $wParam, $iParam)
    #forceref $hWnd, $iMsg, $wParam, $iParam
    If TimerDiff($hDelay) > $iDelay Then
        $hDelay = TimerInit()
        Local $iCol = Random(0,16777215,1)
        ; Switch _WinAPI_GetDlgCtrlID($iParam)
        ; Case $aData[2][1]
        ; _WinAPI_SetTextColor($iParam, $iCol)
        ; _WinAPI_SetBkColor($iParam, $iCol)
        GUICtrlSetBkColor(_WinAPI_GetDlgCtrlID($iParam), $iCol)
        ;            _WinAPI_SetBkMode($wParam, $TRANSPARENT)
        ; _WinAPI_GetStockObject($NULL_BRUSH)
        ; EndSwitch
        ; GUIRegisterMsg($WM_CTLCOLORSTATIC, '_WM_CTLCOLORSTATIC')
        ; Return
    EndIf
    ; Return "GUI_RUNDEFMSG"
EndFunc   ;==>_WM_CTLCOLORSTATIC

 

this is Child_WM_CTLCOLORSTATIC.au3

If $CmdLine[0] = 0 Then Exit

; Read parameters
$iIndex = $CmdLine[1] ; nr. of the control to bind to
$hParent = $CmdLine[2] ; parent window

; Randomize the random process
SRandom(@MSEC)    ; Randomize the Random seed for each child or we get the same colour for each!

; endless cycle
While WinExists(HWnd($hParent)) ; when parent window will close this process will also close itself
    ControlSetText($hParent, "", "Static" & $iIndex, Chr(Random(32, 126, 1))) ; & $iIndex
    Sleep(100)
WEnd

 

Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

I've found the cause of the issue of previous post (somewhat subtle).
(I post here since maybe it can be handy for someone sometime)

In this little standalone script (used as a simplified reproducer) is clearly visible the cause of the problem:
There are an input box and a Label;
When you type into the Input box, keystrokes  are copied from the InputBox to the Label.
There is also an GUIRegisterMsg()  to catch the WM_CTLCOLORSTATIC signal (this signal is fired when the Label content is modified).
Now, since the Label is modified also within the  _ WM_CTLCOLORSTATIC  function, this triggers a closed loop, causing the script to stuck, and the GUICtrlSetBkColor Label going crazy.

The solution (or workaround) I've found is visible in the script within the second function _WM_CTLCOLORSTATIC_ok().
Comment out line the line GUIRegisterMsg($WM_CTLCOLORSTATIC, '_WM_CTLCOLORSTATIC') and use line  GUIRegisterMsg($WM_CTLCOLORSTATIC, '_WM_CTLCOLORSTATIC_ok') instead to see the script working ok.

#include <WindowsConstants.au3>
#include <WinAPI.au3>

$hwnd = GUICreate("test",220, 60)
$hInput = GUICtrlCreateInput("", 10, 5, 20, 20)
$iLabel = GUICtrlCreateLabel("", 10, 30, 200, 20, -1, 0x00020000)
GUISetState()

GUIRegisterMsg($WM_CTLCOLORSTATIC, '_WM_CTLCOLORSTATIC') ; Triggered when Label changes NOT OK
; GUIRegisterMsg($WM_CTLCOLORSTATIC, '_WM_CTLCOLORSTATIC_ok') ; Triggered when Label changes OK
While 1
    If GUIGetMsg() = -3 Then ExitLoop
    $key = GUICtrlRead($hInput)
    If $key Then
        ; following change to the label will trigger the event $WM_CTLCOLORSTATIC
        GUICtrlSetData($iLabel, GUICtrlRead($iLabel) & $key) ; --+
        GUICtrlSetData($hInput, "") ;                            |
        $key = "" ;                                              |
    EndIf ;                                                      |
WEnd ;                                                           |
GUIDelete() ;                                                    |
Exit ;                                                           |
;                                                                |
; This function is problematic                                   |
Func _WM_CTLCOLORSTATIC($hwnd, $iMsg, $wParam, $iParam) ;   <----+---------------------------+
    #forceref $hWnd, $iMsg ;                                                                 |
    Local $iID = _WinAPI_GetDlgCtrlID($iParam) ;                            proble due to    |
    Switch _WinAPI_GetDlgCtrlID($iParam) ;                                  closed loop      |
        Case $iLabel ;                                                                       |
            $iCol = Random(0, 16777215, 1) ;                                                 |
            GUICtrlSetBkColor(_WinAPI_GetDlgCtrlID($iParam), $iCol) ; - trigger fired again -+
            Return
    EndSwitch
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>_WM_CTLCOLORSTATIC

; This function works OK
Func _WM_CTLCOLORSTATIC_ok($hwnd, $iMsg, $wParam, $iParam)
    #forceref $hWnd, $iMsg
    Local Static $bTriggered = False
    Local $iID = _WinAPI_GetDlgCtrlID($iParam) ; from handle to ID
    Switch $iID
        Case $iLabel
            If Not $bTriggered Then ; to prevent the triggering of the "closed loop"
                $iCol = Random(0, 16777215, 1)
                $bTriggered = True ; defuse next trigger
                GUICtrlSetBkColor($iID, $iCol)
                Return
            EndIf
            $bTriggered = False ; ok trigger loop was defused
    EndSwitch
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>_WM_CTLCOLORSTATIC_ok

 

p.s.

Here is the working version of the scripts from post #36

Main.au3

; Main
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <array.au3>

; Array to hold data - ControlIDs of inputs, labels and current colours
Global $aData[101]

; Create GUI
Global $hGUI = GUICreate("Label_Master", 510, 510)
Global $hDelay, $iDelay = 10

; Create labels and hidden inputs
For $i = 0 To 9
    For $j = 0 To 9
        $iIndex = $j + ($i * 10) + 1
        $aData[$iIndex] = GUICtrlCreateLabel("", 10 + ($j * 50), 10 + ($i * 50), 40, 40)
        ; $aData[$iIndex][0] = GUICtrlGetHandle($aData[$iIndex][1])
        GUICtrlSetBkColor(-1, 0x888888)
        GUICtrlSetFont(-1, 12)
    Next
Next
$aData[0] = UBound($aData) - 1
GUISetState()

; Launch 100 child processes - each will change the colour of one label
For $iIndex = 1 To $aData[0]
    ; Pass parameters to the child process
    ; First parameter id the handle of the control
    ; second parameter id the handle of the window
    Run(@AutoItExe & " .\child.au3 " & $aData[$iIndex] & " " & $hGUI)
Next
GUIRegisterMsg($WM_CTLCOLORSTATIC, '_WM_CTLCOLORSTATIC')
MsgBox(0, 0, "Pausa")

GUIDelete()
Exit

Func _WM_CTLCOLORSTATIC($hwnd, $iMsg, $wParam, $iParam)
    #forceref $hWnd, $iMsg, $wParam
    Local Static $bTriggered = False
    Local $iID = _WinAPI_GetDlgCtrlID($iParam) ; from handle to ID
    Switch $iID
        Case $aData[1] To $aData[$aData[0]]
            If Not $bTriggered Then ; to prevent the triggering of the "closed loop"
                $bTriggered = True ; defuse next trigger
                GUICtrlSetBkColor($iID, Random(0, 16777215, 1))
                Return
            EndIf
            $bTriggered = False ; ok trigger loop was defused
    EndSwitch
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>_WM_CTLCOLORSTATIC

 

child.au3

; Child
If $CmdLine[0] = 0 Then Exit

; Read parameters
$iID = $CmdLine[1] ; ID of the control to bind to
$hParentWin = HWnd($CmdLine[2]) ; parent window's handle
Sleep(6000) ; wait a few seconds for all other processes to start before beginning to work all together
; Randomize the random process
SRandom(@MSEC) ; Randomize the Random seed for each child or we get the same colour for each!
; endless cycle
While WinExists(HWnd($hParentWin)) ; when parent window will close, then this process will close itself
    ; Tell master
    ; ControlSetText($hParent, "", $iID, Chr(Random(64, 127, 1))) ; with direct $iID it doesn't works. ??
    ControlSetText($hParentWin, "", "[ID:" & $iID & "]", Chr(Random(64, 127, 1)))
    ; the following delay is for avoiding the overload of the window's signals queue
    ; when there are many child procese running at the same time.
    ; Random's Min and Max values should be calibrated accordingly.
    Sleep(Random(500, 1000, 1)) ; from half to 1 second delay
WEnd

 

Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

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...