[已解决]请问如何响应WM_CLOSE消息
本帖最后由 ScriptFans 于 2018-8-6 17:34 编辑是这样的,我不想用消息循环模式,想要把关闭窗口用事件响应的方式实现,测试代码如下:
#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
上面代码点击关闭没反应,不知该如何实现,请大家指教!
顺便再请教一句:发帖的时候我没找到怎么设置代码高亮
#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
chzj589 发表于 2018-8-5 21:52
#include
#include
抱歉,忘记说明了,我不想用GUICtrlSetOnEvent模式,这个模式是在是太容易出问题了,尤其是在多窗口的情况。我现在想把程序中所有事件响应用guiregistermsg()函数来实现,目前就差关闭窗口没能成功。
我测试过WM_DESDROY可以成功响应,但是WM_CLOSE就是不行。感谢回复,还请继续指教!
ScriptFans 发表于 2018-8-5 21:59
抱歉,忘记说明了,我不想用GUICtrlSetOnEvent模式,这个模式是在是太容易出问题了,尤其是在多窗口的情 ...
我己习惯用GUICtrlSetOnEvent模式,再多的窗口也没有出现问题。
用WM_CLOSE还不会。
期待高手 chzj589 发表于 2018-8-5 22:05
我己习惯用GUICtrlSetOnEvent模式,再多的窗口也没有出现问题。
用WM_CLOSE还不会。
期待高手
还是感谢,记得兄弟的出入库管理系统相当漂亮! 我猜,WM_CLOSE是有窗口关闭时才会发出消息,窗口关闭了,程序也就执行完了,用户函数来不及处理。 本帖最后由 ScriptFans 于 2018-8-6 08:38 编辑
顽固不化 发表于 2018-8-5 23:32
我猜,WM_CLOSE是有窗口关闭时才会发出消息,窗口关闭了,程序也就执行完了,用户函数来不及处理。
这是我百度的:win32应用程序的完整退出过程:点击窗口右上角的关闭按钮,发送WM_CLOSE消息。此消息处理中调用DestroyWindow函数,发送WM_DESTROY消息。此消息处理中调用PostQuitMessage(0)函数,发送WM_QUIT消息到消息队列中。GetMessage捕获到WM_QUIT,返回0,退出循环(应用程序真正退出)。
我试过在消息循环中处理$GUI_EVENT_CLOSE,同时guiregister()注册WM_DESTROY,这样能够响应WM_DESTROY(手机回复,代码不便上),但此时窗口已经关闭了。我想在窗口关闭之前响应消息,应该还得是WM_CLOSE ScriptFans 发表于 2018-8-6 08:31
这是我百度的:win32应用程序的完整退出过程:点击窗口右上角的关闭按钮 ...
恩恩,明白,也许真的有bug。 這個方法呢??
#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 本帖最后由 ScriptFans 于 2018-8-6 16:33 编辑
kk_lee69 发表于 2018-8-6 13:06
這個方法呢??
#include
感谢回复,兄弟的还是用到了消息循环,我本意就是想避开循环,全用guiregistermsg()来响应消息。当然有其他办法注册消息函数也可以。记得自带的_winapi有个shellhook函数(手机回复不便查)好像可以捕捉所有窗口的各类消息,没测试,晚上有空试试,但即使可以,我觉得这类方法也比单纯只处理自身窗口消息要更耗资源。
抱歉,刚才没仔细看代码,晚上我测试下WM_SYSCOMMAND的wParam有没有包含窗口关闭的信息。
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
只是我把離開 註解掉了
不就達成你要的嗎??
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 本帖最后由 ScriptFans 于 2018-8-6 17:32 编辑
kk_lee69 发表于 2018-8-6 16:59
#include
#include
刚百度了一下WM_SYSCOMMAND,正是我想要的,非常感谢兄弟的解答,原来点击窗口右上角那几个按钮的时候发送的是这个消息!一直在外面忙工作,没仔细琢磨代码,真是抱歉!
页:
[1]