Jump to content

GUI problem in Vista and 7 (SOLVED)


Dana
 Share

Recommended Posts

I have a program, nearly all one GUI, that runs fine in XP but not in Vista or Windows 7.

The program creates a listview and some labels aligned with the columns (headers for every row and totals for colums 6-14), or in other modes, input boxes replace some of the labels. When the listview horizonal scrollbar is moved, or a column is resized, the labels and/or input boxes get moved/resized to stay aligned with the listview.

EDIT: The full code is now here.

Note there are two different version of the includes, depending on which OS I'm working on (obfuscator seems to require the full path to the includes).

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Version=beta
#AutoIt3Wrapper_icon=logbook.ico
#AutoIt3Wrapper_Res_Fileversion=0.65.0.0
#AutoIt3Wrapper_Res_LegalCopyright=copyright (c) 2010 Dana M. Hague
#AutoIt3Wrapper_Res_File_Add=LogBookHelp.htm
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#cs
    Logbook program
    1/12/10 DMH
debug version, without working registration code
#ce

Opt("TrayIconDebug", 0)

#cs
#include <C:\Program Files\AutoIt3\Include\GUIConstantsEx.au3>
#include <C:\Program Files\AutoIt3\Include\ListviewConstants.au3>
#include <C:\Program Files\AutoIt3\Include\GuiListView.au3>
#include <C:\Program Files\AutoIt3\Include\EditConstants.au3>
#include <C:\Program Files\AutoIt3\Include\File.au3>
#include <C:\Program Files\AutoIt3\Include\StaticConstants.au3>
#include <C:\Program Files\AutoIt3\Include\WindowsConstants.au3>
#include <C:\Program Files\AutoIt3\Include\GuiScrollBars.au3>
#include <C:\Program Files\AutoIt3\Include\ScrollBarConstants.au3>
#include <C:\Program Files\AutoIt3\Include\ButtonConstants.au3>
#include <C:\Program Files\AutoIt3\Include\Array.au3>
#include <C:\Program Files\AutoIt3\Include\string.au3>
#include <C:\Program Files\AutoIt3\Include\Date.au3>
#ce

    #include <C:\Program Files (x86)\AutoIt3\Include\GUIConstantsEx.au3>
    #include <C:\Program Files (x86)\AutoIt3\Include\ListviewConstants.au3>
    #include <C:\Program Files (x86)\AutoIt3\Include\GuiListView.au3>
    #include <C:\Program Files (x86)\AutoIt3\Include\EditConstants.au3>
    #include <C:\Program Files (x86)\AutoIt3\Include\File.au3>
    #include <C:\Program Files (x86)\AutoIt3\Include\StaticConstants.au3>
    #include <C:\Program Files (x86)\AutoIt3\Include\WindowsConstants.au3>
    #include <C:\Program Files (x86)\AutoIt3\Include\GuiScrollBars.au3>
    #include <C:\Program Files (x86)\AutoIt3\Include\ScrollBarConstants.au3>
    #include <C:\Program Files (x86)\AutoIt3\Include\ButtonConstants.au3>
    #include <C:\Program Files (x86)\AutoIt3\Include\Array.au3>
    #include <C:\Program Files (x86)\AutoIt3\Include\string.au3>
    #include <C:\Program Files (x86)\AutoIt3\Include\Date.au3>
;#ce
$version = "0.65 beta"

; DATE CHECK FOR BETA VERSION ONLY
If StringInStr($version, "beta") And StringLeft(_NowCalcDate(), 4) > 2010 Then
    MsgBox(48, "Expired verson", "This is an expired pre-release development version" & @CRLF & _
            "of this program and is not for general use." & @CRLF & @CRLF & _
            "Please email (deleted) for further information.")
    Exit
EndIf

Global $header[17]
Global $colwidth[16]
Global $colpos[16]
Global $oldcolpos[16]
Global $enterdata[16]
Global $oldcolwidth[16]
Global $newdata[16]
Global $setupdata[17]
Global $headerlabel[16]
Global $dataarray[1][16]
Global $entery
Global $radiohhdh
Global $radiohhmm
;Global $namearray[256]
$linenum = 0
$dataline = 0
$entermode = 0
$editline = 0
$copyline = 0
$setupmode = 0
$demomode = 1
$demolines = 150
;$decmode = 0

$logfile = "logbook.csv"

$decmode = RegRead("HKEY_CURRENT_USER\SOFTWARE\DMH Software\LogBook", "Decimal_Mode")

;read log file or create it if it doesn't exist
If Not FileExists($logfile) Then
    $header[0] = "#"
    $header[1] = "Date"
    $header[2] = "Aircraft Type"
    $header[3] = "Registration"
    $header[4] = "From"
    $header[5] = "To"
    $header[6] = "Total Time"
    $header[7] = "Solo/PIC"
    $header[8] = "Dual"
    $header[9] = "Cross Country"
    $header[10] = "Night"
    $header[11] = " "
    $header[12] = " "
    $header[13] = " "
    $header[14] = " "
    $header[15] = "Remarks"
    $header[16] = "Pilot Name"
    $headerline = $header[0]
    For $i = 1 To 16
        $headerline = $headerline & "|" & $header[$i]
    Next
    $file = FileOpen($logfile, 1) ; open new file to write header line
    FileWriteLine($file, $headerline)
    FileClose($file)
    $linenum = 0
EndIf


;create the GUI window and buttons
$w = @DesktopWidth - 60;1024
;$h = @DesktopHeight - 100; 700
If $w >= 1200 Then $w = 1180
;$w = 1024
$h = 550
$fontsize = 7
Opt("GUIOnEventMode", 1) ; Change to OnEvent mode
$datawindow = GUICreate("Logbook v" & $version, $w, $h, -1, -1) ;$WS_OVERLAPPEDWINDOW

$printbutton = GUICtrlCreateButton("&Print", 30, $h - 40, 60)
$closebutton = GUICtrlCreateButton("&Close", $w - 30 - 60, $h - 40, 60)
$setupbutton = GUICtrlCreateButton("&Setup", 120, $h - 40, 60)
$editbutton = GUICtrlCreateButton("&Edit", 210, $h - 40, 60)
$defbutton = GUICtrlCreateButton("&Add", 300, $h - 40, 60, -1, $BS_DEFPUSHBUTTON) ; default button used for add or save
$helpbutton = GUICtrlCreateButton("&Help", $w - 120 - 60, $h - 40, 60, -1)

$cancelbutton = GUICtrlCreateButton("Cance&l", 390, $h - 40, 60, -1) ; used in data entry mode
GUICtrlSetState($cancelbutton, $GUI_HIDE)


$file = FileOpen($logfile, 0) ; open file for reading

; Now read the data lines and create the listview
$lnum = 1
Dim $total[16]
While 1
    $linedata = FileReadLine($logfile, $lnum)
    If @error = -1 Then ExitLoop ; end of file reached
    If $lnum = 1 Then ; read the column headers and create the listview
        $pilotname = StringRight($linedata, StringLen($linedata) - StringInStr($linedata, "|", 0, -1))
        $linedata = StringLeft($linedata, StringInStr($linedata, "|", 0, -1)) ; strip off the name which we don't want as a column header
        $datalist = GUICtrlCreateListView("||||||||||||||||", 10, 75, $w - 20, $h - 200, BitOR($LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_NOSORTHEADER), BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
    Else ; read the data lines
        ReDim $dataarray[$lnum - 1][16]
        $lineworking = $linedata
        $linedata = ""
        For $col = 0 To 15
            $curcol = StringLeft($lineworking, StringInStr($lineworking, "|") - 1)
            ;If $lnum < 5 Then MsgBox(0, "debug", $lnum & "  " & $col)
            $lineworking = StringTrimLeft($lineworking, StringInStr($lineworking, "|"))
            If $col > 5 And $col < 15 Then
                $dataarray[$lnum - 2][$col] = $curcol ; save time data in raw minutes for calculations
                $total[$col] = $total[$col] + $curcol ; sum the column as each line is read and added
                $curcol = mmtohm($curcol) ; converted display value
            EndIf
            If $col < 15 Then $curcol = $curcol & "|"
            $linedata = $linedata & $curcol
        Next
        GUICtrlCreateListViewItem($linedata, $datalist)
    EndIf
    $lnum = $lnum + 1
WEnd ; end reading the data file and creating the listview
;_ArrayDisplay($dataarray)
FileClose($file)
$lnum = $lnum - 3 ; remove the last increment and change to zero based for working with the listview (1 each for increment, header line, and zero base)

; check program registration key
; not the real version, for debug only
Global $namearray = StringToASCIIArray($pilotname & "LogBook key"); convert padded pilot name into ASCII array
$regkey = ""
If $regkey = RegRead("HKEY_CURRENT_USER\SOFTWARE\DMH Software\LogBook", "Key") Then $demomode = 0
If $demomode Then
    $demobutton = GUICtrlCreateButton("Demo Mode - Click to register", $w - 200, 0, 200, 30)
    GUICtrlSetBkColor($demobutton, 0xff0000) ; Red background
    GUICtrlSetColor($demobutton, 0xffff00) ; yellow text
    GUICtrlSetOnEvent($demobutton, "democlicked")
EndIf
; end of registration check

GUICtrlSetResizing($datalist, 2) ; locks the list to the left side of the window when the window is resized
GUICtrlSetFont($datalist, $fontsize)

$hdatalist = GUICtrlGetHandle($datalist)

_GUICtrlListView_SetColumnWidth($datalist, 0, $fontsize * 4)
_GUICtrlListView_SetColumnWidth($datalist, 1, $fontsize * 9)
_GUICtrlListView_SetColumnWidth($datalist, 2, $fontsize * 9)
_GUICtrlListView_SetColumnWidth($datalist, 3, $fontsize * 8)
_GUICtrlListView_SetColumnWidth($datalist, 4, $fontsize * 8)
_GUICtrlListView_SetColumnWidth($datalist, 5, $fontsize * 8)
For $i = 6 To 14 ; time columns
    _GUICtrlListView_SetColumnWidth($datalist, $i, $fontsize * 9)
Next
_GUICtrlListView_SetColumnWidth($datalist, 15, $fontsize * 100) ; remarks column

For $i = 0 To 15
    $colwidth[$i] = _GUICtrlListView_GetColumnWidth($datalist, $i)
    If $i = 0 Then
        $colpos[$i] = 0
    Else
        $colpos[$i] = $colpos[$i-1] + $colwidth[$i - 1]
    EndIf
    If $i = 0 Then
        $posstr = $colpos[$i]
    Else
        $posstr = $posstr & "|" & $colpos[$i]
    EndIf

    $oldcolpos[$i] = $colpos[$i]
Next
$basecolpos = _GUICtrlListView_GetItemPositionX(GUICtrlGetHandle($datalist), 0)

; create labels for totals
Global $totcol[16]
$totaly = $h - 100
$totcol[5] = GUICtrlCreateLabel("Totals:", $colpos[4], $totaly, 70, 40)
GUICtrlSetFont($totcol[5], 10, 600)
For $i = 6 To 14
    $totcol[$i] = GUICtrlCreateLabel(mmtohm($total[$i]), $colpos[$i] + 10 + 4, $totaly, $colwidth[$i], 40)
    GUICtrlSetFont($totcol[$i], 8, 600)
Next

;create labels for column titles
$headerline = FileReadLine($logfile, 1)
$headery = 35
For $i = 0 To 15
    $header[$i] = StringLeft($headerline, StringInStr($headerline, "|") - 1)
    If $i > 0 And $i < 15 Then $headerlabel[$i] = GUICtrlCreateLabel($header[$i], $colpos[$i] + 10 + 4, $headery, $colwidth[$i] - 2, 35, $SS_CENTER, $WS_EX_TOPMOST)
    If $i = 15 Then $headerlabel[$i] = GUICtrlCreateLabel($header[$i], $colpos[$i] + 10 + 4, $headery, $colwidth[$i] - 2, 35, -1, $WS_EX_TOPMOST)
    GUICtrlSetFont($headerlabel[$i], 7, 600)
    $headerline = StringTrimLeft($headerline, StringInStr($headerline, "|"))
Next


GUISetOnEvent($GUI_EVENT_CLOSE, "CloseClicked")
GUICtrlSetOnEvent($closebutton, "CloseClicked")
GUICtrlSetOnEvent($printbutton, "PrintClicked")
GUICtrlSetOnEvent($setupbutton, "SetupClicked")
GUICtrlSetOnEvent($editbutton, "EditClicked")
GUICtrlSetOnEvent($defbutton, "AddClicked")
GUICtrlSetOnEvent($helpbutton, "HelpClicked")

_GUICtrlListView_Scroll($hdatalist, $colwidth[0] - 2, 99999)
GUICtrlCreateLabel("Pilot Logbook for:", 30, 10)
$namelabel = GUICtrlCreateLabel($pilotname, 150, 10, 200)
GUICtrlSetFont($namelabel, 8, 600)
GUISetState(@SW_SHOW)

$test = _GUICtrlListView_GetItemText($hdatalist, 1, 6)
$hourst = StringLeft($test, 2)

While 1 ; wait for button clicks or window adjustment
    Sleep(100) ; keep the GUI from eating up all the CPU cycles
    ; check if colums have been resized or scrolled and adjust position of totals if so
    For $c = 0 To 15
        $colwidth[$c] = _GUICtrlListView_GetColumnWidth($datalist, $c)
        If $c = 0 Then
            $colpos[$c] = 0
        Else
            $colpos[$c] = $colpos[$c-1] + $colwidth[$c - 1]
        EndIf

        If $oldcolpos[$c] <> $colpos[$c] Or $basecolpos <> _GUICtrlListView_GetItemPositionX(GUICtrlGetHandle($datalist), 0) Or $oldcolwidth[$c] <> $colwidth[$c] Then
            ; Do the actual resizing:
            ; adjust totals
            If $c == 5 Then GUICtrlSetPos($totcol[5], $colpos[4] + _GUICtrlListView_GetItemPositionX(GUICtrlGetHandle($datalist), 5), $totaly)
            If $c > 5 And $c < 15 Then GUICtrlSetPos($totcol[$c], $colpos[$c] + 10 + _GUICtrlListView_GetItemPositionX(GUICtrlGetHandle($datalist), $c), $totaly)
            ; adjust headers
            GUICtrlSetPos($headerlabel[$c], $colpos[$c] + 10 + _GUICtrlListView_GetItemPositionX(GUICtrlGetHandle($datalist), $c), $headery, $colwidth[$c] - 2, 35)

            If $entermode Then ; adjust data entry input boxes
                GUICtrlSetPos($enterdata[$c], $colpos[$c] + 10 + _GUICtrlListView_GetItemPositionX(GUICtrlGetHandle($datalist), $c), $entery, $colwidth[$c])
                If $colpos[$c] + _GUICtrlListView_GetItemPositionX(GUICtrlGetHandle($datalist), $c) < -30 Then
                    GUICtrlSetState($enterdata[$c], $GUI_HIDE)
                Else
                    GUICtrlSetState($enterdata[$c], $GUI_SHOW)
                EndIf
            EndIf

            If $setupmode Then ; adjust header definition input boxes
                GUICtrlSetPos($setupdata[$c], $colpos[$c] + 10 + _GUICtrlListView_GetItemPositionX(GUICtrlGetHandle($datalist), $c), $headery, $colwidth[$c])
                If $colpos[$c] + _GUICtrlListView_GetItemPositionX(GUICtrlGetHandle($datalist), $c) < -30 Then
                    GUICtrlSetState($setupdata[$c], $GUI_HIDE)
                Else
                    GUICtrlSetState($setupdata[$c], $GUI_SHOW)
                EndIf
            EndIf
            $oldcolpos[$c] = $colpos[$c]
            $oldcolwidth[$c] = _GUICtrlListView_GetColumnWidth($datalist, $c)
        EndIf

    Next ; end of column position and width adjustments
    $basecolpos = _GUICtrlListView_GetItemPositionX(GUICtrlGetHandle($datalist), 0) ; reset the base position for the next cycle
WEnd


Func CloseClicked()
    GUIDelete()
    Exit
EndFunc   ;==>CloseClicked


Func PrintClicked()
    ; Put future print function here
    MsgBox(0, "Print", "Sorry, printing not enabled yet.")
EndFunc   ;==>PrintClicked

Func hmtomm($_hhmm)
    $_mm = StringRight($_hhmm, 2)
    $_hh = StringLeft($_hhmm, (StringInStr($_hhmm, ":") - 1))
    Return ($_hh * 60 + $_mm)
EndFunc   ;==>hmtomm

Func mmtohm($_mmmm)
    If $_mmmm = 0 Then
        Return ""
    Else
        $_hh = Floor($_mmmm / 60)
        $_mm = $_mmmm - $_hh * 60
        If $decmode = 0 Then ; use hours:minutes
            If StringLen($_mm) = 1 Then $_mm = "0" & $_mm
            Return $_hh & ":" & $_mm
        Else ; use decimal hours hh.h
            $_dh = Round($_mm / 6)
            Return $_hh & "." & $_dh
        EndIf
    EndIf
EndFunc   ;==>mmtohm


Func SetupClicked()
    If $lnum > 0 Then
        $retyn = MsgBox(4 + 48 + 256, "Warning", "Logbook already has data!" & @CRLF & "Are you sure you want to change the settings?")
        If $retyn = 7 Then Return
    EndIf
    $setupmode = 1
    $headerline = FileReadLine($logfile, 1)
    For $i = 0 To 15
        $header[$i] = StringLeft($headerline, StringInStr($headerline, "|") - 1)
        $headerline = StringTrimLeft($headerline, StringInStr($headerline, "|"))
    Next
    $header[16] = $headerline

    For $i = 1 To 15
        $setupdata[$i] = GUICtrlCreateInput($header[$i], $colpos[$i] + 10 + _GUICtrlListView_GetItemPositionX(GUICtrlGetHandle($datalist), 1), $headery, $colwidth[$i], 40, $ES_MULTILINE)
        GUICtrlSetState($headerlabel[$i], $GUI_HIDE)
        GUICtrlSetFont($setupdata[$i], 7, 600)
    Next
    $setupdata[16] = GUICtrlCreateInput($header[$i], 150, 7, 100, 20)

    $radiohhmm = GUICtrlCreateRadio("Hours:Minutes", $w / 2 - 200, 5)
    $radiohhdh = GUICtrlCreateRadio("Decimal Hours", $w / 2 + 10, 5)
    If $decmode Then
        GUICtrlSetState($radiohhmm, $GUI_UNCHECKED)
        GUICtrlSetState($radiohhdh, $GUI_CHECKED)
    Else
        GUICtrlSetState($radiohhmm, $GUI_CHECKED)
        GUICtrlSetState($radiohhdh, $GUI_UNCHECKED)
    EndIf

    GUICtrlSetData($defbutton, "&Save")
    GUICtrlSetOnEvent($defbutton, "SaveSetup")

    GUICtrlSetState($printbutton, $GUI_HIDE)
    GUICtrlSetState($editbutton, $GUI_HIDE)
    GUICtrlSetState($setupbutton, $GUI_HIDE)
    GUICtrlSetState($cancelbutton, $GUI_SHOW)
    GUICtrlSetState($namelabel, $GUI_DISABLE)
    GUICtrlSetOnEvent($cancelbutton, "EndEdit")


EndFunc   ;==>SetupClicked


Func SaveSetup()
    $header[0] = "#"
    $headerline = $header[0]
    For $i = 1 To 15
        $header[$i] = GUICtrlRead($setupdata[$i])
        GUICtrlSetData($headerlabel[$i], $header[$i])
        If $header[$i] = "" Then $header[$i] = " " ; pad it with a space, otherwise the listview header won't update
        $headerline = $headerline & "|" & $header[$i]
    Next
    $pilotname = GUICtrlRead($setupdata[16])
    GUICtrlSetData($namelabel, $pilotname)
    _FileWriteToLine($logfile, 1, $headerline & "|" & $pilotname, 1)
    $decmode = GUICtrlRead($radiohhdh) == $GUI_CHECKED
    ;RegWrite("HKEY_CURRENT_USER\SOFTWARE\DMH Software\LogBook", "Decimal_Mode", "REG_BINARY", $decmode)
    EndEdit()
EndFunc   ;==>SaveSetup


Func EditClicked()
    If _GUICtrlListView_GetSelectedIndices($hdatalist, False) = "" Then
        MsgBox(4096, "Error", "Error:  No line selected for edit")
    Else
        $editline = _GUICtrlListView_GetSelectedIndices($hdatalist, False) ; determine which row is selected, zero based
        For $i = 0 To 15
            $newdata[$i] = _GUICtrlListView_GetItemText($hdatalist, $editline, $i)
        Next
        enterdata()
    EndIf

EndFunc   ;==>EditClicked

Func AddClicked()
    $lnum = $lnum + 1
    $newdata[0] = $lnum + 1 ; displayed line is one based but lnum is zero based
    If _GUICtrlListView_GetSelectedIndices($hdatalist, False) = "" Then ; no line selected for copy
        For $i = 1 To 15
            $newdata[$i] = ""
            If $i > 6 And $i < 15 Then
                If _GUICtrlListView_GetItemText($hdatalist, $lnum - 1, $i) = _GUICtrlListView_GetItemText($hdatalist, $lnum - 1, 6) Then $newdata[$i] = "->COPY"
            EndIf
        Next

    Else ; line selected to copy into new line
        $copyline = _GUICtrlListView_GetSelectedIndices($hdatalist, False) ; determine which row is selected, zero based
        For $i = 1 To 15
            If $i < 6 Or $i > 14 Then
                $newdata[$i] = _GUICtrlListView_GetItemText($hdatalist, $copyline, $i) ; copy only non time columns
            Else
                $newdata[$i] = ""
            EndIf
            If $i > 6 And $i < 15 Then
                If _GUICtrlListView_GetItemText($hdatalist, $copyline, $i) = _GUICtrlListView_GetItemText($hdatalist, $copyline, 6) Then $newdata[$i] = "->COPY"
            EndIf

        Next
    EndIf
    GUICtrlCreateListViewItem("", $datalist) ; add a blank line
    EnterData()
EndFunc   ;==>AddClicked


Func EnterData() ; this function hides the totals columns and creates the input boxes
    $entermode = 1
    $entery = $h - 100
    For $i = 0 To 15
        If $i > 4 And $i < 15 Then GUICtrlSetState($totcol[$i], $GUI_HIDE) ; hide the total columns under the input boxes
        $enterdata[$i] = GUICtrlCreateInput($newdata[$i], $colpos[$i] + 10 + _GUICtrlListView_GetItemPositionX(GUICtrlGetHandle($datalist), 1), $entery, $colwidth[$i], 25)
        GUICtrlSetFont($enterdata[$i], 8, 400)
        GUICtrlSetState($enterdata[0], $GUI_DISABLE) ; disable the index number
        GUICtrlSetState($enterdata[1], $GUI_FOCUS) ; set focus to the date field
    Next

    GUICtrlSetData($defbutton, "&Save")
    GUICtrlSetOnEvent($defbutton, "SaveClicked")
    GUICtrlSetState($printbutton, $GUI_HIDE)
    GUICtrlSetState($editbutton, $GUI_HIDE)
    GUICtrlSetState($setupbutton, $GUI_HIDE)
    GUICtrlSetState($cancelbutton, $GUI_SHOW)
    GUICtrlSetOnEvent($cancelbutton, "CancelClicked")
    GUICtrlSetOnEvent($defbutton, "SaveClicked")
EndFunc   ;==>EnterData

Func SaveClicked()
    If $editline Then
        $savlnum = $editline
    Else
        $savlnum = $lnum
        ReDim $dataarray[$lnum + 1][15]
    EndIf
    ;MsgBox(0, "debug", $savlnum)
    For $i = 0 To 15
        $newdata[$i] = GUICtrlRead($enterdata[$i])
        If $i > 5 And $i < 15 Then ; time columns
            If StringCompare($newdata[$i], "->COPY", 2) = 0 Then ; stringcompare returns zero if equal
                $newdata[$i] = $newdata[6]
            EndIf
            If StringIsFloat($newdata[$i]) Or $decmode = 1 Then
                $dataarray[$savlnum][$i] = $newdata[$i] * 60 ; convert to minutes
                $newdata[$i] = mmtohm($dataarray[$savlnum][$i]) ; convert back to hhmm or hh.h for display
            Else
                $newdata[$i] = StringReplace($newdata[$i], ":", "") ; if user puts unnecessary colon in
                If Not (StringIsInt($newdata[$i]) Or StringIsSpace($newdata[$i]) Or StringLen($newdata[$i]) = 0) Then
                    MsgBox(48, "Error", "Invalid time value " & $newdata[$i] & " in column " & $i & "... please try again.")
                    Return
                EndIf
                If StringLen($newdata[$i]) < 2 Then ; one or two digits assumed to be minutes only
                    $dataarray[$savlnum][$i] = $newdata[$i] ;save raw minutes in array
                    $newdata[$i] = mmtohm($newdata[$i]) ; convert for display
                Else ; hours and minutes
                    $dataarray[$savlnum][$i] = StringRight($newdata[$i], 2) + (StringLeft($newdata[$i], (StringLen($newdata[$i]) - 2)) * 60)
                    $newdata[$i] = mmtohm(StringRight($newdata[$i], 2) + (StringLeft($newdata[$i], (StringLen($newdata[$i]) - 2)) * 60))
                EndIf

            EndIf

        EndIf
        _GUICtrlListView_SetItemText($hdatalist, $savlnum, $newdata[$i], $i)

    Next
    If $copyline Then _GUICtrlListView_SetItemSelected($hdatalist, $lnum, True)
    ; recalculate the totals
    For $c = 6 To 14
        $total[$c] = 0
        For $l = 0 To $lnum
            ;$total[$c] = $total[$c] + hmtomm(_GUICtrlListView_GetItemText($hdatalist, $l, $c))
            $total[$c] = $total[$c] + $dataarray[$l][$c]
        Next
        GUICtrlSetData($totcol[$c], mmtohm($total[$c]))
    Next
    $writestring = $newdata[0]
    For $i = 1 To 15
        If $i > 5 And $i < 15 Then ; time columns
            $writestring = $writestring & "|" & $dataarray[$savlnum][$i] ; was hmtomm($newdata[$i])
        Else
            $writestring = $writestring & "|" & $newdata[$i]
        EndIf
    Next
    If $editline Then
        _FileWriteToLine($logfile, $savlnum + 2, $writestring, 1)
    Else
        If $demomode = 0 Or $lnum < $demolines Then
            FileWriteLine($logfile, $writestring & "|") ; add trailing bar so file reads properly
        Else
            MsgBox(0 + 16 + 4096, "Demo Limit Exceeded!", "This program is shareware." & @CRLF & _
                    "The free demonstration mode is limited to " & $demolines & " entries." & @CRLF & _
                    "For information on purcasing the full version with no" & @CRLF & _
                    "limitations, please see the help file.")
        EndIf
    EndIf
    ;_ArrayDisplay($dataarray)
    EndEdit() ; Endedit function cleans up and restores the buttons and totals
EndFunc   ;==>SaveClicked

Func CancelClicked()
    If Not $editline Then
        _GUICtrlListView_DeleteItem($hdatalist, $lnum)
        $lnum = $lnum - 1
    EndIf
    EndEdit()
EndFunc   ;==>CancelClicked


Func EndEdit()
    GUICtrlSetData($defbutton, "&Add")
    GUICtrlSetOnEvent($defbutton, "AddClicked")
    GUICtrlSetState($printbutton, $GUI_SHOW)
    GUICtrlSetState($editbutton, $GUI_SHOW)
    GUICtrlSetState($setupbutton, $GUI_SHOW)
    GUICtrlSetState($cancelbutton, $GUI_HIDE)
    GUICtrlSetState($namelabel, $GUI_ENABLE)
    For $i = 0 To 16
        If $entermode And $i < 16 Then GUICtrlDelete($enterdata[$i]) ; delete the entry columns
        If $setupmode And $i > 0 Then GUICtrlDelete($setupdata[$i]) ; delete the entry columns
        If $i > 4 And $i < 15 Then GUICtrlSetState($totcol[$i], $GUI_SHOW) ; show the total columns under the input boxes
        If $i < 16 Then GUICtrlSetState($headerlabel[$i], $GUI_SHOW)
    Next
    If $setupmode Then
        GUICtrlDelete($radiohhdh)
        GUICtrlDelete($radiohhmm)
    EndIf
    $entermode = 0
    $editline = 0
    $setupmode = 0
    _GUICtrlListView_Scroll($hdatalist, 0, 99999)
EndFunc   ;==>EndEdit

Func democlicked()
    If StringLen(RegRead("HKEY_CURRENT_USER\SOFTWARE\DMH Software\LogBook", "Key")) > 2 Then
        $regmsg = "Registration code found, but pilot name """ & $pilotname & """ in LogBook file does not match." & @CRLF & _
                "If you have a new registration key, enter it now or click cancel and correct pilot name in setup mode."
    Else
        $regmsg = "This program is shareware." & @CRLF & _
                "You can save a maximum of 150 lines in demo mode." & @CRLF & @CRLF & _
                "Please enter a registration key or click cancel to continue working in demo mode."
    EndIf
    $newkey = InputBox("Enter Registration Key", $regmsg)
    If $newkey = $regkey Then
        MsgBox(64, "LogBook", "Thank you for registering!   ")
        ;RegWrite("HKEY_CURRENT_USER\SOFTWARE\DMH Software\LogBook", "Key", "REG_SZ", $newkey)
        $demomode = 0
        GUICtrlDelete($demobutton)
    ElseIf @error = 1 Then
        Return
    Else
        MsgBox(48, "Bad Key", "Invalid key entered" & @CRLF & @CRLF & _
                "Program will now continue in demo mode.  ")
    EndIf
EndFunc   ;==>democlicked

Func HelpClicked()
    ;If Not FileExists("logbook.htm") Then FileInstall("LogBookHelp.htm", ".\", 1)
    ;ShellExecute(".\LogBookHelp.htm")
EndFunc   ;==>HelpClicked


Opt("GUIOnEventMode", 0) ; Disable OnEvent mode

As I said, in XP this works perfectly. However, in Vista or W7, only the first six (index 0-5) labels or input boxes get moved when I move the scrollbar. If I adjust a column width using the listview header, they move by he correct amount (but keep any position error from a prior scrollbar movement).

Initially, there are only labels. When the program goes into entermode or setupmode, the totals or headers are hidden and the input boxes are created, then deleted when leaving entermode or setupmode. If I adjust the positions (and in Vista or W7 labels 6-15 don't move as they should), and then run the function to create the inputs, the inputs (all of them) are created correctly in the right place according to the current column positions... but when I again move the scrollbar, as before, they don't move.

It seems too much to be coincidence that the totals are columns 6-14 and those are the columns that don't work in Vista or 7, but I can't see why, nore does that explain why they do work in XP.

One odd thing is that if I resize a column using the listview header row, the corresponding stuff moves as I'm dragging the column, but if I scroll the listview's horizontal scroll bar, they don't move until I let go of the scroll bar.

Another odd thing: originally hid and showed the appropriate headers or setupdata depending on entermode or setupmode, but W7 (I didn't test it in Vista at that point) didn't correctly hide the input boxes... they'd disappear, but then reappear again as the columns were adjusted.

I've tried the various options in Vista and W7, i.e. XP compatibility mode and the various visual things I can disable... none had any effect.

Is this known behavior, or am I missing something stupid?

Edited by Dana
Link to comment
Share on other sites

Leaving out all the control creation and other stuff, here's the main run loop (using gui events to run functions):

I would prefer to have a running example before I take a look :D...
Link to comment
Share on other sites

  • Moderators

Dana,

After a quick look at your script, I have simple question: why not put the titles into the header row of the ListView rather than as labels?

$sTitles = "#|Date|Type|Reg|From|To|Total Time|Solo/PiC|Dual|CC|Night||||Remarks|Pilot Name|"
$datalist = GUICtrlCreateListView($sTitles, 10, 75, $w - 20, $h - 200, BitOR($LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_NOSORTHEADER), BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))

Then they follow automatically as you move the slider without any effort from you. :huggles:

M23

P.S. I really dislike scripts that write stuff in my registry without asking, or anyone telling me that they are going to! :D Or at least I would if I did not check them first. :

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Dana,

After a quick look at your script, I have simple question: why not put the titles into the header row of the ListView rather than as labels?

$sTitles = "#|Date|Type|Reg|From|To|Total Time|Solo/PiC|Dual|CC|Night||||Remarks|Pilot Name|"
$datalist = GUICtrlCreateListView($sTitles, 10, 75, $w - 20, $h - 200, BitOR($LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_NOSORTHEADER), BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))

Then they follow automatically as you move the slider without any effort from you. :huggles:

That's what I originally had (and wanted), but if the text is longer than the available column width, it gets chopped off, since I can't see any way to make a multiline header in the listview. With the labels, it wraps so I can have two lines.

P.S. I really dislike scripts that write stuff in my registry without asking, or anyone telling me that they are going to! :D Or at least I would if I did not check them first. :

Oh, sorry... I knew I took out the one place where it did that, I forgot it was in two other places. It only does that if you save the setup or demo mode, which isn't necessary to test this... I'll edit the original post to comment it out anyway.
Link to comment
Share on other sites

One other thing, since it seemed to be too much to be a coincidence that I had lines (270-271) that adjusted only rows past 5 for the total columns, and those were the rows that don't work properly, I commented them out... but it still made no difference.

Link to comment
Share on other sites

  • Moderators

Dana,

If you are worried about users resizing the columns, here is a way to prevent that: :D

#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>

Opt("GUIOnEventMode", 1)

Global Const $WM_NOTIFY = 0x004E
Global Const $HDN_FIRST = -300
Global Const $HDN_ITEMCHANGINGA = $HDN_FIRST - 0
Global Const $HDN_ITEMCHANGINGW = $HDN_FIRST - 20

$GUI = GUICreate("Static Columns Demo!", 420, 240)
GUISetOnEvent($GUI_EVENT_CLOSE, "Quit")

$ListView = GUICtrlCreateListView("Column1|Column2", 20, 20, 380, 200, $LVS_NOSORTHEADER)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY_EVENTS")

GUICtrlCreateListViewItem("Item 1|SubItem 1", $ListView)
GUICtrlCreateListViewItem("Item 2|SubItem 2", $ListView)

GUICtrlSendMsg($ListView, $LVM_SETCOLUMNWIDTH, 0, 80)
GUICtrlSendMsg($ListView, $LVM_SETCOLUMNWIDTH, 1, 80)

GUISetState(@SW_SHOW)

While 1
    Sleep(100)
WEnd

Func Quit()
    Exit
EndFunc

Func WM_NOTIFY_EVENTS($hWndGUI, $MsgID, $wParam, $lParam)
    Local $TagNMHDR = DllStructCreate("int;int;int", $lParam)
    If @error Then Return

    Local $iEvent = DllStructGetData($TagNMHDR, 3)
    If $iEvent = $HDN_ITEMCHANGINGA Or $iEvent = $HDN_ITEMCHANGINGW Then Return 1

    Return $GUI_RUNDEFMSG
EndFunc

I will keep looking at other solutions. :huggles:

M23

Edit: Convinced that fixing the column width as above will do the trick. Anything else is far too complicated, as you have discovered! :

Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

I solved it.

Turns out the problem is related to the data file I was using. It still does seem to involve a difference between XP and later versions (which I don't yet understand, but no matter).

I was using _GUICtrlListView_GetItemPositionX wrong (I should have studied the example better). The index passed to the function is not the column index, but the row. It returns the x position of the 0 column, regardless of what index you give it. This should have been obvious since I still needed to determine column position based on previous column widths, but that was code that built up over time. It doesn't matter what index number you pass to the function, it always returns the same thing.

The problem seems to be in the way that XP vs. Vista or W7 handles the calls from the UDF (which I haven't studied). XP seems to return the correct value no matter what you pass to the function, but Vista and W7 won't accept a row number that doesn't exist... and I only had 6 lines in the data file on the thumb drive I was moving around to test on other systems, so it only worked for the first 6 columns.

I now have code that looks like this:

While 1 ; wait for button clicks or window adjustment
    Sleep(100) ; keep the GUI from eating up all the CPU cycles
    ; check if colums have been resized or scrolled and adjust position of totals if so
    $scrollpos = _GUICtrlListView_GetItemPositionX(GUICtrlGetHandle($datalist), 0)
    For $c = 0 To 15
        $colwidth[$c] = _GUICtrlListView_GetColumnWidth($datalist, $c)
        If $c = 0 Then
            $colpos[$c] = 0
        Else
            $colpos[$c] = $colpos[$c - 1] + $colwidth[$c - 1]
        EndIf

        If $oldcolpos[$c] <> $colpos[$c] Or $basecolpos <> $scrollpos Or $oldcolwidth[$c] <> $colwidth[$c] Then
            ; Do the actual resizing:
            ; adjust totals
            If $c == 5 Then GUICtrlSetPos($totcol[5], $colpos[4] + $scrollpos, $totaly)
            If $c > 5 And $c < 15 Then GUICtrlSetPos($totcol[$c], $colpos[$c] + 10 + $scrollpos, $totaly)
            ; adjust headers
            GUICtrlSetPos($headerlabel[$c], $colpos[$c] + 10 + $scrollpos, $headery, $colwidth[$c] - 2, 35)

etc.

Now, if anybody has an idea about multi line headers... I do want the user to be able to adjust the column widths, because on a small monitor there isn't always enough room to see what's entered. The column titles are, in many cases, wider than the actual data, and I want to have all columns visible, at least initially, on a screen as small as 1024.

Thanks to all for the assistance...

Edited by Dana
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...