pdm Posted March 15, 2007 Share Posted March 15, 2007 (edited) Obviously there is no real solution for an editable ListView for AutoIt in this Forum or elsewhere. I could find only half-cooked things all around. Editing only the first column is not that amazing! There are nice grids made from a series of inputboxes but they are very slow when scrolling through a certain amount of lines or columns. Using the Office Web Connector OWC seems to be fine, but requires a valid licence from M$. Since i needed a Listview where all cells can be modified, i made some efforts in using a wandering inputbox on top of a standard ListView. And it works fine (with some restrictions though). Some problems had to be solved with scrolling through the embedded scrollbars and with changing the columnwidth in the header. A bunch of events, notifications and messages had to be taken under control, to close and reopen the editbox after the GUI changes. The most complex "hack" has to do with the scrollbars, which appear when the resulting space for the datacells is not big enough. When the horizontal bar appears, it will automatically reduce the number of displayed lines and forces the vertical bar to appear also. I couldn't find any information whether the one or the other scrollbar is present at all, so i fixed ("a weak fix") it by computing the number of displayed rows and columns and the probability that the bars are there or not. Another solution for this can be the detection of the background-colors on the right hand side of the ListView box. When this is not equal to the left hand side, there must be a scrollbar. Possibly this is not that weak as the assumption-computation, because the dimensions of the scrollbars depend on the users Windows configuration (XP-scheme or not, width of scrollbars, ...). I decided to offer and dedicate the work of several weeks to the people in the forum, since i could also benefit from the code of others. And please, i know that there is someone who knows a better way to manage some of this stuff, let us all know it! Especially if you know how to "see" the scrollbars and the resulting datacell area. Edit: 2007/03/29 Code Updated to version 0.4. expandcollapse popup;ELV - Editable ListView ;8o) pdm V0.4 2007/03/29 #include <GUIConstants.au3> #include <GuiListview.au3> #include <GUICombo.au3> Local Const $WM_NOTIFY = 0x004E Local Const $NM_FIRST = 0 Local Const $NM_CLICK = ($NM_FIRST - 2) Local Const $NM_DBLCLK = ($NM_FIRST - 3) Opt("MustDeclareVars", 1) Opt("GUICloseOnESC", 0) ;The data can be defined by the real application, but then it must be a global reference there. ;Something has to be done with the data, but this is defined by the application, not by the ELV. ;Too bad, that there are no data pointers in AutoIt! Then it could be passed to elv_init(). Global $elv_data[20][4] = [["Me", "1959/10/28", 10, 13.5], ["You", "2009/1/12", 12, 27.8], ["her", "1991/8/26", 17, 17.17], ["him", "1995/7/17", 9, 9.9], _ ["she", "1957/11/1", 8, 8.8], ["it", "1997/7/6", 7, 7.7], ["dau", "2011/10/28", 6, 6.6], ["dummy", "2007/3/29", 5, 5.5]] Global $elv_edit_func[4] = ["l_elv_edit_box", "l_elv_dialogue", "l_elv_combo_box", "l_elv_monthcalendar"] #include "dialogue.au3" Local $elv_listview, $inb_elv, $cmb_elv, $cal_elv, $lbl_zero, $Form1 Local $open = 0, $mouse_click = False Local $editfield_on Local $current_col = -1, $clicked_col = 0 Local $current_x = 0, $current_y = 0 Local $current_row = -1 Local $last_row, $last_col Local $b_use_dbl_click = False Local $cbx_doubleclick Local $countix = 0 Local $elv_dialogue_open = False ;#cs ;drop this stuff when you use it in a real application main () Func main () Local $msg, $str #Region ### START Koda GUI section ### Form=T:\_au3\test\EditableListView\EditableListView.kxf Global $Form1 = GUICreate("ELV - Editable ListView 8o) pdm", 393, 350, 303, 219, BitOR($WS_MAXIMIZEBOX,$WS_MINIMIZEBOX,$WS_SIZEBOX,$WS_THICKFRAME,$WS_SYSMENU,$WS_CAPTION,$WS_OVERLAPPEDWINDOW,$WS_TILEDWINDOW,$WS_POPUPWINDOW,$WS_GROUP,$WS_TABSTOP,$WS_BORDER,$WS_CLIPSIBLINGS)) Global $ListView = GUICtrlCreateListView("Name|Birthday|Count|Startdate", 24, 24, 281, 89, BitOR($LVS_REPORT,$LVS_SINGLESEL,$LVS_SHOWSELALWAYS,$WS_CLIPSIBLINGS), BitOR($LVS_EX_GRIDLINES,$LVS_EX_FULLROWSELECT)) Global $cbx_doubleclick = GUICtrlCreateCheckbox("Use double-click", 24, 152, 113, 25, BitOR($BS_CHECKBOX,$BS_AUTOCHECKBOX,$WS_TABSTOP,$WS_CLIPSIBLINGS)) Global $lbl_zero = GUICtrlCreateLabel("", 0, 0, 4, 4) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### For $l = 0 To 9 GUICtrlCreateListViewItem ($elv_data[$l][0] & "|" & $elv_data[$l][1] & "|" & $elv_data[$l][2] & "|" & $elv_data[$l][3], $ListView) $last_row = $l Next $last_col = UBound($elv_data, 2) - 1 GUIRegisterMsg($WM_NOTIFY, "elv_notify") elv_init ($Listview) GUICtrlSetData ($cmb_elv, "cats|dogs|horses|wales","horses") elv_message ($cbx_doubleclick) ;check for double-click selection While 1 $msg = GUIGetMsg() switch $msg Case $GUI_EVENT_CLOSE ExitLoop case Else elv_message ($msg) EndSwitch WEnd _msg ($elv_data[0][0]&"|"&$elv_data[0][1]&"|"&$elv_data[0][2]&"|"&$elv_data[0][3], 1) elv_exit ($Listview) EndFunc ;==>main ;#ce ;keyboard-savers Func _con($msg, $eol = @CRLF) ConsoleWrite($msg & $eol) EndFunc Func _msg($msg, $time = 0) MsgBox(0, "title", $msg, $time) EndFunc ;This should be taken to GUIListView.au3 ;=============================================================================== ; ; Description: _GUICtrlListViewGetSubItemRect ; Parameter(s): $h_listview - controlID/handle ; $row - item index (0-based) ; $col - subitem index (0-based) ; $left - container for the left-position ; $top - container for the top-position ; $height - container for the height-position ; Requirement: None ; Return Value(s): the real width of the defined cell (not the visible width!) ; User CallTip: _GUICtrlListViewGetSubItemRect($h_listview, $row, $col, ByRef $left, ByRef $top, ByRef $height) Retrieve the rectangle of a cell (required: <GuiListView.au3>) ; Author(s): pdm ; Note(s): published on the forum on 15.3.2007 ; ;=============================================================================== Func _GUICtrlListViewGetSubItemRect($h_listview, $row, $col, ByRef $left, ByRef $top, ByRef $height) Local $rectangle, $rv $rectangle = DllStructCreate("int;int;int;int") ;left, top, right, bottom DllStructSetData($rectangle, 1, $LVIR_BOUNDS) DllStructSetData($rectangle, 2, $col) If IsHWnd($h_listview) Then Local $a_ret = DllCall("user32.dll", "int", "SendMessage", "hwnd", $h_listview, "int", $LVM_GETSUBITEMRECT, "int", $row, "ptr", DllStructGetPtr($rectangle)) $rv = $a_ret[0] Else $rv = GUICtrlSendMsg($h_listview, $LVM_GETSUBITEMRECT, $row, DllStructGetPtr($rectangle)) EndIf $left = DllStructGetData($rectangle, 1) $top = DllStructGetData($rectangle, 2) $height = DllStructGetData($rectangle, 4) - $top $rectangle = 0 Return $rv EndFunc ;==>_GUICtrlListViewGetSubItemRect Func _SetCursorState($bValue = 1) DllCall('User32.dll', 'int', 'ShowCursor', 'int', $bValue) EndFunc ;/////////////////////////////////////// ;elv_init () ; ;prepares the used listview and editbox. ;/////////////////////////////////////// Func elv_init ($lv) $elv_listview = $lv l_elv_edit_box ("create") l_elv_combo_box ("create") l_elv_dialogue ("create") GUISwitch ($Form1) l_elv_monthcalendar ("create") $editfield_on = GUICtrlCreateDummy() ;generate unique code for the message handling l_elv_edit_quit() EndFunc ;//////////////////////////// ;elv_exit () ; ;destroys all created objects ;//////////////////////////// Func elv_exit ($lv) $elv_listview = "" l_elv_edit_box ("delete") l_elv_combo_box ("delete") l_elv_dialogue ("delete") GUISwitch ($Form1) l_elv_monthcalendar ("delete") $editfield_on = "" EndFunc ;//////////////////////////////////////////////////////// ;elv_message() ; ;is called from the message-loop of the application above ;//////////////////////////////////////////////////////// func elv_message ($msg) Local $rv if $elv_dialogue_open Then $rv = elv_dialogue_msg ($msg) if $rv <> $msg Then if $rv = 0 Then _con ("cal quit") l_elv_edit_quit () Else _con ("cal save") l_elv_edit_save () EndIf return EndIf Endif Switch $msg Case $cbx_doubleclick if GUICtrlRead ($msg) = $GUI_UNCHECKED Then $b_use_dbl_click = False Else $b_use_dbl_click = True EndIf Case $elv_listview ;_con ("lv-msg") Case $inb_elv, $cmb_elv, $cal_elv ;_con ("edit-msg") l_elv_edit_save() Case $editfield_on l_elv_edit_on() Case 0, -7, -8, -11, -12 Case Else _con("msg=" & $msg); EndSwitch EndFunc ;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ;elv_notify() ; ;is called from the applications notification function or can be registered with GUIRegisterMsg($WM_NOTIFY, "elv_notify") directly ;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Func elv_notify ($hWndGUI, $MsgID, $wParam, $lParam) #forceref $hWndGUI, $MsgID, $wParam Local $tagNMHDR, $event, $tagNMITEMACTIVATE, $rv $rv = $GUI_RUNDEFMSG $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code) If @error Then Return $event = DllStructGetData($tagNMHDR, 3) $rv = 0 Switch $wParam Case $elv_listview Switch $event Case $NM_CLICK l_elv_ListView_Click($elv_listview) Case $NM_DBLCLK l_elv_ListView_DoubleClick($elv_listview) Case -121 ;click inside the listview data area $tagNMITEMACTIVATE = DllStructCreate("int;int;int;int;int;int;int;int;int", $lParam) $clicked_col = DllStructGetData($tagNMITEMACTIVATE, 5) $tagNMITEMACTIVATE = 0 Case - 108, -177, -180, -181 ;header-click, horizontal scroll, vertical scroll up and down l_elv_edit_save() Case Else ;_con ("lvw evnt="& $event) EndSwitch Case $inb_elv Switch $event Case 0 Case Else ;_con ("inb evnt="& $event) EndSwitch case $cal_elv _con ("cal evnt="& $event) Case Else Switch $event Case - 322, -328 ;changes in column width l_elv_edit_save() Case Else _con ("ctrl "& $hWndGUI &" evnt="& $event) EndSwitch EndSwitch $tagNMHDR = 0 $event = 0 $lParam = 0 Return $rv EndFunc ;/////////////////////////// ;l_elv_edit_box() ; ;use an inputbox for editing ;/////////////////////////// func l_elv_edit_box ($cmd, $left_col = 0, $top_row = 0, $width = 0, $height = 0) switch $cmd case "create" $inb_elv = GUICtrlCreateInput ("", 0, 0, 0, 0, BitOR($ES_AUTOHSCROLL,$ES_NOHIDESEL,$WS_BORDER), 0) GUICtrlSetState ($inb_elv, $GUI_HIDE) GUICtrlSetBkColor($inb_elv, 0xC0DCC0) case "delete" $inb_elv = "" case "pos" ; _GUICtrlListViewSetItemSelState($elv_listview, $current_row, 1, 0) GUICtrlSetPos ($inb_elv, $left_col + 4, $top_row + 4, $width, $height) case "hide" HotKeySet("{Enter}") HotKeySet("{TAB}") HotKeySet("+{TAB}") HotKeySet("{DOWN}") HotKeySet("{UP}") HotKeySet("{ESC}") GUICtrlSetState ($inb_elv, $GUI_HIDE) case "show" GUICtrlSetState ($inb_elv, $GUI_SHOW + $GUI_ONTOP + $GUI_FOCUS) case "get" return GUICtrlRead ($inb_elv) case "set" GUICtrlSetData ($inb_elv, $elv_data[$top_row][$left_col]) HotKeySet("{Enter}", "l_elv_edit_right") HotKeySet("{TAB}", "l_elv_edit_right") HotKeySet("+{TAB}", "l_elv_edit_left") HotKeySet("{DOWN}", "l_elv_edit_down") HotKeySet("{UP}", "l_elv_edit_up") HotKeySet("{ESC}", "l_elv_edit_esc") EndSwitch EndFunc ;/////////////////////////// ;l_elv_combo_box() ; ;use a combobox for editing ;/////////////////////////// func l_elv_combo_box ($cmd, $left_col = 0, $top_row = 0, $width = 0, $height = 0) Local $str, $a_xy[2] _con ("combo_box ("& $cmd &", "& $left_col &", "& $top_row &", "& $width &", "& $height &")") switch $cmd case "create" $cmb_elv = GUICtrlCreateCombo ("", 0, 0, 0, 0, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL,$CBS_SORT)) GUICtrlSetState ($cmb_elv, $GUI_HIDE) case "delete" $cmb_elv = "" case "pos" GUICtrlSetPos ($cmb_elv, $left_col + 4, $top_row + 2, $width, $height) $mouse_click = False case "hide" HotKeySet("{Enter}") HotKeySet("{TAB}") HotKeySet("+{TAB}") HotKeySet("{ESC}") GUICtrlSetState ($cmb_elv, $GUI_HIDE) case "show" GUICtrlSetState ($cmb_elv, $GUI_SHOW + $GUI_ONTOP) case "get" return GUICtrlRead ($cmb_elv) case "set" $str = $elv_data[$top_row][$left_col] GUICtrlSetData ($cmb_elv, $str, $elv_data[$top_row][$left_col]) HotKeySet("{Enter}", "l_elv_edit_right") HotKeySet("{TAB}", "l_elv_edit_right") HotKeySet("+{TAB}", "l_elv_edit_left") HotKeySet("{ESC}", "l_elv_edit_esc") EndSwitch EndFunc ;/////////////////////////////////////////// ;l_elv_monthcalendar () ; ;use a monthcalendar to enter a certain date ;/////////////////////////////////////////// func l_elv_monthcalendar ($cmd, $left_col = 0, $top_row = 0, $width = 0, $height = 0) Local $str, $a_xy[2] $countix += 1 _con ("monthcalendar ("& $cmd &", "& $left_col &", "& $top_row &", "& $width &", "& $height &") count="& $countix) switch $cmd case "create" $cal_elv = GUICtrlCreateMonthCal ("1959/10/28", -10000, -10000, 170, 170) ;create outside to avoid flicker GUICtrlSetState ($cal_elv, $GUI_HIDE) case "delete" $cal_elv = "" case "pos" GUICtrlSetPos ($cal_elv, $left_col, $top_row) $mouse_click = False case "hide" HotKeySet("{Enter}") HotKeySet("{TAB}") HotKeySet("+{TAB}") HotKeySet("{ESC}") HotKeySet("{DOWN}") HotKeySet("{UP}") GUICtrlSetState ($cal_elv, $GUI_HIDE) case "show" GUICtrlSetState ($cal_elv, $GUI_SHOW + $GUI_ONTOP + $GUI_FOCUS) GUICtrlSetStyle ($cal_elv, -1, $WS_EX_TOPMOST) case "get" return GUICtrlRead ($cal_elv) case "set" $str = $elv_data[$top_row][$left_col] GUICtrlSetData ($cal_elv, $str, $elv_data[$top_row][$left_col]) HotKeySet("{Enter}", "l_elv_edit_right") HotKeySet("{TAB}", "l_elv_edit_right") HotKeySet("+{TAB}", "l_elv_edit_left") HotKeySet("{ESC}", "l_elv_edit_esc") HotKeySet("{DOWN}", "l_elv_edit_down") HotKeySet("{UP}", "l_elv_edit_up") EndSwitch EndFunc ;//////////////////////// ;l_elv_dialogue () ; ;use a seperate dialogbox ;//////////////////////// func l_elv_dialogue ($cmd, $left_col = 0, $top_row = 0, $width = 0, $height = 0) Local $str, $a_xy[2] $countix += 1 _con ("dialogue ("& $cmd &", "& $left_col &", "& $top_row &", "& $width &", "& $height &") count="& $countix) switch $cmd case "create" elv_dialogue ($cmd) case "delete" elv_dialogue ($cmd) case "pos" elv_dialogue ($cmd, $left_col, $top_row, $lbl_zero) ;lbl_zero must be on position 0,0 in the form containing the listview $mouse_click = False case "hide" HotKeySet("{Enter}") HotKeySet("{TAB}") HotKeySet("+{TAB}") HotKeySet("{ESC}") HotKeySet("{DOWN}") HotKeySet("{UP}") elv_dialogue ($cmd) $elv_dialogue_open = False case "show" elv_dialogue ($cmd) $elv_dialogue_open = True case "get" return elv_dialogue ($cmd) case "set" elv_dialogue ($cmd, $elv_data[$top_row][$left_col]) HotKeySet("{Enter}", "l_elv_edit_right") HotKeySet("{TAB}", "l_elv_edit_right") HotKeySet("+{TAB}", "l_elv_edit_left") HotKeySet("{ESC}", "l_elv_edit_esc") HotKeySet("{DOWN}", "l_elv_edit_down") HotKeySet("{UP}", "l_elv_edit_up") EndSwitch EndFunc Func l_elv_edit_save () If $open = 2 Then ;_con ("save open="& $open) $elv_data[$current_row][$current_col] = call ($elv_edit_func[$current_col], "get") ;GUICtrlRead($inb_elv) _GUICtrlListViewSetItemText ($elv_listview, $current_row, $current_col, $elv_data[$current_row][$current_col]) $open = 1 EndIf l_elv_edit_quit () EndFunc ;==>l_edit_save Func l_elv_edit_quit () If $open <> 0 Then ;_con ("quit open="& $open) call ($elv_edit_func[$current_col], "hide") ;GUICtrlSetState($inb_elv, $GUI_HIDE) GUICtrlSetState($elv_listview, $GUI_ONTOP + $GUI_FOCUS) $open = 0 EndIf If $mouse_click Then $mouse_click = False if $b_use_dbl_click Then Local $a_xy[1] $a_xy = MouseGetPos () MouseClick ("left", $a_xy[0], $a_xy[1], 2) Else MouseClick ("left") EndIf EndIf EndFunc ;==>l_edit_quit Func l_elv_ListView_Click ($lv) if $b_use_dbl_click Then $mouse_click = False l_elv_edit_save () Else l_elv_start_edit () EndIf EndFunc ;==>ListView_Click Func l_elv_ListView_DoubleClick ($lv) if $b_use_dbl_click Then l_elv_start_edit () Else ; EndIf EndFunc func l_elv_start_edit () ;_con ("lv click open="& $open &" clicked col="& $clicked_col) If $clicked_col < 0 Then _con("off mcl=" & $mouse_click) l_elv_edit_save () Return EndIf If $open = 2 Then l_elv_edit_save () ElseIf $open = 1 Then Return EndIf $open = 1 $mouse_click = True l_elv_prepare_edit (_GUICtrlListViewGetCurSel ($elv_listview), $clicked_col) EndFunc ;==>ListView_DoubleClick Func l_elv_prepare_edit ($row, $col) Local $left, $top, $height, $width, $lvw, $a_coord[4], $str, $shift, $colw, $rowh, $vs, $hs, $hh, $sw, $sh ;_con ("prepare open="& $open) $current_row = $row If $current_row < 0 Then ;$current_row = 0 Return EndIf $current_col = $col If $current_col < 0 Then $current_col = 0 _GUICtrlListViewEnsureVisible ($elv_listview, $current_row, 0) $width = _GUICtrlListViewGetColumnWidth ($elv_listview, $current_col) _GUICtrlListViewGetSubItemRect ($elv_listview, $current_row, $current_col, $left, $top, $height) $colw = $width + 2 If $current_col = $last_col Then For $c = 0 To $current_col - 1 $colw += _GUICtrlListViewGetColumnWidth ($elv_listview, $c) + 1 ;+1 for the gridline Next EndIf Opt("GUICoordMode", 0) $a_coord = ControlGetPos ("", "", $elv_listview) ;get coordinates of ListView (x, y, w, h) Opt("GUICoordMode", 1) If Not IsArray ($a_coord) Then Return EndIf $str = _ArrayToString ($a_coord, "/") $lvw = $a_coord[2] ;w $hh = 20 $sw = 24 $sh = 20 ;Under certain conditions, vertical and/or horizontal scrollbars will be displayed. ;The vertical bar reduces the usable width, which can force the horizontal bar to appear. ;The horizontal scrollbar reduces the number of displayed lines and can force a vertical bar to be shown. ;These conditions will affect the editfield in the last column. $rowh = $last_row * ($height + 1) + ($height - 5) ;+1 for the gridline +extra for partial height of last line If $rowh > ($a_coord[3] - $hh) Then $vs = $sw ;vertical slider exists Else $vs = 0 EndIf If $colw > ($a_coord[2] - $vs) Then $hs = $sh ;horizontal slider exists Else $hs = 0 EndIf If $rowh > ($a_coord[3] - $hh - $hs + 4) Then ;+extra due to hysteresis when horizontal bar exists and vertical one still not $vs = $sw ;vertical slider exists EndIf ;_con ($last_row &" rows height "& $height+1 &" *="& $rowh &" hi="& $a_coord[3] &" vs="& $vs &" hs="& $hs) $lvw -= $vs ;w - sliderwidth $shift = 0 If $left > $lvw Then If $width > $lvw Then $width = $lvw $shift = 0 - $left $left = 0 Else $shift = $left - $lvw + $width $left -= $shift EndIf ElseIf $left < 0 Then If $width > $lvw Then $width = $lvw $shift = $left $left = 0 Else $shift = $left $left = 0 EndIf ElseIf $left + $width > $lvw Then If $width > $lvw Then $width = $lvw $shift = 0 - $left $left = 0 Else $shift = $left - $lvw + $width $left -= $shift EndIf EndIf If $shift <> 0 Then _GUICtrlListViewScroll ($elv_listview, $shift, 0) EndIf ;_con ("lv x/y/w/h="& $str &" left="& $left &" top="& $top &" wid="& $width &" hei="& $height &" shift="& $shift &" lvw="& $lvw) _GUICtrlListViewSetItemSelState($elv_listview, $current_row, 1, 0) call ($elv_edit_func[$current_col], "pos", $left + $a_coord[0], $top + $a_coord[1], $width, $height) ;GUICtrlSetPos($inb_elv, $left + $a_coord[0] + 4, $top + $a_coord[1] + 5, $width, $height + 0) $open = 1 GUICtrlSendToDummy ($editfield_on) ;start edit-field EndFunc ;==>l_prepare_edit Func l_elv_edit_on () ;_con ("on open="& $open) call ($elv_edit_func[$current_col], "show") ;GUICtrlSetState($inb_elv, $GUI_SHOW + $GUI_ONTOP + $GUI_FOCUS) call ($elv_edit_func[$current_col], "set", $current_col, $current_row) ;GUICtrlSetData($inb_elv, $elv_data[$current_row][$current_col]) $open = 2 EndFunc ;==>l_edit_on func l_elv_edit_esc () $mouse_click = False l_elv_edit_quit () EndFunc Func l_elv_edit_right () Local $col, $row $row = $current_row $col = $current_col If $col < $last_col Then $col += 1 Else $col = 0 $row += 1 EndIf If $row <= $last_row Then l_elv_edit_save () l_elv_prepare_edit ($row, $col) EndIf EndFunc ;==>l_edit_right Func l_elv_edit_left () Local $col, $row $row = $current_row $col = $current_col If $col > 0 Then $col -= 1 Else $row -= 1 $col = $last_col EndIf If $row >= 0 Then l_elv_edit_save () l_elv_prepare_edit ($row, $col) EndIf EndFunc ;==>l_edit_left Func l_elv_edit_down () If $current_row < $last_row Then l_elv_edit_save () l_elv_prepare_edit ($current_row + 1, $current_col) EndIf EndFunc ;==>l_edit_down Func l_elv_edit_up () If $current_row > 0 Then l_elv_edit_save () l_elv_prepare_edit ($current_row - 1, $current_col) EndIf EndFunc ;==>l_edit_up //////////////////////////////////////////////////////////////////////////////////////////////////////// ;cut this here and put it into dialogue.au3 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\ Local $l_cal_on = False Local $l_org_date = "" Local $l_cal_id Local $l_dia_width, $l_dia_height Local $l_ret_empty = False Local $btn_dia_cancel, $btn_dia_ok, $btn_dia_empty, $frm_calendar, $MonthCal1, $tab_calendar, $frm_calender ;//////////////////////////////////////////////////////////// ;elv_dialogue () ; ;is called from the column-specific function l_elv_dialogue() ;it has a variable number of arguments ;//////////////////////////////////////////////////////////// func elv_dialogue ($cmd, $arg1 = 0, $arg2 = 0, $arg3 = 0) Local $a_coord[4], $hwnd, $x, $y switch $cmd case "create" if $l_cal_on Then return 0 EndIf #Region ### START Koda GUI section ### Form=T:\_au3\test\EditableListView\dialogue.kxf Global $frm_calendar = GUICreate("Calendar", 272, 218, 367, 236, BitOR($WS_CLIPCHILDREN,$WS_CLIPSIBLINGS), $WS_EX_TOOLWINDOW) GUISetIcon("D:09.ico") Global $MonthCal1 = GUICtrlCreateMonthCal("2007/03/27", 8, 8, 185, 177, -1, 0) Global $btn_dia_cancel = GUICtrlCreateButton("X", 232, 8, 25, 25, 0) GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif") Global $btn_dia_ok = GUICtrlCreateButton("OK", 208, 160, 49, 25, 0) Global $btn_dia_empty = GUICtrlCreateButton("Empty", 208, 128, 49, 25, 0) #EndRegion ### END Koda GUI section ### $l_cal_on = True WinMove ($frm_calendar, "", -10000, -10000) ;create outside visible area to avoid flicker GUISetState (@SW_SHOW) WinSetState ($frm_calender, "", @SW_HIDE) $a_coord = WinGetPos ($frm_calendar) ;to keep the dialogue completely visible, we need the real width and height $l_dia_width = $a_coord[2] $l_dia_height = $a_coord[3] case "delete" if not $l_cal_on Then return 0 EndIf GUIDelete ($frm_calendar) $l_cal_on = False case "pos" ;arg1=left arg2=top arg3=lbl_zero $hwnd = ControlGetHandle ( "", "", $arg3) ;get the handle for the lbl_zero, which is at position 0,0 of the application form $a_coord = WinGetPos ($hwnd) ;we need the absolute coordinates of the inner edge of the form $x = $a_coord[0]+ $arg1 + 4 ;add the relative x of the current listview cell $y = $a_coord[1] + $arg2 + 2 ;add the relative y of the current listview cell if $x + $l_dia_width > @DesktopWidth Then $x = @DesktopWidth - $l_dia_width ;keep away from the right screen border EndIf if $y + $l_dia_height > @DesktopHeight Then $y = @DesktopHeight - $l_dia_height - 32 ;-32:assume visible taskbar EndIf WinMove ($frm_calendar, "", $x, $y) $l_ret_empty = False case "hide" WinSetState ($frm_calendar, "", @SW_HIDE) case "show" WinSetState ($frm_calendar, "", @SW_SHOW) case "get" if $l_ret_empty Then return "" EndIf return GUICtrlRead ($MonthCal1) case "set" ;arg1=date $l_org_date = $arg1 GUICtrlSetData ($MonthCal1, $arg1, $arg1) EndSwitch return 0 EndFunc ;/////////////////////////////////////////////////////////////// ;l_elv_dialogue_msg () ; ;this is called from the message handler of the EditableListView ;/////////////////////////////////////////////////////////////// func elv_dialogue_msg ($msg) Local $rv switch $msg case $btn_dia_cancel $rv = 0 case $btn_dia_ok $rv = 1 case $btn_dia_empty $l_ret_empty = True $rv = 1 case Else $rv = $msg EndSwitch return $rv EndFunc I'm still working on improvements to the code above. I want to develop a configuration for every column, which allows to take either an editbox, a combo, a calendar, fileselection or another dialog to enter data into the cells. The whole thing is alive for me, because i'm working (more or less payed) on a management tool for a private school. There are a lot of dialogs to be developed for the various requirements. The tool is an add-on to the commercial product "Magellan", which uses FireBird as SQL-database. This is the prerequisite to run several programs or instances that share the same data. One of my modules manages the user-accounts in the ActiveDirectory automatically from a list of pupils, RTF- and Word-templates are used for mailmerge and various printed lists, and a lot of other things will follow. And all is realized with AutoIt. I love it! Edited March 29, 2007 by pdm Link to comment Share on other sites More sharing options...
MrCreatoR Posted March 15, 2007 Share Posted March 15, 2007 Wow, its realy working! (edit all columns!). Thanks! But... maybe somehow possible make that the edit will activated on dowble click, not on the first click? (like the original way). Spoiler Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1 AutoIt Russian Community My Work... Spoiler Projects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize ProgramUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF Examples: ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating ) * === My topics === * ================================================== ================================================== AutoIt is simple, subtle, elegant. © AutoIt Team Link to comment Share on other sites More sharing options...
pdm Posted March 16, 2007 Author Share Posted March 16, 2007 Wow, its realy working! (edit all columns!). Thanks!But... maybe somehow possible make that the edit will activated on dowble click, not on the first click? (like the original way).Hello MsCreatoR!If you want to start the editing on a double-click basis, you have to move the code from function ListView_Click($lv) into ListView_DoubleClick($lv), but then there will be a problem with the simulated mouse-click in l_edit_quit(). This must be changed to produce a double-click, to re-enter the editfield again. I didn't test this.Btw, who defined the original way you mentioned? In Excel, which is a de-facto standard (like OpenCalc), you simple move to a cell and start editing. I think it's obvious, that my ListView is an editable area, why should a double-click make it easier for the user?I also thought about another way of testing the presence of the vertical scrollbar. The color-checking left and right may work, but there is another problem when all columns together are smaller than the window. The selection only covers the real columns, so that the rest of the line remains at the default background. But i'm still busy with that... Link to comment Share on other sites More sharing options...
MrCreatoR Posted March 16, 2007 Share Posted March 16, 2007 pdmHi,Btw, who defined the original way you mentioned? In Excel, which is a de-facto standard (like OpenCalc), you simple move to a cell and start editing. I think it's obvious, that my ListView is an editable area, why should a double-click make it easier for the user?I meant the original way that in the editable mode of AutoIt's edit control (and of many windows's programs controls) ...But if we look at the “user's convinient”, then it must be like that:I am selecting the item, and i do not want to edit it, just want to get the selection (maby the program retrievs some info when user select the item), and if i do want edit certain item, then i click on it again and wait a few milliseconds (maybe second is fine) untill the item expanded to editable mode - this is the “convinient way” - IMHO. Spoiler Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1 AutoIt Russian Community My Work... Spoiler Projects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize ProgramUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF Examples: ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating ) * === My topics === * ================================================== ================================================== AutoIt is simple, subtle, elegant. © AutoIt Team Link to comment Share on other sites More sharing options...
PantZ4 Posted March 18, 2007 Share Posted March 18, 2007 Very usefull! Woundring if you could turn this into a "include" file so you could make a editable ListView by one command. _GUICtrlCreateEditListView . Anyway great job! Link to comment Share on other sites More sharing options...
pdm Posted March 23, 2007 Author Share Posted March 23, 2007 Thank you for the responses! I cannot react daily, since i'm working on this for my school. But it continues, evolves, grows, ... I improved the editable ListView a bit. Due to the fact, that this is not the application, but part of one, i had to make the interface more clear. Function beginning with "l_" are used only locally (a "private"-scope for functions would be fine!), while the ones starting with "elv_" will form the interface to the "real" application. Additionally, i added a configuration for every column, so that the user may choose to take a combobox in any column to enter data from a list. This is a self-learning object, it adds any manually entered value to the combo-list. And i added an option for the fans of double-clicking (like MsCreatoR) . The functions l_elv_edit_box() and l_elv_combo_box() can be use as templates for other input dialogues. Please let me know, when somebody of you adds more stuff like this. To use a certain dialogue, insert its name into $elv_edit_func[] at the column position of your choice and call it from elv_init() to "create" the resources. If you need notifications, add the required code to elv_notify() . The same applies for messaged in elv_message(). There is a problem with the combo: the box is only shown completely, after the mouse is moved. I tried to automate this, but it was not stable. Sometimes the box appeared, sometimes not, but id did every time after i moved the mouse manually. Maybe it's some timing effect. I hope that somebody is out there to help? expandcollapse popup;ELV - Editable ListView ;8o) pdm #include <GUIConstants.au3> #include <GuiListview.au3> #include <GUICombo.au3> Local Const $WM_NOTIFY = 0x004E Local Const $NM_FIRST = 0 Local Const $NM_CLICK = ($NM_FIRST - 2) Local Const $NM_DBLCLK = ($NM_FIRST - 3) Opt("MustDeclareVars", 1) Opt("GUICloseOnESC", 0) ;The data can be defined by the real application, but then it must be a global reference there. ;Something has to be done with the data, but this is defined by the application, not by the ELV. ;Too bad, that there are no data pointers in AutoIt! Then it could be passed to elv_init(). Global $elv_data[20][3] = [["Me", 10, 13.5], ["You", 12, 27.8], ["her", 17, 17.17], ["him", 9, 9.9], ["she", 8, 8.8], ["it", 7, 7.7], ["dau", 6, 6.6], ["dummy", 5, 5.5]] Global $elv_edit_func[3] = ["l_elv_edit_box", "l_elv_combo_box", "l_elv_edit_box"] Local $elv_listview, $inb_elv, $cmb_elv Local $open = 0, $mouse_click = False Local $editfield_on Local $current_col = -1, $clicked_col = 0 Local $current_x = 0, $current_y = 0 Local $current_row = -1 Local $last_row, $last_col Local $b_use_dbl_click = False Local $cbx_doubleclick ;#cs ;drop this stuff when you use it in a real application main () Func main () Local $msg, $str #Region ### START Koda GUI section ### Form=T:\_au3\test\ListViewEdit\ListViewEdit.kxf Global $Form1 = GUICreate("AForm1", 393, 212, 303, 219, BitOR($WS_MAXIMIZEBOX,$WS_MINIMIZEBOX,$WS_SIZEBOX,$WS_THICKFRAME,$WS_SYSMENU,$WS_CAPTION,$WS_OVERLAPPEDWINDOW,$WS_TILEDWINDOW,$WS_POPUPWINDOW,$WS_GROUP,$WS_TABSTOP,$WS_HSCROLL,$WS_VSCROLL,$WS_BORDER,$WS_CLIPSIBLINGS)) Global $ListView = GUICtrlCreateListView("Name|Rounds|Total", 24, 24, 281, 89, -1, BitOR($LVS_EX_GRIDLINES,$LVS_EX_FULLROWSELECT)) Global $cbx_doubleclick = GUICtrlCreateCheckbox("Use double-click", 24, 152, 113, 25) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### For $l = 0 To 9 GUICtrlCreateListViewItem ($elv_data[$l][0] & "|" & $elv_data[$l][1] & "|" & $elv_data[$l][2], $ListView) $last_row = $l Next $last_col = UBound($elv_data, 2) - 1 GUIRegisterMsg($WM_NOTIFY, "elv_notify") elv_init ($Listview) GUICtrlSetData ($cmb_elv, "cats|dogs|horses|wales","horses") elv_message ($cbx_doubleclick) ;check for double-click selection While 1 $msg = GUIGetMsg() switch $msg Case $GUI_EVENT_CLOSE ExitLoop case Else elv_message ($msg) EndSwitch WEnd _msg ($elv_data[0][0]&"|"&$elv_data[0][1]&"|"&$elv_data[0][2]) EndFunc ;==>main ;#ce ;keyboard-savers Func _con($msg, $eol = @CRLF) ConsoleWrite($msg & $eol) EndFunc Func _msg($msg, $time = 0) MsgBox(0, "title", $msg, $time) EndFunc ;This should be taken to GUIListView.au3 ;=============================================================================== ; ; Description: _GUICtrlListViewGetSubItemRect ; Parameter(s): $h_listview - controlID/handle ; $row - item index (0-based) ; $col - subitem index (0-based) ; $left - container for the left-position ; $top - container for the top-position ; $height - container for the height-position ; Requirement: None ; Return Value(s): the real width of the defined cell (not the visible width!) ; User CallTip: _GUICtrlListViewGetSubItemRect($h_listview, $row, $col, ByRef $left, ByRef $top, ByRef $height) Retrieve the rectangle of a cell (required: <GuiListView.au3>) ; Author(s): pdm ; Note(s): published on the forum on 15.3.2007 ; ;=============================================================================== Func _GUICtrlListViewGetSubItemRect($h_listview, $row, $col, ByRef $left, ByRef $top, ByRef $height) Local $rectangle, $rv $rectangle = DllStructCreate("int;int;int;int") ;left, top, right, bottom DllStructSetData($rectangle, 1, $LVIR_BOUNDS) DllStructSetData($rectangle, 2, $col) If IsHWnd($h_listview) Then Local $a_ret = DllCall("user32.dll", "int", "SendMessage", "hwnd", $h_listview, "int", $LVM_GETSUBITEMRECT, "int", $row, "ptr", DllStructGetPtr($rectangle)) $rv = $a_ret[0] Else $rv = GUICtrlSendMsg($h_listview, $LVM_GETSUBITEMRECT, $row, DllStructGetPtr($rectangle)) EndIf $left = DllStructGetData($rectangle, 1) $top = DllStructGetData($rectangle, 2) $height = DllStructGetData($rectangle, 4) - $top $rectangle = 0 Return $rv EndFunc ;==>_GUICtrlListViewGetSubItemRect Func _SetCursorState($bValue = 1) DllCall('User32.dll', 'int', 'ShowCursor', 'int', $bValue) EndFunc ;/////////////////////////////////////// ;elv_init () ; ;prepares the used listview and editbox. ;/////////////////////////////////////// Func elv_init ($lv) $elv_listview = $lv l_elv_edit_box ("create") l_elv_combo_box ("create") $editfield_on = GUICtrlCreateDummy() ;generate unique code for the message handling l_elv_edit_quit() EndFunc ;//////////////////////////////////////////////////////// ;elv_message() ; ;is called from the message-loop of the application above ;//////////////////////////////////////////////////////// func elv_message ($msg) Switch $msg Case $cbx_doubleclick if GUICtrlRead ($msg) = $GUI_UNCHECKED Then $b_use_dbl_click = False Else $b_use_dbl_click = True EndIf Case $elv_listview ;_con ("lv-msg") Case $inb_elv, $cmb_elv ;_con ("edit-msg") l_elv_edit_save() Case $editfield_on l_elv_edit_on() Case 0, -7, -8, -11, -12 Case Else _con("msg=" & $msg); EndSwitch EndFunc ;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ;elv_notify() ; ;is called from the applications notification function or can be registered with GUIRegisterMsg($WM_NOTIFY, "elv_notify") directly ;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Func elv_notify ($hWndGUI, $MsgID, $wParam, $lParam) #forceref $hWndGUI, $MsgID, $wParam Local $tagNMHDR, $event, $tagNMITEMACTIVATE, $rv $rv = $GUI_RUNDEFMSG $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code) If @error Then Return $event = DllStructGetData($tagNMHDR, 3) $rv = 0 Switch $wParam Case $elv_listview Switch $event Case $NM_CLICK l_elv_ListView_Click($elv_listview) Case $NM_DBLCLK l_elv_ListView_DoubleClick($elv_listview) Case - 121 ;click inside the listview data area $tagNMITEMACTIVATE = DllStructCreate("int;int;int;int;int;int;int;int;int", $lParam) $clicked_col = DllStructGetData($tagNMITEMACTIVATE, 5) $tagNMITEMACTIVATE = 0 Case - 108, -177, -180, -181 ;header-click, horizontal scroll, vertical scroll up and down l_elv_edit_save() Case Else ;_con ("lvw evnt="& $event) EndSwitch Case $inb_elv Switch $event Case 0 Case Else ;_con ("inb evnt="& $event) EndSwitch Case Else Switch $event Case - 322, -328 ;changes in column width l_elv_edit_save() Case Else _con ("ctrl "& $hWndGUI &" evnt="& $event) EndSwitch EndSwitch $tagNMHDR = 0 $event = 0 $lParam = 0 Return $rv EndFunc ;/////////////////////////// ;l_elv_edit_box() ; ;use an inputbox for editing ;/////////////////////////// func l_elv_edit_box ($cmd, $left_col = 0, $top_row = 0, $width = 0, $height = 0) switch $cmd case "create" $inb_elv = GUICtrlCreateInput ("", 0, 0, 0, 0, BitOR($ES_AUTOHSCROLL,$ES_NOHIDESEL,$WS_BORDER), 0) GUICtrlSetState ($inb_elv, $GUI_HIDE) GUICtrlSetBkColor($inb_elv, 0xC0DCC0) case "pos" ; _GUICtrlListViewSetItemSelState($elv_listview, $current_row, 1, 0) GUICtrlSetPos ($inb_elv, $left_col + 4, $top_row + 4, $width, $height) case "hide" GUICtrlSetState ($inb_elv, $GUI_HIDE) case "show" GUICtrlSetState ($inb_elv, $GUI_SHOW + $GUI_ONTOP + $GUI_FOCUS) case "get" return GUICtrlRead ($inb_elv) case "set" GUICtrlSetData ($inb_elv, $elv_data[$top_row][$left_col]) EndSwitch EndFunc ;/////////////////////////// ;l_elv_combo_box() ; ;use a combobox for editing ;/////////////////////////// func l_elv_combo_box ($cmd, $left_col = 0, $top_row = 0, $width = 0, $height = 0) Local $str, $a_xy[2] _con ("combo_box ("& $cmd &", "& $left_col &", "& $top_row &", "& $width &", "& $height &")") switch $cmd case "create" $cmb_elv = GUICtrlCreateCombo ("", 184, 120, 113, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL,$CBS_SORT)) GUICtrlSetState ($cmb_elv, $GUI_HIDE) case "pos" ;Opt ("MouseCoordMode", 2) ;$a_xy = MouseGetPos () ;Opt ("MouseCoordMode", 1) ;$current_x = $a_xy[0] ;$current_y = $a_xy[1] GUICtrlSetPos ($cmb_elv, $left_col + 4, $top_row + 2, $width, $height) $mouse_click = False case "hide" GUICtrlSetState ($cmb_elv, $GUI_HIDE) case "show" GUICtrlSetState ($cmb_elv, $GUI_SHOW + $GUI_ONTOP) case "get" return GUICtrlRead ($cmb_elv) case "set" $str = $elv_data[$top_row][$left_col] ;&"|"& _GUICtrlComboGetList ($cmb_elv) GUICtrlSetData ($cmb_elv, $str, $elv_data[$top_row][$left_col]) EndSwitch EndFunc Func l_elv_edit_save () If $open = 2 Then ;_con ("save open="& $open) $elv_data[$current_row][$current_col] = call ($elv_edit_func[$current_col], "get") ;GUICtrlRead($inb_elv) _GUICtrlListViewSetItemText ($elv_listview, $current_row, $current_col, $elv_data[$current_row][$current_col]) $open = 1 EndIf l_elv_edit_quit () EndFunc ;==>l_edit_save Func l_elv_edit_quit () If $open <> 0 Then ;_con ("quit open="& $open) call ($elv_edit_func[$current_col], "hide") ;GUICtrlSetState($inb_elv, $GUI_HIDE) GUICtrlSetState($elv_listview, $GUI_ONTOP + $GUI_FOCUS) $open = 0 HotKeySet("{Enter}") HotKeySet("{TAB}") HotKeySet("+{TAB}") HotKeySet("{DOWN}") HotKeySet("{UP}") HotKeySet("{ESC}") EndIf If $mouse_click Then $mouse_click = False if $b_use_dbl_click Then Local $a_xy[1] $a_xy = MouseGetPos () MouseClick ("left", $a_xy[0], $a_xy[1], 2) Else MouseClick ("left") EndIf EndIf EndFunc ;==>l_edit_quit Func l_elv_ListView_Click ($lv) if $b_use_dbl_click Then $mouse_click = False l_elv_edit_save () Else l_elv_start_edit () EndIf EndFunc ;==>ListView_Click Func l_elv_ListView_DoubleClick ($lv) if $b_use_dbl_click Then l_elv_start_edit () Else ; EndIf EndFunc func l_elv_start_edit () ;_con ("lv click open="& $open &" clicked col="& $clicked_col) If $clicked_col < 0 Then _con("off mcl=" & $mouse_click) l_elv_edit_save () Return EndIf If $open = 2 Then l_elv_edit_save () ElseIf $open = 1 Then Return EndIf $open = 1 $mouse_click = True l_elv_prepare_edit (_GUICtrlListViewGetCurSel ($elv_listview), $clicked_col) EndFunc ;==>ListView_DoubleClick Func l_elv_prepare_edit ($row, $col) Local $left, $top, $height, $width, $lvw, $a_coord[4], $str, $shift, $colw, $rowh, $vs, $hs, $hh, $sw, $sh ;_con ("prepare open="& $open) $current_row = $row If $current_row < 0 Then ;$current_row = 0 Return EndIf $current_col = $col If $current_col < 0 Then $current_col = 0 _GUICtrlListViewEnsureVisible ($elv_listview, $current_row, 0) $width = _GUICtrlListViewGetColumnWidth ($elv_listview, $current_col) _GUICtrlListViewGetSubItemRect ($elv_listview, $current_row, $current_col, $left, $top, $height) $colw = $width + 2 If $current_col = $last_col Then For $c = 0 To $current_col - 1 $colw += _GUICtrlListViewGetColumnWidth ($elv_listview, $c) + 1 ;+1 for the gridline Next EndIf $a_coord = ControlGetPos ("", "", $elv_listview) ;get coordinates of ListView (x, y, w, h) If Not IsArray ($a_coord) Then Return EndIf $str = _ArrayToString ($a_coord, "/") $lvw = $a_coord[2] ;w local $colorl, $colorr, $x1, $y, $x2 $x1 = $a_coord[0] + 10 $x2 = $a_coord[0] + $a_coord[2] - 10 $y = $top + $a_coord[1] + 4 ;_con ("lv x/y/w/h="& $str &" left="& $left &" top="& $top &" wid="& $width &" hei="& $height &" lvw="& $lvw &" colw="& $colw) $hh = 20 $sw = 24 $sh = 20 ;Under certain conditions, vertical and/or horizontal scrollbars will be displayed. ;The vertical bar reduces the usable width, which can force the horizontal bar to appear. ;The horizontal scrollbar reduces the number of displayed lines and can force a vertical bar to be shown. ;These conditions will affect the editfield in the last column. $rowh = $last_row * ($height + 1) + ($height - 5) ;+1 for the gridline +extra for partial height of last line If $rowh > ($a_coord[3] - $hh) Then $vs = $sw ;vertical slider exists Else $vs = 0 EndIf If $colw > ($a_coord[2] - $vs) Then $hs = $sh ;horizontal slider exists Else $hs = 0 EndIf If $rowh > ($a_coord[3] - $hh - $hs + 4) Then ;+extra due to hysteresis when horizontal bar exists and vertical one still not $vs = $sw ;vertical slider exists EndIf ;_con ($last_row &" rows height "& $height+1 &" *="& $rowh &" hi="& $a_coord[3] &" vs="& $vs &" hs="& $hs) $lvw -= $vs ;w - sliderwidth $shift = 0 If $left > $lvw Then If $width > $lvw Then $width = $lvw $shift = 0 - $left $left = 0 Else $shift = $left - $lvw + $width $left -= $shift EndIf ElseIf $left < 0 Then If $width > $lvw Then $width = $lvw $shift = $left $left = 0 Else $shift = $left $left = 0 EndIf ElseIf $left + $width > $lvw Then If $width > $lvw Then $width = $lvw $shift = 0 - $left $left = 0 Else $shift = $left - $lvw + $width $left -= $shift EndIf EndIf If $shift <> 0 Then _GUICtrlListViewScroll ($elv_listview, $shift, 0) EndIf ;_con ("lv x/y/w/h="& $str &" left="& $left &" top="& $top &" wid="& $width &" hei="& $height &" shift="& $shift &" lvw="& $lvw) _GUICtrlListViewSetItemSelState($elv_listview, $current_row, 1, 0) call ($elv_edit_func[$current_col], "pos", $left + $a_coord[0], $top + $a_coord[1], $width, $height) ;GUICtrlSetPos($inb_elv, $left + $a_coord[0] + 4, $top + $a_coord[1] + 5, $width, $height + 0) $open = 1 GUICtrlSendToDummy ($editfield_on) ;start edit-field EndFunc ;==>l_prepare_edit Func l_elv_edit_on () ;_con ("on open="& $open) call ($elv_edit_func[$current_col], "show") ;GUICtrlSetState($inb_elv, $GUI_SHOW + $GUI_ONTOP + $GUI_FOCUS) call ($elv_edit_func[$current_col], "set", $current_col, $current_row) ;GUICtrlSetData($inb_elv, $elv_data[$current_row][$current_col]) HotKeySet("{Enter}", "l_elv_edit_right") HotKeySet("{TAB}", "l_elv_edit_right") HotKeySet("+{TAB}", "l_elv_edit_left") HotKeySet("{DOWN}", "l_elv_edit_down") HotKeySet("{UP}", "l_elv_edit_up") HotKeySet("{ESC}", "l_elv_edit_esc") $open = 2 EndFunc ;==>l_edit_on func l_elv_edit_esc () $mouse_click = False l_elv_edit_quit () EndFunc Func l_elv_edit_right () Local $col, $row $row = $current_row $col = $current_col If $col < $last_col Then $col += 1 Else $col = 0 $row += 1 EndIf If $row <= $last_row Then l_elv_edit_save () l_elv_prepare_edit ($row, $col) EndIf EndFunc ;==>l_edit_right Func l_elv_edit_left () Local $col, $row $row = $current_row $col = $current_col If $col > 0 Then $col -= 1 Else $row -= 1 $col = $last_col EndIf If $row >= 0 Then l_elv_edit_save () l_elv_prepare_edit ($row, $col) EndIf EndFunc ;==>l_edit_left Func l_elv_edit_down () If $current_row < $last_row Then l_elv_edit_save () l_elv_prepare_edit ($current_row + 1, $current_col) EndIf EndFunc ;==>l_edit_down Func l_elv_edit_up () If $current_row > 0 Then l_elv_edit_save () l_elv_prepare_edit ($current_row - 1, $current_col) EndIf EndFunc ;==>l_edit_up PS: I would like to update the code in my first post, but i there is no edit-button!? Link to comment Share on other sites More sharing options...
MrCreatoR Posted March 23, 2007 Share Posted March 23, 2007 PS: I would like to update the code in my first post, but i there is no edit-button!?When you loged-in, you will see this button at buttom of your post - Spoiler Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1 AutoIt Russian Community My Work... Spoiler Projects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize ProgramUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF Examples: ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating ) * === My topics === * ================================================== ================================================== AutoIt is simple, subtle, elegant. © AutoIt Team Link to comment Share on other sites More sharing options...
pdm Posted March 27, 2007 Author Share Posted March 27, 2007 When you loged-in, you will see this button at buttom of your post - This Edit-button is not available for me. The help pages say that this happens after a certain time has elapsed or when an administrator has not allowed me to edit my posts. I guess it's the second reason, because i'm still treated as a "newbie" . But there are also good news: When i tried to add a month calendar, i saw that it's area was overwritten by the listview, while the part outside the listview area was visible. So i remembered the "Z-Order" which is responsible for the layers of objects. I searched in the forum and came to a post from "holger" in the year 2004 where he wrote about the style $WS_CLIPSIBLINGS. After a little research in the MSDN everything was clear. This style must be applied to all objects that can be covered by other objects complete or partially. Only then the objects above are not overwritten due to the WM_PAINT message. I added this constant to the listview and some other elements of my test GUI and it works! Here is the actual code: _linenums:0'>expandcollapse popup;ELV - Editable ListView ;8o) pdm v0.3 #include #include #include Local Const $WM_NOTIFY = 0x004E Local Const $NM_FIRST = 0 Local Const $NM_CLICK = ($NM_FIRST - 2) Local Const $NM_DBLCLK = ($NM_FIRST - 3) Opt("MustDeclareVars", 1) Opt("GUICloseOnESC", 0) ;The data can be defined by the real application, but then it must be a global reference there. ;Something has to be done with the data, but this is defined by the application, not by the ELV. ;Too bad, that there are no data pointers in AutoIt! Then it could be passed to elv_init(). Global $elv_data[20][3] = [["Me", 10, 13.5], ["You", 12, 27.8], ["her", 17, 17.17], ["him", 9, 9.9], ["she", 8, 8.8], ["it", 7, 7.7], ["dau", 6, 6.6], ["dummy", 5, 5.5]] Global $elv_edit_func[3] = ["l_elv_edit_box", "l_elv_calendar", "l_elv_combo_box"] Local $elv_listview, $inb_elv, $cmb_elv, $cal_elv Local $open = 0, $mouse_click = False Local $editfield_on Local $current_col = -1, $clicked_col = 0 Local $current_x = 0, $current_y = 0 Local $current_row = -1 Local $last_row, $last_col Local $b_use_dbl_click = False Local $cbx_doubleclick Local $countix = 0 ;#cs ;drop this stuff when you use it in a real application main () Func main () Local $msg, $str #Region ### START Koda GUI section ### Form=T:\_au3\test\ListViewEdit\ListViewEdit.kxf Global $Form1 = GUICreate("AForm1", 393, 357, 303, 219, BitOR($WS_MAXIMIZEBOX,$WS_MINIMIZEBOX,$WS_SIZEBOX,$WS_THICKFRAME,$WS_SYSMENU,$WS_CAPTION,$WS_OVERLAPPEDWINDOW,$WS_TILEDWINDOW,$WS_POPUPWINDOW,$WS_GROUP,$WS_TABSTOP,$WS_BORDER,$WS_CLIPSIBLINGS)) Global $ListView = GUICtrlCreateListView("Name|Rounds|Total", 24, 24, 281, 89, BitOR($LVS_REPORT,$LVS_SINGLESEL,$LVS_SHOWSELALWAYS,$WS_CLIPSIBLINGS), BitOR($LVS_EX_GRIDLINES,$LVS_EX_FULLROWSELECT)) Global $cbx_doubleclick = GUICtrlCreateCheckbox("Use double-click", 24, 152, 113, 25, BitOR($BS_CHECKBOX,$BS_AUTOCHECKBOX,$WS_TABSTOP,$WS_CLIPSIBLINGS)) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### For $l = 0 To 9 GUICtrlCreateListViewItem ($elv_data[$l][0] & "|" & $elv_data[$l][1] & "|" & $elv_data[$l][2], $ListView) $last_row = $l Next $last_col = UBound($elv_data, 2) - 1 GUIRegisterMsg($WM_NOTIFY, "elv_notify") elv_init ($Listview) GUICtrlSetData ($cmb_elv, "cats|dogs|horses|wales","horses") elv_message ($cbx_doubleclick) ;check for double-click selection While 1 $msg = GUIGetMsg() switch $msg Case $GUI_EVENT_CLOSE ExitLoop case Else elv_message ($msg) EndSwitch WEnd _msg ($elv_data[0][0]&"|"&$elv_data[0][1]&"|"&$elv_data[0][2]) EndFunc ;==>main ;#ce ;keyboard-savers Func _con($msg, $eol = @CRLF) ConsoleWrite($msg & $eol) EndFunc Func _msg($msg, $time = 0) MsgBox(0, "title", $msg, $time) EndFunc ;This should be taken to GUIListView.au3 ;=============================================================================== ; ; Description: _GUICtrlListViewGetSubItemRect ; Parameter(s): $h_listview - controlID/handle ; $row - item index (0-based) ; $col - subitem index (0-based) ; $left - container for the left-position ; $top - container for the top-position ; $height - container for the height-position ; Requirement: None ; Return Value(s): the real width of the defined cell (not the visible width!) ; User CallTip: _GUICtrlListViewGetSubItemRect($h_listview, $row, $col, ByRef $left, ByRef $top, ByRef $height) Retrieve the rectangle of a cell (required: ) ; Author(s): pdm ; Note(s): published on the forum on 15.3.2007 ; ;=============================================================================== Func _GUICtrlListViewGetSubItemRect($h_listview, $row, $col, ByRef $left, ByRef $top, ByRef $height) Local $rectangle, $rv $rectangle = DllStructCreate("int;int;int;int") ;left, top, right, bottom DllStructSetData($rectangle, 1, $LVIR_BOUNDS) DllStructSetData($rectangle, 2, $col) If IsHWnd($h_listview) Then Local $a_ret = DllCall("user32.dll", "int", "SendMessage", "hwnd", $h_listview, "int", $LVM_GETSUBITEMRECT, "int", $row, "ptr", DllStructGetPtr($rectangle)) $rv = $a_ret[0] Else $rv = GUICtrlSendMsg($h_listview, $LVM_GETSUBITEMRECT, $row, DllStructGetPtr($rectangle)) EndIf $left = DllStructGetData($rectangle, 1) $top = DllStructGetData($rectangle, 2) $height = DllStructGetData($rectangle, 4) - $top $rectangle = 0 Return $rv EndFunc ;==>_GUICtrlListViewGetSubItemRect Func _SetCursorState($bValue = 1) DllCall('User32.dll', 'int', 'ShowCursor', 'int', $bValue) EndFunc ;/////////////////////////////////////// ;elv_init () ; ;prepares the used listview and editbox. ;/////////////////////////////////////// Func elv_init ($lv) $elv_listview = $lv l_elv_edit_box ("create") l_elv_combo_box ("create") l_elv_calendar ("create") $editfield_on = GUICtrlCreateDummy() ;generate unique code for the message handling l_elv_edit_quit() EndFunc ;//////////////////////////////////////////////////////// ;elv_message() ; ;is called from the message-loop of the application above ;//////////////////////////////////////////////////////// func elv_message ($msg) Switch $msg Case $cbx_doubleclick if GUICtrlRead ($msg) = $GUI_UNCHECKED Then $b_use_dbl_click = False Else $b_use_dbl_click = True EndIf Case $elv_listview ;_con ("lv-msg") Case $inb_elv, $cmb_elv, $cal_elv ;_con ("edit-msg") l_elv_edit_save() Case $editfield_on l_elv_edit_on() Case 0, -7, -8, -11, -12 Case Else _con("msg=" & $msg); EndSwitch EndFunc ;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ;elv_notify() ; ;is called from the applications notification function or can be registered with GUIRegisterMsg($WM_NOTIFY, "elv_notify") directly ;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Func elv_notify ($hWndGUI, $MsgID, $wParam, $lParam) #forceref $hWndGUI, $MsgID, $wParam Local $tagNMHDR, $event, $tagNMITEMACTIVATE, $rv $rv = $GUI_RUNDEFMSG $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code) If @error Then Return $event = DllStructGetData($tagNMHDR, 3) $rv = 0 Switch $wParam Case $elv_listview Switch $event Case $NM_CLICK l_elv_ListView_Click($elv_listview) Case $NM_DBLCLK l_elv_ListView_DoubleClick($elv_listview) Case -121 ;click inside the listview data area $tagNMITEMACTIVATE = DllStructCreate("int;int;int;int;int;int;int;int;int", $lParam) $clicked_col = DllStructGetData($tagNMITEMACTIVATE, 5) $tagNMITEMACTIVATE = 0 Case - 108, -177, -180, -181 ;header-click, horizontal scroll, vertical scroll up and down l_elv_edit_save() Case Else ;_con ("lvw evnt="& $event) EndSwitch Case $inb_elv Switch $event Case 0 Case Else ;_con ("inb evnt="& $event) EndSwitch case $cal_elv _con ("cal evnt="& $event) Case Else Switch $event Case - 322, -328 ;changes in column width l_elv_edit_save() Case Else _con ("ctrl "& $hWndGUI &" evnt="& $event) EndSwitch EndSwitch $tagNMHDR = 0 $event = 0 $lParam = 0 Return $rv EndFunc ;/////////////////////////// ;l_elv_edit_box() ; ;use an inputbox for editing ;/////////////////////////// func l_elv_edit_box ($cmd, $left_col = 0, $top_row = 0, $width = 0, $height = 0) switch $cmd case "create" $inb_elv = GUICtrlCreateInput ("", 0, 0, 0, 0, BitOR($ES_AUTOHSCROLL,$ES_NOHIDESEL,$WS_BORDER), 0) GUICtrlSetState ($inb_elv, $GUI_HIDE) GUICtrlSetBkColor($inb_elv, 0xC0DCC0) case "pos" ; _GUICtrlListViewSetItemSelState($elv_listview, $current_row, 1, 0) GUICtrlSetPos ($inb_elv, $left_col + 4, $top_row + 4, $width, $height) case "hide" HotKeySet("{Enter}") HotKeySet("{TAB}") HotKeySet("+{TAB}") HotKeySet("{DOWN}") HotKeySet("{UP}") HotKeySet("{ESC}") GUICtrlSetState ($inb_elv, $GUI_HIDE) case "show" GUICtrlSetState ($inb_elv, $GUI_SHOW + $GUI_ONTOP + $GUI_FOCUS) case "get" return GUICtrlRead ($inb_elv) case "set" GUICtrlSetData ($inb_elv, $elv_data[$top_row][$left_col]) HotKeySet("{Enter}", "l_elv_edit_right") HotKeySet("{TAB}", "l_elv_edit_right") HotKeySet("+{TAB}", "l_elv_edit_left") HotKeySet("{DOWN}", "l_elv_edit_down") HotKeySet("{UP}", "l_elv_edit_up") HotKeySet("{ESC}", "l_elv_edit_esc") EndSwitch EndFunc ;/////////////////////////// ;l_elv_combo_box() ; ;use a combobox for editing ;/////////////////////////// func l_elv_combo_box ($cmd, $left_col = 0, $top_row = 0, $width = 0, $height = 0) Local $str, $a_xy[2] _con ("combo_box ("& $cmd &", "& $left_col &", "& $top_row &", "& $width &", "& $height &")") switch $cmd case "create" $cmb_elv = GUICtrlCreateCombo ("", 0, 0, 0, 0, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL,$CBS_SORT)) GUICtrlSetState ($cmb_elv, $GUI_HIDE) case "pos" GUICtrlSetPos ($cmb_elv, $left_col + 4, $top_row + 2, $width, $height) $mouse_click = False case "hide" HotKeySet("{Enter}") HotKeySet("{TAB}") HotKeySet("+{TAB}") HotKeySet("{ESC}") GUICtrlSetState ($cmb_elv, $GUI_HIDE) case "show" GUICtrlSetState ($cmb_elv, $GUI_SHOW + $GUI_ONTOP) case "get" return GUICtrlRead ($cmb_elv) case "set" $str = $elv_data[$top_row][$left_col] GUICtrlSetData ($cmb_elv, $str, $elv_data[$top_row][$left_col]) HotKeySet("{Enter}", "l_elv_edit_right") HotKeySet("{TAB}", "l_elv_edit_right") HotKeySet("+{TAB}", "l_elv_edit_left") HotKeySet("{ESC}", "l_elv_edit_esc") EndSwitch EndFunc func l_elv_calendar ($cmd, $left_col = 0, $top_row = 0, $width = 0, $height = 0) Local $str, $a_xy[2] $countix += 1 _con ("calendar ("& $cmd &", "& $left_col &", "& $top_row &", "& $width &", "& $height &") count="& $countix) switch $cmd case "create" $cal_elv = GUICtrlCreateMonthCal ("1959/10/28", 10, 10, 170, 170) GUICtrlSetState ($cal_elv, $GUI_HIDE) case "pos" GUICtrlSetPos ($cal_elv, $left_col, $top_row) $mouse_click = False case "hide" HotKeySet("{Enter}") HotKeySet("{TAB}") HotKeySet("+{TAB}") HotKeySet("{ESC}") HotKeySet("{DOWN}") HotKeySet("{UP}") GUICtrlSetState ($cal_elv, $GUI_HIDE) case "show" GUICtrlSetState ($cal_elv, $GUI_SHOW + $GUI_ONTOP + $GUI_FOCUS) GUICtrlSetStyle ($cal_elv, -1, $WS_EX_TOPMOST) case "get" return GUICtrlRead ($cal_elv) case "set" $str = $elv_data[$top_row][$left_col] GUICtrlSetData ($cal_elv, $str, $elv_data[$top_row][$left_col]) HotKeySet("{Enter}", "l_elv_edit_right") HotKeySet("{TAB}", "l_elv_edit_right") HotKeySet("+{TAB}", "l_elv_edit_left") HotKeySet("{ESC}", "l_elv_edit_esc") HotKeySet("{DOWN}", "l_elv_edit_save") HotKeySet("{UP}", "l_elv_edit_save") EndSwitch EndFunc Func l_elv_edit_save () If $open = 2 Then ;_con ("save open="& $open) $elv_data[$current_row][$current_col] = call ($elv_edit_func[$current_col], "get") ;GUICtrlRead($inb_elv) _GUICtrlListViewSetItemText ($elv_listview, $current_row, $current_col, $elv_data[$current_row][$current_col]) $open = 1 EndIf l_elv_edit_quit () EndFunc ;==>l_edit_save Func l_elv_edit_quit () If $open <> 0 Then ;_con ("quit open="& $open) call ($elv_edit_func[$current_col], "hide") ;GUICtrlSetState($inb_elv, $GUI_HIDE) GUICtrlSetState($elv_listview, $GUI_ONTOP + $GUI_FOCUS) $open = 0 EndIf If $mouse_click Then $mouse_click = False if $b_use_dbl_click Then Local $a_xy[1] $a_xy = MouseGetPos () MouseClick ("left", $a_xy[0], $a_xy[1], 2) Else MouseClick ("left") EndIf EndIf EndFunc ;==>l_edit_quit Func l_elv_ListView_Click ($lv) if $b_use_dbl_click Then $mouse_click = False l_elv_edit_save () Else l_elv_start_edit () EndIf EndFunc ;==>ListView_Click Func l_elv_ListView_DoubleClick ($lv) if $b_use_dbl_click Then l_elv_start_edit () Else ; EndIf EndFunc func l_elv_start_edit () ;_con ("lv click open="& $open &" clicked col="& $clicked_col) If $clicked_col < 0 Then _con("off mcl=" & $mouse_click) l_elv_edit_save () Return EndIf If $open = 2 Then l_elv_edit_save () ElseIf $open = 1 Then Return EndIf $open = 1 $mouse_click = True l_elv_prepare_edit (_GUICtrlListViewGetCurSel ($elv_listview), $clicked_col) EndFunc ;==>ListView_DoubleClick Func l_elv_prepare_edit ($row, $col) Local $left, $top, $height, $width, $lvw, $a_coord[4], $str, $shift, $colw, $rowh, $vs, $hs, $hh, $sw, $sh ;_con ("prepare open="& $open) $current_row = $row If $current_row < 0 Then ;$current_row = 0 Return EndIf $current_col = $col If $current_col < 0 Then $current_col = 0 _GUICtrlListViewEnsureVisible ($elv_listview, $current_row, 0) $width = _GUICtrlListViewGetColumnWidth ($elv_listview, $current_col) _GUICtrlListViewGetSubItemRect ($elv_listview, $current_row, $current_col, $left, $top, $height) $colw = $width + 2 If $current_col = $last_col Then For $c = 0 To $current_col - 1 $colw += _GUICtrlListViewGetColumnWidth ($elv_listview, $c) + 1 ;+1 for the gridline Next EndIf $a_coord = ControlGetPos ("", "", $elv_listview) ;get coordinates of ListView (x, y, w, h) If Not IsArray ($a_coord) Then Return EndIf $str = _ArrayToString ($a_coord, "/") $lvw = $a_coord[2] ;w local $colorl, $colorr, $x1, $y, $x2 $x1 = $a_coord[0] + 10 $x2 = $a_coord[0] + $a_coord[2] - 10 $y = $top + $a_coord[1] + 4 ;_con ("lv x/y/w/h="& $str &" left="& $left &" top="& $top &" wid="& $width &" hei="& $height &" lvw="& $lvw &" colw="& $colw) $hh = 20 $sw = 24 $sh = 20 ;Under certain conditions, vertical and/or horizontal scrollbars will be displayed. ;The vertical bar reduces the usable width, which can force the horizontal bar to appear. ;The horizontal scrollbar reduces the number of displayed lines and can force a vertical bar to be shown. ;These conditions will affect the editfield in the last column. $rowh = $last_row * ($height + 1) + ($height - 5) ;+1 for the gridline +extra for partial height of last line If $rowh > ($a_coord[3] - $hh) Then $vs = $sw ;vertical slider exists Else $vs = 0 EndIf If $colw > ($a_coord[2] - $vs) Then $hs = $sh ;horizontal slider exists Else $hs = 0 EndIf If $rowh > ($a_coord[3] - $hh - $hs + 4) Then ;+extra due to hysteresis when horizontal bar exists and vertical one still not $vs = $sw ;vertical slider exists EndIf ;_con ($last_row &" rows height "& $height+1 &" *="& $rowh &" hi="& $a_coord[3] &" vs="& $vs &" hs="& $hs) $lvw -= $vs ;w - sliderwidth $shift = 0 If $left > $lvw Then If $width > $lvw Then $width = $lvw $shift = 0 - $left $left = 0 Else $shift = $left - $lvw + $width $left -= $shift EndIf ElseIf $left < 0 Then If $width > $lvw Then $width = $lvw $shift = $left $left = 0 Else $shift = $left $left = 0 EndIf ElseIf $left + $width > $lvw Then If $width > $lvw Then $width = $lvw $shift = 0 - $left $left = 0 Else $shift = $left - $lvw + $width $left -= $shift EndIf EndIf If $shift <> 0 Then _GUICtrlListViewScroll ($elv_listview, $shift, 0) EndIf ;_con ("lv x/y/w/h="& $str &" left="& $left &" top="& $top &" wid="& $width &" hei="& $height &" shift="& $shift &" lvw="& $lvw) _GUICtrlListViewSetItemSelState($elv_listview, $current_row, 1, 0) call ($elv_edit_func[$current_col], "pos", $left + $a_coord[0], $top + $a_coord[1], $width, $height) ;GUICtrlSetPos($inb_elv, $left + $a_coord[0] + 4, $top + $a_coord[1] + 5, $width, $height + 0) $open = 1 GUICtrlSendToDummy ($editfield_on) ;start edit-field EndFunc ;==>l_prepare_edit Func l_elv_edit_on () ;_con ("on open="& $open) call ($elv_edit_func[$current_col], "show") ;GUICtrlSetState($inb_elv, $GUI_SHOW + $GUI_ONTOP + $GUI_FOCUS) call ($elv_edit_func[$current_col], "set", $current_col, $current_row) ;GUICtrlSetData($inb_elv, $elv_data[$current_row][$current_col]) $open = 2 EndFunc ;==>l_edit_on func l_elv_edit_esc () $mouse_click = False l_elv_edit_quit () EndFunc Func l_elv_edit_right () Local $col, $row $row = $current_row $col = $current_col If $col < $last_col Then $col += 1 Else $col = 0 $row += 1 EndIf If $row <= $last_row Then l_elv_edit_save () l_elv_prepare_edit ($row, $col) EndIf EndFunc ;==>l_edit_right Func l_elv_edit_left () Local $col, $row $row = $current_row $col = $current_col If $col > 0 Then $col -= 1 Else $row -= 1 $col = $last_col EndIf If $row >= 0 Then l_elv_edit_save () l_elv_prepare_edit ($row, $col) EndIf EndFunc ;==>l_edit_left Func l_elv_edit_down () If $current_row < $last_row Then l_elv_edit_save () l_elv_prepare_edit ($current_row + 1, $current_col) EndIf EndFunc ;==>l_edit_down Func l_elv_edit_up () If $current_row > 0 Then l_elv_edit_save () l_elv_prepare_edit ($current_row - 1, $current_col) EndIf EndFunc ;==>l_edit_up I still have to find out how the calendar can be closed with the mouse. It works when you click into the visible part of the listview area or by hitting the RETURN key. A click onto a certain day causes a message, but then the user can revert a false selection only by reentering the calendar again. I think about a double-click to take the date over the listview. The next thing i want to realize is a dialogue that allows any other form of selections. I need to have this feature to select a person from different database tables (pupils, teachers, parents, others), which requires a bit more than a combobox... Link to comment Share on other sites More sharing options...
pdm Posted March 29, 2007 Author Share Posted March 29, 2007 And another version again! Now i added a dialogue box which allows to enter a date or an empty string to get rid of one. This is the most flexible way to enter data, because it only depends on the dialogue GUI and function what is written to the ListView cell. Here is the actual code: Take care! This also contains the code for dialogue.au3, the code for the entry dialogue. You can also download the attached ZIP-file EditableListView04.zip with the .au3- and .kxf-sources. expandcollapse popup;ELV - Editable ListView ;8o) pdm V0.4 2007/03/29 #include <GUIConstants.au3> #include <GuiListview.au3> #include <GUICombo.au3> Local Const $WM_NOTIFY = 0x004E Local Const $NM_FIRST = 0 Local Const $NM_CLICK = ($NM_FIRST - 2) Local Const $NM_DBLCLK = ($NM_FIRST - 3) Opt("MustDeclareVars", 1) Opt("GUICloseOnESC", 0) ;The data can be defined by the real application, but then it must be a global reference there. ;Something has to be done with the data, but this is defined by the application, not by the ELV. ;Too bad, that there are no data pointers in AutoIt! Then it could be passed to elv_init(). Global $elv_data[20][4] = [["Me", "1959/10/28", 10, 13.5], ["You", "2009/1/12", 12, 27.8], ["her", "1991/8/26", 17, 17.17], ["him", "1995/7/17", 9, 9.9], _ ["she", "1957/11/1", 8, 8.8], ["it", "1997/7/6", 7, 7.7], ["dau", "2011/10/28", 6, 6.6], ["dummy", "2007/3/29", 5, 5.5]] Global $elv_edit_func[4] = ["l_elv_edit_box", "l_elv_dialogue", "l_elv_combo_box", "l_elv_monthcalendar"] #include "dialogue.au3" Local $elv_listview, $inb_elv, $cmb_elv, $cal_elv, $lbl_zero, $Form1 Local $open = 0, $mouse_click = False Local $editfield_on Local $current_col = -1, $clicked_col = 0 Local $current_x = 0, $current_y = 0 Local $current_row = -1 Local $last_row, $last_col Local $b_use_dbl_click = False Local $cbx_doubleclick Local $countix = 0 Local $elv_dialogue_open = False ;#cs ;drop this stuff when you use it in a real application main () Func main () Local $msg, $str #Region ### START Koda GUI section ### Form=T:\_au3\test\EditableListView\EditableListView.kxf Global $Form1 = GUICreate("ELV - Editable ListView 8o) pdm", 393, 350, 303, 219, BitOR($WS_MAXIMIZEBOX,$WS_MINIMIZEBOX,$WS_SIZEBOX,$WS_THICKFRAME,$WS_SYSMENU,$WS_CAPTION,$WS_OVERLAPPEDWINDOW,$WS_TILEDWINDOW,$WS_POPUPWINDOW,$WS_GROUP,$WS_TABSTOP,$WS_BORDER,$WS_CLIPSIBLINGS)) Global $ListView = GUICtrlCreateListView("Name|Birthday|Count|Startdate", 24, 24, 281, 89, BitOR($LVS_REPORT,$LVS_SINGLESEL,$LVS_SHOWSELALWAYS,$WS_CLIPSIBLINGS), BitOR($LVS_EX_GRIDLINES,$LVS_EX_FULLROWSELECT)) Global $cbx_doubleclick = GUICtrlCreateCheckbox("Use double-click", 24, 152, 113, 25, BitOR($BS_CHECKBOX,$BS_AUTOCHECKBOX,$WS_TABSTOP,$WS_CLIPSIBLINGS)) Global $lbl_zero = GUICtrlCreateLabel("", 0, 0, 4, 4) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### For $l = 0 To 9 GUICtrlCreateListViewItem ($elv_data[$l][0] & "|" & $elv_data[$l][1] & "|" & $elv_data[$l][2] & "|" & $elv_data[$l][3], $ListView) $last_row = $l Next $last_col = UBound($elv_data, 2) - 1 GUIRegisterMsg($WM_NOTIFY, "elv_notify") elv_init ($Listview) GUICtrlSetData ($cmb_elv, "cats|dogs|horses|wales","horses") elv_message ($cbx_doubleclick) ;check for double-click selection While 1 $msg = GUIGetMsg() switch $msg Case $GUI_EVENT_CLOSE ExitLoop case Else elv_message ($msg) EndSwitch WEnd _msg ($elv_data[0][0]&"|"&$elv_data[0][1]&"|"&$elv_data[0][2]&"|"&$elv_data[0][3], 1) elv_exit ($Listview) EndFunc ;==>main ;#ce ;keyboard-savers Func _con($msg, $eol = @CRLF) ConsoleWrite($msg & $eol) EndFunc Func _msg($msg, $time = 0) MsgBox(0, "title", $msg, $time) EndFunc ;This should be taken to GUIListView.au3 ;=============================================================================== ; ; Description: _GUICtrlListViewGetSubItemRect ; Parameter(s): $h_listview - controlID/handle ; $row - item index (0-based) ; $col - subitem index (0-based) ; $left - container for the left-position ; $top - container for the top-position ; $height - container for the height-position ; Requirement: None ; Return Value(s): the real width of the defined cell (not the visible width!) ; User CallTip: _GUICtrlListViewGetSubItemRect($h_listview, $row, $col, ByRef $left, ByRef $top, ByRef $height) Retrieve the rectangle of a cell (required: <GuiListView.au3>) ; Author(s): pdm ; Note(s): published on the forum on 15.3.2007 ; ;=============================================================================== Func _GUICtrlListViewGetSubItemRect($h_listview, $row, $col, ByRef $left, ByRef $top, ByRef $height) Local $rectangle, $rv $rectangle = DllStructCreate("int;int;int;int") ;left, top, right, bottom DllStructSetData($rectangle, 1, $LVIR_BOUNDS) DllStructSetData($rectangle, 2, $col) If IsHWnd($h_listview) Then Local $a_ret = DllCall("user32.dll", "int", "SendMessage", "hwnd", $h_listview, "int", $LVM_GETSUBITEMRECT, "int", $row, "ptr", DllStructGetPtr($rectangle)) $rv = $a_ret[0] Else $rv = GUICtrlSendMsg($h_listview, $LVM_GETSUBITEMRECT, $row, DllStructGetPtr($rectangle)) EndIf $left = DllStructGetData($rectangle, 1) $top = DllStructGetData($rectangle, 2) $height = DllStructGetData($rectangle, 4) - $top $rectangle = 0 Return $rv EndFunc ;==>_GUICtrlListViewGetSubItemRect Func _SetCursorState($bValue = 1) DllCall('User32.dll', 'int', 'ShowCursor', 'int', $bValue) EndFunc ;/////////////////////////////////////// ;elv_init () ; ;prepares the used listview and editbox. ;/////////////////////////////////////// Func elv_init ($lv) $elv_listview = $lv l_elv_edit_box ("create") l_elv_combo_box ("create") l_elv_dialogue ("create") GUISwitch ($Form1) l_elv_monthcalendar ("create") $editfield_on = GUICtrlCreateDummy() ;generate unique code for the message handling l_elv_edit_quit() EndFunc ;//////////////////////////// ;elv_exit () ; ;destroys all created objects ;//////////////////////////// Func elv_exit ($lv) $elv_listview = "" l_elv_edit_box ("delete") l_elv_combo_box ("delete") l_elv_dialogue ("delete") GUISwitch ($Form1) l_elv_monthcalendar ("delete") $editfield_on = "" EndFunc ;//////////////////////////////////////////////////////// ;elv_message() ; ;is called from the message-loop of the application above ;//////////////////////////////////////////////////////// func elv_message ($msg) Local $rv if $elv_dialogue_open Then $rv = elv_dialogue_msg ($msg) if $rv <> $msg Then if $rv = 0 Then _con ("cal quit") l_elv_edit_quit () Else _con ("cal save") l_elv_edit_save () EndIf return EndIf Endif Switch $msg Case $cbx_doubleclick if GUICtrlRead ($msg) = $GUI_UNCHECKED Then $b_use_dbl_click = False Else $b_use_dbl_click = True EndIf Case $elv_listview ;_con ("lv-msg") Case $inb_elv, $cmb_elv, $cal_elv ;_con ("edit-msg") l_elv_edit_save() Case $editfield_on l_elv_edit_on() Case 0, -7, -8, -11, -12 Case Else _con("msg=" & $msg); EndSwitch EndFunc ;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ;elv_notify() ; ;is called from the applications notification function or can be registered with GUIRegisterMsg($WM_NOTIFY, "elv_notify") directly ;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Func elv_notify ($hWndGUI, $MsgID, $wParam, $lParam) #forceref $hWndGUI, $MsgID, $wParam Local $tagNMHDR, $event, $tagNMITEMACTIVATE, $rv $rv = $GUI_RUNDEFMSG $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code) If @error Then Return $event = DllStructGetData($tagNMHDR, 3) $rv = 0 Switch $wParam Case $elv_listview Switch $event Case $NM_CLICK l_elv_ListView_Click($elv_listview) Case $NM_DBLCLK l_elv_ListView_DoubleClick($elv_listview) Case -121 ;click inside the listview data area $tagNMITEMACTIVATE = DllStructCreate("int;int;int;int;int;int;int;int;int", $lParam) $clicked_col = DllStructGetData($tagNMITEMACTIVATE, 5) $tagNMITEMACTIVATE = 0 Case - 108, -177, -180, -181 ;header-click, horizontal scroll, vertical scroll up and down l_elv_edit_save() Case Else ;_con ("lvw evnt="& $event) EndSwitch Case $inb_elv Switch $event Case 0 Case Else ;_con ("inb evnt="& $event) EndSwitch case $cal_elv _con ("cal evnt="& $event) Case Else Switch $event Case - 322, -328 ;changes in column width l_elv_edit_save() Case Else _con ("ctrl "& $hWndGUI &" evnt="& $event) EndSwitch EndSwitch $tagNMHDR = 0 $event = 0 $lParam = 0 Return $rv EndFunc ;/////////////////////////// ;l_elv_edit_box() ; ;use an inputbox for editing ;/////////////////////////// func l_elv_edit_box ($cmd, $left_col = 0, $top_row = 0, $width = 0, $height = 0) switch $cmd case "create" $inb_elv = GUICtrlCreateInput ("", 0, 0, 0, 0, BitOR($ES_AUTOHSCROLL,$ES_NOHIDESEL,$WS_BORDER), 0) GUICtrlSetState ($inb_elv, $GUI_HIDE) GUICtrlSetBkColor($inb_elv, 0xC0DCC0) case "delete" $inb_elv = "" case "pos" ; _GUICtrlListViewSetItemSelState($elv_listview, $current_row, 1, 0) GUICtrlSetPos ($inb_elv, $left_col + 4, $top_row + 4, $width, $height) case "hide" HotKeySet("{Enter}") HotKeySet("{TAB}") HotKeySet("+{TAB}") HotKeySet("{DOWN}") HotKeySet("{UP}") HotKeySet("{ESC}") GUICtrlSetState ($inb_elv, $GUI_HIDE) case "show" GUICtrlSetState ($inb_elv, $GUI_SHOW + $GUI_ONTOP + $GUI_FOCUS) case "get" return GUICtrlRead ($inb_elv) case "set" GUICtrlSetData ($inb_elv, $elv_data[$top_row][$left_col]) HotKeySet("{Enter}", "l_elv_edit_right") HotKeySet("{TAB}", "l_elv_edit_right") HotKeySet("+{TAB}", "l_elv_edit_left") HotKeySet("{DOWN}", "l_elv_edit_down") HotKeySet("{UP}", "l_elv_edit_up") HotKeySet("{ESC}", "l_elv_edit_esc") EndSwitch EndFunc ;/////////////////////////// ;l_elv_combo_box() ; ;use a combobox for editing ;/////////////////////////// func l_elv_combo_box ($cmd, $left_col = 0, $top_row = 0, $width = 0, $height = 0) Local $str, $a_xy[2] _con ("combo_box ("& $cmd &", "& $left_col &", "& $top_row &", "& $width &", "& $height &")") switch $cmd case "create" $cmb_elv = GUICtrlCreateCombo ("", 0, 0, 0, 0, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL,$CBS_SORT)) GUICtrlSetState ($cmb_elv, $GUI_HIDE) case "delete" $cmb_elv = "" case "pos" GUICtrlSetPos ($cmb_elv, $left_col + 4, $top_row + 2, $width, $height) $mouse_click = False case "hide" HotKeySet("{Enter}") HotKeySet("{TAB}") HotKeySet("+{TAB}") HotKeySet("{ESC}") GUICtrlSetState ($cmb_elv, $GUI_HIDE) case "show" GUICtrlSetState ($cmb_elv, $GUI_SHOW + $GUI_ONTOP) case "get" return GUICtrlRead ($cmb_elv) case "set" $str = $elv_data[$top_row][$left_col] GUICtrlSetData ($cmb_elv, $str, $elv_data[$top_row][$left_col]) HotKeySet("{Enter}", "l_elv_edit_right") HotKeySet("{TAB}", "l_elv_edit_right") HotKeySet("+{TAB}", "l_elv_edit_left") HotKeySet("{ESC}", "l_elv_edit_esc") EndSwitch EndFunc ;/////////////////////////////////////////// ;l_elv_monthcalendar () ; ;use a monthcalendar to enter a certain date ;/////////////////////////////////////////// func l_elv_monthcalendar ($cmd, $left_col = 0, $top_row = 0, $width = 0, $height = 0) Local $str, $a_xy[2] $countix += 1 _con ("monthcalendar ("& $cmd &", "& $left_col &", "& $top_row &", "& $width &", "& $height &") count="& $countix) switch $cmd case "create" $cal_elv = GUICtrlCreateMonthCal ("1959/10/28", -10000, -10000, 170, 170) ;create outside to avoid flicker GUICtrlSetState ($cal_elv, $GUI_HIDE) case "delete" $cal_elv = "" case "pos" GUICtrlSetPos ($cal_elv, $left_col, $top_row) $mouse_click = False case "hide" HotKeySet("{Enter}") HotKeySet("{TAB}") HotKeySet("+{TAB}") HotKeySet("{ESC}") HotKeySet("{DOWN}") HotKeySet("{UP}") GUICtrlSetState ($cal_elv, $GUI_HIDE) case "show" GUICtrlSetState ($cal_elv, $GUI_SHOW + $GUI_ONTOP + $GUI_FOCUS) GUICtrlSetStyle ($cal_elv, -1, $WS_EX_TOPMOST) case "get" return GUICtrlRead ($cal_elv) case "set" $str = $elv_data[$top_row][$left_col] GUICtrlSetData ($cal_elv, $str, $elv_data[$top_row][$left_col]) HotKeySet("{Enter}", "l_elv_edit_right") HotKeySet("{TAB}", "l_elv_edit_right") HotKeySet("+{TAB}", "l_elv_edit_left") HotKeySet("{ESC}", "l_elv_edit_esc") HotKeySet("{DOWN}", "l_elv_edit_down") HotKeySet("{UP}", "l_elv_edit_up") EndSwitch EndFunc ;//////////////////////// ;l_elv_dialogue () ; ;use a seperate dialogbox ;//////////////////////// func l_elv_dialogue ($cmd, $left_col = 0, $top_row = 0, $width = 0, $height = 0) Local $str, $a_xy[2] $countix += 1 _con ("dialogue ("& $cmd &", "& $left_col &", "& $top_row &", "& $width &", "& $height &") count="& $countix) switch $cmd case "create" elv_dialogue ($cmd) case "delete" elv_dialogue ($cmd) case "pos" elv_dialogue ($cmd, $left_col, $top_row, $lbl_zero) ;lbl_zero must be on position 0,0 in the form containing the listview $mouse_click = False case "hide" HotKeySet("{Enter}") HotKeySet("{TAB}") HotKeySet("+{TAB}") HotKeySet("{ESC}") HotKeySet("{DOWN}") HotKeySet("{UP}") elv_dialogue ($cmd) $elv_dialogue_open = False case "show" elv_dialogue ($cmd) $elv_dialogue_open = True case "get" return elv_dialogue ($cmd) case "set" elv_dialogue ($cmd, $elv_data[$top_row][$left_col]) HotKeySet("{Enter}", "l_elv_edit_right") HotKeySet("{TAB}", "l_elv_edit_right") HotKeySet("+{TAB}", "l_elv_edit_left") HotKeySet("{ESC}", "l_elv_edit_esc") HotKeySet("{DOWN}", "l_elv_edit_down") HotKeySet("{UP}", "l_elv_edit_up") EndSwitch EndFunc Func l_elv_edit_save () If $open = 2 Then ;_con ("save open="& $open) $elv_data[$current_row][$current_col] = call ($elv_edit_func[$current_col], "get") ;GUICtrlRead($inb_elv) _GUICtrlListViewSetItemText ($elv_listview, $current_row, $current_col, $elv_data[$current_row][$current_col]) $open = 1 EndIf l_elv_edit_quit () EndFunc ;==>l_edit_save Func l_elv_edit_quit () If $open <> 0 Then ;_con ("quit open="& $open) call ($elv_edit_func[$current_col], "hide") ;GUICtrlSetState($inb_elv, $GUI_HIDE) GUICtrlSetState($elv_listview, $GUI_ONTOP + $GUI_FOCUS) $open = 0 EndIf If $mouse_click Then $mouse_click = False if $b_use_dbl_click Then Local $a_xy[1] $a_xy = MouseGetPos () MouseClick ("left", $a_xy[0], $a_xy[1], 2) Else MouseClick ("left") EndIf EndIf EndFunc ;==>l_edit_quit Func l_elv_ListView_Click ($lv) if $b_use_dbl_click Then $mouse_click = False l_elv_edit_save () Else l_elv_start_edit () EndIf EndFunc ;==>ListView_Click Func l_elv_ListView_DoubleClick ($lv) if $b_use_dbl_click Then l_elv_start_edit () Else ; EndIf EndFunc func l_elv_start_edit () ;_con ("lv click open="& $open &" clicked col="& $clicked_col) If $clicked_col < 0 Then _con("off mcl=" & $mouse_click) l_elv_edit_save () Return EndIf If $open = 2 Then l_elv_edit_save () ElseIf $open = 1 Then Return EndIf $open = 1 $mouse_click = True l_elv_prepare_edit (_GUICtrlListViewGetCurSel ($elv_listview), $clicked_col) EndFunc ;==>ListView_DoubleClick Func l_elv_prepare_edit ($row, $col) Local $left, $top, $height, $width, $lvw, $a_coord[4], $str, $shift, $colw, $rowh, $vs, $hs, $hh, $sw, $sh ;_con ("prepare open="& $open) $current_row = $row If $current_row < 0 Then ;$current_row = 0 Return EndIf $current_col = $col If $current_col < 0 Then $current_col = 0 _GUICtrlListViewEnsureVisible ($elv_listview, $current_row, 0) $width = _GUICtrlListViewGetColumnWidth ($elv_listview, $current_col) _GUICtrlListViewGetSubItemRect ($elv_listview, $current_row, $current_col, $left, $top, $height) $colw = $width + 2 If $current_col = $last_col Then For $c = 0 To $current_col - 1 $colw += _GUICtrlListViewGetColumnWidth ($elv_listview, $c) + 1 ;+1 for the gridline Next EndIf Opt("GUICoordMode", 0) $a_coord = ControlGetPos ("", "", $elv_listview) ;get coordinates of ListView (x, y, w, h) Opt("GUICoordMode", 1) If Not IsArray ($a_coord) Then Return EndIf $str = _ArrayToString ($a_coord, "/") $lvw = $a_coord[2] ;w $hh = 20 $sw = 24 $sh = 20 ;Under certain conditions, vertical and/or horizontal scrollbars will be displayed. ;The vertical bar reduces the usable width, which can force the horizontal bar to appear. ;The horizontal scrollbar reduces the number of displayed lines and can force a vertical bar to be shown. ;These conditions will affect the editfield in the last column. $rowh = $last_row * ($height + 1) + ($height - 5) ;+1 for the gridline +extra for partial height of last line If $rowh > ($a_coord[3] - $hh) Then $vs = $sw ;vertical slider exists Else $vs = 0 EndIf If $colw > ($a_coord[2] - $vs) Then $hs = $sh ;horizontal slider exists Else $hs = 0 EndIf If $rowh > ($a_coord[3] - $hh - $hs + 4) Then ;+extra due to hysteresis when horizontal bar exists and vertical one still not $vs = $sw ;vertical slider exists EndIf ;_con ($last_row &" rows height "& $height+1 &" *="& $rowh &" hi="& $a_coord[3] &" vs="& $vs &" hs="& $hs) $lvw -= $vs ;w - sliderwidth $shift = 0 If $left > $lvw Then If $width > $lvw Then $width = $lvw $shift = 0 - $left $left = 0 Else $shift = $left - $lvw + $width $left -= $shift EndIf ElseIf $left < 0 Then If $width > $lvw Then $width = $lvw $shift = $left $left = 0 Else $shift = $left $left = 0 EndIf ElseIf $left + $width > $lvw Then If $width > $lvw Then $width = $lvw $shift = 0 - $left $left = 0 Else $shift = $left - $lvw + $width $left -= $shift EndIf EndIf If $shift <> 0 Then _GUICtrlListViewScroll ($elv_listview, $shift, 0) EndIf ;_con ("lv x/y/w/h="& $str &" left="& $left &" top="& $top &" wid="& $width &" hei="& $height &" shift="& $shift &" lvw="& $lvw) _GUICtrlListViewSetItemSelState($elv_listview, $current_row, 1, 0) call ($elv_edit_func[$current_col], "pos", $left + $a_coord[0], $top + $a_coord[1], $width, $height) ;GUICtrlSetPos($inb_elv, $left + $a_coord[0] + 4, $top + $a_coord[1] + 5, $width, $height + 0) $open = 1 GUICtrlSendToDummy ($editfield_on) ;start edit-field EndFunc ;==>l_prepare_edit Func l_elv_edit_on () ;_con ("on open="& $open) call ($elv_edit_func[$current_col], "show") ;GUICtrlSetState($inb_elv, $GUI_SHOW + $GUI_ONTOP + $GUI_FOCUS) call ($elv_edit_func[$current_col], "set", $current_col, $current_row) ;GUICtrlSetData($inb_elv, $elv_data[$current_row][$current_col]) $open = 2 EndFunc ;==>l_edit_on func l_elv_edit_esc () $mouse_click = False l_elv_edit_quit () EndFunc Func l_elv_edit_right () Local $col, $row $row = $current_row $col = $current_col If $col < $last_col Then $col += 1 Else $col = 0 $row += 1 EndIf If $row <= $last_row Then l_elv_edit_save () l_elv_prepare_edit ($row, $col) EndIf EndFunc ;==>l_edit_right Func l_elv_edit_left () Local $col, $row $row = $current_row $col = $current_col If $col > 0 Then $col -= 1 Else $row -= 1 $col = $last_col EndIf If $row >= 0 Then l_elv_edit_save () l_elv_prepare_edit ($row, $col) EndIf EndFunc ;==>l_edit_left Func l_elv_edit_down () If $current_row < $last_row Then l_elv_edit_save () l_elv_prepare_edit ($current_row + 1, $current_col) EndIf EndFunc ;==>l_edit_down Func l_elv_edit_up () If $current_row > 0 Then l_elv_edit_save () l_elv_prepare_edit ($current_row - 1, $current_col) EndIf EndFunc ;==>l_edit_up //////////////////////////////////////////////////////////////////////////////////////////////////////// ;cut this here and put it into dialogue.au3 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ Local $l_cal_on = False Local $l_org_date = "" Local $l_cal_id Local $l_dia_width, $l_dia_height Local $l_ret_empty = False Local $btn_dia_cancel, $btn_dia_ok, $btn_dia_empty, $frm_calendar, $MonthCal1, $tab_calendar, $frm_calender ;//////////////////////////////////////////////////////////// ;elv_dialogue () ; ;is called from the column-specific function l_elv_dialogue() ;it has a variable number of arguments ;//////////////////////////////////////////////////////////// func elv_dialogue ($cmd, $arg1 = 0, $arg2 = 0, $arg3 = 0) Local $a_coord[4], $hwnd, $x, $y switch $cmd case "create" if $l_cal_on Then return 0 EndIf #Region ### START Koda GUI section ### Form=T:\_au3\test\EditableListView\dialogue.kxf Global $frm_calendar = GUICreate("Calendar", 272, 218, 367, 236, BitOR($WS_CLIPCHILDREN,$WS_CLIPSIBLINGS), $WS_EX_TOOLWINDOW) GUISetIcon("D:09.ico") Global $MonthCal1 = GUICtrlCreateMonthCal("2007/03/27", 8, 8, 185, 177, -1, 0) Global $btn_dia_cancel = GUICtrlCreateButton("X", 232, 8, 25, 25, 0) GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif") Global $btn_dia_ok = GUICtrlCreateButton("OK", 208, 160, 49, 25, 0) Global $btn_dia_empty = GUICtrlCreateButton("Empty", 208, 128, 49, 25, 0) #EndRegion ### END Koda GUI section ### $l_cal_on = True WinMove ($frm_calendar, "", -10000, -10000) ;create outside visible area to avoid flicker GUISetState (@SW_SHOW) WinSetState ($frm_calender, "", @SW_HIDE) $a_coord = WinGetPos ($frm_calendar) ;to keep the dialogue completely visible, we need the real width and height $l_dia_width = $a_coord[2] $l_dia_height = $a_coord[3] case "delete" if not $l_cal_on Then return 0 EndIf GUIDelete ($frm_calendar) $l_cal_on = False case "pos" ;arg1=left arg2=top arg3=lbl_zero $hwnd = ControlGetHandle ( "", "", $arg3) ;get the handle for the lbl_zero, which is at position 0,0 of the application form $a_coord = WinGetPos ($hwnd) ;we need the absolute coordinates of the inner edge of the form $x = $a_coord[0]+ $arg1 + 4 ;add the relative x of the current listview cell $y = $a_coord[1] + $arg2 + 2 ;add the relative y of the current listview cell if $x + $l_dia_width > @DesktopWidth Then $x = @DesktopWidth - $l_dia_width ;keep away from the right screen border EndIf if $y + $l_dia_height > @DesktopHeight Then $y = @DesktopHeight - $l_dia_height - 32 ;-32:assume visible taskbar EndIf WinMove ($frm_calendar, "", $x, $y) $l_ret_empty = False case "hide" WinSetState ($frm_calendar, "", @SW_HIDE) case "show" WinSetState ($frm_calendar, "", @SW_SHOW) case "get" if $l_ret_empty Then return "" EndIf return GUICtrlRead ($MonthCal1) case "set" ;arg1=date $l_org_date = $arg1 GUICtrlSetData ($MonthCal1, $arg1, $arg1) EndSwitch return 0 EndFunc ;/////////////////////////////////////////////////////////////// ;l_elv_dialogue_msg () ; ;this is called from the message handler of the EditableListView ;/////////////////////////////////////////////////////////////// func elv_dialogue_msg ($msg) Local $rv switch $msg case $btn_dia_cancel $rv = 0 case $btn_dia_ok $rv = 1 case $btn_dia_empty $l_ret_empty = True $rv = 1 case Else $rv = $msg EndSwitch return $rv EndFunc Now i'm going to make my first steps and use this ELV with my real application. If i or someone else find bugs, i will fix them in this test-version also. So please, folks, test it and give me feedback, hints, warnings or whatever is appropriate for this useful tool (from my point of view)! Link to comment Share on other sites More sharing options...
pdm Posted March 29, 2007 Author Share Posted March 29, 2007 Very usefull!Woundring if you could turn this into a "include" file so you could make a editable ListView by one command._GUICtrlCreateEditListView .Anyway great job!Hello Mr. Zero! There is another version of my EditableListView! (Look at the bottom of this topic, since i do not have an edit button yet...) You asked me to put this into an "include"-file. I think this is possible, but there is a certain interface required for this. It needs init- and exit-functions and has to participate on the message and notification loops of the application above it. And there need to be some specific settings to do what the application needs it to do. I have to go on with my payed work and already have a certain interface to the ELV, but this is not generic. I guess, it would be wise to create a more generic one, bBut maybe there is somebody in the forum to improve this... 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