kk_lee69 发表于 2016-5-18 01:12:42

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

chzj589 发表于 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

yhxhappy 发表于 2016-5-18 09:19:22

回复 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

haijie1223 发表于 2016-5-18 11:46:17

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

kk_lee69 发表于 2016-5-18 11:56:05

回复 4# haijie1223


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

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

在子窗循環的時候   原本 主窗的 控件其實是回沒反應的怎麼解決這個問題

kk_lee69 发表于 2016-5-18 13:27:18

回复 2# chzj589

GUISetOnEvent($GUI_EVENT_CLOSE, "SUBClose")

使用了事件模式我想要了解的方法是 不使用 事件模式的

kk_lee69 发表于 2016-5-18 13:31:03

本帖最后由 kk_lee69 于 2016-5-18 13:35 编辑

回复 3# yhxhappy


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

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

不知道是否 還有其他 方式呢??一樣可以 寫成 比較 用函數方式呼叫的

haijie1223 发表于 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

kk_lee69 发表于 2016-5-18 17:07:52

回复 9# haijie1223

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

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

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

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

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

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

前面看了大家的回答3F 的 方式是沒有註冊 任何的消息只是 他把兩個窗口 一起建立
變成一個大循環

haijie1223 发表于 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

kk_lee69 发表于 2016-5-19 00:20:21

回复 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

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

基本邏輯是 一個循環其他 用 判斷處理

chzj589 发表于 2016-5-19 07:54:41

回复 11# haijie1223

请教一下,如何正确使用 循环模式与事件模式?
也就是说什么情况下使用 循环模式或事件模式?

yhxhappy 发表于 2016-5-19 09:43:10

回复 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

水木子 发表于 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

haijie1223 发表于 2016-5-19 18:09:37

回复 13# chzj589


    任何情况下都可以用两种模式,个人习惯。
页: [1] 2
查看完整版本: GUI 循环模式下 可以做多窗口的写法吗?? 如何让所有按键都有作用??[已解决]