xiehuahere 发表于 2011-11-4 15:09:27

【已解决】状态栏内嵌滚动条在GUI restore后显示位置不正确

本帖最后由 xiehuahere 于 2011-11-6 21:59 编辑

点击Create按钮后,状态栏内嵌滚动条开始滚动,最小化GUI然后再restore,滚动条显示的位置不对了。看了半天没找到症结所在,请大大们帮忙看看。

代码如下:
#Include <GuiEdit.au3>
#include <GUIListView.au3>
#include <GuiStatusBar.au3>
#include <Editconstants.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <ProgressConstants.au3>
#include <SendMessage.au3>
#Include <Misc.au3>

If _Singleton("test", 1) = 0 Then
    Msgbox(4096, "test", "Program is already running!")
    Exit 1
EndIf

Global $msg, $hWnd, $hListview, $hEdit, $hStatus, $progress, $hProgress, $aHit, $hDC, $hBrush
Global $isCreating = 0, $isEnterResp = 0
Global $maxImageNum = 500

Opt("GUIOnEventMode", 1)
Const $width = 280, $height = 320

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("test", $width, $height, (@DesktopWidth - $width) / 2, (@DesktopHeight - $height) / 2)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Main")
$Label = GUICtrlCreateLabel('Fill in image number for each folder and then click Create button.', 6, 12, 268, 32)
GUICtrlSetFont(-1, 10, 400, 0, "Default", 5)    ; CLEARTYPE_QUALITY=5
GUICtrlSetColor(-1, 0x000080)
; ===============================================================================
; Listview
$hListview = _GUICtrlListView_Create($Form1, '', 6, 60, 266, 157, BitOR($LVS_EDITLABELS, $LVS_REPORT))
_GUICtrlListView_SetExtendedListViewStyle($hListview, BitOR($LVS_EX_GRIDLINES, $LVS_EX_BORDERSELECT, $LVS_EX_FULLROWSELECT))
; ===============================================================================
$Button1 = GUICtrlCreateButton("Create", 60, 248, 160, 32)      ;$BS_DEFPUSHBUTTON
GUICtrlSetOnEvent(-1, "_Main")
GUICtrlSetState(-1, $GUI_FOCUS)
; ===============================================================================
; Status bar - Defaults to 1 part, no text
$hStatus = _GUICtrlStatusBar_Create ($Form1)
_GUICtrlStatusBar_SetMinHeight ($hStatus, 20)
; ===============================================================================
; Insert column into listview and set width
_GUICtrlListView_InsertColumn($hListview, 0, 'Folder', 50)
_GUICtrlListView_InsertColumn($hListview, 1, 'Image Number', 84)
_GUICtrlListView_InsertColumn($hListview, 2, 'Image index range', 132)
; Set Text-Centered format for all three columns
_GUICtrlListView_JustifyColumn($hListview, 0, 2)
_GUICtrlListView_JustifyColumn($hListview, 1, 2)
_GUICtrlListView_JustifyColumn($hListview, 2, 2)
; Add item/subitem
For $i = 0 To 9
        _GUICtrlListView_AddItem($hListview, $i, $i)    ; 1st column
        _GUICtrlListView_AddSubItem($hListview, $i, '0', 1)   ; 2nd column
        _GUICtrlListView_AddSubItem($hListview, $i, '-', 2)   ; 3rd column
Next
; ===============================================================================

GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

; Update status bar
; ===============================================================================
; Initialize parts for status bar
Const $aParts =
_GUICtrlStatusBar_SetParts ($hStatus, $aParts)
; Part 1 - Text status information
; Part 2 - Embedded progress bar
If @OSTYPE = "WIN32_WINDOWS" Then
        $progress = GUICtrlCreateProgress(0, 0, -1, -1, $PBS_SMOOTH)
        $hProgress = GUICtrlGetHandle($progress)
        _GUICtrlStatusBar_EmbedControl ($hStatus, 1, $hProgress)
Else    ; Generally Win32_NT
        $progress = GUICtrlCreateProgress(0, 0, -1, -1, $PBS_MARQUEE) ; marquee works on Win XP and above
        $hProgress = GUICtrlGetHandle($progress)
        _GUICtrlStatusBar_EmbedControl ($hStatus, 1, $hProgress)
        _SendMessage($hProgress, $PBM_SETMARQUEE, True, 100) ; marquee works on Win XP and above
EndIf

GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND')

GUICtrlSetState($progress, $GUI_HIDE)

While 1
        Sleep(10)
WEnd

Func _Main()
        Switch @GUI_CtrlId
                Case -3 ; $GUI_EVENT_CLOSE
                                Exit
                Case $Button1
                        $isCreating = 1
                        GUICtrlSetState($Button1, $GUI_DISABLE)
                        GUICtrlSetState($progress, $GUI_SHOW)
                        Sleep(20000)
                        GUICtrlSetState($progress, $GUI_HIDE)
                        GUICtrlSetState($Button1, $GUI_ENABLE)
                        $isCreating = 0
        EndSwitch
EndFunc

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
        Local $tNMHDR, $hWndFrom, $iCode

        $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
        $hWndFrom = DllStructGetData($tNMHDR, 'hWndFrom')
        $iCode = DllStructGetData($tNMHDR, 'Code')

        Switch $iCode
                Case $NM_CLICK
                        $aHit = _GUICtrlListView_SubItemHitTest($hListview)
                        If $aHit = 1 And $isCreating = 0 Then
                                Local $aRect = _GUICtrlListView_GetSubItemRect($hListview, $aHit, $aHit)
                                Local $aPos = ControlGetPos($hWnd, '', $hListview)
                                Local $text = _GUICtrlListView_GetItemText($hListview, $aHit, $aHit)
                                Local $iStyle = BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT, $ES_NUMBER)

                                $hEdit = _GUICtrlEdit_Create($hWnd, $text, $aPos + $aRect, $aPos + $aRect, _
                                                        _GUICtrlListView_GetColumnWidth($hListview, $aHit), 17, $iStyle)
                                _GUICtrlEdit_SetSel($hEdit, 0, -1)
                                _WinAPI_SetFocus($hEdit)
                                $hDC = _WinAPI_GetWindowDC($hEdit)
                                $hBrush = _WinAPI_CreateSolidBrush(0xFF6600)

                                Local $stRect = DllStructCreate('int;int;int;int')
                                DllStructSetData($stRect, 1, 0) ; left
                                DllStructSetData($stRect, 2, 0) ; top
                                DllStructSetData($stRect, 3, _GUICtrlListView_GetColumnWidth($hListview, $aHit)) ; width
                                DllStructSetData($stRect, 4, 17); height
                                _WinAPI_FrameRect($hDC, DllStructGetPtr($stRect), $hBrush)

                                HotKeySet("{ENTER}", "confirm_listview_input_2")
                                $isEnterResp = 0
                        EndIf
        EndSwitch
EndFunc   ;==>WM_NOTIFY

Func WM_COMMAND($hWnd, $msg, $wParam, $lParam)
        Local $iCode = BitShift($wParam, 16); Get hi-word
        Switch $lParam
                Case $hEdit
                        Switch $iCode
                                Case $EN_KILLFOCUS
                                        If Not $isEnterResp Then confirm_listview_input_1()
                                Case $EN_CHANGE
                                        ; Reset the whole "Image index range" column
                                        For $i = 0 To 9
                                                        _GUICtrlListView_SetItemText($hListview, $i, "-", 2)
                                        Next
                        EndSwitch
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func confirm_listview_input_2()
        $isEnterResp = 1
        confirm_listview_input_1()
        _GUICtrlListView_SetItemSelected($hListview, $aHit)
EndFunc

Func confirm_listview_input_1()
        Local $sum = 0
        HotKeySet("{ENTER}")    ; Unset hot key

        Local $iText = _GUICtrlEdit_GetText($hEdit)
        _GUICtrlListView_SetItemText($hListview, $aHit, Number($iText), $aHit)

        ; Data validation
        For $i = 0 To 9
                        $sum += _GUICtrlListView_GetItemText($hListview, $i, 1)
        Next
        If $sum > $maxImageNum Then
                        MsgBox(4096, "Warning", "Total image number is limited to " & $maxImageNum & "!", 0, $Form1)
                        _GUICtrlListView_SetItemText($hListview, $aHit, $maxImageNum-($sum-Number($iText)), $aHit)
        EndIf

        _WinAPI_DeleteObject($hBrush)
        _WinAPI_ReleaseDC($hEdit, $hDC)
        _WinAPI_DestroyWindow($hEdit)
        _GUICtrlEdit_Destroy($hEdit)
EndFunc

附带一个小问题:
162行的_GUICtrlListView_SetItemSelected()没有生效,同样没搞清问题在哪儿。

xiehuahere 发表于 2011-11-5 12:00:44

看客多,答者少......
对于提问哪里不清楚,请提出。我继续补充。

afan 发表于 2011-11-5 15:01:54

#include <GuiEdit.au3>
#include <GUIListView.au3>
#include <GuiStatusBar.au3>
#include <Editconstants.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <ProgressConstants.au3>
#include <SendMessage.au3>
#include <Misc.au3>

If _Singleton("test", 1) = 0 Then
        MsgBox(4096, "test", "Program is already running!")
        Exit 1
EndIf

Global $msg, $hWnd, $hListview, $hEdit, $hStatus, $progress, $hProgress, $aHit, $hDC, $hBrush
Global $isCreating = 0, $isEnterResp = 0
Global $maxImageNum = 500

Opt("GUIOnEventMode", 1)
Const $width = 280, $height = 320

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("test", $width, $height, (@DesktopWidth - $width) / 2, (@DesktopHeight - $height) / 2)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Main")
$Label = GUICtrlCreateLabel('Fill in image number for each folder and then click Create button.', 6, 12, 268, 32)
GUICtrlSetFont(-1, 10, 400, 0, "Default", 5) ; CLEARTYPE_QUALITY=5
GUICtrlSetColor(-1, 0x000080)
; ===============================================================================
; Listview
$hListview = _GUICtrlListView_Create($Form1, '', 6, 60, 266, 157, BitOR($LVS_EDITLABELS, $LVS_REPORT))
_GUICtrlListView_SetExtendedListViewStyle($hListview, BitOR($LVS_EX_GRIDLINES, $LVS_EX_BORDERSELECT, $LVS_EX_FULLROWSELECT))
; ===============================================================================
$Button1 = GUICtrlCreateButton("Create", 60, 248, 160, 32) ;$BS_DEFPUSHBUTTON
GUICtrlSetOnEvent(-1, "_Main")
GUICtrlSetState(-1, $GUI_FOCUS)
; ===============================================================================
; Status bar - Defaults to 1 part, no text
$hStatus = _GUICtrlStatusBar_Create($Form1)
_GUICtrlStatusBar_SetMinHeight($hStatus, 20)
; ===============================================================================
; Insert column into listview and set width
_GUICtrlListView_InsertColumn($hListview, 0, 'Folder', 50)
_GUICtrlListView_InsertColumn($hListview, 1, 'Image Number', 84)
_GUICtrlListView_InsertColumn($hListview, 2, 'Image index range', 132)
; Set Text-Centered format for all three columns
_GUICtrlListView_JustifyColumn($hListview, 0, 2)
_GUICtrlListView_JustifyColumn($hListview, 1, 2)
_GUICtrlListView_JustifyColumn($hListview, 2, 2)
; Add item/subitem
For $i = 0 To 9
        _GUICtrlListView_AddItem($hListview, $i, $i) ; 1st column
        _GUICtrlListView_AddSubItem($hListview, $i, '0', 1) ; 2nd column
        _GUICtrlListView_AddSubItem($hListview, $i, '-', 2) ; 3rd column
Next
; ===============================================================================

GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

; Update status bar
; ===============================================================================
; Initialize parts for status bar
Const $aParts =
_GUICtrlStatusBar_SetParts($hStatus, $aParts)
; Part 1 - Text status information
; Part 2 - Embedded progress bar
If @OSType = "WIN32_WINDOWS" Then
        $progress = GUICtrlCreateProgress(0, 0, -1, -1, $PBS_SMOOTH)
        $hProgress = GUICtrlGetHandle($progress)
        _GUICtrlStatusBar_EmbedControl($hStatus, 1, $hProgress)
Else ; Generally Win32_NT
        $progress = GUICtrlCreateProgress(0, 0, -1, -1, $PBS_MARQUEE) ; marquee works on Win XP and above
        $hProgress = GUICtrlGetHandle($progress)
        _GUICtrlStatusBar_EmbedControl($hStatus, 1, $hProgress)
        _SendMessage($hProgress, $PBM_SETMARQUEE, True, 100) ; marquee works on Win XP and above
EndIf

GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND')
GUIRegisterMsg($WM_ACTIVATE, 'WM_ACTIVATE')

GUICtrlSetState($progress, $GUI_HIDE)

While 1
        Sleep(10)
WEnd

Func _Main()
        Switch @GUI_CtrlId
                Case -3 ; $GUI_EVENT_CLOSE
                        Exit
                Case $Button1
                        $isCreating = 1
                        GUICtrlSetState($Button1, $GUI_DISABLE)
                        GUICtrlSetState($progress, $GUI_SHOW)
                        Sleep(20000)
                        GUICtrlSetState($progress, $GUI_HIDE)
                        GUICtrlSetState($Button1, $GUI_ENABLE)
                        $isCreating = 0
        EndSwitch
EndFunc   ;==>_Main

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
        Local $tNMHDR, $hWndFrom, $iCode
        $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
        $hWndFrom = DllStructGetData($tNMHDR, 'hWndFrom')
        $iCode = DllStructGetData($tNMHDR, 'Code')

        Switch $iCode
                Case $NM_CLICK
                        $aHit = _GUICtrlListView_SubItemHitTest($hListview)
                        If $aHit = 1 And $isCreating = 0 Then
                                Local $aRect = _GUICtrlListView_GetSubItemRect($hListview, $aHit, $aHit)
                                Local $aPos = ControlGetPos($hWnd, '', $hListview)
                                Local $text = _GUICtrlListView_GetItemText($hListview, $aHit, $aHit)
                                Local $iStyle = BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT, $ES_NUMBER)

                                $hEdit = _GUICtrlEdit_Create($hWnd, $text, $aPos + $aRect, $aPos + $aRect, _
                                                _GUICtrlListView_GetColumnWidth($hListview, $aHit), 17, $iStyle)
                                _GUICtrlEdit_SetSel($hEdit, 0, -1)
                                _WinAPI_SetFocus($hEdit)
                                $hDC = _WinAPI_GetWindowDC($hEdit)
                                $hBrush = _WinAPI_CreateSolidBrush(0xFF6600)

                                Local $stRect = DllStructCreate('int;int;int;int')
                                DllStructSetData($stRect, 1, 0) ; left
                                DllStructSetData($stRect, 2, 0) ; top
                                DllStructSetData($stRect, 3, _GUICtrlListView_GetColumnWidth($hListview, $aHit)) ; width
                                DllStructSetData($stRect, 4, 17) ; height
                                _WinAPI_FrameRect($hDC, DllStructGetPtr($stRect), $hBrush)

                                HotKeySet("{ENTER}", "confirm_listview_input_2")
                                $isEnterResp = 0
                        EndIf
        EndSwitch
EndFunc   ;==>WM_NOTIFY

Func WM_ACTIVATE($hWnd, $msg, $wParam)
        #forceref $hWnd, $msg
        If $wParam = 1 Then _GUICtrlStatusBar_EmbedControl($hStatus, 1, $hProgress)
Endfunc

Func WM_COMMAND($hWnd, $msg, $wParam, $lParam)
        Local $iCode = BitShift($wParam, 16) ; Get hi-word

        Switch $lParam
                Case $hEdit
                        Switch $iCode
                                Case $EN_KILLFOCUS
                                        If Not $isEnterResp Then confirm_listview_input_1()
                                Case $EN_CHANGE
                                        ; Reset the whole "Image index range" column
                                        For $i = 0 To 9
                                                _GUICtrlListView_SetItemText($hListview, $i, "-", 2)
                                        Next
                        EndSwitch
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func confirm_listview_input_2()
        $isEnterResp = 1
        confirm_listview_input_1()
        _GUICtrlListView_SetItemSelected($hListview, $aHit)
EndFunc   ;==>confirm_listview_input_2

Func confirm_listview_input_1()
        Local $sum = 0
        HotKeySet("{ENTER}") ; Unset hot key

        Local $iText = _GUICtrlEdit_GetText($hEdit)
        _GUICtrlListView_SetItemText($hListview, $aHit, Number($iText), $aHit)

        ; Data validation
        For $i = 0 To 9
                $sum += _GUICtrlListView_GetItemText($hListview, $i, 1)
        Next
        If $sum > $maxImageNum Then
                MsgBox(4096, "Warning", "Total image number is limited to " & $maxImageNum & "!", 0, $Form1)
                _GUICtrlListView_SetItemText($hListview, $aHit, $maxImageNum - ($sum - Number($iText)), $aHit)
        EndIf

        _WinAPI_DeleteObject($hBrush)
        _WinAPI_ReleaseDC($hEdit, $hDC)
        _WinAPI_DestroyWindow($hEdit)
        _GUICtrlEdit_Destroy($hEdit)
EndFunc   ;==>confirm_listview_input_1

menfan1 发表于 2011-11-5 15:33:21

楼上正解。。呵呵

xiehuahere 发表于 2011-11-5 17:36:43

本帖最后由 xiehuahere 于 2011-11-5 17:37 编辑

回复 3# afan


    原来是需要处理 WM_ACTIVATE,谢谢afan! 虽然并不是很明白为什么滚动条控件在窗口被重新激活后需要再次嵌入。
   
   上面的第二个问题能否也帮忙回答一下?
   我代码中的162行(你代码里的168行)这句,为啥没有生效呢?即在listview中第二列输入内容并按回车确认后,该行(item)不能被高亮选中。

drunk 发表于 2011-11-6 00:32:45

listview选中高亮问题我也遇到过
后来查原因发现是样式问题
你去掉样式试下

xiehuahere 发表于 2011-11-6 13:18:37

回复 6# drunk


    样式都是必须的,不能去啊。。。去掉了试过,也不行。
    谢谢关注!

afan 发表于 2011-11-6 13:35:09

listview控件失去了焦点而已

xiehuahere 发表于 2011-11-6 21:36:26

本帖最后由 xiehuahere 于 2011-11-6 21:58 编辑

回复 8# afan


早就怀疑是这个问题。但就是一直不知道如何解决。
现在不得不老老实实地换成:$Listview = GUICtrlCreateListView('', 6, 60, 266, 157, $LVS_REPORT)
$hListview = GUICtrlGetHandle($Listview)然后,Case $EN_KILLFOCUS
             If $isEnterResp Then
                     GUICtrlSetState($Listview, $GUI_FOCUS)
              _GUICtrlListView_SetItemSelected($hListview, $aHit)
             Else
                     confirm_listview_input_1()
            EndIf问题解决。
afan,还是多谢了!
我杀鸡还是用了你这把牛刀。
页: [1]
查看完整版本: 【已解决】状态栏内嵌滚动条在GUI restore后显示位置不正确