kk_lee69 发表于 2012-11-14 01:18:00

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

本帖最后由 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   

gzh888666 发表于 2012-11-14 04:12:27

AU3不支持多线程,不可以双循环!呼出的GUI不用循环也可以运行的!

kk_lee69 发表于 2012-11-14 09:08:55

回复 2# gzh888666

請問一下不用循環 怎麼處理按鍵沒反應.....一關掉就全部關掉了

jingygr 发表于 2012-11-14 09:30:23

我也想知道这个怎么解决

afan 发表于 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
                Case -3
                        If $aMsg = $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

kk_lee69 发表于 2012-11-14 20:34:30

回复 5# afan

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

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

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

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

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

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

請問這是因為消息模式造成的嗎還是因為我寫法的問題呢??...

afan 发表于 2012-11-14 20:38:38

回复 6# kk_lee69


    消息模式就是循环模式啊(消息循环),莫非你所指的循环模式是指事件模式?

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

afan 发表于 2012-11-14 20:46:25

回复 8# kk_lee69


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

如果多个窗口都需要响应操作,最好使用一个模式,以免遇到诸如此类的问题。

kk_lee69 发表于 2012-11-14 20:48:41

回复 7# afan

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

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

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

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

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

只是他寫的複雜需要時間研究看看

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

kk_lee69 发表于 2012-11-14 21:10:12

回复 11# afan


    果然加一行 Sleep(1)CPU 就正常了....真神奇@@ 感謝幫忙

blue_dvd 发表于 2012-11-15 17:41:40

路过学习一下!

fanxiang_1984 发表于 2013-1-30 13:21:25

学习了。。。

xyhqqaa 发表于 2018-11-28 14:05:31

学习了。。刚好需要
页: [1]
查看完整版本: [已解决]一个GUI窗口下 LISTVIEW双击事件呼叫另外一个GUI窗口,程序会卡住求解