Popular Post LarsJ Posted November 30, 2015 Popular Post Share Posted November 30, 2015 (edited) Items in a standard listview in details/report view (this example deals only with listviews in details/report view) can display a single line of text. There seems not to be any options to change this. There is no word wrap option. If you search the forums, it's possible to find examples of listviews with multiple lines of text in each row. The multi-line items are implemented as owner drawn items through LVS_OWNERDRAWFIXED control style and WM_DRAWITEM messages. A problem with the owner drawn technique is that you are forced to draw everything yourself. Besides item texts and the background behind texts (white for non-selected items, dark blue for selected items with focus, button face for selected items without focus) you also have to draw checkboxes, images, icons and the background behind these elements yourself. Another technique is custom drawn listview items. Custom drawn items are implemented through NM_CUSTOMDRAW notifications included in WM_NOTIFY messages. NM_CUSTOMDRAW notifications are generated automatically by the code in ComCtl32.dll when the listview is updated. Implementing custom drawn items is a matter of responding to these messages or not. The great advantage of custom drawn items is that the drawing process is divided into several stages. For a listview up to six different stages. Some of these stages can be used for default drawing without any additional code at all. Other stages can be used for custom drawing with your own code. Multi-line text items fits perfectly with the custom drawn technique. Item texts and the background is drawn by custom code. Checkboxes, images, icons and the background is drawn by default code. Increase height of listview items The usual way to increase the height of listview items is to respond to WM_MEASUREITEM messages. But this method can only be used for owner drawn listviews. In a custom drawn listview the height can be increased by defining a text font with a suitable height: Func _GUICtrlListView_SetItemHeightByFont( $hListView, $iHeight ) ; Get font of ListView control ; Copied from _GUICtrlGetFont example by KaFu ; See https://www.autoitscript.com/forum/index.php?showtopic=124526 Local $hDC = _WinAPI_GetDC( $hListView ), $hFont = _SendMessage( $hListView, $WM_GETFONT ) Local $hObject = _WinAPI_SelectObject( $hDC, $hFont ), $lvLOGFONT = DllStructCreate( $tagLOGFONT ) _WinAPI_GetObject( $hFont, DllStructGetSize( $lvLOGFONT ), DllStructGetPtr( $lvLOGFONT ) ) Local $hLVfont = _WinAPI_CreateFontIndirect( $lvLOGFONT ) ; Original ListView font _WinAPI_SelectObject( $hDC, $hObject ) _WinAPI_ReleaseDC( $hListView, $hDC ) _WinAPI_DeleteObject( $hFont ) ; Set height of ListView items by applying text font with suitable height $hFont = _WinAPI_CreateFont( $iHeight, 0 ) _WinAPI_SetFont( $hListView, $hFont ) _WinAPI_DeleteObject( $hFont ) ; Restore font of Header control Local $hHeader = _GUICtrlListView_GetHeader( $hListView ) If $hHeader Then _WinAPI_SetFont( $hHeader, $hLVfont ) ; Return original ListView font Return $hLVfont EndFunc Large images will also increase the height of listview items. See example E. Height of listview If the height of the listview does not fit an integer number of rows, you can see empty space below last row in the bottom of the listview. This issue is exacerbated by tall items. The following function is used to calculate the height of the listview to match a given number of rows: Func _GUICtrlListView_GetHeightToFitRows( $hListView, $iRows ) ; Get height of Header control Local $tRect = _WinAPI_GetClientRect( $hListView ) Local $hHeader = _GUICtrlListView_GetHeader( $hListView ) Local $tWindowPos = _GUICtrlHeader_Layout( $hHeader, $tRect ) Local $iHdrHeight = DllStructGetData( $tWindowPos , "CY" ) ; Get height of ListView item 0 (item 0 must exist) Local $aItemRect = _GUICtrlListView_GetItemRect( $hListView, 0, 0 ) ; Return height of ListView to fit $iRows items ; Including Header height and 8 pixels of additional room Return ( $aItemRect[3] - $aItemRect[1] ) * $iRows + $iHdrHeight + 8 EndFunc The calculation includes the height of the header. This means that the function works for a multi-line header with tall items (example A and B). Reference example WM_NOTIFY messages and NM_CUSTOMDRAW notifications are send to the parent of the listview control. The parent is the AutoIt GUI and messages can be handled by a function registered with GUIRegisterMsg. Example 1 is a reference example which shows the different stages of the custom drawing process. None of the stages contains any code except for ConsoleWrite statements. This is code for the reference example: expandcollapse popup#include <GUIConstants.au3> #include <GuiListView.au3> #include "GuiListViewEx.au3" Opt( "MustDeclareVars", 1 ) Global $hGui, $idListView, $hListView, $fListViewHasFocus = 0, $iItems = 3, $bAutoItMsgLoop = False Example() Func Example() ; Create GUI $hGui = GUICreate( "Custom draw stages", 420, 200 ) ; Create ListView $idListView = GUICtrlCreateListView( "", 10, 10, 400, 180, $GUI_SS_DEFAULT_LISTVIEW-$LVS_SINGLESEL, $WS_EX_CLIENTEDGE+$LVS_EX_FULLROWSELECT+$LVS_EX_GRIDLINES ) $hListView = GUICtrlGetHandle( $idListView ) ; Add columns to ListView _GUICtrlListView_AddColumn( $hListView, "Column 1", 94 ) _GUICtrlListView_AddColumn( $hListView, "Column 2", 94 ) _GUICtrlListView_AddColumn( $hListView, "Column 3", 94 ) _GUICtrlListView_AddColumn( $hListView, "Column 4", 94 ) ; Fill ListView For $i = 0 To $iItems - 1 GUICtrlCreateListViewItem( $i & "/Column 1|" & $i & "/Column 2|" & $i & "/Column 3|" & $i & "/Column 4", $idListView ) Next ; Adjust height of GUI and ListView to fit ten rows Local $iLvHeight = _GUICtrlListView_GetHeightToFitRows( $hListView, 10 ) WinMove( $hGui, "", Default, Default, Default, WinGetPos( $hGui )[3] - WinGetClientSize( $hGui )[1] + $iLvHeight + 20 ) WinMove( $hListView, "", Default, Default, Default, $iLvHeight ) ; Register WM_NOTIFY message handler ; To handle NM_CUSTOMDRAW notifications ; And to check when ListView receives/loses focus GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) ; Register WM_ACTIVATE message handler ; If GUI loses focus selected listview items are drawn with a button face background color. ; To check when GUI receives/loses focus ; When GUI receives focus selected items are redrawn with the dark blue background color. GUIRegisterMsg( $WM_ACTIVATE, "WM_ACTIVATE" ) ; Detection of received focus is faster through the WM_ACTIVATE message than directly ; through the listview. This provides a faster and smoother redraw of selected items. ; Show GUI GUISetState( @SW_SHOW ) ; Message loop While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch If Not $bAutoItMsgLoop Then _ ; We want to see only one message at a time $bAutoItMsgLoop = ( ConsoleWrite( "AutoIt message loop <<<<<<<<<<<<<<<<<<<<<" & @CRLF ) > 0 ) WEnd ; Cleanup GUIDelete() EndFunc ; WM_NOTIFY message handler Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) #forceref $hWnd, $iMsg, $wParam Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) Local $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) Local $iCode = DllStructGetData( $tNMHDR, "Code" ) Switch $hWndFrom Case $hListView Switch $iCode Case $NM_CUSTOMDRAW $bAutoItMsgLoop = False Local $tNMLVCustomDraw = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam ) Local $dwDrawStage = DllStructGetData( $tNMLVCustomDraw, "dwDrawStage" ) Switch $dwDrawStage ; Specifies the drawing stage ; Stage 1 Case $CDDS_PREPAINT ; Before the paint cycle begins ConsoleWrite( "Stage 1: CDDS_PREPAINT" & @CRLF ) Return $CDRF_NOTIFYITEMDRAW + _ ; Stage 2 will be carried out $CDRF_NOTIFYPOSTPAINT ; Stage 6 will be carried out Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window before an item is painted Return $CDRF_NOTIFYPOSTPAINT ; Notify the parent window after the paint cycle is complete ; Stage 2 Case $CDDS_ITEMPREPAINT ; Before an item is painted ConsoleWrite( "Stage 2: CDDS_ITEMPREPAINT" & @CRLF ) Return $CDRF_NOTIFYSUBITEMDRAW + _ ; Stage 3 will be carried out $CDRF_NOTIFYPOSTPAINT ; Stage 5 will be carried out Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window before a subitem is painted Return $CDRF_NOTIFYPOSTPAINT ; Notify the parent window after an item is painted ; Stage 3 Case BitOR( $CDDS_ITEMPREPAINT, _ $CDDS_SUBITEM ) ; Before a subitem is painted ConsoleWrite( "Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM" & @CRLF ) Return $CDRF_NOTIFYPOSTPAINT ; Stage 4 will be carried out Return $CDRF_NOTIFYPOSTPAINT ; Notify the parent window after a subitem is painted ; Stage 4 Case BitOR( $CDDS_ITEMPOSTPAINT, _ $CDDS_SUBITEM ) ; After a subitem has been painted ConsoleWrite( "Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM" & @CRLF ) ; Stage 5 Case $CDDS_ITEMPOSTPAINT ; After an item has been painted ConsoleWrite( "Stage 5: CDDS_ITEMPOSTPAINT" & @CRLF ) ; Stage 6 Case $CDDS_POSTPAINT ; After the paint cycle is complete ConsoleWrite( "Stage 6: CDDS_POSTPAINT" & @CRLF ) EndSwitch Case $NM_KILLFOCUS If $fListViewHasFocus Then GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, 0, $iItems - 1 ) $fListViewHasFocus = 0 EndIf Case $NM_SETFOCUS If Not $fListViewHasFocus Then _ GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, 0, $iItems - 1 ) $fListViewHasFocus = 2 EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ; WM_ACTIVATE message handler Func WM_ACTIVATE( $hWnd, $iMsg, $wParam, $lParam ) #forceref $iMsg, $lParam If $hWnd = $hGui Then _ $fListViewHasFocus = BitAND( $wParam, 0xFFFF ) ? 1 : 0 Return $GUI_RUNDEFMSG EndFunc Code is added to check when GUI and listview receives and loses focus. This is important in the other examples. Output in SciTE console immediately after example is opened: Stage 1: CDDS_PREPAINT Stage 2: CDDS_ITEMPREPAINT Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM Stage 5: CDDS_ITEMPOSTPAINT Stage 2: CDDS_ITEMPREPAINT Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM Stage 5: CDDS_ITEMPOSTPAINT Stage 2: CDDS_ITEMPREPAINT Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM Stage 3: CDDS_ITEMPREPAINT, CDDS_SUBITEM Stage 4: CDDS_ITEMPOSTPAINT, CDDS_SUBITEM Stage 5: CDDS_ITEMPOSTPAINT Stage 6: CDDS_POSTPAINT AutoIt message loop <<<<<<<<<<<<<<<<<<<<< Note that the entire custom draw process from stage 1 to 6 is not interrupted by the AutoIt message loop. The other examples are all based on the reference example. Examples This is common to all examples. First line in item texts is stored directly in the listview. Additional lines are stored in a global array named $aLines. Index in the array is item ID as returned by GUICtrlCreateListViewItem and stored in ItemParam internally in listview memory. Item texts and background is drawn with custom code. Other item elements and background is drawn with default code. In all examples LVS_SINGLESEL style is removed to be able to select multiple items. This is a picture of example E: Example 2, 3 and 4 are simple examples. Example 5 and 6 deals with subitem icons and colors. Example 7 about listview notifications shows a way to catch double click and Enter key. A dummy control is used to forward the double click event to AutoIt main message loop to avoid lengthy or blocking code in WM_NOTIFY function. Example 8 and 9 shows how to respond to header notifications and how to rearrange columns by dragging header items with the mouse. In both examples LVS_EX_HEADERDRAGDROP extended style is added to the listview. When columns are rearranged, header item index and listview subitem index is always the same independent of column position, while header item order changes depending on column position. Because the header is a child control of the listview, the listview must be subclassed to catch header notifications. Subclassing is implemented with the four functions SetWindowSubclass, GetWindowSubclass, RemoveWindowSubclass and DefSubclassProc (all implemented in WinAPIShellEx.au3). Since we are subclassing a header control contained in a listview this issue must be taking into account. Note that the subclass callback function is only running while the primary mouse button is pressed on the header. This means no performance impact on the listview eg. when you are dragging the scroll bar. This is important for a custom drawn listview. Quite a lot of extra code is added (most easily seen in example 9) to fix an issue due to column 0 and other columns have different left margins. When first column is moved to another position there is a white gap between columns for selected rows (Windows XP), or the text is painted too close to the left edge of the item (Windows 7). The problem is seen in the picture to the right where the two first columns are swapped: LVS_EX_HEADERDRAGDROP style is only used in example 8 and 9. Usage of a multi-line header is demonstrated in example A and B. See Custom/owner drawn multi-line header in ListView for more information. Example C shows a method to deal with focus issues when more controls (here just a single button) are added to the GUI. When the listview has focus selected items are drawn with the dark blue background color. The problem arises if the listview and GUI loses focus eg. to Calculator. When focus is lost selected items are drawn with the button face background color. If GUI receives focus again by clicking the button (and not the listview), selected items are first very briefly redrawn with the dark blue background color (it seems like a blink) and then with the correct button face background color. To avoid this issue a hidden label control is added to the GUI. Immediately before the GUI loses focus, focus is moved from the listview to the label. In example D items are added with the commands _GUICtrlListView_AddItem and _GUICtrlListView_AddSubItem. In all examples an array is used to store the multi-line item texts. The array contains all lines except the first line which is stored directly in the listview. This example shows how to manually store array row index in ItemParam when items are added with _GUICtrlListView_AddItem and _GUICtrlListView_AddSubItem. Inspiration for example E about large images in first column (see picture above) comes from this thread. In example E the images are used to increase the height of the listview items instead of a text font. Because it's large 128x128 pixel images there is plenty of room in subitems in second and third column. In all examples 15 lines of code is used to repaint the first line item text. The text that was painted by default code in middle of the item is first deleted by filling the item with the background color. Then the text is extracted from the listview and repainted in top of item. This code can be avoided by storing all text lines in the array. This is demonstrated in example F. This makes the custom draw code faster. Performance considerations In a custom drawn (or owner drawn or virtual) listview performance considerations are important because the custom drawing (or owner drawing or data display) is performed by AutoIt code. In a normal listview drawing and data display is performed by compiled C++ code in ComCtl32.dll. Lengthy and slow code in NM_CUSTOMDRAW Case statements (or WM_DRAWITEM functions or LVN_GETDISPINFO Case statements) should be avoided. Perform as many calculations as possible before the repetitive and fast executions of these code blocks. Use static variables to avoid repeating the same calculation again and again. Executing a function directly with DllCall or GUICtrlSendMsg is faster than executing the same function through an implementation in an UDF. Simple GDI functions are faster than more advanced GDI+ functions. Use different drawing stages to optimize custom drawing. The CDDS_PREPAINT stage is only performed once for the entire drawing process. The CDDS_ITEMPREPAINT stage is performed once per item. The stage given by BitOR( CDDS_ITEMPREPAINT, CDDS_SUBITEM ) is performed once per subitem including subitem 0. Default drawing should be used as much as possible, because the code is running in ComCtl32.dll. In a listview the time it takes to update all visible rows is proportional to the number of visible rows. Reducing the height of the list view and thus the number of visible rows improves performance. Especially in a custom drawn (or owner drawn or virtual) listview. ListviewMultilineItems.7z 1) Custom draw stages.au3 2) Two-line listview items.au3 3) Three-line listview items.au3 4) First column checkbox and icon.au3 5) Check boxes and icons.au3 6) Background and text colors.au3 7) ListView notifications.au3 8) Header notifications.au3 9) Rearrange columns.au3 A) Multi-line header 1.au3 A) Multi-line header 2.au3 C) Button control.au3 D) _GUICtrlListView_AddItem.au3 E) Large images in first column.au3 F) Storing all lines in array.au3 GuiHeaderEx.au3 GuiListViewEx.au3 ListViewCustomDraw.au3 Images\ 8 images for example E You need AutoIt 3.3.10 or later. Tested on Windows 7 32/64 bit and Windows XP 32 bit. Comments are welcome. Let me know if there are any issues. (Set tab width = 2 in SciTE to line up comments by column.) ListviewMultilineItems.7z Edited January 30, 2018 by LarsJ Image links IErrors, BJR, Celtic88 and 10 others 12 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
mLipok Posted December 1, 2015 Share Posted December 1, 2015 (edited) AutoItMagic +5btw. (little off topic)Sorry for bothering but I think you should update your Signature, as is incomplete - I mean here:ListView controls: Custom drawn colors and fonts, Virtual listviews for huge number of rows Edited December 1, 2015 by mLipok Signature beginning:* Please remember: "AutoIt"..... * Wondering who uses AutoIt and what it can be used for ? * Forum Rules ** ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Code * for other useful stuff click the following button: Spoiler Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API * ErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 * My contribution to others projects or UDF based on others projects: * _sql.au3 UDF * POP3.au3 UDF * RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF * SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane * Useful links: * Forum Rules * Forum etiquette * Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * Wiki: * Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX IE Related: * How to use IE.au3 UDF with AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskScheduler * IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related: * How to get reference to PDF object embeded in IE * IE on Windows 11 * I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions * EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *I also encourage you to check awesome @trancexx code: * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuff * OnHungApp handler * Avoid "AutoIt Error" message box in unknown errors * HTML editor * winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/ "Homo sum; humani nil a me alienum puto" - Publius Terentius Afer"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming" , be and \\//_. Anticipating Errors : "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty." Signature last update: 2023-04-24 Link to comment Share on other sites More sharing options...
UEZ Posted December 1, 2015 Share Posted December 1, 2015 Great work LarsJ. Thanks for sharing! Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
mLipok Posted December 1, 2015 Share Posted December 1, 2015 (edited) 9) Rearrange columns.au3This is great.Do you have any concept how Column order can be saved, and restored ?I mean user change order and this should be saved for "future" program runs. EDIT:E) Large images in first column.au3Is just awesome.After a brief moment of reverie, I've got to possible use in one of my projects. Edited December 1, 2015 by mLipok Signature beginning:* Please remember: "AutoIt"..... * Wondering who uses AutoIt and what it can be used for ? * Forum Rules ** ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Code * for other useful stuff click the following button: Spoiler Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API * ErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 * My contribution to others projects or UDF based on others projects: * _sql.au3 UDF * POP3.au3 UDF * RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF * SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane * Useful links: * Forum Rules * Forum etiquette * Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * Wiki: * Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX IE Related: * How to use IE.au3 UDF with AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskScheduler * IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related: * How to get reference to PDF object embeded in IE * IE on Windows 11 * I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions * EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *I also encourage you to check awesome @trancexx code: * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuff * OnHungApp handler * Avoid "AutoIt Error" message box in unknown errors * HTML editor * winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/ "Homo sum; humani nil a me alienum puto" - Publius Terentius Afer"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming" , be and \\//_. Anticipating Errors : "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty." Signature last update: 2023-04-24 Link to comment Share on other sites More sharing options...
LarsJ Posted December 2, 2015 Author Share Posted December 2, 2015 (edited) mLipok, In this version of example 9 code is added to read and save column order in "HdrItemOrder.ini".expandcollapse popup#include <GUIConstants.au3> #include <GuiListView.au3> #include <WinAPIShellEx.au3> #include "GuiListViewEx.au3" #include "ListViewCustomDraw.au3" Opt( "MustDeclareVars", 1 ) Global $hGui, $idListView, $hListView, $fListViewHasFocus = 0, $hLVfont, $iItems = 1000, $aLines[1][4] Global $hHeader, $fHeaderOrderOfItem0 = 0 ; $fHeaderOrderOfItem0 is used to handle column 0 issue Example() Func Example() ; Create GUI $hGui = GUICreate( "Rearrange columns", 440, 320 ) ; Create ListView $idListView = GUICtrlCreateListView( "", 10, 10, 420, 300, $GUI_SS_DEFAULT_LISTVIEW-$LVS_SINGLESEL, $WS_EX_CLIENTEDGE+$LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT+$LVS_EX_GRIDLINES+$LVS_EX_HEADERDRAGDROP ) $hListView = GUICtrlGetHandle( $idListView ) ; Reduce flicker ; Increase item height $hLVfont = _GUICtrlListView_SetItemHeightByFont( $hListView, 26 ) ; Add columns to ListView _GUICtrlListView_AddColumn( $hListView, "Column 1", 94 ) _GUICtrlListView_AddColumn( $hListView, "Column 2", 94 ) _GUICtrlListView_AddColumn( $hListView, "Column 3", 94 ) _GUICtrlListView_AddColumn( $hListView, "Column 4", 94 ) ; Fill ListView Local $idItem For $i = 0 To $iItems - 1 $idItem = GUICtrlCreateListViewItem( $i & " Column 1|" & $i & " Column 2|" & $i & " Column 3|" & $i & " Column 4", $idListView ) ; $idItem (controlID) is stored in ItemParam in the internal storage allocated for the ListView If Not $i Then ReDim $aLines[$idItem+$iItems][4] ; Second line in ListView items is stored in $aLines array $aLines[$idItem][0] = $i & " Line 2/1" ; $idItem (controlID, stored in ItemParam) is row index in $aLines $aLines[$idItem][1] = $i & " Line 2/2" ; Four item texts are stored in four columns in $aLines array $aLines[$idItem][2] = $i & " Line 2/3" ; If line texts are stored as strings it's easy to test for empty texts $aLines[$idItem][3] = $i & " Line 2/4" Next ; Adjust height of GUI and ListView to fit ten rows Local $iLvHeight = _GUICtrlListView_GetHeightToFitRows( $hListView, 10 ) WinMove( $hGui, "", Default, Default, Default, WinGetPos( $hGui )[3] - WinGetClientSize( $hGui )[1] + $iLvHeight + 20 ) WinMove( $hListView, "", Default, Default, Default, $iLvHeight ) ; Column 0 issue ; Header handle and position $hHeader = _GUICtrlListView_GetHeader( $hListView ) Local $tRect = _WinAPI_GetClientRect( $hListView ) Local $tPos = _GUICtrlHeader_Layout( $hHeader, $tRect ) Local $aHdrPos = WinGetPos( $hHeader ) ; Left/top corner in screen coordinates $aHdrPos[2] = $aHdrPos[0] + DllStructGetData( $tPos, "CX" ) ; Right/bottom corner in screen coordinates $aHdrPos[3] = $aHdrPos[1] + DllStructGetData( $tPos, "CY" ) Local $bMouseClickHeader = False ; Read Header item order Local $aHdrItemOrder0 = [ 4, 0, 1, 2, 3 ], $aHdrItemOrder, $sOrder If FileExists( "HdrItemOrder.ini" ) Then $sOrder = FileReadLine( "HdrItemOrder.ini" ) $aHdrItemOrder = StringSplit( $sOrder, "|", 2 ) ; 2 = $STR_NOCOUNT For $i = 1 To $aHdrItemOrder[0] If $aHdrItemOrder[$i] <> $aHdrItemOrder0[$i] Then ExitLoop Next If $i < $aHdrItemOrder[0] Then _GUICtrlHeader_SetOrderArray( $hHeader, $aHdrItemOrder ) $aHdrItemOrder0 = $aHdrItemOrder EndIf EndIf ; Register WM_NOTIFY message handler ; To handle NM_CUSTOMDRAW notifications ; And to check when ListView receives/loses focus GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) ; Register WM_ACTIVATE message handler ; If GUI loses focus selected listview items are drawn with a button face background color. ; To check when GUI receives/loses focus ; When GUI receives focus selected items are redrawn with the dark blue background color. GUIRegisterMsg( $WM_ACTIVATE, "WM_ACTIVATE" ) ; Detection of received focus is faster through the WM_ACTIVATE message than directly ; through the listview. This provides a faster and smoother redraw of selected items. ; Show GUI GUISetState( @SW_SHOW ) ; Message loop While 1 Switch GUIGetMsg() ; Two Case sections to handle column 0 issue Case $GUI_EVENT_PRIMARYDOWN Local $aPos = MouseGetPos() If $aHdrPos[0] <= $aPos[0] And $aPos[0] <= $aHdrPos[2] And _ $aHdrPos[1] <= $aPos[1] And $aPos[1] <= $aHdrPos[3] Then ; Mouse click in header ; Register callback function to subclass ListView Local $pListViewProc = DllCallbackGetPtr( DllCallbackRegister( "ListViewProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) ) _WinAPI_SetWindowSubclass( $hListView, $pListViewProc, 9999, 0 ) ; $iSubclassId = 9999, $pData = 0 $bMouseClickHeader = True EndIf Case $GUI_EVENT_PRIMARYUP If $bMouseClickHeader Then ; Remove callback function _WinAPI_RemoveWindowSubclass( $hListView, $pListViewProc, 9999 ) $bMouseClickHeader = False EndIf Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Save Header item order if changed $aHdrItemOrder = _GUICtrlHeader_GetOrderArray( $hHeader ) For $i = 1 To $aHdrItemOrder[0] If $aHdrItemOrder[$i] <> $aHdrItemOrder0[$i] Then ExitLoop Next If $i < $aHdrItemOrder[0] Then $sOrder = $aHdrItemOrder[0] For $i = 1 To $aHdrItemOrder[0] $sOrder &= "|" & $aHdrItemOrder[$i] Next Local $hHdrIni = FileOpen( "HdrItemOrder.ini", 2 ) ; 2 = $FO_OVERWRITE FileWriteLine( $hHdrIni, $sOrder ) FileClose( $hHdrIni ) EndIf ; Cleanup GUIDelete() EndFunc ; ListViewProc callback function to handle column 0 issue Func ListViewProc( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData ) If $iMsg <> $WM_NOTIFY Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] If HWnd( DllStructGetData( DllStructCreate( $tagNMHDR, $lParam ), "hWndFrom" ) ) <> $hHeader Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] #forceref $iSubclassId, $pData Switch DllStructGetData( DllStructCreate( $tagNMHDR, $lParam ), "Code" ) Case $HDN_ENDDRAG ; A Header item has been dragged with the mouse $fHeaderOrderOfItem0 = -1 ; Recalculate order of Header item with index 0 EndSwitch ; Call next function in subclass chain Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] EndFunc ; WM_NOTIFY message handler Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) #forceref $hWnd, $iMsg, $wParam Local Static $iLvIndex, $iArrayIdx, $iSelected, $tRect = DllStructCreate( $tagRECT ), $pRect = DllStructGetPtr( $tRect ), $hDC Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) Local $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) Local $iCode = DllStructGetData( $tNMHDR, "Code" ) Switch $hWndFrom Case $hListView Switch $iCode Case $NM_CUSTOMDRAW Local $tNMLVCustomDraw = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam ) Local $dwDrawStage = DllStructGetData( $tNMLVCustomDraw, "dwDrawStage" ) Switch $dwDrawStage ; Specifies the drawing stage ; Stage 1 Case $CDDS_PREPAINT ; Before the paint cycle begins If $fHeaderOrderOfItem0 = -1 Then ; Handle column 0 issue ; Calculate order of Header item with index 0 Local $tHdrItem = DllStructCreate( $tagHDITEM ) DllStructSetData( $tHdrItem, "Mask", $HDI_ORDER ) DllCall( "user32.dll", "lresult", "SendMessageW", "hwnd", $hHeader, "uint", $HDM_GETITEMW, "wparam", 0, "struct*", $tHdrItem ) $fHeaderOrderOfItem0 = DllStructGetData( $tHdrItem, "Order" ) EndIf $hDC = DllStructGetData( $tNMLVCustomDraw, "hDC" ) ; Device context _WinAPI_SelectObject( $hDC, $hLVfont ) ; Set original font _WinAPI_SetBkMode( $hDC, $TRANSPARENT ) ; Transparent background Return $CDRF_NOTIFYITEMDRAW+$CDRF_NEWFONT ; Notify the parent window before an item is painted ; Stage 2 Case $CDDS_ITEMPREPAINT ; Before an item is painted $iLvIndex = DllStructGetData( $tNMLVCustomDraw, "dwItemSpec" ) ; Item index $iArrayIdx = DllStructGetData( $tNMLVCustomDraw, "lItemlParam" ) ; Array index $iSelected = GUICtrlSendMsg( $idListView, $LVM_GETITEMSTATE, $iLvIndex, $LVIS_SELECTED ) ; Item state Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window before a subitem is painted ; Stage 3 Case BitOR( $CDDS_ITEMPREPAINT, $CDDS_SUBITEM ) ; Before a subitem is painted: Default painting of checkbox, image, icon Return $CDRF_NOTIFYPOSTPAINT ; Notify the parent window after a subitem is painted ; Stage 4 Case BitOR( $CDDS_ITEMPOSTPAINT, $CDDS_SUBITEM ) ; After a subitem has been painted: Custom painting of text lines Local $iSubItem = DllStructGetData( $tNMLVCustomDraw, "iSubItem" ) ; Subitem index ; Subitem rectangle DllStructSetData( $tRect, "Top", $iSubItem ) DllStructSetData( $tRect, "Left", $iSubItem ? $LVIR_BOUNDS : $LVIR_LABEL ) GUICtrlSendMsg( $idListView, $LVM_GETSUBITEMRECT, $iLvIndex, $pRect ) ; Subitem text color DllCall( "gdi32.dll", "int", "SetTextColor", "handle", $hDC, "int", ( $iSelected And $fListViewHasFocus ) ? 0xFFFFFF : 0x000000 ) ; _WinAPI_SetTextColor ; Custom painting of first text line in subitem If $fHeaderOrderOfItem0 Then ; Handle column 0 issue ; Handle column 0 issue due to column 0 and other columns have different left margins RepaintFirstTextLineCol0( $idListView, $iLvIndex, $iSubItem, $iSelected, $fListViewHasFocus, $hDC, $tRect ) Else RepaintFirstTextLine( $idListView, $iLvIndex, $iSubItem, $iSelected, $fListViewHasFocus, $hDC, $tRect ) EndIf ; Custom painting of second text line in subitem If Not $aLines[$iArrayIdx][$iSubItem] Then Return $CDRF_NEWFONT DllStructSetData( $tRect, "Top", DllStructGetData( $tRect, "Top" ) + 12 ) ; Top margin DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $aLines[$iArrayIdx][$iSubItem], "int", -1, "struct*", $tRect, "uint", $DT_WORD_ELLIPSIS ) ; _WinAPI_DrawText Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndSwitch Case $NM_KILLFOCUS If $fListViewHasFocus Then GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, 0, $iItems - 1 ) $fListViewHasFocus = 0 EndIf Case $NM_SETFOCUS If Not $fListViewHasFocus Then _ GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, 0, $iItems - 1 ) $fListViewHasFocus = 2 EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ; WM_ACTIVATE message handler Func WM_ACTIVATE( $hWnd, $iMsg, $wParam, $lParam ) #forceref $iMsg, $lParam If $hWnd = $hGui Then _ $fListViewHasFocus = BitAND( $wParam, 0xFFFF ) ? 1 : 0 Return $GUI_RUNDEFMSG EndFuncI have obviously forgotten to update my signature for a long time. I will go through the examples and update the signature in the weekend. Thank you. For everybody: Always nice to get feedback. Thank you. Edited December 2, 2015 by LarsJ mLipok 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
t0nZ Posted December 16, 2015 Share Posted December 16, 2015 Fantastic stuff... I was seaching for a set of complete examples like these.But I can't figure out in scripts number 4 & 5 how to check the state of checkboxes... Link to comment Share on other sites More sharing options...
LarsJ Posted December 16, 2015 Author Share Posted December 16, 2015 (edited) You can use_GUICtrlListView_GetItemChecked( $hListView, $iIndex )where $iIndex is the zero based index (row number). Edited December 16, 2015 by LarsJ Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
t0nZ Posted December 16, 2015 Share Posted December 16, 2015 So simple.. sure !I forgot there is the built-in function...Thank you. Link to comment Share on other sites More sharing options...
Zedna Posted December 23, 2015 Share Posted December 23, 2015 Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
mLipok Posted January 6, 2016 Share Posted January 6, 2016 @LarsJ I want to ask you if you can provide one more example.I use _GUICtrlListView_GetItemText.au3 example from HelpFile and I was made little modyfication.#include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <MsgBoxConstants.au3> Example() Func Example() Local $idListview GUICreate("ListView Get Item Text", 400, 300) $idListview = GUICtrlCreateListView("", 2, 2, 394, 268) GUISetState(@SW_SHOW) ; Add columns _GUICtrlListView_AddColumn($idListview, "Items", 100) ; Add items _GUICtrlListView_AddItem($idListview, "Item 1") _GUICtrlListView_AddItem($idListview, "Item 2") _GUICtrlListView_AddItem($idListview, "Item 3") ; Set item 2 text ; HERE I ADD NEW LINE _GUICtrlListView_SetItemText($idListview, 1, "New Item 2" & @CRLF & "second line") MsgBox($MB_SYSTEMMODAL, "Information", "Item 2 Text: " & _GUICtrlListView_GetItemText($idListview, 1)) ; Loop until the user exits. Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>ExampleHow you can see Listview internally stores @CRLF char.So I wonder how to make it possible to just check if desired ListViewItem contain NewLine character and then show them in a proper way (multiline).In such case user do not must create any special array to store ListViewItem properties.mLipok Signature beginning:* Please remember: "AutoIt"..... * Wondering who uses AutoIt and what it can be used for ? * Forum Rules ** ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Code * for other useful stuff click the following button: Spoiler Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API * ErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 * My contribution to others projects or UDF based on others projects: * _sql.au3 UDF * POP3.au3 UDF * RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF * SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane * Useful links: * Forum Rules * Forum etiquette * Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * Wiki: * Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX IE Related: * How to use IE.au3 UDF with AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskScheduler * IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related: * How to get reference to PDF object embeded in IE * IE on Windows 11 * I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions * EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *I also encourage you to check awesome @trancexx code: * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuff * OnHungApp handler * Avoid "AutoIt Error" message box in unknown errors * HTML editor * winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/ "Homo sum; humani nil a me alienum puto" - Publius Terentius Afer"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming" , be and \\//_. Anticipating Errors : "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty." Signature last update: 2023-04-24 Link to comment Share on other sites More sharing options...
LarsJ Posted January 8, 2016 Author Share Posted January 8, 2016 It can be done:expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <MsgBoxConstants.au3> #include <WindowsConstants.au3> Opt( "MustDeclareVars", 1 ) Global $hGui, $idListView, $hListView, $fListViewHasFocus = 0, $hLVfont, $iItems Example() Func Example() $hGui = GUICreate("ListView Get Item Text", 500, 300) ; $hGui is used in WM_ACTIVATE $idListView = GUICtrlCreateListView("", 2, 2, 494, 268) $hListView = GUICtrlGetHandle( $idListView ) ;GUISetState(@SW_SHOW) ; Increase item height ; Because a larger font is set for the listview, all $hLVfont = _GUICtrlListView_SetItemHeightByFont( $hListView, 26 ) ; items must be displayed through WM_NOTIFY function ; to be able to display the text with the original font. ; Add columns _GUICtrlListView_AddColumn($idListView, "Items", 100) _GUICtrlListView_AddColumn($idListView, "Column 2", 100) _GUICtrlListView_AddColumn($idListView, "Column 3", 100) _GUICtrlListView_AddColumn($idListView, "Column 4", 100) ; Add items ;_GUICtrlListView_AddItem($idListView, "Item 1") ; More columns and lines are added to be able ;_GUICtrlListView_AddItem($idListView, "Item 2") ; to test performance with the scrollbar. If ;_GUICtrlListView_AddItem($idListView, "Item 3") ; scrolling is OK performance is OK. For $i = 1 To 1000 If Mod( $i, 3 ) = 2 Then ; GUICtrlCreateListViewItem is used because of performance GUICtrlCreateListViewItem( "Item " & $i & @CRLF & "Second line" & "|Item " & $i & " Col 2" & @CRLF & "Second line col 2" & "|Item " & $i & " Col 3" & @CRLF & "Second line col 3" & "|Item " & $i & " Col 4" & @CRLF & "Second line col 4", $idListView ) Else GUICtrlCreateListViewItem( "Item " & $i & "|Item " & $i & " Col 2" & "|Item " & $i & " Col 3" & "|Item " & $i & " Col 4", $idListView ) EndIf Next _GUICtrlListView_SetColumnWidth( $idListView, 0, 100 ) ; The long text lines have changed the column widths _GUICtrlListView_SetColumnWidth( $idListView, 1, 100 ) _GUICtrlListView_SetColumnWidth( $idListView, 2, 100 ) _GUICtrlListView_SetColumnWidth( $idListView, 3, 100 ) ; Set item 2 text ; HERE I ADD NEW LINE ;_GUICtrlListView_SetItemText($idListView, 1, "New Item 2" & @CRLF & "second line") ;MsgBox($MB_SYSTEMMODAL, "Information", "Item 2 Text: " & _GUICtrlListView_GetItemText($idListView, 1)) $iItems = _GUICtrlListView_GetItemCount( $idListView ) ; Register WM_NOTIFY message handler ; To handle NM_CUSTOMDRAW notifications ; And to check when ListView receives/loses focus GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) ; Register WM_ACTIVATE message handler ; If GUI loses focus selected listview items are drawn with a button face background color. ; To check when GUI receives/loses focus ; When GUI receives focus selected items are redrawn with the dark blue background color. GUIRegisterMsg( $WM_ACTIVATE, "WM_ACTIVATE" ) ; Detection of received focus is faster through the WM_ACTIVATE message than directly ; through the listview. This provides a faster and smoother redraw of selected items. GUISetState(@SW_SHOW) ; Showing the GUI at this point ensures that the listview ; items are displayed through the WM_NOTIFY function. ; Loop until the user exits. Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>Example ; WM_NOTIFY message handler Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) #forceref $hWnd, $iMsg, $wParam ; Use static variables to avoid recalculating everything on each function call Local Static $hDC, $iItem, $iSelected, $tRect = DllStructCreate( $tagRECT ), $pRect = DllStructGetPtr( $tRect ) Local Static $tLVitem = DllStructCreate( $tagLVITEM ), $pLVitem = DllStructGetPtr( $tLVitem ) Local Static $tBuffer = DllStructCreate( "wchar Text[4096]" ), $pBuffer = DllStructGetPtr( $tBuffer ) Local Static $hBrushNormal = _WinAPI_CreateSolidBrush( 0xFFFFFF ), $hBrushHighLight = _WinAPI_GetSysColorBrush( $COLOR_HIGHLIGHT ), $hBrushButtonFace = _WinAPI_GetSysColorBrush( $COLOR_BTNFACE ) Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) Local $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) Local $iCode = DllStructGetData( $tNMHDR, "Code" ) Switch $hWndFrom Case $hListView Switch $iCode Case $NM_CUSTOMDRAW Local $tNMLVCustomDraw = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam ) Local $dwDrawStage = DllStructGetData( $tNMLVCustomDraw, "dwDrawStage" ) Switch $dwDrawStage ; Specifies the drawing stage ; Stage 1 Case $CDDS_PREPAINT ; Before the paint cycle begins $hDC = DllStructGetData( $tNMLVCustomDraw, "hDC" ) ; Device context _WinAPI_SelectObject( $hDC, $hLVfont ) ; Set original font <<<<<<<<<<<<<<<<<<<<<<<<<<<< _WinAPI_SetBkMode( $hDC, $TRANSPARENT ) ; Transparent background Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window before an item is painted ; Stage 2 Case $CDDS_ITEMPREPAINT ; Before an item is painted $iItem = DllStructGetData( $tNMLVCustomDraw, "dwItemSpec" ) ; Item index $iSelected = GUICtrlSendMsg( $idListView, $LVM_GETITEMSTATE, $iItem, $LVIS_SELECTED ) ; Item state Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window before a subitem is painted ; Stage 3 Case BitOR( $CDDS_ITEMPREPAINT, $CDDS_SUBITEM ) ; Before a subitem is painted: Default painting of checkbox, image, icon Return $CDRF_NOTIFYPOSTPAINT ; Notify the parent window after a subitem is painted ; Stage 4 Case BitOR( $CDDS_ITEMPOSTPAINT, $CDDS_SUBITEM ) ; After a subitem has been painted: Custom painting of text lines Local $iSubItem = DllStructGetData( $tNMLVCustomDraw, "iSubItem" ) ; Subitem index ; Subitem rectangle DllStructSetData( $tRect, "Top", $iSubItem ) DllStructSetData( $tRect, "Left", $iSubItem ? $LVIR_BOUNDS : $LVIR_LABEL ) GUICtrlSendMsg( $idListView, $LVM_GETSUBITEMRECT, $iItem, $pRect ) ; Subitem back ground color ; Delete default painting of text because it's painted in the middle of the subitem ; And because it paints the entire text string including any @CRLF characters ; The text is deleted by filling the subitem rectangle with the back ground color DllCall( "user32.dll", "int", "FillRect", "handle", $hDC, "struct*", $tRect, "handle", $iSelected ? ( $fListViewHasFocus ? $hBrushHighLight : $hBrushButtonFace ) : $hBrushNormal ) ; _WinAPI_FillRect ; Subitem text color (fore color) DllCall( "gdi32.dll", "int", "SetTextColor", "handle", $hDC, "int", ( $iSelected And $fListViewHasFocus ) ? 0xFFFFFF : 0x000000 ) ; _WinAPI_SetTextColor ; Left margin of item text DllStructSetData( $tRect, "Left", DllStructGetData( $tRect, "Left" ) + ( $iSubItem ? 6 : 2 ) ) ; Extract text line directly from ListView DllStructSetData( $tLVitem, "Mask", $LVIF_TEXT ) DllStructSetData( $tLVitem, "SubItem", $iSubItem ) DllStructSetData( $tLVitem, "Text", $pBuffer ) DllStructSetData( $tLVitem, "TextMax", 4096 ) GUICtrlSendMsg( $idListView, $LVM_GETITEMTEXTW, $iItem, $pLVitem ) ; Does the text contain a @CRLF character combination Local $iPos = StringInStr( DllStructGetData( $tBuffer, "Text" ), @CRLF ) If Not $iPos Then ; No @CRLF characters, draw text line DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", DllStructGetData( $tBuffer, "Text" ), "int", -1, "struct*", $tRect, "uint", $DT_WORD_ELLIPSIS ) ; _WinAPI_DrawText Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndIf ; The text is divided into two lines ; Paint first part of the text line DllStructSetData( $tBuffer, "Text", 0, $iPos ) ; 0-terminate first part of the text DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", DllStructGetData( $tBuffer, "Text" ), "int", -1, "struct*", $tRect, "uint", $DT_WORD_ELLIPSIS ) ; _WinAPI_DrawText ; Paint second part of the text line DllStructSetData( $tRect, "Top", DllStructGetData( $tRect, "Top" ) + 12 ) ; Top margin Local $tBuffer2 = DllStructCreate( "wchar Text[" & 4096-$iPos-2 & "]", $pBuffer + 2 * $iPos + 2 ) ; Buffer for second part of the text DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", DllStructGetData( $tBuffer2, "Text" ), "int", -1, "struct*", $tRect, "uint", $DT_WORD_ELLIPSIS ) ; _WinAPI_DrawText Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndSwitch Case $NM_KILLFOCUS If $fListViewHasFocus Then GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, 0, $iItems - 1 ) $fListViewHasFocus = 0 EndIf Case $NM_SETFOCUS If Not $fListViewHasFocus Then _ GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, 0, $iItems - 1 ) $fListViewHasFocus = 2 EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ; WM_ACTIVATE message handler Func WM_ACTIVATE( $hWnd, $iMsg, $wParam, $lParam ) #forceref $iMsg, $lParam If $hWnd = $hGui Then _ $fListViewHasFocus = BitAND( $wParam, 0xFFFF ) ? 1 : 0 Return $GUI_RUNDEFMSG EndFunc Func _GUICtrlListView_SetItemHeightByFont( $hListView, $iHeight ) ; Get font of ListView control ; Copied from _GUICtrlGetFont example by KaFu ; See https://www.autoitscript.com/forum/index.php?showtopic=124526 Local $hDC = _WinAPI_GetDC( $hListView ), $hFont = _SendMessage( $hListView, $WM_GETFONT ) Local $hObject = _WinAPI_SelectObject( $hDC, $hFont ), $lvLOGFONT = DllStructCreate( $tagLOGFONT ) _WinAPI_GetObject( $hFont, DllStructGetSize( $lvLOGFONT ), DllStructGetPtr( $lvLOGFONT ) ) Local $hLVfont = _WinAPI_CreateFontIndirect( $lvLOGFONT ) ; Original ListView font _WinAPI_SelectObject( $hDC, $hObject ) _WinAPI_ReleaseDC( $hListView, $hDC ) _WinAPI_DeleteObject( $hFont ) ; Set height of ListView items by applying text font with suitable height $hFont = _WinAPI_CreateFont( $iHeight, 0 ) _WinAPI_SetFont( $hListView, $hFont ) _WinAPI_DeleteObject( $hFont ) ; Restore font of Header control Local $hHeader = _GUICtrlListView_GetHeader( $hListView ) If $hHeader Then _WinAPI_SetFont( $hHeader, $hLVfont ) ; Return original ListView font Return $hLVfont EndFuncI'll admit it would have been easier with some kind of UDF. I'm working on that. mLipok 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
mLipok Posted January 8, 2016 Share Posted January 8, 2016 (edited) 'll admit it would have been easier with some kind of UDF. I'm working on that.Awesome news !!! EDIT:I have one suggestion/wish/request :Can you use this:This should facilitate the adaptation, in existing projects.And one question:Are you going in the UDFs provide the ability to assign different functions to different ListView?Because you can at the same time use multiple ListView. And second question:Do you want to combine all your "ListView magic" (Header, colors, multiline, virtual......) in this one UDF ? Edited January 8, 2016 by mLipok Signature beginning:* Please remember: "AutoIt"..... * Wondering who uses AutoIt and what it can be used for ? * Forum Rules ** ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Code * for other useful stuff click the following button: Spoiler Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API * ErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 * My contribution to others projects or UDF based on others projects: * _sql.au3 UDF * POP3.au3 UDF * RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF * SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane * Useful links: * Forum Rules * Forum etiquette * Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * Wiki: * Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX IE Related: * How to use IE.au3 UDF with AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskScheduler * IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related: * How to get reference to PDF object embeded in IE * IE on Windows 11 * I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions * EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *I also encourage you to check awesome @trancexx code: * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuff * OnHungApp handler * Avoid "AutoIt Error" message box in unknown errors * HTML editor * winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/ "Homo sum; humani nil a me alienum puto" - Publius Terentius Afer"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming" , be and \\//_. Anticipating Errors : "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty." Signature last update: 2023-04-24 Link to comment Share on other sites More sharing options...
LarsJ Posted February 29, 2016 Author Share Posted February 29, 2016 (edited) A little late reply. But at that time I had simply not enough track of the details to give a proper answer. You can find a description of the ideas here (from post 19 onwards). The UDF will be able to support multiple listviews. At first, I'll create UDFs for a topic at a time. Edited February 29, 2016 by LarsJ x_bennY 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
x_bennY Posted January 30, 2018 Share Posted January 30, 2018 (edited) @LarsJ Are you working on that project? Is it possible to have different cell heights? -------------------- *How could i get the text of a selected item? Tryied with "_GUICtrlListView_GetItemText" but didn't work Solution: local $iIndex = _GUICtrlListView_GetSelectedIndices($idListView) local $txt = _GUICtrlListView_GetItemText ( $idListView, number($iIndex)) msgbox (0, $iIndex, $txt) Edited January 30, 2018 by x_bennY Link to comment Share on other sites More sharing options...
LarsJ Posted January 30, 2018 Author Share Posted January 30, 2018 (edited) I'm still working on new and old listview projects. You cannot have different row heights in a custom drawn listview but it's possible in an owner drawn. I've seen your question of identifying a control that looks like a listview. From the picture, I'm quite sure that it can be implemented as an owner drawn listview. Edited January 30, 2018 by LarsJ x_bennY 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
x_bennY Posted January 30, 2018 Share Posted January 30, 2018 @LarsJ Yeah... i'm trying to do that, it's been hard. I'll wait anxiously for your project! Thx Link to comment Share on other sites More sharing options...
Efo74 Posted March 18, 2018 Share Posted March 18, 2018 Thank you for these wonderful code examples on the listview. Today I modified one of the examples to get a listview with the text on up to 2 lines. Now I'm trying to change the background of the lines alternately. Can anyone help me ?. Is it possible to further simplify the code? Thank you for the support. ModListviewMultiItem.au3 :rolleyes: Link to comment Share on other sites More sharing options...
LarsJ Posted March 19, 2018 Author Share Posted March 19, 2018 I don't think you can use $GUI_BKCOLOR_LV_ALTERNATE flag to create alternating row colors in this listview. The item texts are drawn in the custom draw post paint stage with _WinAPI_DrawText function. Alternating row colors must be implemented in a similar way with _WinAPI_CreateSolidBrush and _WinAPI_FillRect functions. If you search for these functions you should be able to find a number of examples. If you need more help on the details I'll recommend you to ask a question in the General Help and Support forum. I'm busy working on my next project which will be published in this forum the first coming weekend (in five days). Don't miss the Examples forum next weekend. Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
Efo74 Posted March 19, 2018 Share Posted March 19, 2018 Thanks for the support. I will try to study the examples :rolleyes: Link to comment Share on other sites More sharing options...
x_bennY Posted May 1, 2018 Share Posted May 1, 2018 @LarsJ hey! any progress with that project? On 30/01/2018 at 5:06 PM, LarsJ said: I'm still working on new and old listview projects. You cannot have different row heights in a custom drawn listview but it's possible in an owner drawn. I've seen your question of identifying a control that looks like a listview. From the picture, I'm quite sure that it can be implemented as an owner drawn listview. 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