This example is about implementing Rectangular Selection in a listview with mouse and keyboard. By default, listviews only supports selection of entire rows. Either a single row or multiple rows. The purpose of this UDF is also to support selection of a rectangular group of cells. Either a single rectangular group of cells or multiple rectangular groups of cells.
The UDF supports all four types of listviews: The conventional (all examples in the help file), virtual (includes the $LVS_OWNERDATA style), ownerdrawn (includes the $LVS_OWNERDRAWFIXED style) and ownerdrawn+virtual listview.
The examples are all about virtual listviews to verify that the code still works with a large number of additional WM_NOTIFY messages needed to populate a virtual listview. One additional message per cell for all cells visible on a listview page. If a page shows 40 rows and 15 columns, this means 600 additional messages to fill the page with data.
The first post here is about selecting a single rectangular group of cells. The next post is about selecting multiple rectangular groups of cells.
Single selectionSelecting a single rectangular group of cells forming a rectangular selection can be performed by selecting the first corner cell of the rectangle as a fixed starting cell and then selecting the opposite corner cell of the rectangle based on the Single Cell Navigation technique.
The technique of creating a single rectangular selection in this post and of creating multiple rectangular selections in the next post is heavily based on the Single Cell Navigation (SCN) UDF.
The ideas in code to implement resizable GUIs and listviews and the use of multiple listviews are exactly the same in terms of Rectangular Selections as they are in terms of Single Cell Navigation.
And the requirements for a listview to implement Rectangular Selections are the same as the requirements for implementing Single Cell Navigation:
The $LVS_EX_HEADERDRAGDROP style (drag/drop reordering of columns) is not supported.
Zero-width columns are not supported. In the code it's checked that columns are not narrower than 10 pixels.
ExampleThis is the Virtual-SRS.au3 example. The example demonstrates the use of the pure UDF. The rectangle selection is not used in user code. Run the example in SciTE with F5. Right-click listview and select "Single rectangle selection". You should try to create a selection using all four methods described below:
The yellow cell is the active cell that is subject of keyboard navigation.
There are four ways to create a rectangle selection.
Click and drag a selection with the mouse. Releasing the mouse button completes the selection.
The advantage of this method is that it's simple, fast and intuitive. The disadvantage is that it can only be used to make a selection on the current visible page in the listview. When using the mouse to create the selection, you cannot use the mouse on the scrollbars at the same time.
The other three ways uses the Shift key to create the selection. This allows you to continue a selection by pressing the Shift key and performing single cell navigation on the yellow active cell in one of the corners of the current selection. You can also continue a selection started with the Click and drag method above.
The ability to continue a selection allows you to create large selections that span multiple listview pages and navigate the listview with the scrollbars in between each subselection.
The three methods with the Shift key are fully integrated. You can start a selection with one method and continue with another method.
The yellow active cell is the fixed start cell in the selection rectangle. Press the Shift key and
Use keyboard navigation to create the selection rectangle.
Click the opposite corner of the selection rectangle with the mouse. Using the scrollbars, you can navigate around the listview before clicking the opposite corner.
Click and drag a selection with the mouse. Releasing Shift key and mouse button temporarily completes the selection.
Since only a single rectangle selection is supported, a click of the mouse, a movement of the yellow active cell with the keyboard or starting a new selection will immediately delete the current selection.
The codeSingle Rectangle Selection (SRS) is implemented as a UDF in Includes\GuiListViewSRS.au3. GuiListViewSRS.au3 was started as a direct copy of GuiListViewSCN.au3. The UDF contains two functions to enable and disable SRS functionality. The functions starts and stops two message handlers implemented through the subclassing technique that takes care of the actual Single Rectangle Selection. One message handler, SRS_GuiHandler(), takes care of WM_NOTIFY messages (listview and header notifications and messages) sent to the main GUI. The other message handler, SRS_ListViewHandler(), takes care of mouse and keyboard messages sent directly to the listview.
ExamplesRun examples in SciTE with F5.
There are only two examples of single rectangle selections.
Virtual-SRS.au3 is the example shown above.
Virtual-SRS-Ex.au3 is a very simple example of using the rectangle selection in the user code. It's used to draw a corresponding rectangle in the user code. Right-click listview and select "Single rectangle selection" to switch to UDF code. Create a rectangle selection. Right-click listview and select "Default row selection" to switch back to user code. Because the UDF only supports single selections, the rectangle is passed to the user code as item/subitem (row/column) coordinates (indexes) of two opposite corner cells in the rectangle. This means that even a very large rectangle is passed instantly. You should see the rectangel in the user code.
7z-fileThe 7z-file contains source code for UDFs and examples.
You need AutoIt 3.3.12 or later. Tested on Windows 7 and Windows 10.
Comments are welcome. Let me know if there are any issues.
RectangularSelection.7z