找回密码
 加入
搜索
查看: 4097|回复: 15

[AU3基础] GUI 循环模式下 可以做多窗口的写法吗?? 如何让所有按键都有作用??[已解决]

 火.. [复制链接]
发表于 2016-5-18 01:12:42 | 显示全部楼层 |阅读模式
本帖最后由 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
发表于 2016-5-18 07:06:38 | 显示全部楼层
回复 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
发表于 2016-5-18 09:19:22 | 显示全部楼层
[/code][b]回复 [url=http://www.autoitx.com/forum.php?mod=redirect&goto=findpost&pid=652349&ptid=52267]1#[/url] [i]kk_lee69 

有个前提就是子窗口必须先创建,或子窗口控件及窗口变量须事先声明

[code]#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[1]
   Case $SUB
          Switch $msg[0]                  ;子窗口事件
          Case -3
                 GUISetState(@SW_HIDE, $SUB)
                 WinActivate($MAIN,"")
          Case $KB
                 MsgBox(0,"B","我是子窗  主窗能後有反應嗎??")
          EndSwitch
   Case $MAIN                                ;主窗口事件
          Switch $msg[0]
          Case -3
                 Exit
          Case $LA
                 GUISetState(@SW_SHOW, $SUB)
          Case $LB
                 MsgBox(0,"A","可以看到我嗎??")
          EndSwitch
   EndSwitch
WEnd

评分

参与人数 1金钱 +40 贡献 +5 收起 理由
kk_lee69 + 40 + 5 感謝回復

查看全部评分

发表于 2016-5-18 11:46:17 | 显示全部楼层
其实没有那么麻烦了,这种问题论坛不是早就有讨论过吗?为什么不去搜索。
楼主的代码肯定是关闭子窗口后,主窗口没有反应了,无非就是在第二个while循环中没有退出来。
没有实际测试,目测在楼主的31行加个ExitLoop即可。
当然可以用:2楼的GUIOnEventMode;也可以用3楼的先创建后控制界面显示状态;
切换窗口时最好加上GUISwitch。
 楼主| 发表于 2016-5-18 11:56:05 | 显示全部楼层
回复 4# haijie1223


   難怪昨天我寫案例的時候 覺得怪  沒反應  忘了多一個 ExitLoop

另外其實我想了解解決的是   

在子窗循環的時候   原本 主窗的 控件  其實是回沒反應的  怎麼解決這個問題
 楼主| 发表于 2016-5-18 13:27:18 | 显示全部楼层
回复 2# chzj589

GUISetOnEvent($GUI_EVENT_CLOSE, "SUBClose")

使用了事件模式  我想要了解的方法是 不使用 事件模式的
 楼主| 发表于 2016-5-18 13:31:03 | 显示全部楼层
本帖最后由 kk_lee69 于 2016-5-18 13:35 编辑

回复 3# yhxhappy


你的方法是 寫成一個 大迴圈  了解意思了 跟方法  

感謝回復   不過這樣的方法  如果 軟體越寫越大 或者加入模組的話  其實 不好  維護

不知道是否 還有其他 方式呢??  一樣可以 寫成 比較 用  函數方式呼叫的
发表于 2016-5-18 16:48:08 | 显示全部楼层
是这样吗?
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
 楼主| 发表于 2016-5-18 17:07:52 | 显示全部楼层
回复 9# haijie1223

感謝 版主的回覆  這個方法 我知道

因為 昨天晚上 看了 循環跟消息模式的一些文章,突然想到如果  今天我不 註冊消息 單純使用
AU3 內定的循環模式  是否 有可能做到 可以多個視窗  同時控件都有反應

因為 當初一開始接觸 AU3 我只會用循環方式  因此 寫出來的東西都是 單一個步驟 一步一步來
主畫面的循環 跳到 子視窗的時候 就把 主窗口 鎖住    不讓使用者操作
因此 只能 使用子窗口的循環  所以 子窗口的按鈕沒問題.......

子窗口消失後  跳回主循環   才 開放 使用 主窗口 ,所以 主窗口的反應也不會有問題...

但是 這樣  畫面都是只能是單一個窗口 的操作....  其他的窗口 就都不能使用...

所以 就想了解一下  除了 註冊消息外  是否 有 循環的寫法  可以做到多窗口  但是
中間過程不註冊任何消息  單純用 循環處理 的寫法

前面看了大家的回答  3F 的 方式  是沒有註冊 任何的消息  只是 他把  兩個窗口 一起建立
變成一個大循環
发表于 2016-5-18 19:51:38 | 显示全部楼层
回复 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
 楼主| 发表于 2016-5-19 00:20:21 | 显示全部楼层
回复 3# yhxhappy

看了你的邏輯  我 想到了一個方法  有興趣的朋友 可以參考看看

DIM $FROM[1][2],$BITTON[1][2]

$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[0]
                Case -3
                        IF $msg[1]=$MAIN Then
                                Exit
                        EndIf
                        For $i = 0 To UBound($FROM) - 1
                                If $FROM[$i][0]=$msg[1]  Then
                                        GUIDelete($FROM[$i][0])
                                        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][0]=$msg[0] Then
                                        Execute($BITTON[$i][1])
                                EndIf
                        Next
                        
        EndSwitch
        
        SLEEP(10)
WEnd
        
        
Func MA()
        Local $j = 0
        For $i = 0 To UBound($FROM) - 1
                If Not IsHWnd($FROM[$i][0]) Then
                        $j = $i
                        ExitLoop
                EndIf
        Next

        If $j < 1 Then
                $j = $i
                ReDim $FROM[$j + 1][2]
                ReDim $BITTON[$j + 1][2]
        EndIf
        
        $FROM[$j][0] = GuiCreate('SUB',500,400) 
        
        $BITTON[$j][0] = GuiCtrlCreateButton('C:子窗按鈕', 10, 100, 200, 30)
        $BITTON[$j][1] ='MsgBox(0,"","我是子窗'&$FROM[$j][0]&'  按鈕是'&$BITTON[$j][0]&'??")'
        
        GUISetState()


EndFunc


這樣就 可以 產生多少子窗  都可以同時作業了

基本邏輯是 一個循環  其他 用 判斷處理
发表于 2016-5-19 07:54:41 | 显示全部楼层
回复 11# haijie1223

请教一下,如何正确使用 循环模式与事件模式?
也就是说什么情况下使用 循环模式或事件模式?
发表于 2016-5-19 09:43:10 | 显示全部楼层
回复 12# kk_lee69

简化了代码。用_ArraySearch 应该比 For 更快些。
#include <Array.au3>

DIM $FROM[1] = [0], $BITTON[2][2] = [[0, ""]]

$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[0]
   Case -3
          IF $msg[1] = $MAIN Then
                 Exit
          Else
                 $F = _ArraySearch($FROM, $msg[1], 1)
                 If Not @error Then
                        GUIDelete($FROM[$F])
                        WinActivate($MAIN, "")
                 EndIf
          EndIf
   Case $LA
          MA()
   Case $LB
          MsgBox(0,"A","可以看到我嗎??")
   CASE $BITTON[1][0] To $BITTON[$BITTON[0][0]][0]
          $i = _ArraySearch($BITTON, $msg[0], 1)
          If Not @error Then
                 Execute($BITTON[$i][1])
          EndIf
   EndSwitch
   SLEEP(10)
WEnd


Func MA()
   $Title = 'SUB ' & $FROM[0]
   $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[0][0] = UBound($BITTON)-1
   $FROM[0] = UBound($FROM)-1
EndFunc
发表于 2016-5-19 16:19:28 | 显示全部楼层
没这么复杂吧!

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

评分

参与人数 1金钱 +10 收起 理由
haijie1223 + 10 不错,用布尔判断更效率更准确!

查看全部评分

发表于 2016-5-19 18:09:37 | 显示全部楼层
回复 13# chzj589


    任何情况下都可以用两种模式,个人习惯。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-11-17 00:43 , Processed in 0.083306 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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