Dana Posted January 13, 2010 Share Posted January 13, 2010 (edited) 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).expandcollapse popup#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 modeAs 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 January 13, 2010 by Dana Link to comment Share on other sites More sharing options...
KaFu Posted January 13, 2010 Share Posted January 13, 2010 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 ... Â OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2022-Nov-26)Â BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Feb-16) HMW - Hide my Windows (2018-Sep-16) HRC - HotKey Resolution Changer (2012-May-16)Â ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2023-Jun-03) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
Dana Posted January 13, 2010 Author Share Posted January 13, 2010 OK, my first post above now contains the full program. You may need to adjust the include statements path depending on whether you're working on an x64 system or not. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 13, 2010 Moderators Share Posted January 13, 2010 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. M23 P.S. I really dislike scripts that write stuff in my registry without asking, or anyone telling me that they are going to! Or at least I would if I did not check them first.  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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
Dana Posted January 13, 2010 Author Share Posted January 13, 2010 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. 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! 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 More sharing options...
Dana Posted January 13, 2010 Author Share Posted January 13, 2010 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 More sharing options...
Moderators Melba23 Posted January 13, 2010 Moderators Share Posted January 13, 2010 (edited) Dana, If you are worried about users resizing the columns, here is a way to prevent that: expandcollapse popup#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. 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 January 13, 2010 by Melba23  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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
Dana Posted January 13, 2010 Author Share Posted January 13, 2010 (edited) 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 January 13, 2010 by Dana Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now