找回密码
 加入
搜索
查看: 7701|回复: 32

[系统综合] 消息模式与循环模式写法差异问题,求写法解[已解决]

 火.. [复制链接]
发表于 2017-7-6 01:48:58 | 显示全部楼层 |阅读模式
本帖最后由 kk_lee69 于 2017-7-10 00:55 编辑

消息模式与循环模式写法差异问题,求写法解

这个问题有点复杂 需要稍微解释一下才能说得清楚
请先看一下 下面的语法

Opt("GUIOnEventMode", 1) ;使用消息模式
$WinMain = GuiCreate("主程式".....)

$BUTTON1
$BUTTON2
.
.
.

GUICtrlSetOnEvent($BUTTON1, "GUI_COMMAND")
GUICtrlSetOnEvent($BUTTON2, "GUI_COMMAND")

While 1

Sleep(20)

WEnd


Func GUI_COMMAND()
        Case $BUTTON1
                MENU1()
        Case $BUTTON2
                MENU2()
EndFunc



Func MENU1()
        Opt("GUIOnEventMode", 0) ;切換回 循環模式
        
        $B1
        $B2
        $B3
        .
        .
        .
        $B20  ;20個按鈕 
        While 1
                Case $GUI_EVENT_CLOSE
                        ;離開這個 窗口
                        Opt("GUIOnEventMode", 1) ;切換回 消息模式
                Case $B1
                Case $B2
                Case $B3
                Case $B4
                .
                .
        WEnd


EndFunc

Func MENU2()
        Opt("GUIOnEventMode", 0) ;切換回 循環模式
        
        $C1
        $C2
        $C3
        .
        .
        .
        $C20  ;20個按鈕 
        While 1
                Case $GUI_EVENT_CLOSE
                        ;離開這個 窗口
                        Opt("GUIOnEventMode", 1) ;切換回 消息模式
                Case $C1
                Case $C2
                Case $C3
                Case $C4
                .
                .
        WEnd



基本上我的写法是 采用 消息模式当主循环,然后当有需要时 呼叫
MENU1 或者 MENU2 出现,譬如呼叫MENU1 时 切换成循环模式
等到离开 MENU1时再切回 消息模式

每个Func 都是一个窗口

这样的好处是 MENU1() 里面的20个按钮的功能 都写在一起
以后要复制到其他的程序应用只要把 MENU1整个 Func 一起复制到其他程序
就可以直接应用 Func 的20个按钮的功能
简单好记  也好找 自己辛辛苦苦建立的 Func 内容 P.S 实际一个Func 可能有上千行程序,而且 当我需要 MENU3 时 可以直接复制 MENU1,改几个重点就好 其他的变量 都可以跟MENU1一样 因为两者不会同时出现..

缺点是 每次呼叫 都只能跑一个窗口 要等循环跑完了 回到消息模式 才能呼叫第二个


所以想改成 全部采用 消息模式 就可以 同时出现两个 窗口……

请看下面的语法示意



Opt("GUIOnEventMode", 1) ;使用消息模式
$WinMain = GuiCreate("主程式".....)

$BUTTON1
$BUTTON2
.
.
.

GUICtrlSetOnEvent($BUTTON1, "GUI_COMMAND")
GUICtrlSetOnEvent($BUTTON2, "GUI_COMMAND")

While 1

Sleep(20)

WEnd


Func GUI_COMMAND()
        Case $BUTTON1
                MENU1()
        Case $BUTTON2
                MENU2()
        Case $B1
        Case $B2
        Case $C1
        Case $C2        
EndFunc



Func MENU1()
        
        $B1
        $B2
        $B3
        .
        .
        .
        $B20  ;20個按鈕 

GUICtrlSetOnEvent($B1, "GUI_COMMAND")
GUICtrlSetOnEvent($B2, "GUI_COMMAND")
.
.

EndFunc

Func MENU2()
        Opt("GUIOnEventMode", 0) ;切換回 循環模式
        
        $C1
        $C2
        $C3
        .
        .
        .
        $C20  ;20個按鈕 
GUICtrlSetOnEvent($C1, "GUI_COMMAND")
GUICtrlSetOnEvent($C2, "GUI_COMMAND")
.
.

EndFunc




可是这样缺点来了……我本来 全部放在 Func 里的20个按钮功能必须要拆开写
放入到 GUI_COMMAND() 里面 ,这样下次我想移转到 另外的程序的时候,就必须要 分很多段 复制


~~~以上是我的观念,不知道是否正确………想请教

1.        在循环模式下是否只能一次 跑一个窗口 因为每个 Func 都是一个窗口
2.        如果我改成 第二种 消息模式的写法,有没有办法让我可以达到 第一种写法的优点呢?? 可以方便容易的复制我的 每个 Func 功能到其他程序呢??
以上杂七杂八的 说了 一堆 ,希望高手有耐心看完,可以给我一些逻辑上的建议  感谢!!
发表于 2017-7-6 10:40:29 | 显示全部楼层
Opt("GUIOnEventMode", 1) ;一般这种叫事件模式

Opt("GUIOnEventMode", 0) + GUIGetMsg() 是消息循环模式

事件模式更易于函数模块化,可移植性更好,也可使用特殊的事件宏
 楼主| 发表于 2017-7-6 11:05:32 | 显示全部楼层
回复 2# afan

理解 不過  版主 我想請教的就是

我以前使用 Opt("GUIOnEventMode", 0) + GUIGetMsg() 是消息循环模式

我可以 寫一個 FUNC  把幾千行的程式  寫入到這個 FUNC 包含每個按鈕的判斷跟 功能

移植的時候 我只有 移植一個 FUNC

但是  使用 Opt("GUIOnEventMode", 1) ;一般这种叫事件模式

我可能˙被迫要將 程式拆成很多段 放在 不同位置

這樣移植的時候 我就必須要 一段一段的移植

所以我想問的就是....
事件模式....有沒有怎樣的寫法邏輯 可以達到  我可以 複製  連續的 一整段 程式碼 就可以ㄧ 可以達到  我可以 複製  連續的 一整段 程式碼 就可以移植
发表于 2017-7-6 11:49:50 | 显示全部楼层
回复 3# kk_lee69
下面的例子你看看

#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <ComboConstants.au3>
Opt("GUIOnEventMode", 1)
Global $GUI1, $GUI2, $label6, $label, $BUTTON1, $BUTTON2, $BUTTON3, $BUTTON4, $BBUTTON1, $BBUTTON2, $BBUTTON3, $BBUTTON4
Form1()


While 1
        Sleep(1000)
WEnd
Func _Form1Close()

        GUIDelete()
        Exit
EndFunc   ;==>_Form1Close
Func Form1()
        Global $GUI1 = GUICreate('A窗口激活')
        GUISetOnEvent($GUI_EVENT_CLOSE, "_Form1Close")
        $label = GUICtrlCreateLabel("", 13, 60, 355, 60)
        GUICtrlSetFont(-1, 14, 800, 0, "微软雅黑")
        GUICtrlSetColor($label, 0x000000)
        $Button1 = GUICtrlCreateButton("A1", 10, 200, 80, 25, 0)
        GUICtrlSetCursor(-1, "SIZEALL");鼠标指针
        GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
        GUICtrlSetOnEvent(-0x00000001, "_msg")
        $Button2 = GUICtrlCreateButton("A2", 100, 200, 80, 25, 0)
        GUICtrlSetCursor(-1, "SIZEALL");鼠标指针
        GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
        GUICtrlSetOnEvent(-0x00000001, "_msg")
        $Button3 = GUICtrlCreateButton("A3", 190, 200, 80, 25, 0)
        GUICtrlSetCursor(-1, "SIZEALL");鼠标指针
        GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
        GUICtrlSetOnEvent(-0x00000001, "_msg")
        $Button4= GUICtrlCreateButton("A4", 280, 200, 80, 25, 0)
        GUICtrlSetCursor(-1, "SIZEALL");鼠标指针
        GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
        GUICtrlSetOnEvent(-0x00000001, "_msg")
        Global $GUI2 = GUICreate('B窗口激活')
        GUISetOnEvent($GUI_EVENT_CLOSE, "_Form1Close")
        $label6 = GUICtrlCreateLabel("", 13, 60, 355, 60)
        GUICtrlSetFont(-1, 14, 800, 0, "微软雅黑")
        GUICtrlSetColor($label6, 0x000000)
        $BButton1 = GUICtrlCreateButton("B1", 10, 200, 80, 25, 0)
        GUICtrlSetCursor(-1, "SIZEALL");鼠标指针
        GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
        GUICtrlSetOnEvent(-0x00000001, "_msg")
        $BButton2 = GUICtrlCreateButton("B2", 100, 200, 80, 25, 0)
        GUICtrlSetCursor(-1, "SIZEALL");鼠标指针
        GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
        GUICtrlSetOnEvent(-0x00000001, "_msg")
        $BButton3 = GUICtrlCreateButton("B3", 190, 200, 80, 25, 0)
        GUICtrlSetCursor(-1, "SIZEALL");鼠标指针
        GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
        GUICtrlSetOnEvent(-0x00000001, "_msg")
        $BButton4= GUICtrlCreateButton("B4", 280, 200, 80, 25, 0)
        GUICtrlSetCursor(-1, "SIZEALL");鼠标指针
        GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
        GUICtrlSetOnEvent(-0x00000001, "_msg")
        GUISetState(@SW_SHOW, $GUI1)
        GUISetState(@SW_SHOW, $GUI2)
        GUIRegisterMsg($WM_ACTIVATE, "WM_ACTIVATE")

EndFunc   ;==>Form1
Func _MSG()
        Select
                Case @GUI_CtrlId = $BUTTON1
                        MsgBox(0, "", "点击 A1" )
                Case @GUI_CtrlId = $BUTTON2
                        MsgBox(0, "", "点击 A2" )
                Case @GUI_CtrlId = $BUTTON3
                        MsgBox(0, "", "点击 A3" )
                Case @GUI_CtrlId = $BUTTON4
                        MsgBox(0, "", "点击 A4" )
                Case @GUI_CtrlId = $BBUTTON1
                        MsgBox(0, "", "点击 B1" )
                Case @GUI_CtrlId = $BBUTTON2
                        MsgBox(0, "", "点击 B2" )
                Case @GUI_CtrlId = $BBUTTON3
                        MsgBox(0, "", "点击 B3" )
                Case @GUI_CtrlId = $BBUTTON4
                        MsgBox(0, "", "点击 B4" )
        EndSelect
EndFunc   ;==>_MSG

Func WM_ACTIVATE($hWnd, $iMsg, $iwParam, $ilParam)
        Local $Activemode = _WinAPI_LoWord($iwParam)
        Switch $Activemode
                Case 0
                        ;$Activemode = "disactive"
                        Return
                Case 1
                        $Activemode = "其他方式激活"
                        $Acti = "信息" & @CRLF & "当前激活窗口为 :" & WinGetTitle($hWnd) & @CRLF & "激活方式为 :" & $Activemode
                        GUICtrlSetData($label6, $Acti)
                        GUICtrlSetColor($label6, 0x009900)
                Case 2
                        $Activemode = "鼠标点击激活"
                        $Acti = "信息" & @CRLF & "当前激活窗口为 :" & WinGetTitle($hWnd) & @CRLF & "激活方式为 :" & $Activemode
                        GUICtrlSetData($label, $Acti)
                        GUICtrlSetColor($label, 0xFF00FF)
        EndSwitch
        ConsoleWrite("信息" & @CRLF & "当前激活窗口为 :" & WinGetTitle($hWnd) & @CRLF & "激活方式为 :" & $Activemode)
        ;MsgBox(0, "", "信息" & @CRLF & "当前激活窗口为 :" & WinGetTitle($hWnd) & @CRLF & "激活方式为 :" & $Activemode)
        $Acti = "信息" & @CRLF & "当前激活窗口为 :" & WinGetTitle($hWnd) & @CRLF & "激活方式为 :" & $Activemode
        GUICtrlSetData($label, $Acti)
        GUICtrlSetColor($label, 0x0000FF)
EndFunc   ;==>WM_ACTIVATE
发表于 2017-7-6 12:02:12 | 显示全部楼层
回复 3# kk_lee69


    GUIGetMsg(1) 高级模式可以实现n个窗口在一个消息循环中捕获处理,但并不能达到你直接复制整段使用的目的。
建议,每个消息(事件)还是单独写成函数,这样虽然分散,但更便于管理与调用。如果只是个人编程,适合自己的书写习惯就好,其它也无所谓…
发表于 2017-7-6 14:36:45 | 显示全部楼层
本帖最后由 yamakawa 于 2017-7-6 14:50 编辑

回复 3# kk_lee69


    其实,看了半天还是不明白你想干什么。。如果说是想把事件模式的代码用一个func调用的话,很简单的。。。。用@GUI_CTRLID 做判断就好了
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

Opt("GUIOnEventMode", 1) ;使用消息模式
$WinMain = GuiCreate("主程式",300,400)
 
Local $BUTTON1 = GUICtrlCreateButton("Button1",10,10)
Local $BUTTON2= GUICtrlCreateButton("Button2",10,40)
    GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents")
GUICtrlSetOnEvent($BUTTON1, "GUI_COMMAND")
GUICtrlSetOnEvent($BUTTON2, "GUI_COMMAND")
 GUISetState(@SW_SHOW)
While 1
 
Sleep(20)
 
WEnd
 
 
Func GUI_COMMAND()
        Switch @GUI_CTRLID  
        Case  $BUTTON1
                MsgBox(0,"","Button1 is Clicked!")
                                ;可以调用子函数,也可以直接写入代码
                                ;直接写入代码的话,到时候直接复制这个函数GUI_COMMAND()就可以移植了
        Case  $BUTTON2
                _Button2()
      
        EndSwitch
        
EndFunc  ;==>GUI_COMMAND
 
 Func _Button2()
         MsgBox(0,"","Button2 is clicked!")
 EndFunc  ;==>_Button2
 

Func SpecialEvents()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            MsgBox($MB_SYSTEMMODAL, "Close Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)

            GUIDelete()
            Exit

        Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
            MsgBox($MB_SYSTEMMODAL, "Window Minimized", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)

        Case @GUI_CtrlId = $GUI_EVENT_RESTORE
            MsgBox($MB_SYSTEMMODAL, "Window Restored", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)

    EndSelect
EndFunc   ;==>SpecialEvents
 楼主| 发表于 2017-7-6 16:37:27 | 显示全部楼层
本帖最后由 kk_lee69 于 2017-7-6 16:52 编辑

回复 6# yamakawa


    感謝回復   你的範例我看了 我可以了解你的意思  當然  我們可以把很多的BUTTON 的功能 寫在一個 FUNC 裡面

假設 我現在的程式  可以產生10個窗口    每個窗口 有20個按鈕的功能.....我們事實上是可以把 10*20
=200個按鈕的功能 寫在 一個 FUNC 裡面

但是 如果我要移植 其中一個窗口  我就必須從 那個 寫了200個 按鈕功能的 FUNC 裡面拆出 屬於窗口A的20個

這樣拆法會 容易亂掉....

我希望的是 不用花大腦想   只要複製其中一段 就可以把整個窗口的功能 移植到其他程式
发表于 2017-7-6 17:15:30 | 显示全部楼层
回复 7# kk_lee69


    写代码的时候写清楚点就好了。。。
Switch @GUI_WinHandle
        Case $gui1
                Switch @GUI_CtrlId
                        Case $a
                                ;==>code
                        Case $b
                                ;==>code
                EndSwitch
        Case $gui2
                Switch @GUI_CtrlId
                        Case $c
                                ;==>code                                
                        Case $d
                                ;==>code
                EndSwitch
EndSwitch
 楼主| 发表于 2017-7-6 17:54:45 | 显示全部楼层
回复 8# yamakawa


呵呵  話這麼說 也沒錯啦   這也是個做法  看了你的範例 我懂意思  每個GUI 先 CASE  然後屬於那個 GUI 在放在他下面

但是 我的 之所有會有這個  疑問的原因是

我習慣在 FUNC 左手邊按 一 就會把整個 FUNC 縮起來  然後 不管中間有幾千行  我只要  框起 整個

FUNC   複製 貼上   就可以 移植到其他程式.....

所以 才有這樣的疑問.......

理解您的意思  這倒也是個方法
发表于 2017-7-6 23:33:59 | 显示全部楼层
回复  yamakawa


呵呵  話這麼說 也沒錯啦   這也是個做法  看了你的範例 我懂意思  每個GUI 先 CASE ...
kk_lee69 发表于 2017-7-6 17:54



    @GUI_CtrlId 是事件模式才能用的(我在2#提到过),这样写成的函数跟你的消息循环模式不通用。
发表于 2017-7-7 09:13:09 | 显示全部楼层
回复 9# kk_lee69
4楼的例子有看吗?应该能解决你的问题
 楼主| 发表于 2017-7-7 09:52:58 | 显示全部楼层
回复 11# chzj589
    例子看了 .....程式 我會寫  我只是在找 如何寫 可以解決我的問題

你的範例  就是個 事件模式的範例  這個我理解  ...............
 楼主| 发表于 2017-7-7 10:01:40 | 显示全部楼层
回复 10# afan

看來 我的表達還是有問題的 ....

我原本的寫法是 消息循環模式  其最大的優點是  可以整段複製 移植到 其他程式使用

但是 我想改成  事件模式   缺點是我覺得程式必須要分散掉 寫在同一個 處理事件的FUNC 裡面,

而  yamakawa  的意思 應該是  在 處理 事件的FUNC 的寫法上  可以 先判斷是 哪個窗口來的消息

然後再 判斷 是哪個 BUTTON  這樣 會 是  一小段一小段的  一個一個的範圍

到時候 只要複製這一小段就好.....

所以我說這到也是個方法

我的最終目的 還是希望 寫成 事件模式
发表于 2017-7-7 10:09:53 | 显示全部楼层
回复 12# kk_lee69
处理一下,不就能你想需要复制哪段就复制哪段
 楼主| 发表于 2017-7-7 10:15:18 | 显示全部楼层
回复 14# chzj589

我懂 當然程式   我都可以 想複製哪段 就是哪段

但是 我的 之所有會有這個  疑問的原因是

我習慣在 FUNC 左手邊按 一 就會把整個 FUNC 縮起來  然後 不管中間有幾千行  我只要  框起 整個

FUNC   複製 貼上   就可以 移植到其他程式.....

我只做一次複製動作........

事件模式的寫法  會造成 我可能 要複製三次 到 四次  因為分屬在不同的地方....

這樣我可能會亂掉  漏了某一段.....

所以 我習慣一個 FUNC 複製一次就好.....

所以在尋求 可以達到這個目的的事件模式寫法
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-4-26 20:02 , Processed in 0.078076 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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