Jump to content

About GUICtrlListView


johnmcloud
 Share

Recommended Posts

Hi guys,

I'm playing aroud with _GUICtrlListView_Create, i think can be useful to have a complete example for the future.

This is what i have do:

#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiEdit.au3>
#include <GuiMenu.au3>
#include <WinAPI.au3>

Global $hEdit, $hDC, $hBrush, $Item = -1, $SubItem = 0, $Number = 0, $hMenu
Global Enum $idMoveUp = 1000, $idMoveDown, $idDelete
Global $Style = BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT)

HotKeySet("{DELETE}", "Delete_Item")
HotKeySet("{UP}", "Move_Up")
HotKeySet("{DOWN}", "Move_Down")

$GUI = GUICreate("_GUICtrlListView_Example", 262, 351, -1, -1)
$hListView = _GUICtrlListView_Create($GUI, "N°|Name|Subject", 5, 5, 250, 272)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_BORDERSELECT))
_GUICtrlListView_SetColumnWidth($hListView, 0, 35)
_GUICtrlListView_SetColumnWidth($hListView, 1, 107)
_GUICtrlListView_SetColumnWidth($hListView, 2, 108)
$Label = GUICtrlCreateLabel("Name", 13, 290, 67, 17)
$Add = GUICtrlCreateButton("Add", 90, 315, 80, 25)
$Info = GUICtrlCreateInput("Subject", 88, 286, 83, 21)
$Save = GUICtrlCreateButton("Save", 174, 284, 80, 25)
GUISetState(@SW_SHOW)

$hMenu = _GUICtrlMenu_CreatePopup()
_GUICtrlMenu_InsertMenuItem($hMenu, 0, "Move Up", $idMoveUp)
_GUICtrlMenu_InsertMenuItem($hMenu, 1, "Move Down", $idMoveDown)
_GUICtrlMenu_InsertMenuItem($hMenu, 3, "", 0)
_GUICtrlMenu_InsertMenuItem($hMenu, 3, "Delete", $idDelete)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

While 1
 $nMsg = GUIGetMsg()
 Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit
  Case $Add
   Add_Item()
  Case $Save
   Save_List()
 EndSwitch
WEnd

Func Add_Item()
 $Number += 1
 _GUICtrlListView_AddItem($hListView, $Number)
 _GUICtrlListView_AddSubItem($hListView, $Number - 1, GUICtrlRead($Label), 1)
 _GUICtrlListView_AddSubItem($hListView, $Number - 1, GUICtrlRead($Info), 2)
EndFunc   ;==>Add_Item

Func Delete_Item()
 _GUICtrlListView_DeleteItemsSelected($hListView)
 _Arrange_Numbers()
EndFunc   ;==>Delete_Item

Func _Arrange_Numbers()
 Dim $iCount = 0
 $Total_Number = _GUICtrlListView_GetItemCount($hListView) - 1
 For $i = 0 To $Total_Number
   $iCount += 1
  _GUICtrlListView_SetItemText($hListView, $i, $iCount)
 Next
EndFunc

Func Save_List()
 Local $Save = FileSaveDialog("Save", @WorkingDir, "Txt Files (*.txt)", 2, "Test_File_" & @MDAY & "-" & @MON & "-" & @YEAR & "_" & @HOUR & "-" & @MIN)
 If @error Then
  ConsoleWrite("Abort")
 Else
  $List = FileOpen($Save & ".txt", 2)
  $Number_items = _GUICtrlListView_GetItemCount($hListView)
  For $i = 0 To $Number_items - 1 Step +1
   $output = StringReplace(_GUICtrlListView_GetItemTextString($hListView, $i), "|", " - ")
   FileWriteLine($List, $output)
  Next
  FileClose($List)
 EndIf
EndFunc   ;==>Save_List

Func Move_Up()
 Local $Sel, $aArrayListView
 $aArrayListView = _GUICtrlListView_CreateArray($hListView)
 $Sel = _GUICtrlListView_GetNextItem($hListView)
 If $Sel > 0 Then
  Local $SelItem, $NxtItem
  $SelItem = _GUICtrlListView_GetItemTextArray($hListView, $Sel)
  $PrvItem = _GUICtrlListView_GetItemTextArray($hListView, $Sel - 1)
  For $i = 1 To $SelItem[0]
   $aArrayListView[$Sel][$i - 1] = $PrvItem[$i]
   $aArrayListView[$Sel - 1][$i - 1] = $SelItem[$i]
   _GUICtrlListView_SetItemText($hListView, $Sel, $PrvItem[$i], $i - 1)
   _GUICtrlListView_SetItemText($hListView, $Sel - 1, $SelItem[$i], $i - 1)
   _GUICtrlListView_SetItemSelected($hListView, $Sel - 1)
  Next
 EndIf
 _Arrange_Numbers()
EndFunc   ;==>Move_Up

Func Move_Down()
 Local $Sel, $Lst, $aArrayListView
 $aArrayListView = _GUICtrlListView_CreateArray($hListView)
 $Sel = _GUICtrlListView_GetNextItem($hListView)
 $Lst = _GUICtrlListView_GetItemCount($hListView) - 1
 If $Sel < $Lst And $Sel <> -1 Then
  Local $SelItem, $NxtItem
  $SelItem = _GUICtrlListView_GetItemTextArray($hListView, $Sel)
  $NxtItem = _GUICtrlListView_GetItemTextArray($hListView, $Sel + 1)
  For $i = 1 To $SelItem[0]
   $aArrayListView[$Sel][$i - 1] = $NxtItem[$i]
   $aArrayListView[$Sel + 1][$i - 1] = $SelItem[$i]
   _GUICtrlListView_SetItemText($hListView, $Sel, $NxtItem[$i], $i - 1)
   _GUICtrlListView_SetItemText($hListView, $Sel + 1, $SelItem[$i], $i - 1)
   _GUICtrlListView_SetItemSelected($hListView, $Sel + 1)
  Next
 EndIf
 _Arrange_Numbers()
EndFunc   ;==>Move_Down

Func _GUICtrlListView_CreateArray($hListView, $sDelimeter = '|')
 Local $iColumnCount = _GUICtrlListView_GetColumnCount($hListView), $iDim = 0, $iItemCount = _GUICtrlListView_GetItemCount($hListView)
 If $iColumnCount < 3 Then
  $iDim = 3 - $iColumnCount
 EndIf
 If $sDelimeter = Default Then
  $sDelimeter = '|'
 EndIf
 Local $aColumns = 0, $aReturn[$iItemCount + 1][$iColumnCount + $iDim] = [[$iItemCount, $iColumnCount, '']]
 For $i = 0 To $iColumnCount - 1
  $aColumns = _GUICtrlListView_GetColumn($hListView, $i)
  $aReturn[0][2] &= $aColumns[5] & $sDelimeter
 Next
 $aReturn[0][2] = StringTrimRight($aReturn[0][2], StringLen($sDelimeter))
 For $i = 0 To $iItemCount - 1
  For $j = 0 To $iColumnCount - 1
   $aReturn[$i + 1][$j] = _GUICtrlListView_GetItemText($hListView, $i, $j)
  Next
 Next
 Return SetError(Number($aReturn[0][0] = 0), 0, $aReturn)
EndFunc   ;==>_GUICtrlListView_CreateArray

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
 Local $tNMHDR, $hWndFrom, $iCode
 $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
 $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
 $iCode = DllStructGetData($tNMHDR, "Code")
 Switch $hWndFrom
  Case $hListView
   Switch $iCode
    Case $NM_DBLCLK
     Local $aHit = _GUICtrlListView_SubItemHitTest($hListView)
     If ($aHit[0] <> -1) And ($aHit[1] = 0) Then
      $Item = $aHit[0]
      $SubItem = 0
      Local $aRect = _GUICtrlListView_GetItemRect($hListView, $Item)
     ElseIf ($aHit[0] <> -1) And ($aHit[1] > 0) Then
      $Item = $aHit[0]
      $SubItem = $aHit[1]
      Local $aRect = _GUICtrlListView_GetSubItemRect($hListView, $Item, $SubItem)
     Else
      Return $GUI_RUNDEFMSG
     EndIf
     Local $iItemText = _GUICtrlListView_GetItemText($hListView, $Item, $SubItem)
     Local $iLen = _GUICtrlListView_GetStringWidth($hListView, $iItemText)
     $hEdit = _GUICtrlEdit_Create($GUI, $iItemText, $aRect[0] + 3, $aRect[1], $iLen + 10, 17, $Style)
     _GUICtrlEdit_SetSel($hEdit, 0, -1)
     _WinAPI_SetFocus($hEdit)
     $hDC = _WinAPI_GetWindowDC($hEdit)
     $hBrush = _WinAPI_CreateSolidBrush(0x0000FF)
     FrameRect($hDC, 0, 0, $iLen + 10, 17, $hBrush)
    Case $NM_RCLICK
     $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
     If DllStructGetData($tInfo, "Item") > -1 Then
      _GUICtrlMenu_TrackPopupMenu($hMenu, $GUI)
     EndIf
   EndSwitch
 EndSwitch
 Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func FrameRect($hDC, $nLeft, $nTop, $nRight, $nBottom, $hBrush)
 Local $stRect = DllStructCreate("int;int;int;int")
 DllStructSetData($stRect, 1, $nLeft)
 DllStructSetData($stRect, 2, $nTop)
 DllStructSetData($stRect, 3, $nRight)
 DllStructSetData($stRect, 4, $nBottom)
 DllCall("user32.dll", "int", "FrameRect", "hwnd", $hDC, "ptr", DllStructGetPtr($stRect), "hwnd", $hBrush)
EndFunc   ;==>FrameRect

Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
 Local $iCode = BitShift($wParam, 16)
 Switch $lParam
  Case $hEdit
   Switch $iCode
    Case $EN_KILLFOCUS
     Local $iText = _GUICtrlEdit_GetText($hEdit)
     _GUICtrlListView_SetItemText($hListView, $Item, $iText, $SubItem)
     _WinAPI_DeleteObject($hBrush)
     _WinAPI_ReleaseDC($hEdit, $hDC)
     _WinAPI_DestroyWindow($hEdit)
     $Item = -1
     $SubItem = 0
   EndSwitch
 EndSwitch
 Switch $wParam
  Case $idMoveUp
   Move_Up()
  Case $idMoveDown
   Move_Down()
  Case $idDelete
   Delete_Item()
 EndSwitch
 Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

With this example script you can do:

1) Add item ;)

2) First column have an automatically number sequence

3) You can delete a single item with the HotKeySet DEL, but not the multiple, see point 6)

4) You can save the list of the item

5) You can reneame the item with double click, i'm not totally satisfied with the result and i don't know if can impoved, anyway i'd like to confirm the item name with Return key but i don't know how to do

6) Move up and move down item with UP and DOWN key , but is bugged because not compatible with $LVS_REPORT

7) A context menu using left click with three option

I'd like to add to make it complete:

1) A context menu using left click with example three option:

Move up - Move Down - Delete

1) Resolve "Move up" and "move down" bug, make it compatible with $LVS_REPORT

2) Delete item will automatically redo the first number sequence

2) Click on the column name for rearrange the item

I think it's all that you can do with GUICtrlListView.

Thanks for any help :D

Edited by johnmcloud
Link to comment
Share on other sites

Mmm no answer...anyway i have update the code ( again )

#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiEdit.au3>
#include <GuiMenu.au3>
#include <WinAPI.au3>

Global $hEdit, $hDC, $hBrush, $Item = -1, $SubItem = 0, $Number = 0, $hMenu
Global Enum $idMoveUp = 1000, $idMoveDown, $idDelete
Global $Style = BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT)

HotKeySet("{DELETE}", "Delete_Item")
HotKeySet("{UP}", "Move_Up")
HotKeySet("{DOWN}", "Move_Down")

$GUI = GUICreate("_GUICtrlListView_Example", 262, 351, -1, -1)
$hListView = GUICtrlCreateListView("N°|Name|Subject", 5, 5, 250, 272, -1, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES))
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 35)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 105)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 2, 106)
_GUICtrlListView_RegisterSortCallBack($hListView)
$Label = GUICtrlCreateLabel("Name", 13, 290, 67, 17)
$Add = GUICtrlCreateButton("Add", 90, 315, 80, 25)
$Info = GUICtrlCreateInput("Subject", 88, 286, 83, 21)
$Save = GUICtrlCreateButton("Save", 174, 284, 80, 25)
GUISetState(@SW_SHOW)

$hMenu = _GUICtrlMenu_CreatePopup()
_GUICtrlMenu_InsertMenuItem($hMenu, 0, "Move Up", $idMoveUp)
_GUICtrlMenu_InsertMenuItem($hMenu, 1, "Move Down", $idMoveDown)
_GUICtrlMenu_InsertMenuItem($hMenu, 3, "", 0)
_GUICtrlMenu_InsertMenuItem($hMenu, 3, "Delete", $idDelete)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

While 1
 $nMsg = GUIGetMsg()
 Switch $nMsg
  Case $GUI_EVENT_CLOSE
               _GUICtrlListView_UnRegisterSortCallBack($hListView)
               Exit
         Case $hListView
               _GUICtrlListView_SortItems($hListView, GUICtrlGetState($hListView))
  Case $Add
   Add_Item()
  Case $Save
   Save_List()
 EndSwitch
WEnd

Func Add_Item()
 $Number += 1
 _GUICtrlListView_AddItem($hListView, $Number, -1, _GUICtrlListView_GetItemCount($hListView) + 1000 )
 _GUICtrlListView_AddSubItem($hListView, _GUICtrlListView_GetItemCount($hListView) - 1, GUICtrlRead($Label), 1)
 _GUICtrlListView_AddSubItem($hListView, _GUICtrlListView_GetItemCount($hListView) - 1, GUICtrlRead($info), 2)
EndFunc   ;==>Add_Item

Func Delete_Item()
 _GUICtrlListView_DeleteItemsSelected(GUICtrlGetHandle($hListView))
 _Arrange_Numbers()
EndFunc   ;==>Delete_Item
Func _Arrange_Numbers()
 Dim $iCount = 0
 $Total_Number = _GUICtrlListView_GetItemCount($hListView) - 1
 For $i = 0 To $Total_Number
   $iCount += 1
  _GUICtrlListView_SetItemText($hListView, $i, $iCount)
 Next
EndFunc

Func Save_List()
 Local $Save = FileSaveDialog("Save", @WorkingDir, "Txt Files (*.txt)", 2, "Test_File_" & @MDAY & "-" & @MON & "-" & @YEAR & "_" & @HOUR & "-" & @MIN)
 If @error Then
  ConsoleWrite("Abort")
 Else
  $List = FileOpen($Save & ".txt", 2)
  $Number_items = _GUICtrlListView_GetItemCount($hListView)
  For $i = 0 To $Number_items - 1 Step +1
   $output = StringReplace(_GUICtrlListView_GetItemTextString($hListView, $i), "|", " - ")
   FileWriteLine($List, $output)
  Next
  FileClose($List)
 EndIf
EndFunc   ;==>Save_List

Func Move_Up()
 Local $Sel, $aArrayListView
 $aArrayListView = _GUICtrlListView_CreateArray($hListView)
 $Sel = _GUICtrlListView_GetNextItem($hListView)
 If $Sel > 0 Then
  Local $SelItem, $NxtItem
  $SelItem = _GUICtrlListView_GetItemTextArray($hListView, $Sel)
  $PrvItem = _GUICtrlListView_GetItemTextArray($hListView, $Sel - 1)
  For $i = 1 To $SelItem[0]
   $aArrayListView[$Sel][$i - 1] = $PrvItem[$i]
   $aArrayListView[$Sel - 1][$i - 1] = $SelItem[$i]
   _GUICtrlListView_SetItemText($hListView, $Sel, $PrvItem[$i], $i - 1)
   _GUICtrlListView_SetItemText($hListView, $Sel - 1, $SelItem[$i], $i - 1)
   _GUICtrlListView_SetItemSelected($hListView, $Sel - 1)
  Next
 EndIf
 _Arrange_Numbers()
EndFunc   ;==>Move_Up

Func Move_Down()
 Local $Sel, $Lst, $aArrayListView
 $aArrayListView = _GUICtrlListView_CreateArray($hListView)
 $Sel = _GUICtrlListView_GetNextItem($hListView)
 $Lst = _GUICtrlListView_GetItemCount($hListView) - 1
 If $Sel < $Lst And $Sel <> -1 Then
  Local $SelItem, $NxtItem
  $SelItem = _GUICtrlListView_GetItemTextArray($hListView, $Sel)
  $NxtItem = _GUICtrlListView_GetItemTextArray($hListView, $Sel + 1)
  For $i = 1 To $SelItem[0]
   $aArrayListView[$Sel][$i - 1] = $NxtItem[$i]
   $aArrayListView[$Sel + 1][$i - 1] = $SelItem[$i]
   _GUICtrlListView_SetItemText($hListView, $Sel, $NxtItem[$i], $i - 1)
   _GUICtrlListView_SetItemText($hListView, $Sel + 1, $SelItem[$i], $i - 1)
   _GUICtrlListView_SetItemSelected($hListView, $Sel + 1)
  Next
 EndIf
 _Arrange_Numbers()
EndFunc   ;==>Move_Down

Func _GUICtrlListView_CreateArray($hListView, $sDelimeter = '|')
 Local $iColumnCount = _GUICtrlListView_GetColumnCount($hListView), $iDim = 0, $iItemCount = _GUICtrlListView_GetItemCount($hListView)
 If $iColumnCount < 3 Then
  $iDim = 3 - $iColumnCount
 EndIf
 If $sDelimeter = Default Then
  $sDelimeter = '|'
 EndIf
 Local $aColumns = 0, $aReturn[$iItemCount + 1][$iColumnCount + $iDim] = [[$iItemCount, $iColumnCount, '']]
 For $i = 0 To $iColumnCount - 1
  $aColumns = _GUICtrlListView_GetColumn($hListView, $i)
  $aReturn[0][2] &= $aColumns[5] & $sDelimeter
 Next
 $aReturn[0][2] = StringTrimRight($aReturn[0][2], StringLen($sDelimeter))
 For $i = 0 To $iItemCount - 1
  For $j = 0 To $iColumnCount - 1
   $aReturn[$i + 1][$j] = _GUICtrlListView_GetItemText($hListView, $i, $j)
  Next
 Next
 Return SetError(Number($aReturn[0][0] = 0), 0, $aReturn)
EndFunc   ;==>_GUICtrlListView_CreateArray

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
 Local $tNMHDR, $hWndFrom, $iCode
 $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
 $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
 $iCode = DllStructGetData($tNMHDR, "Code")
 Switch $hWndFrom
  Case $hListView
   Switch $iCode
    Case $NM_DBLCLK
     Local $aHit = _GUICtrlListView_SubItemHitTest($hListView)
     If ($aHit[0] <> -1) And ($aHit[1] = 0) Then
      $Item = $aHit[0]
      $SubItem = 0
      Local $aRect = _GUICtrlListView_GetItemRect($hListView, $Item)
     ElseIf ($aHit[0] <> -1) And ($aHit[1] > 0) Then
      $Item = $aHit[0]
      $SubItem = $aHit[1]
      Local $aRect = _GUICtrlListView_GetSubItemRect($hListView, $Item, $SubItem)
     Else
      Return $GUI_RUNDEFMSG
     EndIf
     Local $iItemText = _GUICtrlListView_GetItemText($hListView, $Item, $SubItem)
     Local $iLen = _GUICtrlListView_GetStringWidth($hListView, $iItemText)
     $hEdit = _GUICtrlEdit_Create($GUI, $iItemText, $aRect[0] + 3, $aRect[1], $iLen + 10, 17, $Style)
     _GUICtrlEdit_SetSel($hEdit, 0, -1)
     _WinAPI_SetFocus($hEdit)
     $hDC = _WinAPI_GetWindowDC($hEdit)
     $hBrush = _WinAPI_CreateSolidBrush(0x0000FF)
     FrameRect($hDC, 0, 0, $iLen + 10, 17, $hBrush)
    Case $NM_RCLICK
     $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
     If DllStructGetData($tInfo, "Item") > -1 Then
      _GUICtrlMenu_TrackPopupMenu($hMenu, $GUI)
     EndIf
   EndSwitch
 EndSwitch
 Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func FrameRect($hDC, $nLeft, $nTop, $nRight, $nBottom, $hBrush)
 Local $stRect = DllStructCreate("int;int;int;int")
 DllStructSetData($stRect, 1, $nLeft)
 DllStructSetData($stRect, 2, $nTop)
 DllStructSetData($stRect, 3, $nRight)
 DllStructSetData($stRect, 4, $nBottom)
 DllCall("user32.dll", "int", "FrameRect", "hwnd", $hDC, "ptr", DllStructGetPtr($stRect), "hwnd", $hBrush)
EndFunc   ;==>FrameRect

Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
 Local $iCode = BitShift($wParam, 16)
 Switch $lParam
  Case $hEdit
   Switch $iCode
    Case $EN_KILLFOCUS
     Local $iText = _GUICtrlEdit_GetText($hEdit)
     _GUICtrlListView_SetItemText($hListView, $Item, $iText, $SubItem)
     _WinAPI_DeleteObject($hBrush)
     _WinAPI_ReleaseDC($hEdit, $hDC)
     _WinAPI_DestroyWindow($hEdit)
     $Item = -1
     $SubItem = 0
   EndSwitch
 EndSwitch
 Switch $wParam
  Case $idMoveUp
   Move_Up()
  Case $idMoveDown
   Move_Down()
  Case $idDelete
   Delete_Item()
 EndSwitch
 Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

I have replaced _GUICtrlListView_Create with GUICtrlCreateListView, now i can sort...but i can't double click for edit the item and left click, the context menu, not work anymore. What is the error?

Edited by johnmcloud
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...