找回密码
 加入
搜索
查看: 6658|回复: 14

[GUI管理] [已解决]一个GUI窗口下 LISTVIEW双击事件呼叫另外一个GUI窗口,程序会卡住求解

 火.. [复制链接]
发表于 2012-11-14 01:18:00 | 显示全部楼层 |阅读模式
本帖最后由 kk_lee69 于 2012-11-14 21:14 编辑

求助  一个GUI窗口下 LISTVIEW双击事件呼叫另外一个GUI窗口,程序会卡住求解

設計了一個主表單  裡面有個 LISTVIEW  利用 LISTVIEW 的雙擊事件 呼叫 另外一個表單,請教寫法與思路....

因為我自己的寫法 會造成 程式卡住........我自己認為是因為 迴圈之類的問題 造成 卡住.......變成程式無回應.....

因為程式有4千多行......因此濃縮如下:  只剩下主架構......求高手 解惑一下 , 怎要修改 才不會卡住


$WinMain = GuiCreate('主選單',900,700)
; 創建窗口

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

$listview = GUICtrlCreateListView("合約編號 |合約日期 |客戶名稱  ", 10, 35, 880, 310, -1, BitOR( $LVS_REPORT,$LVS_SHOWSELALWAYS));,$LVS_SORTDESCENDING)


GuiSetState()
; 顯示視窗
While 1
        ;_ReduceMemory(@AutoItPID)
        Switch GUIGetMsg()

                Case $GUI_EVENT_CLOSE
                        Exit

                Case $listview
                        ; Kick off the sort callback
                        _GUICtrlListView_SortItems($listview, GUICtrlGetState($listview))
                        
        EndSwitch
WEnd



Func WM_NOTIFY($hWnd, $message, $wParam, $sParam)
        Local $tNmhdr, $hWndFrom, $code
        $tNmhdr = DLLStructCreate($tagNmhdr, $sParam)
        $hWndFrom = DLLStructGetData($tNmhdr, "hWndFrom")
        $code = DLLStructGetData($tNmhdr, "code")
        $tNmhdr = 0
        Switch $code
                Case $NM_CLICK
                        Switch $hWndFrom
                                Case $hWndFrom = GuiCtrlGetHandle($ListView)
                                
                                Case $hWndFrom = GuiCtrlGetHandle($ListView2)
                                
                                CASE $hWndFrom = GuiCtrlGetHandle($ListView3)

                                Case $hWndFrom = GuiCtrlGetHandle($ListView4)
                                
                        EndSwitch


                Case $NM_DBLCLK
                        Switch $hWndFrom
                                Case $hWndFrom = GuiCtrlGetHandle($ListView)
                                        ContractMENU() ;雙擊事件 呼叫另外一個 FROM
                                
                        EndSwitch                        
                        
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc ;==>_wmNotify()




Func ContractMENU()
                
                        $WinSUB = GuiCreate('批次刪除 已經輸入過的 支票資料',800,600,-1,-1,-1,-1);,$WinMain)

                        GUICtrlCreateGroup('帳款資料', 5, 5, 790, 400)

                        $DELACC1 = GuiCtrlCreateButton('刪除全部現金付款', 10, 420, 120, 30); 清除紀錄按鈕
                        $DELACC2 = GuiCtrlCreateButton('刪除全部支票資料', 135, 420, 120, 30); 清除紀錄按鈕
                        $DELACC3 = GuiCtrlCreateButton('刪除全部本票資料', 260, 420, 120, 30); 清除紀錄按鈕
                        $DELACC4 = GuiCtrlCreateButton('刪除全部 ACH 轉帳',385, 420, 120, 30); 清除紀錄按鈕
                        $DELACC5 = GuiCtrlCreateButton('刪除全部超商繳款', 510, 420, 120, 30); 清除紀錄按鈕
                        $DELACC6 = GuiCtrlCreateButton('刪除全部其他資料', 635, 420, 120, 30); 清除紀錄按鈕
                        
                        GUISetState()
                        While 1
                                Switch guigetmsg()
                                        Case $GUI_EVENT_CLOSE
                                                GUISetState(@SW_ENABLE,$WinMain)
                                                GUIDelete($WinSUB)
                                                WinActivate($WinMain,"")
                                                ExitLoop



                                EndSwitch
                        WEnd


EndFunc   
发表于 2012-11-14 04:12:27 | 显示全部楼层
AU3不支持多线程,不可以双循环!呼出的GUI不用循环也可以运行的!
 楼主| 发表于 2012-11-14 09:08:55 | 显示全部楼层
回复 2# gzh888666

請問一下不用循環 怎麼處理  按鍵沒反應.....一關掉就全部關掉了
发表于 2012-11-14 09:30:23 | 显示全部楼层
我也想知道这个怎么解决
发表于 2012-11-14 11:57:47 | 显示全部楼层
本帖最后由 afan 于 2012-11-14 12:42 编辑

可以先创建所有窗口及控件,在一个循环中显隐窗口及控件
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>
#include <GuiListView.au3>

$WinMain = GUICreate('主選單', 900, 700); 創建窗口
GUIRegisterMsg(0x4E, "WM_NOTIFY")
$listview = GUICtrlCreateListView("合約編號 |合約日期 |客戶名稱  ", 10, 35, 880, 310, -1, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS));,$LVS_SORTDESCENDING)
GUICtrlCreateListViewItem("项目 1|子项 1|子项 2", $listview)
GUISetState(); 顯示視窗

$WinSUB = GUICreate('批次刪除 已經輸入過的 支票資料', 800, 600, -1, -1, -1, -1);,$WinMain)
GUICtrlCreateGroup('帳款資料', 5, 5, 790, 400)
$DELACC1 = GUICtrlCreateButton('刪除全部現金付款', 10, 420, 120, 30); 清除紀錄按鈕
$DELACC2 = GUICtrlCreateButton('刪除全部支票資料', 135, 420, 120, 30); 清除紀錄按鈕
$DELACC3 = GUICtrlCreateButton('刪除全部本票資料', 260, 420, 120, 30); 清除紀錄按鈕
$DELACC4 = GUICtrlCreateButton('刪除全部 ACH 轉帳', 385, 420, 120, 30); 清除紀錄按鈕
$DELACC5 = GUICtrlCreateButton('刪除全部超商繳款', 510, 420, 120, 30); 清除紀錄按鈕
$DELACC6 = GUICtrlCreateButton('刪除全部其他資料', 635, 420, 120, 30); 清除紀錄按鈕

While 1
        $aMsg = GUIGetMsg(1)
        Switch $aMsg[0]
                Case -3
                        If $aMsg[1] = $WinMain Then
                                Exit
                        Else
                                GUISetState(0, $WinSUB)
                        EndIf

                Case $listview ; Kick off the sort callback

                Case $DELACC1
                        MsgBox(0, '子窗口点击', '刪除全部現金付款')

                Case $DELACC2
                        ;...
        EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $message, $wParam, $sParam)
        Local $tNmhdr, $hWndFrom, $code
        $tNmhdr = DllStructCreate($tagNmhdr, $sParam)
        $hWndFrom = DllStructGetData($tNmhdr, "hWndFrom")
        $code = DllStructGetData($tNmhdr, "code")
        $tNmhdr = 0
        Switch $code
                Case $NM_CLICK

                Case $NM_DBLCLK
                        Switch $hWndFrom
                                Case $hWndFrom = GUICtrlGetHandle($listview)
                                        GUISetState(1, $WinSUB) ;雙擊事件 呼叫另外一個 FROM
                        EndSwitch

        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
 楼主| 发表于 2012-11-14 20:34:30 | 显示全部楼层
回复 5# afan

老大 收到了  了解 概念了  感謝....

不過另外請較一個事情......昨天晚上自己用了一個方法是.....

主視窗裡面的 LISTVIEW 雙擊事件後  啟動 呼叫 另外一個 子GUI窗口

在子 GUI窗口啟動後 改成消息模式......等待 接收 子窗口的關閉事件.....

子窗口關閉後 再改回 原來的 循環模式.......

這樣的方式  不會卡住 但是會造成 CPU 飆升到50%  ..........

請問這是因為消息模式造成的嗎  還是因為我寫法的問題呢??...
发表于 2012-11-14 20:38:38 | 显示全部楼层
回复 6# kk_lee69


    消息模式就是循环模式啊(消息循环),莫非你所指的循环模式是指事件模式?
 楼主| 发表于 2012-11-14 20:41:26 | 显示全部楼层
本帖最后由 kk_lee69 于 2012-11-14 20:43 编辑

回复 7# afan

對 那就是 是件模式  來源是 參考 下面文章

http://www.autoitx.com/forum.php?mod=viewthread&tid=476


    OnEvent模式进阶教程


Func ContractMENU()

                        GuiSetState(@SW_DISABLE,$WinMain) ; 禁用視窗,以防用戶作出其他更改
                        
                        

                        
                        $WinSUB = GuiCreate('批次刪除 已經輸入過的 支票資料',800,600,-1,-1,-1,-1,$WinMain)

                        GUICtrlCreateGroup('帳款資料', 5, 5, 790, 400)
                        Opt("GUIOnEventMode", 1)
                        
                        GUISetOnEvent($GUI_EVENT_CLOSE, "ContractMENU_COMMAND")


                        $DELACC1 = GuiCtrlCreateButton('刪除全部現金付款', 10, 420, 120, 30); 清除紀錄按鈕
                        $DELACC2 = GuiCtrlCreateButton('刪除全部支票資料', 135, 420, 120, 30); 清除紀錄按鈕
                        $DELACC3 = GuiCtrlCreateButton('刪除全部本票資料', 260, 420, 120, 30); 清除紀錄按鈕
                        $DELACC4 = GuiCtrlCreateButton('刪除全部 ACH 轉帳',385, 420, 120, 30); 清除紀錄按鈕
                        $DELACC5 = GuiCtrlCreateButton('刪除全部超商繳款', 510, 420, 120, 30); 清除紀錄按鈕
                        $DELACC6 = GuiCtrlCreateButton('刪除全部其他資料', 635, 420, 120, 30); 清除紀錄按鈕
                        
                        GUISetState()



EndFunc   




Func ContractMENU_COMMAND()

    Switch @GUI_CtrlId

        Case $GUI_EVENT_CLOSE
                        Switch @GUI_WINHANDLE
                                Case ELSE
                                        GUIDelete(@GUI_WINHANDLE)
                                        Opt("GUIOnEventMode", 0)
                                        GUISetState(@SW_ENABLE,$WinMain)
                                        WinActivate($WinMain,"")
                                        
                        ;MsgBox(0,"A","A")
                        
                        EndSwitch
    EndSwitch

EndFunc
发表于 2012-11-14 20:46:25 | 显示全部楼层
回复 8# kk_lee69


    事件模式同样是可以的,甚至更好~
我不知道你的代码是如何的,可能在主循环中未加入含Sleep()的代码。

如果多个窗口都需要响应操作,最好使用一个模式,以免遇到诸如此类的问题。
 楼主| 发表于 2012-11-14 20:48:41 | 显示全部楼层
回复 7# afan

這邊又發現一個 好玩的事情

http://www.autoitx.com/forum.php?mod=viewthread&tid=476

這篇文章的範例 也會讓CPU 飆升到 50%

但是 看過 網站有位朋友寫的 進銷存管理的系統

似乎 也是採用  事件模式  但是 不會造成CPU 負擔ㄟ

只是他寫的複雜  需要時間研究看看
发表于 2012-11-14 20:55:14 | 显示全部楼层
回复 10# kk_lee69


    因为他的主循环缺少Sleep(),加一行即可
While 1
        If $start >= 0 Then
                Sleep(50)
                $start += 1
                If $start > 100 Then $start = 0
                If $start >= 0 Then
                        $ostart = $start
                        GUICtrlSetData($Progress_1, $start)
                Else
                        ContinueLoop
                EndIf
        EndIf
        Sleep(1)
WEnd
 楼主| 发表于 2012-11-14 21:10:12 | 显示全部楼层
回复 11# afan


    果然  加一行 Sleep(1)  CPU 就正常了....真神奇@@ 感謝幫忙
发表于 2012-11-15 17:41:40 | 显示全部楼层
路过学习一下!
发表于 2013-1-30 13:21:25 | 显示全部楼层
学习了。。。
发表于 2018-11-28 14:05:31 | 显示全部楼层
学习了。。刚好需要
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-4-26 21:53 , Processed in 0.077097 second(s), 19 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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