CYCho Posted March 7, 2021 Share Posted March 7, 2021 (edited) _GUICtrlListView_EnsureVisible() ensures a selected item to be visible, but the item is usually at the bottom or top of the listview window. The following code places the selected item at the center of the window. One thing I'm not certain is the header height and line height. 26(2+24) and 19 pixels are based on Korean Windows 10. They may vary depending on OS, default language and font. I would expect to have comments on this from someone who knows. expandcollapse popup#include <GUIConstants.au3> #include <EditConstants.au3> #include <GuiListView.au3> Local $idListview, $idLabel, $idInput Local $iViewHeight= 237, $iItemCount = 100, $iItemToSelect GUICreate("ListView Scroll", 400, 300) $idListview = GUICtrlCreateListView("", 2, 2, 394, $iViewHeight) $idLabel = GUICtrlCreateLabel("Input a number between 1 and " & $iItemCount & " and press Enter:", 20, 260, 300, 20) $idInput = GUICtrlCreateInput("", 325, 256, 30, 18, $ES_CENTER + $ES_NUMBER) GUICtrlSetState($idInput, $GUI_FOCUS) GUISetState(@SW_SHOW) _GUICtrlListView_AddColumn($idListview, "Items", 100) For $iI = 1 To 500 _GUICtrlListView_AddItem($idListview, "Item " & $iI) Next $iItemCount = _GUICtrlListView_GetItemCount($idListview) Local $aItemRect = _GUICtrlListView_GetItemRect($idListview, 0, 0) $iLineHeight = $aItemRect[3] - $aItemRect[1] Local $hHeader = _GUICtrlListView_GetHeader($idListview) $iHeaderHeight = _WinAPI_GetWindowHeight($hHeader) GUICtrlSetData($idLabel, "Input a number between 1 and " & $iItemCount & " and press Enter:") While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idInput $iItemToSelect = GUICtrlRead($idInput) If $iItemToSelect > 0 And $iItemToSelect <= $iItemCount Then _Scroll() Else MsgBox(0, "Listview Scroll", "The item number entered is invalid.") EndIf GUICtrlSetState($idListview, $GUI_FOCUS) EndSwitch WEnd GUIDelete() Func _Scroll() ; Scroll $iItemToSelect to the center of listview window _GUICtrlListView_SetItemSelected($idListview, $iItemToSelect-1, True, True) _GUICtrlListView_Scroll($idListview, 0, $iItemCount*-$iLineHeight) _GUICtrlListView_Scroll($idListview, 0, ($iItemToSelect-($iViewHeight-$iHeaderHeight)/$iLineHeight/2)*$iLineHeight) EndFunc Edited December 7, 2022 by CYCho Reflect @Nine/@pixelsearch's input on header and item heights zPlayer - A Small Audio and Video Player Time Sync + SystemTimeAdjustment Link to comment Share on other sites More sharing options...
Nine Posted March 7, 2021 Share Posted March 7, 2021 (edited) Actually you could calculate the line width and the header height. It would make your script independent of OS, styles, theme and Region. #include <WinAPISysWin.au3> #include <WinAPIConv.au3> Example() Func Example() Local $hWnd = GUICreate("test") Local $iHeight = _WinAPI_GetClientHeight($hWnd) Local $iWidth = _WinAPI_GetClientWidth($hWnd) Local $tRECT = _WinAPI_GetWindowRect($hWnd) Local $tPoint1 = DllStructCreate($tagPOINT) $tPoint1.X = 0 $tPoint1.Y = 0 _WinAPI_ClientToScreen($hWnd, $tPoint1) Local $tPoint2 = DllStructCreate($tagPOINT) $tPoint2.X = $iWidth $tPoint2.Y = $iHeight _WinAPI_ClientToScreen($hWnd, $tPoint2) ConsoleWrite("Actual " & $tRECT.left & "/" & $tRECT.top & "/" & $tRECT.right & "/" & $tRECT.bottom & @CRLF) ConsoleWrite("Client " & $tPoint1.X & "/" & $tPoint1.Y & "/" & $tPoint2.X & "/" & $tPoint2.Y & @CRLF) EndFunc ;==>Example Edited March 7, 2021 by Nine corrected a small bug CYCho 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
CYCho Posted March 7, 2021 Author Share Posted March 7, 2021 @Nine, As always, you amaze me. Thanks. zPlayer - A Small Audio and Video Player Time Sync + SystemTimeAdjustment Link to comment Share on other sites More sharing options...
Nine Posted March 7, 2021 Share Posted March 7, 2021 Thanks. Corrected a bug (inversion of width and height). “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
CYCho Posted March 7, 2021 Author Share Posted March 7, 2021 Now, how do i calculate the the sysheader32 height and individual item height in AutoIt listviews? Maybe it's an easy job for you, but I don't get it. You didn't even create a listview control in the gui. zPlayer - A Small Audio and Video Player Time Sync + SystemTimeAdjustment Link to comment Share on other sites More sharing options...
Nine Posted March 7, 2021 Share Posted March 7, 2021 Oh, I thought you wanted to calculate window coordinates. But I believe it doesn't matter. You can use the exact same code with the handle of the list view (instead of the handle of the window) to get the same information. For individual item, you can use _GUICtrlListView_GetItemRect to get coordinates of that item. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
pixelsearch Posted March 7, 2021 Share Posted March 7, 2021 (edited) Hi CYCho, These 8 lines are directly extracted from the code of my CSV file editor, with variables renamed to match your script. expandcollapse popup#include <GUIConstants.au3> #include <EditConstants.au3> #include <GuiListView.au3> Local $idListview, $idLabel, $idInput Local $iViewHeight= 237, $iItemCount = 100, $iItemToSelect ; Local Const $iHeaderHeight = 28, $iLineHeight = 19 ; based on Korean Win 10, may vary depending on OS, default language and font GUICreate("ListView Scroll", 400, 300) $idListview = GUICtrlCreateListView("", 2, 2, 394, $iViewHeight) $idLabel = GUICtrlCreateLabel("Input a number between 1 and " & $iItemCount & " and press Enter:", 20, 260, 300, 20) $idInput = GUICtrlCreateInput("", 325, 256, 30, 18, $ES_CENTER + $ES_NUMBER) GUICtrlSetState($idInput, $GUI_FOCUS) ; ======================================================= ; Calculate item height (item height depends on each computer, windows theme fonts, scaling...) $hHeader = _GUICtrlListView_GetHeader($idListView) Local $iHeaderHeight = _WinAPI_GetWindowHeight($hHeader) Local $iNbItemsPerPage = _GUICtrlListView_GetCounterPage($idListView) $iLineHeight = ($iViewHeight - $iHeaderHeight) / $iNbItemsPerPage ConsoleWrite("$iHeaderHeight = " & $iHeaderHeight & @crlf & _ "$iNbItemsPerPage = " & $iNbItemsPerPage & @crlf & _ "$iLineHeight = " & $iLineHeight & @crlf) ; ======================================================= GUISetState(@SW_SHOW) _GUICtrlListView_AddColumn($idListview, "Items", 100) For $iI = 1 To 500 _GUICtrlListView_AddItem($idListview, "Item " & $iI) Next $iItemCount = _GUICtrlListView_GetItemCount($idListview) GUICtrlSetData($idLabel, "Input a number between 1 and " & $iItemCount & " and press Enter:") While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idInput $iItemToSelect = GUICtrlRead($idInput) If $iItemToSelect > 0 And $iItemToSelect <= $iItemCount Then _Scroll() Else MsgBox(0, "Listview Scroll", "The item number entered is invalid.") EndIf GUICtrlSetState($idListview, $GUI_FOCUS) EndSwitch WEnd GUIDelete() Func _Scroll() ; Scroll $iItemToSelect to the center of listview window _GUICtrlListView_SetItemSelected($idListview, $iItemToSelect-1, True, True) _GUICtrlListView_Scroll($idListview, 0, $iItemCount*-$iLineHeight) _GUICtrlListView_Scroll($idListview, 0, ($iItemToSelect-($iViewHeight-$iHeaderHeight)/$iLineHeight/2)*$iLineHeight) EndFunc This is what the console shows and a pic of your LV on my computer (real size) : $iHeaderHeight = 20 $iNbItemsPerPage = 14 $iLineHeight = 15.5 But then when I input a number, your scroll function doesn't place the desired line exactly in the middle of the LV, so there's something to be a bit reworked : * or in my code * or in your scroll code Let's wait & see Edited March 7, 2021 by pixelsearch Just re-checked this: (14 rows x 15.5 pixels height) + header 20 pixels = 237 pixels (your LV height) Link to comment Share on other sites More sharing options...
Nine Posted March 7, 2021 Share Posted March 7, 2021 (edited) Same results (almost) : expandcollapse popup#include <WinAPISysWin.au3> #include <WinAPIConv.au3> #include <GUIConstants.au3> #include <GuiListView.au3> Example2() Func Example1($hWnd) Local $iWidth = _WinAPI_GetClientWidth($hWnd) Local $iHeight = _WinAPI_GetClientHeight($hWnd) Local $tRECT = _WinAPI_GetWindowRect($hWnd) Local $tPoint1 = DllStructCreate($tagPOINT) $tPoint1.X = 0 $tPoint1.Y = 0 _WinAPI_ClientToScreen($hWnd, $tPoint1) Local $tPoint2 = DllStructCreate($tagPOINT) $tPoint2.X = $iWidth $tPoint2.Y = $iHeight _WinAPI_ClientToScreen($hWnd, $tPoint2) ConsoleWrite("Actual " & $tRECT.left & "/" & $tRECT.top & "/" & $tRECT.right & "/" & $tRECT.bottom & @CRLF) ConsoleWrite("Client " & $tPoint1.X & "/" & $tPoint1.Y & "/" & $tPoint2.X & "/" & $tPoint2.Y & @CRLF) $tRECT = _GUICtrlListView_GetItemRectEx($hWnd, 0, 0) Local $tPoint1i = DllStructCreate($tagPOINT) $tPoint1i.X = $tRECT.left $tPoint1i.Y = $tRECT.top _WinAPI_ClientToScreen($hWnd, $tPoint1i) Local $tPoint2i = DllStructCreate($tagPOINT) $tPoint2i.X = $tRECT.right $tPoint2i.Y = $tRECT.bottom _WinAPI_ClientToScreen($hWnd, $tPoint2i) ConsoleWrite("Item0 " & $tPoint1i.X & "/" & $tPoint1i.Y & "/" & $tPoint2i.X & "/" & $tPoint2i.Y & @CRLF) ConsoleWrite ("=============== Nine ================" & @CRLF) ConsoleWrite ("Header height = " & $tPoint1i.Y - $tPoint1.Y & @CRLF) ConsoleWrite ("Item height = " & $tPoint2i.Y - $tPoint1i.Y & @CRLF) EndFunc ;==>Example1 Func Example2() $hGUI = GUICreate("ListView Scroll", 400, 300) $idListview = GUICtrlCreateListView("", 2, 2, 394, 237) $hList = GUICtrlGetHandle($idListview) GUISetState(@SW_SHOW) _GUICtrlListView_AddColumn($idListview, "Items", 100) For $iI = 1 To 500 _GUICtrlListView_AddItem($idListview, "Item " & $iI) Next $iItemCount = _GUICtrlListView_GetItemCount($idListview) Example1($hList) ; ======================================================= ; Calculate item height (item height depends on each computer, windows theme fonts, scaling...) $hHeader = _GUICtrlListView_GetHeader($idListview) Local $iHeaderHeight = _WinAPI_GetWindowHeight($hHeader) Local $iNbItemsPerPage = _GUICtrlListView_GetCounterPage($idListview) $iLineHeight = (237 - $iHeaderHeight) / $iNbItemsPerPage ConsoleWrite ("============ PixelSearch ============" & @CRLF) ConsoleWrite("$iHeaderHeight = " & $iHeaderHeight & @CRLF & _ "$iNbItemsPerPage = " & $iNbItemsPerPage & @CRLF & _ "$iLineHeight = " & $iLineHeight & @CRLF) ; ======================================================= While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd EndFunc ;==>Example2 Fraction of a pixel is not really possible Edited March 7, 2021 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
pixelsearch Posted March 7, 2021 Share Posted March 7, 2021 (edited) 3 hours ago, Nine said: Fraction of a pixel is not really possible Not yet... though after viewing (again) "Interstellar" on TV a few days ago, I'm not sure of anything Gladly in my CSV script, the decimal part didn't do any harm because the concerned variable (named $iLineHeight above) was used "as-is" (no multiplication or division) in 2 parts of the script, to indicate the height of the "en place" edit box as seen in this pic, or the height of the red wanderer "marker for deletion" label in that pic. I guess AutoIt always rounds it to Integer. Sometimes I comment it in the code (after having tested the result), for example : WinMove($hGUI2, "", $iParentNewCliW * $nRatioX, $iParentNewCliH * $nRatioY, _ $iParentNewCliW * $nRatioW, $iParentNewCliH * $nRatioH) ; WinMove will use Int coords Some other time a serious error may appear (error 10, extended 3) when you got decimals in this kind of line : $hCloneArea = _GDIPlus_BitmapCloneArea($hImage_Resized, $iCrop_Left2, $iCrop_Top2, $iX_resized, $iY_resized) The error being fixed with Int() because both variables had decimals : $hCloneArea = _GDIPlus_BitmapCloneArea($hImage_Resized, $iCrop_Left2, $iCrop_Top2, Int($iX_resized), Int($iY_resized)) Strange that I like decimals so much Edited March 7, 2021 by pixelsearch Link to comment Share on other sites More sharing options...
pixelsearch Posted March 7, 2021 Share Posted March 7, 2021 @Nine : concerning the Item height, what do you think of this 2-liner ? $aItemRect = _GUICtrlListView_GetItemRect($idListview, 0, 0) $iItemHeight = $aItemRect[3] - $aItemRect[1] Concerning the header's height, it's already a 2-liner : $hHeader = _GUICtrlListView_GetHeader($idListView) $iHeaderHeight = _WinAPI_GetWindowHeight($hHeader) Link to comment Share on other sites More sharing options...
Nine Posted March 7, 2021 Share Posted March 7, 2021 I did use the EX version. Well to be honest, I am glad that my EX is very far away I agree with you the getHeader is the best way. But to know all the infos from all angles, I was trying to show how to do it. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
CYCho Posted March 7, 2021 Author Share Posted March 7, 2021 (edited) @Nine and @pixelsearch, You really came up with perfect solution while I was asleep. Once again you made me realize this world is worth living. Thank you. Below is my revised code. In fact I used this logic in my zPlayer and I'll have to reflect your solution in my next update. expandcollapse popup#include <GUIConstants.au3> #include <EditConstants.au3> #include <GuiListView.au3> Local $idListview, $idLabel, $idInput Local $iViewHeight= 237, $iItemCount = 100, $iItemToSelect Local $mainGUI = GUICreate("ListView Scroll", 400, 300) $idListview = GUICtrlCreateListView("", 2, 2, 394, $iViewHeight) $idLabel = GUICtrlCreateLabel("Input a number between 1 and " & $iItemCount & " and press Enter:", 20, 260, 300, 20) $idInput = GUICtrlCreateInput("", 325, 256, 30, 18, $ES_CENTER + $ES_NUMBER) GUICtrlSetState($idInput, $GUI_FOCUS) GUISetState(@SW_SHOW) _GUICtrlListView_AddColumn($idListview, "Items", 100) For $iI = 1 To 5000 _GUICtrlListView_AddItem($idListview, "Item " & $iI) Next $iItemCount = _GUICtrlListView_GetItemCount($idListview) GUICtrlSetData($idLabel, "Input a number between 1 and " & $iItemCount & " and press Enter:") Local $aItemRect = _GUICtrlListView_GetItemRect($idListview, 0, 0) Local $iItemHeight = $aItemRect[3] - $aItemRect[1] Local $hHeader = _GUICtrlListView_GetHeader($idListView) Local $iHeaderHeight = _WinAPI_GetWindowHeight($hHeader) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idInput $iItemToSelect = GUICtrlRead($idInput) If $iItemToSelect > 0 And $iItemToSelect <= $iItemCount Then _Scroll() GUICtrlSetState($idListview, $GUI_FOCUS) Else MsgBox(0, "Listview Scroll", "The item number entered is invalid.") GUICtrlSetState($idInput, $GUI_FOCUS) EndIf EndSwitch WEnd GUIDelete() Func _Scroll() ; Scroll $iItemToSelect to the center of listview window _GUICtrlListView_SetItemSelected($idListview, $iItemToSelect-1, True, True) _GUICtrlListView_Scroll($idListview, 0, $iItemCount*-$iItemHeight) _GUICtrlListView_Scroll($idListview, 0, ($iItemToSelect-($iViewHeight-$iHeaderHeight)/$iItemHeight/2)*$iItemHeight) EndFunc Edited December 7, 2022 by CYCho pixelsearch 1 zPlayer - A Small Audio and Video Player Time Sync + SystemTimeAdjustment Link to comment Share on other sites More sharing options...
pixelsearch Posted March 7, 2021 Share Posted March 7, 2021 @CYCho : glad we could help, now your script works fine on my computer too Nine is always creative and brings up ideas & working solutions, so it's a pleasure to join the party and share some ideas. Thanks to his EX ! CYCho 1 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