Jump to content
gil900

Multiple guis using MY_WM_COMMAND approach

Recommended Posts

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

Thank you so much for existing, Autoit and it's community is awesome and gave me very much!
I am so grateful so I contributed 100$ because I feel that this is the right thing to do  :)
If anyone also thinks that he should contribute because he benefits from Autoit, I suggest doing the same

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

×
×
  • Create New...