# GUI Reference - MessageLoop Mode

In the MessageLoop mode your script will spend the majority of its time in a tight loop. This loop will simply poll the GUI using the GUIGetMsg function. When an event has occurred the return value of the GUIGetMsg function will show the details (a button is clicked, the GUI has been closed, etc.).

The MessageLoop mode is the default message mode for AutoIt GUIs - the other possible mode is the OnEvent mode.

In the MessageLoop mode you will only receive events while you are actively polling the GUIGetMsg function so you must ensure that you call it many times a second otherwise your GUI will be unresponsive.

## Basic MessageLoop Format

The general layout of MessageLoop code is:

    Local $iMsg = 0

    While 1
        $iMsg = GUIGetMsg()
        ...
        ...
    WEnd

Usually a tight loop like the one shown would send the CPU to 100% - fortunately the GUIGetMsg function automatically idles the CPU when there are no events waiting. Do not put a manual sleep in the loop for fear of stressing the CPU - this will only cause the GUI to become unresponsive.

## GUI Events

There are three types of event messages that GUIGetMsg will return:

- No Event
- Control Event
- System Event

No Event

When there are no events waiting to be processed GUIGetMsg returns 0. In a usual GUI this is the most common event.

Control Event

When a control is clicked or changes a control event is sent - this event is a positive number that corresponds to the controlID that was returned when the control was created with GUICtrlCreate....

System Event

System events - such as the GUI closing - are negative numbers. The different events are shown below and are defined in GUIConstantsEx.au3:

    $GUI_EVENT_CLOSE
    $GUI_EVENT_MINIMIZE
    $GUI_EVENT_RESTORE
    $GUI_EVENT_MAXIMIZE
    $GUI_EVENT_PRIMARYDOWN
    $GUI_EVENT_PRIMARYUP
    $GUI_EVENT_SECONDARYDOWN
    $GUI_EVENT_SECONDARYUP
    $GUI_EVENT_MOUSEMOVE
    $GUI_EVENT_RESIZED
    $GUI_EVENT_DROPPED

## Example GUI

In the main GUI Reference page we started a simple Hello World example that looked like this:

    #include <GUIConstantsEx.au3>

    GUICreate("Hello World", 200, 100)
    GUICtrlCreateLabel("Hello world! How are you?", 30, 10)
    GUICtrlCreateButton("OK", 70, 50, 60)
    GUISetState(@SW_SHOW)
    Sleep(2000)

Now we will finish the code using a MessageLoop and some of the event messages described above. It is usual because of the number of possible messages to use a Switch statement for readability.

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

    Local $hGUI = GUICreate("Hello World", 200, 100)
    GUICtrlCreateLabel("Hello world! How are you?", 30, 10)
    Local $iOKButton = GUICtrlCreateButton("OK", 70, 50, 60)
    GUISetState(@SW_SHOW, $hGUI)

    Local $iMsg = 0
    While 1
        $iMsg = GUIGetMsg()
        Switch $iMsg
            Case $iOKButton
                MsgBox($MB_SYSTEMMODAL, "GUI Event", "You selected the OK button.")

            Case $GUI_EVENT_CLOSE
                MsgBox($MB_SYSTEMMODAL, "GUI Event", "You selected the Close button. Exiting...")
                ExitLoop
        EndSwitch
    WEnd

    GUIDelete($hGUI)

It's that simple. Obviously the more windows and controls you create the more complicated it gets but the above shows you the basics.

## Advanced GUIGetMsg and Multiple Windows

Control IDs are unique, even when you have multiple windows, so the above code with work fine with controls and multiple windows. However, when processing events such as $GUI_EVENT_CLOSE or $GUI_MOUSEMOVE you need to know which GUI window generated the event. To do this you must call GUIGetMsg like so:

    $iMsg = GUIGetMsg(1)

When called with the 1 parameter instead of returning an event value an array will be returned, the array contains the event ( in $aArray[0] ) and extra information such as the window handle ( in $aArray[1] ). If two windows were created in the previous example then the correct way to write the code would be:

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

    Local $hMainGUI = GUICreate("Hello World", 200, 100)
    GUICtrlCreateLabel("Hello world! How are you?", 30, 10)
    Local $iOKButton = GUICtrlCreateButton("OK", 70, 50, 60)

    Local $hDummyGUI = GUICreate("Dummy window for testing", 200, 100)

    GUISwitch($hMainGUI)
    GUISetState(@SW_SHOW)

    Local $aMsg = 0
    While 1
        $aMsg = GUIGetMsg(1)

        Select
            Case $aMsg[0] = $iOKButton
                MsgBox($MB_SYSTEMMODAL, "GUI Event", "You selected OK!")

            Case $aMsg[0] = $GUI_EVENT_CLOSE And $aMsg[1] = $hMainGUI
                MsgBox($MB_SYSTEMMODAL, "GUI Event", "You selected CLOSE on the main GUI! Exiting...")
                ExitLoop
        EndSelect
    WEnd

The first major change is the GUISwitch function call - when a new window is created it becomes the "default" window for future GUI operations (including control creation). In our case we want to work with the main "Hello World" window, not the test window, so we "switch". Some GUI functions allow you to use the window handle in the function call itself - these functions will do the switch automatically. In our example we could have done this with:

    GUISetState(@SW_SHOW, $hMainGUI)

The next change is the way GUIGetMsg is called and how the events are checked - notice the use of $msg[0] and $msg[1] - now we only exit the script if the close event is sent and the event is from our main window.