关于父子窗口的消息传递的问题
求教大佬,最近测试一个父子窗口例子。发现个问题,界面1与界面2同时打开的时候,按钮弹窗正常,但是先打开界面1关闭后,再打开界面2,按钮弹窗就异常了~~,感觉是$WM_COMMAND消息有问题,但是不知道哪错了- -!!!
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
Global $Main_Form,$MainButton1,$ck_Form,$Button1,$Button2,$ck_in_Form,$ck_in_ok,$ck_in_esc,$ck_out_Form,$ck_out_ok,$ck_out_esc
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND")
main()
Do
Sleep(10)
Until GUIGetMsg() = $GUI_EVENT_CLOSE
Func main();父界面
$Main_Form = GUICreate("父界面", 556, 310, -1, -1)
$MainButton1 = GUICtrlCreateButton("子界面", 212, 80, 75, 25)
GUISetState(@SW_SHOW,$Main_Form)
EndFunc
Func ck();子界面
$ck_Form = GUICreate("子界面", 456, 210, -1, -1)
$Button1 = GUICtrlCreateButton("界面1", 72, 80, 75, 25)
$Button2 = GUICtrlCreateButton("界面2", 232, 80, 75, 25)
GUISetState(@SW_SHOW,$ck_Form)
EndFunc
Func ck_in();界面1
$ck_in_Form = GUICreate("界面1", 172, 296, -1, -1, $WS_SYSMENU, $WS_EX_APPWINDOW,$ck_Form)
$ck_in_ok = GUICtrlCreateButton("入库",12, 38, 83, 41)
$ck_in_esc = GUICtrlCreateButton("取消", 12,88, 83, 41)
GUISetState(@SW_SHOW,$ck_in_Form)
EndFunc ;==>ck_Inventory_manager_in
Func ck_out();界面2
$ck_out_Form = GUICreate("界面2", 172, 296, -1, -1, $WS_SYSMENU, $WS_EX_APPWINDOW,$ck_Form)
$ck_out_ok = GUICtrlCreateButton("出库", 12, 38, 83, 41)
$ck_out_esc = GUICtrlCreateButton("取消", 12, 88, 83, 41)
GUISetState(@SW_SHOW,$ck_out_Form)
EndFunc ;==>ck_Inventory_manager_in
Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) ;感觉是这边有问题,但是不太清楚,求有时间的大佬解析下。
Switch $hWnd
Case $Main_Form,$ck_Form,$ck_in_Form,$ck_out_Form ;主界面
ck_Event_COMMAND($hWnd, BitAND($wParam, 0x0000FFFF), BitShift($wParam, 16), $lParam)
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_COMMAND
Func ck_Event_COMMAND($hWnd, $iControl, $iMsg, $ilParam)
Switch $iControl
Case $MainButton1
;GUISetState(@SW_HIDE, $main_Form)
ck()
Case $Button1
ck_in()
Case $Button2
ck_out()
Case $ck_in_ok
MsgBox("", "", "入库")
Case $ck_out_ok
MsgBox("", "", "出库")
Case $ck_in_esc;
MsgBox("", "", "入库退出")
GUIDelete($ck_in_Form)
WinActivate("子界面")
Case $ck_out_esc
MsgBox("", "", "出库退出")
GUIDelete($ck_out_Form)
WinActivate("子界面")
EndSwitch
EndFunc ;==>ck_Inventory_manager_Event_COMMAND
Func WM_SYSCOMMAND($hWnd, $Msg, $wParam, $lParam)
Local $SC_CLOSE = 0xF060
Local $nID = BitAND($wParam, 0x0000FFFF)
Switch $nID
Case $SC_CLOSE
If $hWnd = $Main_Form Then
Exit
Else
GUIDelete($hWnd)
EndIf
EndSwitch
EndFunc ;==>WM_SYSCOMMAND
我测试没问题。
>运行 AU3Check (3.3.14.2) 检查代码.参数: D:\AutoIt3au3 文件: D:\AU3调试\ListView例子资料\关于父子窗口的消息传递.au3
+>08:34:32 AU3Check 语法检查结束.rc: 0
>运行:D:\AutoIt3\autoit3_x64.exe(3.3.14.2), 脚本: D:\AutoIt3\autoit3_x64.exe "D:\AU3调试\ListView例子资料\关于父子窗口的消息传递.au3"
Win7_64系统 像你这种动态创建窗口及控件的话,操作不应使用控件ID,而应该用控件句柄。控件ID一般是根据控件创建顺序依次+1,而你界面1和界面2如果创建顺序不同,会引起控件ID发生变化。如果界面1未创建,而先创建了界面2,界面2内的控件ID就变成了你原本期望界面1创建的控件ID。
两种解决办法:
1。不要动态创建窗口,在程序开始时就创建好所有要使用的窗口及控件,在后续处理时,显隐相应窗口,这样控件ID就不会发生变化。
2。动态创建窗口,使用句柄来操作控件。
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
Global $Main_Form,$MainButton1,$ck_Form,$Button1,$Button2,$ck_in_Form,$ck_in_ok,$ck_in_esc,$ck_out_Form,$ck_out_ok,$ck_out_esc
Global $hMainButton1, $hButton1, $hButton2, $hck_in_ok, $hck_in_esc, $hck_out_ok,$hck_out_esc
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND")
main()
Do
Sleep(10)
Until GUIGetMsg() = $GUI_EVENT_CLOSE
Func main();父界面
$Main_Form = GUICreate("父界面", 556, 310, -1, -1)
$MainButton1 = GUICtrlCreateButton("子界面", 212, 80, 75, 25)
$hMainButton1 = GUICtrlGetHandle($MainButton1)
GUISetState(@SW_SHOW,$Main_Form)
EndFunc
Func ck();子界面
$ck_Form = GUICreate("子界面", 456, 210, -1, -1)
$Button1 = GUICtrlCreateButton("界面1", 72, 80, 75, 25)
$hButton1 = GUICtrlGetHandle($Button1)
$Button2 = GUICtrlCreateButton("界面2", 232, 80, 75, 25)
$hButton2 = GUICtrlGetHandle($Button2)
GUISetState(@SW_SHOW,$ck_Form)
EndFunc
Func ck_in();界面1
$ck_in_Form = GUICreate("界面1", 172, 296, -1, -1, $WS_SYSMENU, $WS_EX_APPWINDOW,$ck_Form)
$ck_in_ok = GUICtrlCreateButton("入库",12, 38, 83, 41)
$hck_in_ok = GUICtrlGetHandle($ck_in_ok)
$ck_in_esc = GUICtrlCreateButton("取消", 12,88, 83, 41)
$hck_in_esc = GUICtrlGetHandle($ck_in_esc)
GUISetState(@SW_SHOW,$ck_in_Form)
EndFunc ;==>ck_Inventory_manager_in
Func ck_out();界面2
$ck_out_Form = GUICreate("界面2", 172, 296, -1, -1, $WS_SYSMENU, $WS_EX_APPWINDOW,$ck_Form)
$ck_out_ok = GUICtrlCreateButton("出库", 12, 38, 83, 41)
$hck_out_ok = GUICtrlGetHandle($ck_out_ok)
$ck_out_esc = GUICtrlCreateButton("取消", 12, 88, 83, 41)
$hck_out_esc = GUICtrlGetHandle($ck_out_esc)
GUISetState(@SW_SHOW,$ck_out_Form)
EndFunc ;==>ck_Inventory_manager_in
Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) ;感觉是这边有问题,但是不太清楚,求有时间的大佬解析下。
Switch $hWnd
Case $Main_Form,$ck_Form,$ck_in_Form,$ck_out_Form ;主界面
ck_Event_COMMAND($hWnd, BitAND($wParam, 0x0000FFFF), BitShift($wParam, 16), $lParam)
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_COMMAND
Func ck_Event_COMMAND($hWnd, $iControl, $iMsg, $ilParam)
Switch $ilParam
Case $hMainButton1
;GUISetState(@SW_HIDE, $main_Form)
ck()
Case $hButton1
ck_in()
Case $hButton2
ck_out()
Case $hck_in_ok
MsgBox("", "", "入库")
Case $hck_out_ok
MsgBox("", "", "出库")
Case $hck_in_esc;
MsgBox("", "", "入库退出")
GUIDelete($ck_in_Form)
WinActivate("子界面")
Case $hck_out_esc
MsgBox("", "", "出库退出")
GUIDelete($ck_out_Form)
WinActivate("子界面")
EndSwitch
EndFunc ;==>ck_Inventory_manager_Event_COMMAND
Func WM_SYSCOMMAND($hWnd, $Msg, $wParam, $lParam)
Local $SC_CLOSE = 0xF060
Local $nID = BitAND($wParam, 0x0000FFFF)
Switch $nID
Case $SC_CLOSE
If $hWnd = $Main_Form Then
Exit
Else
GUIDelete($hWnd)
EndIf
EndSwitch
EndFunc ;==>WM_SYSCOMMAND
这种含子窗口的操作使用事件模式比较方便,当然习惯消息循环模式也可以直接在主循环中处理。对于这种基本操作,无需注册系统消息。
#include <WindowsConstants.au3>
Global $Main_Form, $MainButton1, $ck_Form = -1, $Button1, $Button2, $ck_in_Form = -1, $ck_in_ok, $ck_in_esc, $ck_out_Form = -1, $ck_out_ok, $ck_out_esc
main()
Local $aiMSG
While 1
$aiMSG = GUIGetMsg(1)
Switch $aiMSG
Case $Main_Form
Switch $aiMSG
Case -3
Exit
Case $MainButton1
ck()
EndSwitch
Case $ck_Form
Switch $aiMSG
Case -3
GUISetState(@SW_HIDE, $ck_Form)
Case $Button1
ck_in()
Case $Button2
ck_out()
EndSwitch
Case $ck_in_Form
Switch $aiMSG
Case -3, $ck_in_esc
GUISetState(@SW_HIDE, $ck_in_Form)
Case $ck_in_ok
MsgBox("", "", "入库")
EndSwitch
Case $ck_out_Form
Switch $aiMSG
Case -3, $ck_out_esc
GUISetState(@SW_HIDE, $ck_out_Form)
Case $ck_out_ok
MsgBox("", "", "出库")
EndSwitch
EndSwitch
WEnd
Func main();父界面
$Main_Form = GUICreate("父界面", 556, 310, -1, -1)
$MainButton1 = GUICtrlCreateButton("子界面", 212, 80, 75, 25)
GUISetState(@SW_SHOW, $Main_Form)
EndFunc ;==>main
Func ck();子界面
If IsHWnd($ck_Form) Then Return GUISetState(@SW_SHOW, $ck_Form)
$ck_Form = GUICreate("子界面", 456, 210, -1, -1)
$Button1 = GUICtrlCreateButton("界面1", 72, 80, 75, 25)
$Button2 = GUICtrlCreateButton("界面2", 232, 80, 75, 25)
GUISetState(@SW_SHOW, $ck_Form)
EndFunc ;==>ck
Func ck_in();界面1
If IsHWnd($ck_in_Form) Then Return GUISetState(@SW_SHOW, $ck_in_Form)
$ck_in_Form = GUICreate("界面1", 172, 296, -1, -1, $WS_SYSMENU, $WS_EX_APPWINDOW, $ck_Form)
$ck_in_ok = GUICtrlCreateButton("入库", 12, 38, 83, 41)
$ck_in_esc = GUICtrlCreateButton("取消", 12, 88, 83, 41)
GUISetState(@SW_SHOW, $ck_in_Form)
EndFunc ;==>ck_in
Func ck_out();界面2
If IsHWnd($ck_out_Form) Then Return GUISetState(@SW_SHOW, $ck_out_Form)
$ck_out_Form = GUICreate("界面2", 172, 296, -1, -1, $WS_SYSMENU, $WS_EX_APPWINDOW, $ck_Form)
$ck_out_ok = GUICtrlCreateButton("出库", 12, 38, 83, 41)
$ck_out_esc = GUICtrlCreateButton("取消", 12, 88, 83, 41)
GUISetState(@SW_SHOW, $ck_out_Form)
EndFunc ;==>ck_out tubaba 发表于 2021-11-30 10:18
像你这种动态创建窗口及控件的话,操作不应使用控件ID,而应该用控件句柄。控件ID一般是根据控件创建顺序依 ...
感谢大佬在如此卡顿的情况下,还给予解答~~明白了!!:face (31): 本帖最后由 xyhqqaa 于 2021-11-30 20:31 编辑
afan 发表于 2021-11-30 13:19
这种含子窗口的操作使用事件模式比较方便,当然习惯消息循环模式也可以直接在主循环中处理。对于这种基本操 ...
感谢A版的回复。。。最近论坛这么卡都能回复,万分感谢,您的思路方法我再学习下~~~回复不易~~:face (36): chzj589 发表于 2021-11-30 08:37
我测试没问题。
>运行 AU3Check (3.3.14.2) 检查代码.参数: D:\AutoIt3au3 文件: D:\AU3调试\ListView ...
感谢回复,不过您这边需要多点几次就会出现问题,大致如tu大佬所说。我琢磨好几天,大致猜得到,但是还是听完大佬的解释才清楚。 xyhqqaa 发表于 2021-11-30 20:25
感谢A版的回复。。。最近论坛这么卡都能回复,万分感谢,您的思路方法我再学习下~~~回复不易~~:face (36) ...
确实很卡,不过你的问题贴描述很到位、图文并茂、精简且可重现问题的代码,再卡都要助推一把~ afan 发表于 2021-11-30 21:57
确实很卡,不过你的问题贴描述很到位、图文并茂、精简且可重现问题的代码,再卡都要助推一把~
:face (27):说的我都不意思了。感谢A版的代码~~~学习ing
页:
[1]