找回密码  加入

AUTOIT CN

搜索
查看: 335|回复: 12

[AU3基础] [已解决]请问如何响应WM_CLOSE消息

[复制链接]
发表于 2018-8-5 21:28:01 | 显示全部楼层 |阅读模式
本帖最后由 ScriptFans 于 2018-8-6 17:34 编辑

是这样的,我不想用消息循环模式,想要把关闭窗口用事件响应的方式实现,测试代码如下:
[mw_shl_code=actionscript3,true]#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$Form1 = GUICreate("Form1", 369, 222, 192, 124)
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_CLOSE, "WM_CLOSE")

While 1
        ;$nMsg = GUIGetMsg()
        ;Switch $nMsg
        ;        Case $GUI_EVENT_CLOSE
        ;                Exit
        ;EndSwitch
        Sleep(10000)
WEnd

Func WM_CLOSE($a, $b, $c, $d)
        MsgBox(0,"","关闭")
        Exit
EndFunc[/mw_shl_code]
上面代码点击关闭没反应,不知该如何实现,请大家指教!

顺便再请教一句:发帖的时候我没找到怎么设置代码高亮
发表于 2018-8-5 21:52:26 | 显示全部楼层
[au3]
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
$Form1 = GUICreate("Form1", 369, 222, 192, 124)
GUISetOnEvent($GUI_EVENT_CLOSE, "_CloseExit")
$Button1 = GUICtrlCreateButton("关闭", 300, 190, 60, 22, 0)
GUICtrlSetOnEvent($Button1, "_CloseExit")
GUISetState(@SW_SHOW)
While 1
        Sleep(10000)
WEnd
Func _CloseExit()
        MsgBox(0,"","关闭")
        Exit
EndFunc
[/au3]

评分

1

查看全部评分

 楼主| 发表于 2018-8-5 21:59:00 | 显示全部楼层
chzj589 发表于 2018-8-5 21:52
[AU3]
#include
#include

抱歉,忘记说明了,我不想用GUICtrlSetOnEvent模式,这个模式是在是太容易出问题了,尤其是在多窗口的情况。我现在想把程序中所有事件响应用guiregistermsg()函数来实现,目前就差关闭窗口没能成功。
我测试过WM_DESDROY可以成功响应,但是WM_CLOSE就是不行。感谢回复,还请继续指教!
发表于 2018-8-5 22:05:29 | 显示全部楼层
ScriptFans 发表于 2018-8-5 21:59
抱歉,忘记说明了,我不想用GUICtrlSetOnEvent模式,这个模式是在是太容易出问题了,尤其是在多窗口的情 ...

我己习惯用GUICtrlSetOnEvent模式,再多的窗口也没有出现问题。
用WM_CLOSE还不会。
期待高手
 楼主| 发表于 2018-8-5 22:25:50 | 显示全部楼层
chzj589 发表于 2018-8-5 22:05
我己习惯用GUICtrlSetOnEvent模式,再多的窗口也没有出现问题。
用WM_CLOSE还不会。
期待高手

还是感谢,记得兄弟的出入库管理系统相当漂亮!
发表于 2018-8-5 23:32:50 | 显示全部楼层
我猜,WM_CLOSE是有窗口关闭时才会发出消息,窗口关闭了,程序也就执行完了,用户函数来不及处理。
 楼主| 发表于 2018-8-6 08:31:29 | 显示全部楼层
本帖最后由 ScriptFans 于 2018-8-6 08:38 编辑
顽固不化 发表于 2018-8-5 23:32
我猜,WM_CLOSE是有窗口关闭时才会发出消息,窗口关闭了,程序也就执行完了,用户函数来不及处理。

这是我百度的:[mw_shl_code=applescript,true]win32应用程序的完整退出过程:点击窗口右上角的关闭按钮,发送WM_CLOSE消息。此消息处理中调用DestroyWindow函数,发送WM_DESTROY消息。此消息处理中调用PostQuitMessage(0)函数,发送WM_QUIT消息到消息队列中。GetMessage捕获到WM_QUIT,返回0,退出循环(应用程序真正退出)。[/mw_shl_code]
我试过在消息循环中处理$GUI_EVENT_CLOSE,同时guiregister()注册WM_DESTROY,这样能够响应WM_DESTROY(手机回复,代码不便上),但此时窗口已经关闭了。我想在窗口关闭之前响应消息,应该还得是WM_CLOSE
发表于 2018-8-6 09:17:07 | 显示全部楼层
ScriptFans 发表于 2018-8-6 08:31
这是我百度的:[mw_shl_code=applescript,true]win32应用程序的完整退出过程:点击窗口右上角的关闭按钮 ...

恩恩,明白,也许真的有bug。
发表于 2018-8-6 13:06:05 | 显示全部楼层
這個方法呢??

[au3]#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[/au3]

评分

1

查看全部评分

 楼主| 发表于 2018-8-6 15:00:07 | 显示全部楼层
本帖最后由 ScriptFans 于 2018-8-6 16:33 编辑
kk_lee69 发表于 2018-8-6 13:06
這個方法呢??

[AU3]#include

感谢回复,兄弟的还是用到了消息循环,我本意就是想避开循环,全用guiregistermsg()来响应消息。当然有其他办法注册消息函数也可以。记得自带的_winapi有个shellhook函数(手机回复不便查)好像可以捕捉所有窗口的各类消息,没测试,晚上有空试试,但即使可以,我觉得这类方法也比单纯只处理自身窗口消息要更耗资源。
抱歉,刚才没仔细看代码,晚上我测试下WM_SYSCOMMAND的wParam有没有包含窗口关闭的信息。
发表于 2018-8-6 16:57:38 | 显示全部楼层
ScriptFans 发表于 2018-8-6 15:00
感谢回复,兄弟的还是用到了消息循环,我本意就是想避开循环,全用guiregistermsg()来响应消息。当然有其 ...

真的不能理解??   
原文 我不想用消息循环模式,想要把关闭窗口用事件响应的方式实现

消息循環模式  不就是
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

只是我把離開 註解掉了

不就達成你要的嗎??
发表于 2018-8-6 16:59:53 | 显示全部楼层
ScriptFans 发表于 2018-8-6 15:00
感谢回复,兄弟的还是用到了消息循环,我本意就是想避开循环,全用guiregistermsg()来响应消息。当然有其 ...

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

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

While 1
    $msg = GUIGetMsg()
        SLEEP(10)
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

评分

3

查看全部评分

 楼主| 发表于 2018-8-6 17:30:38 | 显示全部楼层
本帖最后由 ScriptFans 于 2018-8-6 17:32 编辑

刚百度了一下WM_SYSCOMMAND,正是我想要的,非常感谢兄弟的解答,原来点击窗口右上角那几个按钮的时候发送的是这个消息!一直在外面忙工作,没仔细琢磨代码,真是抱歉!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|小黑屋|手机版|AUTOIT CN ( 鲁ICP备15028933号-3 )谷歌 百度

GMT+8, 2018-10-18 01:23 , Processed in 0.096972 second(s), 16 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表