Jump to content

[Solved] How to detect GUI Close...


Recommended Posts

Hello Forum :D ,

my GUI is working in event mode. If I trigger a func which does not return immediately, the gui event 'exit' (click close X) is buffered until the func returns. Is there a way to detect this Exit command via GUIRegisterMsg()? I noticed that WM_Notifiy events are not buffered and executed immediately, so I'm searching for something similar for GUI functions (min, max, close).

Best Regards

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

$Form = GUICreate('', 600, 600)

$ListView = GUICtrlCreateListView(' ', 10, 10, 280, 580, BitOR($LVS_NOCOLUMNHEADER, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_SORTASCENDING))
$hListView = GUICtrlGetHandle($ListView)
_GUICtrlListView_SetColumnWidth($ListView, 0, 258 + 100)
GUIRegisterMsg($WM_CLOSE, 'WM_CLOSE')
GUISetState()

$FileList = _FileListToArray('C:\WINDOWS\system32', '*.ini', 1)
For $i = 1 To $FileList[0]
    GUICtrlCreateListViewItem($FileList[$i], $ListView)
Next

While 1
    $Msg = GUIGetMsg()
    Switch $Msg
        Case 0
            ContinueLoop
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

Func WM_CLOSE($hWnd, $iMsg, $wParam, $lParam)

    Local $tNMHDR = DllStructCreate($tagNMITEMACTIVATE, $lParam)
    Local $IDFrom = DllStructGetData($tNMHDR, 'IDFrom')
    Local $Index = DllStructGetData($tNMHDR, 'Index')
    Local $Code = DllStructGetData($tNMHDR, 'Code')

    ConsoleWrite($IDFrom & @TAB & $Index & @TAB & $Code & @CRLF)

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_CLOSE
Edited by KaFu
Link to comment
Share on other sites

Hello Forum :D ,

my GUI is working in event mode. If I trigger a func which does not return immediately, the gui event 'exit' (click close X) is buffered until the func returns. Is there a way to detect this Exit command via GUIRegisterMsg()? I noticed that WM_Notifiy events are not buffered and executed immediately, so I'm searching for something similar for GUI functions (min, max, close).

Best Regards

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

$Form = GUICreate('', 600, 600)

$ListView = GUICtrlCreateListView(' ', 10, 10, 280, 580, BitOR($LVS_NOCOLUMNHEADER, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_SORTASCENDING))
$hListView = GUICtrlGetHandle($ListView)
_GUICtrlListView_SetColumnWidth($ListView, 0, 258 + 100)
GUIRegisterMsg($WM_CLOSE, 'WM_CLOSE')
GUISetState()

$FileList = _FileListToArray('C:\WINDOWS\system32', '*.ini', 1)
For $i = 1 To $FileList[0]
    GUICtrlCreateListViewItem($FileList[$i], $ListView)
Next

While 1
    $Msg = GUIGetMsg()
    Switch $Msg
        Case 0
            ContinueLoop
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

Func WM_CLOSE($hWnd, $iMsg, $wParam, $lParam)

    Local $tNMHDR = DllStructCreate($tagNMITEMACTIVATE, $lParam)
    Local $IDFrom = DllStructGetData($tNMHDR, 'IDFrom')
    Local $Index = DllStructGetData($tNMHDR, 'Index')
    Local $Code = DllStructGetData($tNMHDR, 'Code')

    ConsoleWrite($IDFrom & @TAB & $Index & @TAB & $Code & @CRLF)

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_CLOSE
I'm not quite sure that I have understood your question, but if you have a function which takes some time and you want to respond to an event like Close while the function is executing, you need to make sure that the function isn't directly called by an event itself.

So, suppose you register an event to call func1 like this

guiregistermsg($eventA,"func1")
GuiRegisterMsg($EventB,"fun2")
while 1
  sleep(20)
wend

Func Func1()
 something which takes time and blocks eventB
endfunc

Func Func2()

endfunc

Then you can get an immediate response to eventB while the function is executing if you do this

guiregistermsg($eventA,"func1")
GuiRegisterMsg($EventB,"fun2")
$Run1a = false
 while 1
   sleep(20)
  If Run1A then 
    func1A()
    Run1A = false
 endif
 wend
 

Func Func1()
 Run1A = true
EndFunc

 Func Func1A()
  something which takes time but doesn't block EventB
 endfunc
 
 Func Func2()
 
 endfunc
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

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

$Form = GUICreate('', 600, 600)

$ListView = GUICtrlCreateListView(' ', 10, 10, 280, 580, BitOR($LVS_NOCOLUMNHEADER, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_SORTASCENDING))
$hListView = GUICtrlGetHandle($ListView)
_GUICtrlListView_SetColumnWidth($ListView, 0, 258 + 100)
GUIRegisterMsg($WM_CLOSE, 'WM_CLOSE')
GUIRegisterMsg($WM_NCLBUTTONDOWN, 'WM_NCLBUTTONDOWN')
GUISetState()

$FileList = _FileListToArray('C:\WINDOWS\system32', '*.dll', 1)
For $i = 1 To $FileList[0]
    GUICtrlCreateListViewItem($FileList[$i], $ListView)
Next

While 1
    $Msg = GUIGetMsg()
    Switch $Msg
        Case 0
            ContinueLoop
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

Func WM_CLOSE($hWnd, $iMsg, $wParam, $lParam)

    Local $tNMHDR = DllStructCreate($tagNMITEMACTIVATE, $lParam)
    Local $IDFrom = DllStructGetData($tNMHDR, 'IDFrom')
    Local $Index = DllStructGetData($tNMHDR, 'Index')
    Local $Code = DllStructGetData($tNMHDR, 'Code')

    ConsoleWrite($IDFrom & @TAB & $Index & @TAB & $Code & @CRLF)

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_CLOSE

Func WM_NCLBUTTONDOWN($hwnd, $iMsg, $iwParam, $ilParam)
    If $iwParam = 0x14 Then
        GUIDelete()
        Exit
    EndIf
    
    Return $GUI_RUNDEFMSG
EndFunc

Link to comment
Share on other sites

I'm not quite sure that I have understood your question, but if you have a function which takes some time and you want to respond to an event like Close while the function is executing, you need to make sure that the function isn't directly called by an event itself.

Thanks for the tip, but my code is much to advanced that I want to change the overall design at this late stage :D , normally I intercept GUI messages by WM_COMMAND, those changes are instantaneously (i set an exit bool for the functions, set to true in WM_COMMAND and at certain time consuming loops in the funcs I check bool, if true then exitloop).

@Authenticity

Nice, that's what I asked for ;) ... but answers lead to new questions :D

It intercepts the close button on the GUI, but not the doubleclick on the upper left icon (it detects single = 0x03), nor ALT+F4 and I also set GUICloseOnESC... *sigh*, will do more research, thanks for the replies.

Link to comment
Share on other sites

After some research I found the following code satisfies my needs, maybe it's helpful for someone else too...

It's derived from Siao's example "Easy shell hooking example, no dlls, no callback udf required..."

; derived from Siao's example: Easy shell hooking example, no dlls, no callback udf required...
; http://www.autoitscript.com/forum/index.php?showtopic=56536&st=0&start=0

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

Local $msg
GUICreate("My GUI")
GUIRegisterMsg($WM_SYSCOMMAND, "On_WM_SYSCOMMAND")
GUISetState(@SW_SHOW)

While 1
    $msg = GUIGetMsg()

    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd
GUIDelete()


Func On_WM_SYSCOMMAND($hWnd, $msg, $wParam, $lParam)
    Local Const $SC_MOVE = 0xF010
    Local Const $SC_SIZE = 0xF000
    Local Const $SC_CLOSE = 0xF060

    Switch BitAND($wParam, 0xFFF0)
        Case $SC_MOVE
            ConsoleWrite("WM_Move detected" & @CRLF)
        Case $SC_SIZE
            ConsoleWrite("WM_Size detected" & @CRLF)
        Case $SC_CLOSE
            ConsoleWrite("WM_Close intercepted" & @CRLF)
            ;Exit
            Return -1
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>On_WM_SYSCOMMAND
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...