gil900

Multiple guis using MY_WM_COMMAND approach

1 post in this topic

#1 ·  Posted (edited)

Hello,

I worte this example:

#AutoIt3Wrapper_Run_AU3Check=n
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <MenuConstants.au3>
#include <Array.au3>




; ----------------------------------------------------- High Level Code -------------------------------------------------------
HotKeySet('{ESC}','Exit1')
Func Exit1()
    Exit
EndFunc


#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Main GUI", 188, 122)
$Button1 = GUICtrlCreateButton("Button1", 24, 16, 145, 33)
$Button2 = GUICtrlCreateButton("Button2", 24, 64, 145, 33)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###



SubGUI1(1) ; Create SubGUI1 in "background loop"
SubGUI2(1) ; Create SubGUI2 in "background loop"


While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE ; Click X to Exit from the main loop. **you  should close SubGUI1 and SubGUI2 first!
            GUIDelete($Form1)
            ExitLoop
        Case $Button1
            ConsoleWrite('$Button1 Selected' & @CRLF)
        Case $Button2
            ConsoleWrite('$Button2 Selected' & @CRLF)
    EndSwitch
WEnd


SubGUI1(0) ; Create again SubGUI1 AS MAIN LOOP mode (no need for while)

; ------------------------------------------------------ End -------------------------------------------------------








; ------------------------------------------------- SubGUI1 ------------------------------------------------
Func SubGUI1($background)
    #Region ### START Koda GUI section ### Form=
    #Region ### START Koda GUI section ### Form=
    Local $SubGUI1 = GUICreate("Sub GUI 1", 188, 180,-1, -1, BitOR($WS_MINIMIZEBOX, $WS_GROUP))
    Local $Button1 = GUICtrlCreateButton("Button1", 24, 16, 145, 33)
    Local $Button2 = GUICtrlCreateButton("Button2", 24, 64, 145, 33)
    Local $Button3 = GUICtrlCreateButton("Close", 24, 104, 145, 33)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

    SubGUI1_While(0, _
    $Button1, _
    $Button2, _
    $Button3)


    If Not $background Then
        Do
        Until SubGUI1_While(GUIGetMsg())
        GUIDelete($SubGUI1)
    Else
        MY_WM_COMMAND_AddRemoveGui(1,$SubGUI1,'SubGUI1_While')
    EndIf
EndFunc

Func SubGUI1_While($Msg,$LButton1 = 0,$LButton2 = 0,$LButton3 = 0)
    Local Static $Button1,$Button2,$Button3
;~  If $Msg = -1 Then
;~      $Button1 = 0
;~      $Button2 = 0
;~      $Button3 = 0
;~      Return
;~  EndIf

    If $LButton1 Then
        $Button1 = $LButton1
        $Button2 = $LButton2
        $Button3 = $LButton3
        Return
    EndIf

    ;ConsoleWrite($nMsg2[1] & @CRLF)
    Switch $Msg
        Case $Button1
            ConsoleWrite('$Button1' & @CRLF)
        Case $Button2
            ConsoleWrite('$Button2' & @CRLF)
        Case $Button3
            ConsoleWrite('$Button3' & @CRLF)
            Return 1 ; <-------------------- Must RETURN 1 in order to close the GUI !!!!!!
    EndSwitch
EndFunc
; -----------------------------------------------------------------------------------------------------







; ------------------------------------------------- SubGUI2 ------------------------------------------------
Func SubGUI2($background)

    #Region ### START Koda GUI section ### Form=
    #Region ### START Koda GUI section ### Form=
    Local $SubGUI1 = GUICreate("Sub GUI 2", 188, 180,-1, -1, BitOR($WS_MINIMIZEBOX, $WS_GROUP))
    Local $Button1 = GUICtrlCreateButton("Button1", 24, 16, 145, 33)
    Local $Button2 = GUICtrlCreateButton("Button2", 24, 64, 145, 33)
    Local $Button3 = GUICtrlCreateButton("Close", 24, 104, 145, 33)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

    SubGUI2_While(0, _
    $Button1, _
    $Button2, _
    $Button3)


    If Not $background Then
        Do
        Until SubGUI2_While(GUIGetMsg())
        GUIDelete($SubGUI2)
    Else
        MY_WM_COMMAND_AddRemoveGui(1,$SubGUI1,'SubGUI2_While')
    EndIf
EndFunc


Func SubGUI2_While($Msg,$LButton1 = 0,$LButton2 = 0,$LButton3 = 0)
    Local Static $Button1,$Button2,$Button3
;~  If $Msg = -1 Then
;~      $Button1 = 0
;~      $Button2 = 0
;~      $Button3 = 0
;~      Return
;~  EndIf

    If $LButton1 Then
        $Button1 = $LButton1
        $Button2 = $LButton2
        $Button3 = $LButton3
        Return
    EndIf

    ;ConsoleWrite($nMsg2[1] & @CRLF)
    Switch $Msg
        Case $Button1
            ConsoleWrite('$Button1' & @CRLF)
        Case $Button2
            ConsoleWrite('$Button2' & @CRLF)
        Case $Button3
            ConsoleWrite('$Button3' & @CRLF)
            Return 1 ; <-------------------- Must RETURN 1 in order to close the GUI !!!!!!
    EndSwitch
EndFunc
; -----------------------------------------------------------------------------------------------------







;
Func MY_WM_COMMAND_Register($Register)
    Local Static $IsRegistred,$Globals
    If Not $Globals Then
        Global $g_aGUIs[1][2] = [[0]]
        $Globals = 1
    EndIf

    If $Register Then
        If $IsRegistred Then Return
        GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")
        $IsRegistred = 1
    Else
        If Not $IsRegistred Then Return
        GUIRegisterMsg($WM_COMMAND, "")
        $IsRegistred = 0
    EndIf

;~  _ArrayDisplay($g_aGUIs)
EndFunc

Func MY_WM_COMMAND_AddRemoveGui($AddRemove,$hGUI,$sFunction)
    If $AddRemove = 3 Then
        Global $g_aGUIs[1][2] = [[0]]
        Return
    EndIf

    If $AddRemove Then
        MY_WM_COMMAND_Register(1)
        $g_aGUIs[0][0] += 1
        ReDim $g_aGUIs[$g_aGUIs[0][0]+1][2]
        $g_aGUIs[$g_aGUIs[0][0]][0] = $hGUI
        $g_aGUIs[$g_aGUIs[0][0]][1] = $sFunction
    Else
        Local $SIndex = $sFunction
        If Not IsNumber($SIndex) Then $SIndex = Array2DSearch($g_aGUIs, $sFunction, 1)
        If $SIndex < 0 Then Return
        _ArrayDelete($g_aGUIs,$SIndex)
        $g_aGUIs[0][0] -= 1
        If Not $g_aGUIs[0][0] Then MY_WM_COMMAND_Register(0)
    EndIf

;~  _ArrayDisplay($g_aGUIs)
EndFunc




; React on a button click
Func MY_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)

    Local $nNotifyCode = BitShift($wParam, 16),$nID = BitAND($wParam, 0x0000FFFF),$hCtrl = $lParam

    If $nID <> 2 And $nNotifyCode = 0 Then ; Check for IDCANCEL - 2

        ; Ownerdrawn buttons don't send something by pressing ENTER
        ; So IDOK - 1 comes up, now check for the control that has the current focus
        If $nID = 1 Then
            Local $hFocus = DllCall("user32.dll", "hwnd", "GetFocus"), _
            $nCtrlID = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hFocus[0])
            PostButtonClick($hWnd, $nCtrlID[0])
        Else

            Local $SIndex = Array2DSearch($g_aGUIs, $hWnd, 0)
            If $SIndex > 0 Then

                If Call($g_aGUIs[$SIndex][1],$nID) Then



                    GUIDelete($g_aGUIs[$SIndex][0])
                    MY_WM_COMMAND_AddRemoveGui(0,Default,$SIndex)

                EndIf
            EndIf

;~          ConsoleWrite("GUIHWnd" & @TAB & ":" & $hWnd & @CRLF & _
;~          "MsgID" & @TAB & ":" & $Msg & @CRLF & _
;~          "wParam" & @TAB & ":" & $wParam & @CRLF & _
;~          "lParam" & @TAB & ":" & $lParam & @CRLF & @CRLF & _
;~          "WM_COMMAND - Infos:" & @CRLF & _
;~          "-----------------------------" & @CRLF & _
;~          "Code" & @TAB & ":" & $nNotifyCode & @CRLF & _
;~          "CtrlID" & @TAB & ":" & $nID & @CRLF & _
;~          "CtrlHWnd" & @TAB & ":" & $hCtrl)
        EndIf
;~         Return 0 ; Only workout clicking on the button
    EndIf

    Return $GUI_RUNDEFMSG
EndFunc   ;==>MY_WM_COMMAND







Func _WM_SYSCOMMAND($hWnd, $Msg, $wParam, $lParam)

    If $wParam = $SC_CLOSE Then
        ConsoleWrite("Close detected" & @CRLF)
    EndIf

EndFunc


; RePost a WM_COMMAND message to a ctrl in a gui window
Func PostButtonClick($hWnd, $nCtrlID)
    DllCall("user32.dll", "int", "PostMessage", _
            "hwnd", $hWnd, _
            "int", $WM_COMMAND, _
            "int", BitAND($nCtrlID, 0x0000FFFF), _
            "hwnd", GUICtrlGetHandle($nCtrlID))
EndFunc   ;==>PostButtonClick


Func Array2DSearch($aArray, $String, $Dimension, $StartIndex = 1, $EndIndex = "")
    Local $Output = -1, $a
    ;If IsArray($aArray) Then
    ;   Local $a
    If $EndIndex = "" Then $EndIndex = UBound($aArray) - 1
    If $StartIndex >= 0 And $StartIndex <= $EndIndex Then
        For $a = $StartIndex To $EndIndex
            If $aArray[$a][$Dimension] = $String Then
                $Output = $a
                ExitLoop
            EndIf
        Next
    EndIf
    ;EndIf
    Return $Output
EndFunc   ;==>Array2DSearch

EDIT (11.2.2015): I did some corrections example

 

In my case, the structure of my software is one main GUI with its own loop..

I had to think of an elegant solution how to get the ability to open/run others GUIs that run alongside to the main gui without freezing the main GUI and without touching the structure of the code..

 

 I do not know if you get what I said (I hope you do)

So this is how I did it.

I hope you liked it and you will find it useful

Edited by gil900

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