Jump to content

Using controls to edit cells in a listview


Recommended Posts

Hello again,

  I'm having some slight difficulty modifying this script.  When I add another ComboBox to the my GUI i'm having difficulty 'separating' the events of the ComboBox Control that appears in the 'ListView' and my other 'standalone' ComboBox Control.  I have modified the 'GUIGetMsg()' routine:

Switch GUIGetMsg()

;...

Case $GUI_EVENT_PRIMARYDOWN, $GUI_EVENT_SECONDARYDOWN

;insert new code here...
if NOT $hListView Then 
$_index_select = _GUICtrlComboBox_GetCurSel($_DB_FIELD)  
  ;read the selected value in the '$_DB_FIELD' ComboBox Control, which is another 'standalone' ComboBox control in the GUI...  
EndIf  ;NOT '$hListView'...

if Not $bComboOpen Then ContinueLoop
if $bListboxOpen Then ContinueLoop
Local $aPos = MouseGetWindowPos($hListView)
 if Not ($aPos[0] > $aRect[0] AND $aPos[0] < $aRect[2] AND $aPos[1] > $aRect[1] AND $aPos[1] < $aRect[1] + 20) Then 
 GUICtrlSendToDummy($idComboClose)  ;Delete ComboBox
 if $aPos[0] > 0 AND $aPos[1] > 0 AND $aPos[0] < $aSize[2] AND $aPos[1] < $aSize[3] Then 
   _WinAPI_SetFocus($hListView)  ;Set focus to ListView if mouse click is inside ListView
 EndIf  

EndSwitch

As you can see i'm trying to separate the 'native' code from this contribution with new code i've added to attempt to manipulate my other Combobox control...by using 'if Not $hListView Then' command...however this part of the routine seems to be ignored and not processed...is there a way to add in the ability to manipulate other controls in the GUI using the same 'WM_NOTIFY' and/or 'GUIGetMsg() functions...?   I thank you in advance for any guidance.  Regards.

Link to post
Share on other sites
  • Replies 49
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

In the forums you can find several questions about how to edit the text in a ListView cell with a standard control eg. an Edit control or a ComboBox. The zip below contains three examples with an Edit

I wish I read these 2 sentences more carefully, instead of debugging during hours the following issue : * Left side of the pic : though editing has started, my mouse pointer keeps its Arrow

After playing around with EditControlKeyboard.au3, I discovered that dragging the first column to a different location prevents this from working correctly. _GUICtrlListView_SetExtendedListVi

Posted Images

$hListView in my part of the code is listview control handle and is not zero. Thus, the code inside the If-statement will never be executed. But maybe you've changed the code.

Post all your code and I'll look into it.

Link to post
Share on other sites

Thanks for the response.  No I did not change the '$hListView' handle, I just mis-understood it...sorry about that.  here is a basic synopsis of the issue I am having recognizing a ComboBox Control that I add to the same (TAB) page the ListView control is within:

$hGui = GUICreate("test", 768, 689), $hEdit, $tEdit
GUISetState(@SW_SHOW, $hGui)

$_THE_TABS = GUICtrlCreateTab(1, 40, 768, 612, BitOR($GUI_SS_DEFAULT_TAB, $TCS_FOCUSONBUTTONDOWN))
GUICtrlSetState($_THE_TABS, $GUI_ENABLE)
GUICtrlSetState($_THE_TABS, $GUI_SHOW)

 $_Startup_TAB = GUICtrlCreateTabItem("Startup")
 
 ;...some stuff
 
 $_DB_TAB = GUICtrlCreateTabItem("Databases")
 
$_DB_FIELD = GUICtrlCreateCombo("", 10, 126, 175, 300)
GUICtrlSetState($_DB_FIELD, $GUI_ENABLE)
GUICtrlSetState($_DB_FIELD, $GUI_SHOW)
GUICtrlComboBox_AddString($_DB_FIELD, String("Testing1")
GUICtrlComboBox_AddString($_DB_FIELD, String("Testing2")

 ;this seems to work to store the 'handles' for the control...
 if _GUICtrlComboBox_GetComboBoxInfor($_DB_FIELD, $tInfo) Then 
 $idTBLCombo = DLLStructGetData($tInfo, "hCombo")
 $idTBLEdit = DLLStructGetData($tInfo, "hEdit")
 $idTBLList = DLLStructGetData($tInfo, "hList")
 EndIf  ;establish handles to structures of the ComboBox Control  
 
 
$idListView = GUICtrlCreateListView("", 10, 300, 400, 180, $GUI_SS_DEFAULT_LISTVIEW-$LVS_SINGLESEL, $WS_EX_CLIENTEDGE)
_GUICtrlListView_SetExtendedListViewStyle($idListView, $LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT+$LVS_EX_HEADERDRAGDROP)
$hHeader = _GUICtrlListView_GetHeader($idListView)
$hListView = GUICtrlGetHandle($idListView)

;CombBox open and close events
$idComboOpen = GUICtrlCreateDummy()
$idComboClose = GUICtrlCreateDummy()

;Handle WM_NOTIFY messages for the ListView
;Open the ComboBox on click/double click
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

;Subclass callback functions
Local $pListViewCallback = DllCallbackGetPtr(DllCallbackRegister("ListViewCallback", "lresult", "hwnd;uint,wparam,lparam,uint_ptr,dword_ptr")) 
Local $pHeaderCallback = DllCallbackGetPtr(DllCallbackRegister("HeaderCallback", "lresult", "hwnd;uint,wparam,lparam,uint_ptr,dword_ptr")) 
Local $pEidtCallback = DllCallbackGetPtr(DllCallbackRegister("EditCallback", "lresult", "hwnd;uint,wparam,lparam,uint_ptr,dword_ptr")) 
Local $pListCommand = DllCallbackGetPtr(DllCallbackRegister("ListCommand", "lresult", "hwnd;uint,wparam,lparam,uint_ptr,dword_ptr")) 
Local $pGuiCallback = DllCallbackGetPtr(DllCallbackRegister("GuiCallback", "lresult", "hwnd;uint,wparam,lparam,uint_ptr,dword_ptr")) 

 
 ...
 
 While 1
 
  Sleep(10)
  
  $_MAIN_MOUSE_ID = GUIGetCursorInfo($hGui)
   if IsArray($_MAIN_MOUSE_ID) == 1 Then 
   $_MAIN_MOUSE_ID = $_MAIN_MOUSE_ID[4]
   $hHandle = ControlGetHandle($hGui, "", $_MAIN_MOUSE_ID)
   
   
   $aMsg = GUIGetMsg($GUI_EVENT_ARRAY)
   
    Switch $aMsg[1]
        Case $hGui
        
            Switch $aMsg[0]
                Case $idTBLCombo
                 MsgBox(0, "$idTBLCombo", "ComboBox clicked")  ;IGNORED...NEVER fires
                Case $idTBLEdit
                 MsgBox(0, "$idTBLEdit", "Edit clicked")  ;IGNORED...NEVER fires
                Case $idTBLList
                 MsgBox(0, "$idTBLList", "List clicked")  ;IGNORED...NEVER fires                 
   
                Case $GUI_EVENT_PRIMARYDOWN, $GUI_EVENT_SECONDARYDOWN
                 
                 if $hHandle <> $hListView Then 
                 consolewrite("Mouse is HOVERED over 'Control Handle': " & $hHandle & @CRLF)  ;works to show handle
                 consolewrite("'$idTBLCombo': " & $idTBLCombo & @CRLF)  ;NEVER fires...
                 consolewrite("'$idTBLEdit': " & $idTBLEdit & @CRLF)  ;will fire if click is inside 'Edit' of the Combox
                 consolewrite("'$idTBLList': " & $idTBLList & @CRLF)  ;only seems to display the area of the GUI after Listbox
                                                                      ;is no longer displayed on the click...
                 EndIf  ;'click' event was NOT on the ListView Control...
   
                 if Not $bComboOpen Then ContinueLoop
                 if $bListboxOpen Then ContinueLoop
                 Local $aPos = MouseGetWindowPos($hListView)
                  if Not ($aPos[0] > $aRect[0] AND $aPos[0] < $aRect[2] AND $aPos[1] > $aRect[1] AND $aPos[1] < $aRect[1] + 20) Then 
                  GUICtrlSendToDummy($idComboClose)  ;Delete ComboBox
                 if $aPos[0] > 0 AND $aPos[1] > 0 AND $aPos[0] < $aSize[2] AND $aPos[1] < $aSize[3] Then 
                 _WinAPI_SetFocus($hListView)  ;Set focus to ListView if mouse click is inside ListView
                 EndIf    
   
            EndSwitch
   
    EndSwitch
   EndIf  ;$_MAIN_MOUSE_ID is an array
   
 Wend

  I thank you in advance for any suggestions...as I noted in the code example above...I seem to be able to recognize a 'click' event within the 'Edit' of my ComboBox only...i'd like to be able to fire off some commands as soon as the selection is made in the 'List' part of the control...when the user clicks one of the items in the dropdown list.  Regards. 

Link to post
Share on other sites

Note that the $idTBLCombo, $idTBLEdit and $idTBLList variables are control handles and therefore can not be used in an AutoIt message loop. Only $_DB_FIELD which is a controlID can be used in an AutoIt message loop.

It's difficult to get events from the listbox in the combo control. Since you only have the listbox control handle you can only get events as WM_COMMAND notifications. And since the listbox is a child of the combo control you need to subclass the combo control to get these WM_COMMAND notifications.

I think the easiest way is to implement your own code first. When your own code works, you can add my code so that you can edit the text in the listview cells.

Link to post
Share on other sites
  • 1 year later...
On 5/14/2016 at 8:59 AM, LarsJ said:

Comments are welcome. Let me know if there are any issues.

Hi LarsJ,
Great functions as always, fantastic documentation (in the Forum and inside the au3 too) :thumbsup:
Could there be a little problem with the horizontal scrolling in EditControlKeyboard.au3 ?

1606435790_LarsJscroll.png.0f1e85ae875dc9ca7d693ec98b52bd5c.png

Starting the Edit with a double-click on any cell in the half-hidden column 4 doesn't scroll totally this column 4 horizontally. It seems to scroll only by 50 pixels, just read that number in Func MakeColumnVisible() :P

I noticed this because I'm working on the same kind of behavior in a never-ending script. The automatical horizontal scrolling seems a bit easier to code for a half-hidden column on the left side, compared to a half-hidden column on the right side where we have to constantly check if a vertical scrollbar is there (or not) to calculate exactly how many pixels are required by the horizontal scroll to have this column on the right side totally visible before the frame is drawn and the edit can start :

1820879806_Pixelscroll.png.caf4c47a9210b1cf08ae31aaf92c33ae.png

But it doesn't seem to be a scrollbar width issue in Func MakeColumnVisible(), maybe you'll tell us the reason :)

Edited by pixelsearch
Link to post
Share on other sites
19 hours ago, pixelsearch said:

Could there be a little problem with the horizontal scrolling in EditControlKeyboard.au3 ?

It depends on how you look at it. One can, eg. change the red texts in this way:

Actual scroll behavior -> Respecting horizontal user scroll as good as possible

Better horizontal scroll -> Overruling user scroll by code more than neccessary

My idea is, as far as I remember, to perform horizontal scrolling in code only if absolutely necessary when there is no space for the control to edit the cell. The 50 pixels is my minimum width for a ComboBox.

The idea of making a column along the left or right edge fully visible when editing could be a good idea when the columns are not too wide. But it may not be the best solution if eg. there are columns that are 1000 pixels wide.

In a specific situation, finding the solution that suits you is not that difficult. This is also why the code here is just examples. It's much more difficult to make a generally applicable UDF. There are a huge variety of situations to take into account.

Link to post
Share on other sites
On 5/14/2016 at 8:59 AM, LarsJ said:

Because the [edit] control is created on top of the ListView cell, it's very important that the ListView is set as the parent window. This ensures that mouse clicks and key presses are captured by the control and not by the ListView.

I wish I read these 2 sentences more carefully, instead of debugging during hours the following issue :

883504432_Mousepointerscompared.png.b0842cef1af466ce5300ad00fd0294f3.png

* Left side of the pic : though editing has started, my mouse pointer keeps its Arrow shape, so you can't click at a certain position inside the edited text (thanks Musashi for reporting this). Of course you can press the home key (or the end key) and the selection disappears, then edit without mouse support (because as soon as you click anywhere in the edit control, the edit automatically ends). Or you can even prevent the cell to be selected by commenting this line :

_GUICtrlEdit_SetSel($hEdit, 0, -1) ; select all text (comment that line if you don't want the text to be selected)

* Right side of the pic : editing has started and LarsJ's mouse pointer is a Text select pointer (as it should be in an edited control), which makes it easier to insert/suppress any character in the middle of the edited text.

I also noticed that in Melba23's UDF (GUIListViewEx.au3), while editing, the mouse pointer appears the same as LarsJ's (a text select pointer), so I decided this afternoon to find the reason why mine was different, no matter how long it would take. Let's start with Melba23, then LarsJ.

=> Melba23 disables the Listview before edit starts, like this :

; Disable ListView
WinSetState($hGLVEx_Editing, "", @SW_DISABLE)

He probably disables it for other reasons but I noticed that, as soon as I commented this line, his mouse pointer turned to an Arrow, like mine !

=> Now LarsJ's turn... step by step, I commented many blocks of code in EditControlKeyboard.au3 and Functions.au3, starting with each of the 3 "Subclass callback functions" (which unfortunately are a bit difficult for me to understand) as I felt that one of the 3 Subclass, when commented, would turn LarsJ's mouse pointer to an Arrow.

Bad luck (or good luck in fact), even with the 3 Subclass code parts commented, his mouse pointer was still a Text select pointer. Anyway, at the very end part of debugging, when few active lines of code remained, I finally found the reason. Here is how I create the Edit control :

$hEdit = _GUICtrlEdit_Create($hGUI, ...

And here is how Lars creates it :

$hEdit = _GUICtrlEdit_Create( $hListView, ...

See the difference ?
Now my mouse pointer wont be an Arrow anymore, though I need to re-adjust the coords of the Edit control :)

Edited by pixelsearch
Link to post
Share on other sites

Create an account or sign in to comment

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

Create an account

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

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...