GUI 循环模式下 可以做多窗口的写法吗?? 如何让所有按键都有作用??[已解决]
本帖最后由 kk_lee69 于 2016-5-23 21:44 编辑GUI 循环模式下 可以做多窗口的写法吗?? 如何让所有按键都有作用??
以下的程序能否 在 不使用事件模式的情况下,让所有的按键都有作用呢??
$MAIN = GuiCreate('MAIN',600,500)
$LA = GuiCtrlCreateButton('A:新增子窗', 10, 50, 120, 30)
$LB = GuiCtrlCreateButton('B:子窗產生後 點我是否有反應', 10, 100, 200, 30)
GUISetState()
While 1
Switch guigetmsg()
Case -3
Exit
Case $LA
MA()
Case $LB
MsgBox(0,"A","可以看到我嗎??")
EndSwitch
SLEEP(10)
WEnd
Func MA()
$SUB = GuiCreate('SUB',500,400)
$KB = GuiCtrlCreateButton('C:子窗按鈕', 10, 100, 200, 30)
GUISetState()
While 1
Switch guigetmsg()
Case -3
GUIDelete($SUB)
WinActivate($MAIN,"")
Case $KB
MsgBox(0,"B","我是子窗主窗能後有反應嗎??")
EndSwitch
SLEEP(10)
WEnd
EndFunc 回复 1# kk_lee69
这样理解不知对不对?
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
Global $MAIN, $SUB
GUI_A()
While 1
Sleep(1000)
WEnd
Func GUI_A()
$MAIN = GUICreate('MAIN', 600, 500)
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Close")
$LA = GUICtrlCreateButton('A:新增子窗', 10, 50, 120, 30)
GUICtrlSetOnEvent($LA, "MA")
$LB = GUICtrlCreateButton('B:子窗產生後 點我是否有反應', 10, 100, 200, 30)
GUICtrlSetOnEvent($LB, "MAA")
GUISetState()
EndFunc ;==>GUI_A
Func Form1Close() ;关闭窗口
Exit
EndFunc ;==>Form1Close
Func MAA()
MsgBox(0, "AA", "我是主窗,可以看到我嗎??")
EndFunc ;==>MAA
Func MA()
$SUB = GUICreate('SUB', 500, 400)
GUISetOnEvent($GUI_EVENT_CLOSE, "SUBClose")
$KB = GUICtrlCreateButton('C:子窗按鈕', 10, 100, 200, 30)
GUICtrlSetOnEvent($KB, "MBA")
GUISetState()
EndFunc ;==>MA
Func SUBClose() ;关闭窗口
GUIDelete($SUB)
WinActivate($MAIN, "")
EndFunc ;==>SUBClose
Func MBA()
MsgBox(0, "B", "我是子窗,可以看到我嗎??")
EndFunc ;==>MBA 回复 1# kk_lee69
有个前提就是子窗口必须先创建,或子窗口控件及窗口变量须事先声明
#include <ARRAY.au3>
$MAIN = GuiCreate('MAIN',600,500)
$LA = GuiCtrlCreateButton('A:新增子窗', 10, 50, 120, 30)
$LB = GuiCtrlCreateButton('B:子窗產生後 點我是否有反應', 10, 100, 200, 30)
$SUB = GuiCreate('SUB',500,400)
$KB = GuiCtrlCreateButton('C:子窗按鈕', 10, 100, 200, 30)
GUISetState(@SW_SHOW, $MAIN)
While 1
$msg = guigetmsg(1)
Switch $msg
Case $SUB
Switch $msg ;子窗口事件
Case -3
GUISetState(@SW_HIDE, $SUB)
WinActivate($MAIN,"")
Case $KB
MsgBox(0,"B","我是子窗主窗能後有反應嗎??")
EndSwitch
Case $MAIN ;主窗口事件
Switch $msg
Case -3
Exit
Case $LA
GUISetState(@SW_SHOW, $SUB)
Case $LB
MsgBox(0,"A","可以看到我嗎??")
EndSwitch
EndSwitch
WEnd
其实没有那么麻烦了,这种问题论坛不是早就有讨论过吗?为什么不去搜索。
楼主的代码肯定是关闭子窗口后,主窗口没有反应了,无非就是在第二个while循环中没有退出来。
没有实际测试,目测在楼主的31行加个ExitLoop即可。
当然可以用:2楼的GUIOnEventMode;也可以用3楼的先创建后控制界面显示状态;
切换窗口时最好加上GUISwitch。 回复 4# haijie1223
難怪昨天我寫案例的時候 覺得怪沒反應忘了多一個 ExitLoop
另外其實我想了解解決的是
在子窗循環的時候 原本 主窗的 控件其實是回沒反應的怎麼解決這個問題 回复 2# chzj589
GUISetOnEvent($GUI_EVENT_CLOSE, "SUBClose")
使用了事件模式我想要了解的方法是 不使用 事件模式的 本帖最后由 kk_lee69 于 2016-5-18 13:35 编辑
回复 3# yhxhappy
你的方法是 寫成一個 大迴圈了解意思了 跟方法
感謝回復 不過這樣的方法如果 軟體越寫越大 或者加入模組的話其實 不好維護
不知道是否 還有其他 方式呢??一樣可以 寫成 比較 用函數方式呼叫的 是这样吗?
Global $SC_CLOSE = 0xF060
Global $WM_SYSCOMMAND = 0x112
Global $GUI_RUNDEFMSG = 'GUI_RUNDEFMSG'
$MAIN = GUICreate('MAIN', 600, 500)
$LA = GUICtrlCreateButton('A:新增子窗', 10, 50, 120, 30)
$LB = GUICtrlCreateButton('B:子窗產生後 點我是否有反應', 10, 100, 200, 30)
GUISetState(@SW_SHOW)
$SUB = GUICreate('SUB', 500, 400, -1, -1, -1, -1, $MAIN)
$KB = GUICtrlCreateButton('C:子窗按鈕', 10, 100, 200, 30)
GUISetState(@SW_HIDE)
GUIRegisterMsg($WM_SYSCOMMAND, 'WM_SYSCOMMAND')
While 1
Switch GUIGetMsg()
Case $LA
GUISwitch($SUB)
GUISetState(@SW_SHOW, $SUB)
Case $LB
GUISwitch($MAIN)
MsgBox(0, "A", "可以看到我嗎??")
Case $KB
GUISwitch($SUB)
MsgBox(0, "B", "我是子窗主窗能後有反應嗎??")
EndSwitch
WEnd
Func WM_SYSCOMMAND($hWnd, $sMsg, $sWParam, $slParam)
Switch $hWnd
Case $MAIN
Switch $sWParam
Case $SC_CLOSE
Exit
EndSwitch
Case $SUB
Switch $sWParam
Case $SC_CLOSE
GUISetState(@SW_HIDE, $SUB)
GUISwitch($MAIN)
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_SYSCOMMAND
回复 9# haijie1223
感謝 版主的回覆這個方法 我知道
因為 昨天晚上 看了 循環跟消息模式的一些文章,突然想到如果今天我不 註冊消息 單純使用
AU3 內定的循環模式是否 有可能做到 可以多個視窗同時控件都有反應
因為 當初一開始接觸 AU3 我只會用循環方式因此 寫出來的東西都是 單一個步驟 一步一步來
主畫面的循環 跳到 子視窗的時候 就把 主窗口 鎖住 不讓使用者操作
因此 只能 使用子窗口的循環所以 子窗口的按鈕沒問題.......
子窗口消失後跳回主循環 才 開放 使用 主窗口 ,所以 主窗口的反應也不會有問題...
但是 這樣畫面都是只能是單一個窗口 的操作....其他的窗口 就都不能使用...
所以 就想了解一下除了 註冊消息外是否 有 循環的寫法可以做到多窗口但是
中間過程不註冊任何消息單純用 循環處理 的寫法
前面看了大家的回答3F 的 方式是沒有註冊 任何的消息只是 他把兩個窗口 一起建立
變成一個大循環 回复 10# kk_lee69
曲线救国吧,做事情总得有个目的吧。有方法能实现就好,为什么这么较真呢。
$MAIN = GUICreate('MAIN', 600, 500)
$LA = GUICtrlCreateButton('A:新增子窗', 10, 50, 120, 30)
$LB = GUICtrlCreateButton('B:子窗產生後 點我是否有反應', 10, 100, 200, 30)
GUISetState(@SW_SHOW)
$SUB = GUICreate('SUB', 500, 400, -1, -1, -1, -1, $MAIN)
$KB = GUICtrlCreateButton('C:子窗按鈕', 10, 100, 200, 30)
GUISetState(@SW_HIDE)
While 1
Switch GUIGetMsg()
Case -3
If WinActive($MAIN) Then
Exit
ElseIf WinActivate($SUB) Then
GUISetState(@SW_HIDE, $SUB)
GUISwitch($MAIN)
EndIf
Case $LA
GUISwitch($SUB)
GUISetState(@SW_SHOW, $SUB)
Case $LB
GUISwitch($MAIN)
MsgBox(0, "A", "可以看到我嗎??")
Case $KB
GUISwitch($SUB)
MsgBox(0, "B", "我是子窗主窗能後有反應嗎??")
EndSwitch
WEnd
回复 3# yhxhappy
看了你的邏輯我 想到了一個方法有興趣的朋友 可以參考看看
DIM $FROM,$BITTON
$MAIN = GuiCreate('MAIN',600,500)
$LA = GuiCtrlCreateButton('A:新增子窗', 10, 50, 120, 30)
$LB = GuiCtrlCreateButton('B:子窗產生後 點我是否有反應', 10, 100, 200, 30)
GUISetState()
While 1
$msg = guigetmsg(1)
Switch$msg
Case -3
IF $msg=$MAIN Then
Exit
EndIf
For $i = 0 To UBound($FROM) - 1
If $FROM[$i]=$msgThen
GUIDelete($FROM[$i])
WinActivate($MAIN,"")
;ExitLoop
EndIf
Next
Case $LA
MA()
Case $LB
MsgBox(0,"A","可以看到我嗎??")
CASE ELSE
For $i = 0 To UBound($BITTON) - 1
If $BITTON[$i]=$msg Then
Execute($BITTON[$i])
EndIf
Next
EndSwitch
SLEEP(10)
WEnd
Func MA()
Local $j = 0
For $i = 0 To UBound($FROM) - 1
If Not IsHWnd($FROM[$i]) Then
$j = $i
ExitLoop
EndIf
Next
If $j < 1 Then
$j = $i
ReDim $FROM[$j + 1]
ReDim $BITTON[$j + 1]
EndIf
$FROM[$j] = GuiCreate('SUB',500,400)
$BITTON[$j] = GuiCtrlCreateButton('C:子窗按鈕', 10, 100, 200, 30)
$BITTON[$j] ='MsgBox(0,"","我是子窗'&$FROM[$j]&'按鈕是'&$BITTON[$j]&'??")'
GUISetState()
EndFunc
這樣就 可以 產生多少子窗都可以同時作業了
基本邏輯是 一個循環其他 用 判斷處理 回复 11# haijie1223
请教一下,如何正确使用 循环模式与事件模式?
也就是说什么情况下使用 循环模式或事件模式? 回复 12# kk_lee69
简化了代码。用_ArraySearch 应该比 For 更快些。#include <Array.au3>
DIM $FROM = , $BITTON = []
$MAIN = GuiCreate('MAIN',600,500)
$LA = GuiCtrlCreateButton('A:新增子窗', 10, 50, 120, 30)
$LB = GuiCtrlCreateButton('B:子窗產生後 點我是否有反應', 10, 100, 200, 30)
GUISetState()
While 1
$msg = guigetmsg(1)
Switch$msg
Case -3
IF $msg = $MAIN Then
Exit
Else
$F = _ArraySearch($FROM, $msg, 1)
If Not @error Then
GUIDelete($FROM[$F])
WinActivate($MAIN, "")
EndIf
EndIf
Case $LA
MA()
Case $LB
MsgBox(0,"A","可以看到我嗎??")
CASE $BITTON To $BITTON[$BITTON]
$i = _ArraySearch($BITTON, $msg, 1)
If Not @error Then
Execute($BITTON[$i])
EndIf
EndSwitch
SLEEP(10)
WEnd
Func MA()
$Title = 'SUB ' & $FROM
$GUI = GuiCreate($Title, 500, 400)
_ArrayAdd($FROM, $GUI)
$Btn = GuiCtrlCreateButton('C:子窗按鈕', 10, 100, 200, 30)
$Execute ='MsgBox(0,"","我是子窗' & $Title &'按鈕是' & $Btn & '??")'
_ArrayAdd($BITTON, $Btn & "|" & $Execute)
GUISetState()
$BITTON = UBound($BITTON)-1
$FROM = UBound($FROM)-1
EndFunc
没这么复杂吧!
Global $bWinState = False
$hGui1 = GUICreate('MAIN', 600, 500)
$Button1_1 = GUICtrlCreateButton('显示子窗口', 10, 50, 120, 30)
$Button1_2 = GUICtrlCreateButton('子窗產生後 點我是否有反應', 10, 100, 200, 30)
GUISetState()
$hGui2 = GUICreate('SUB', 500, 400)
$Button2_1 = GUICtrlCreateButton('C:子窗按鈕', 10, 100, 200, 30)
While 1
Switch GUIGetMsg()
Case -3
If $bWinState = True Then
GUISetState(@SW_HIDE, $hGui2)
$bWinState = False
Else
Exit
EndIf
Case $Button1_1
GUISetState(@SW_SHOW, $hGui2)
$bWinState = True
Case $Button1_2
MsgBox(0, "A", "可以看到我嗎??")
Case $Button2_1
MsgBox(0, "B", "我是子窗主窗能後有反應嗎??")
EndSwitch
WEnd 回复 13# chzj589
任何情况下都可以用两种模式,个人习惯。
页:
[1]
2