消息模式与循环模式写法差异问题,求写法解[已解决]
本帖最后由 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 功能到其他程序呢??
以上杂七杂八的 说了 一堆 ,希望高手有耐心看完,可以给我一些逻辑上的建议感谢!! Opt("GUIOnEventMode", 1) ;一般这种叫事件模式
Opt("GUIOnEventMode", 0) + GUIGetMsg() 是消息循环模式
事件模式更易于函数模块化,可移植性更好,也可使用特殊的事件宏 回复 2# afan
理解 不過版主 我想請教的就是
我以前使用 Opt("GUIOnEventMode", 0) + GUIGetMsg() 是消息循环模式
我可以 寫一個 FUNC把幾千行的程式寫入到這個 FUNC 包含每個按鈕的判斷跟 功能
移植的時候 我只有 移植一個 FUNC
但是使用 Opt("GUIOnEventMode", 1) ;一般这种叫事件模式
我可能˙被迫要將 程式拆成很多段 放在 不同位置
這樣移植的時候 我就必須要 一段一段的移植
所以我想問的就是....
事件模式....有沒有怎樣的寫法邏輯 可以達到我可以 複製連續的 一整段 程式碼 就可以ㄧ 可以達到我可以 複製連續的 一整段 程式碼 就可以移植 回复 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
回复 3# kk_lee69
GUIGetMsg(1) 高级模式可以实现n个窗口在一个消息循环中捕获处理,但并不能达到你直接复制整段使用的目的。
建议,每个消息(事件)还是单独写成函数,这样虽然分散,但更便于管理与调用。如果只是个人编程,适合自己的书写习惯就好,其它也无所谓… 本帖最后由 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 本帖最后由 kk_lee69 于 2017-7-6 16:52 编辑
回复 6# yamakawa
感謝回復 你的範例我看了 我可以了解你的意思當然我們可以把很多的BUTTON 的功能 寫在一個 FUNC 裡面
假設 我現在的程式可以產生10個窗口 每個窗口 有20個按鈕的功能.....我們事實上是可以把 10*20
=200個按鈕的功能 寫在 一個 FUNC 裡面
但是 如果我要移植 其中一個窗口我就必須從 那個 寫了200個 按鈕功能的 FUNC 裡面拆出 屬於窗口A的20個
這樣拆法會 容易亂掉....
我希望的是 不用花大腦想 只要複製其中一段 就可以把整個窗口的功能 移植到其他程式 回复 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
回复 8# yamakawa
呵呵話這麼說 也沒錯啦 這也是個做法看了你的範例 我懂意思每個GUI 先 CASE然後屬於那個 GUI 在放在他下面
但是 我的 之所有會有這個疑問的原因是
我習慣在 FUNC 左手邊按 一 就會把整個 FUNC 縮起來然後 不管中間有幾千行我只要框起 整個
FUNC 複製 貼上 就可以 移植到其他程式.....
所以 才有這樣的疑問.......
理解您的意思這倒也是個方法 回复yamakawa
呵呵話這麼說 也沒錯啦 這也是個做法看了你的範例 我懂意思每個GUI 先 CASE ...
kk_lee69 发表于 2017-7-6 17:54 http://www.autoitx.com/images/common/back.gif
@GUI_CtrlId 是事件模式才能用的(我在2#提到过),这样写成的函数跟你的消息循环模式不通用。 回复 9# kk_lee69
4楼的例子有看吗?应该能解决你的问题 回复 11# chzj589
例子看了 .....程式 我會寫我只是在找 如何寫 可以解決我的問題
你的範例就是個 事件模式的範例這個我理解............... 回复 10# afan
看來 我的表達還是有問題的 ....
我原本的寫法是 消息循環模式其最大的優點是可以整段複製 移植到 其他程式使用
但是 我想改成事件模式 缺點是我覺得程式必須要分散掉 寫在同一個 處理事件的FUNC 裡面,
而yamakawa的意思 應該是在 處理 事件的FUNC 的寫法上可以 先判斷是 哪個窗口來的消息
然後再 判斷 是哪個 BUTTON這樣 會 是一小段一小段的一個一個的範圍
到時候 只要複製這一小段就好.....
所以我說這到也是個方法
我的最終目的 還是希望 寫成 事件模式 回复 12# kk_lee69
处理一下,不就能你想需要复制哪段就复制哪段 回复 14# chzj589
我懂 當然程式 我都可以 想複製哪段 就是哪段
但是 我的 之所有會有這個疑問的原因是
我習慣在 FUNC 左手邊按 一 就會把整個 FUNC 縮起來然後 不管中間有幾千行我只要框起 整個
FUNC 複製 貼上 就可以 移植到其他程式.....
我只做一次複製動作........
事件模式的寫法會造成 我可能 要複製三次 到 四次因為分屬在不同的地方....
這樣我可能會亂掉漏了某一段.....
所以 我習慣一個 FUNC 複製一次就好.....
所以在尋求 可以達到這個目的的事件模式寫法