So happy to talk to you
- First, i want to thanks you for your rapid fix, it works perfectly
- Second, i want to thanks you very much for this splendid library i use each time i need a listicon editable
- Third, never you imagine what your servant dare to do ????
He have adding three cowpat functions into the splendid jewel code of his favorite MASTER
And you know what ???? that works !!!! (so i hope )
KCC have adding
Code: Select all
; First function
Debug LigneSelection(#ListIcon) ; Return the number of the line selected
; Second function
Debug CaseEditable(1, 1) ; Return the state of the cell (#True the cell is editable or #False the cell is not editable)
CaseEditable(1, 1, #False) ; Make the cell row1/Line1 not editable
CaseEditable(1, 1, #True) ; Make the cell row1/Line1 editable
; Third function
ColonneEditable(1) ; Return the state of the column 1 (#True the collumn 1 is editable or #False the column 1 is not editable)
ColonneEditable(1, #False) ; Make the full column 1 not editable
ColonneEditable(1, #True) ; Make the full column 1 editable
If a kind member have the courage to use this code and is harmed....the "KCC corporation society" decline all responsability
Code: Select all
;'Edit ListIcon'.
;-----------------
; MASTER Author : Stephen Rodriguez.
; Blaster author : KCC [ Adding LigneSelection() + CaseEditable() + ColonneEditable() ]
; Created with Purebasic 4.02 for Windows (date: May 2007).
; Maintained with PB 4.4.
; Platforms: Windows (tested on XP and Vista 32-bit).
; Licence: DAYLike
; (Do As You Like with it! - No Warranties!) AND AGAIN MORE AFTER KCC HAVE ADDING HIS COWPAT FUNCTIONS !!!
; A credit to myself, whilst nice, is not absolutely necessary.
;*******************************************************************************************
;NOTES.
;------
; 1) Register a listicon gadget to have editable cells by using the command SetListIconEditable(listID).
; You MUST set up such listicons to have a column zero of zero width.
; 2) Cells are made editable by intercepting double-clicks, setting the #LVS_EDITLABELS style,
; repositioning the edit control which Windows uses to edit the labels in column zero and copying
; the resulting text to the listicon cell.
; 3) Cells can also be edited by means of the command EditCell().
;*******************************************************************************************
#LVM_SUBITEMHITTEST = #LVM_FIRST+57
#LVM_GETSUBITEMRECT = #LVM_FIRST+56
#LVM_GETHEADER = #LVM_FIRST+31
#EC_RIGHTMARGIN = 2
Structure _LIEdit ; ListIcon editable
listOldProc.l
editHwnd.l
item.l
subitem.l
x.l
y.l
cx.l
cy.l
EndStructure
Structure Cellule
Col.i
Lig.i
EndStructure
Declare.l SetListIconEditable(listID)
Declare.l _LIEwinProc(hWnd, uMsg, wParam, lParam)
Declare.l _LIEListProc(hWnd, uMsg, wParam, lParam)
Declare.l _LIEeditProc(hWnd, uMsg, wParam, lParam)
Global NewList ListCasesNonEditables.Cellule()
Global Dim TabloColonneNonEditables(0)
Procedure LigneSelection(PbIdListIcon) ; Créée par Kcc
PInfo.LVHITTESTINFO
hWnd = GadgetID(PbIdListIcon)
GetCursorPos_(@PInfo\pt)
MapWindowPoints_(0, hWnd, @PInfo\pt, 1)
SendMessage_(hWnd, #LVM_SUBITEMHITTEST, 0, PInfo)
ProcedureReturn PInfo\iItem
EndProcedure
Procedure CaseEditable(Colonne, Ligne, Editable = -1) ; Créée par Kcc
; Editable = #False (N'est plus editable)
; Editable = #True (Devient editable)
; Editable = -1 (Demande l'état de la case == > Retourne 1 si la case est editable et 0 si elle ne l'est pas)
Select Editable
Case #False
AddElement(ListCasesNonEditables())
ListCasesNonEditables()\Col = Colonne
ListCasesNonEditables()\Lig = Ligne
Case #True
ForEach ListCasesNonEditables()
If ListCasesNonEditables()\Col = Colonne And ListCasesNonEditables()\Lig = Ligne
DeleteElement(ListCasesNonEditables())
EndIf
Next
Case -1
NonEditable = #False
ForEach ListCasesNonEditables()
If ListCasesNonEditables()\Col = Colonne And ListCasesNonEditables()\Lig = Ligne
NonEditable = #True
Break
EndIf
Next
ProcedureReturn Bool(Not NonEditable)
EndSelect
EndProcedure
Procedure ColonneEditable(Colonne, Editable = -1) ; Créée par Kcc
; Editable = #False (La colonne complete n'est plus editable)
; Editable = #True (La colonne complete devient editable)
; Editable = -1 (Demande l'état de la colonne complete == > Retourne 1 si la colonne est editable et 0 si elle ne l'est pas)
Select Editable
Case #False
TabloColonneNonEditables(Colonne) = #True
Case #True
TabloColonneNonEditables(Colonne) = #False
Case -1
ProcedureReturn Bool(Not TabloColonneNonEditables(Colonne))
EndSelect
EndProcedure
Procedure.l SetListIconEditable(listID) ; ListIcon editable (Returns zero if an error)
Protected result, parenthWnd, *mem._LIEdit, hWnd
;Check that listID references a valid listicon.
If IsGadget(listID) And GadgetType(listID)=#PB_GadgetType_ListIcon
hWnd = GadgetID(listID)
numcols = SendMessage_(SendMessage_(hWnd,#LVM_GETHEADER,0,0), #HDM_GETITEMCOUNT,0,0) ; Rajout KCC
ReDim TabloColonneNonEditables(numcols) ; Rajout KCC
;Is the listicon already registered?
If GetProp_(hWnd, "_LIEdit")=0 ;No!
;Allocate enough memory for a _LIEdit structure.
*mem=AllocateMemory(SizeOf(_LIEdit))
If *mem
SetWindowLong_(hWnd, #GWL_STYLE, GetWindowLong_(hWnd, #GWL_STYLE)&~#LVS_EDITLABELS)
;Set the fields of the _LIEedit structure.
*mem\listOldProc = SetWindowLong_(hWnd, #GWL_WNDPROC, @_LIEListProc())
;Store a pointer to this structure in a window property ofthe listicon.
SetProp_(hWnd, "_LIEdit", *mem)
;Subclass the parent window if not already through another listicon.
parenthWnd=GetParent_(hWnd)
If GetProp_(parenthWnd, "_LIEditOldProc")=0 ;No!
SetProp_(parenthWnd, "_LIEditOldProc", SetWindowLong_(parenthWnd, #GWL_WNDPROC, @_LIEwinProc()))
EndIf
result=1
EndIf
EndIf
EndIf
ProcedureReturn result
EndProcedure
ProcedureDLL EditCell(listID, item, subitem) ; ListIcon editable (Sets the specified cell To be edited)
Protected hWnd, *liedit._LIEdit, numrows, numcols
;Check that listID references a valid listicon.
If IsGadget(listID) And GadgetType(listID)=#PB_GadgetType_ListIcon
;Check that the listicon is registered as editable.
hWnd = GadgetID(listID)
*liedit = GetProp_(hWnd, "_LIEdit")
If *liedit
;Check parameters are in range.
numrows = CountGadgetItems(listID)
numcols = SendMessage_(SendMessage_(hWnd,#LVM_GETHEADER,0,0), #HDM_GETITEMCOUNT,0,0)
If item>=0 And item < numrows And subitem>0 And subitem < numcols
*liedit\item = item
*liedit\subitem = subitem
SetWindowLong_(hWnd, #GWL_STYLE, GetWindowLong_(hWnd, #GWL_STYLE)|#LVS_EDITLABELS)
SetActiveGadget(listID)
SendMessage_(hWnd, #LVM_EDITLABEL, item, 0)
EndIf
EndIf
EndIf
EndProcedure
Procedure.l _LIEwinProc(hWnd, uMsg, wParam, lParam) ; ListIcon editable (Window proc of the ListIcon parent window)
Protected result, oldwinproc, *nmh. NMHDR, listhWnd, edithWnd, *liedit._LIEdit, *lvd.LV_DISPINFO, rc.RECT
Static celltext$
;Retrieve the address of the old proc.
oldwinproc = GetProp_(hWnd, "_LIEditOldProc")
Select uMsg
Case #WM_NOTIFY
*nmh=lParam
Select *nmh\code
Case #LVN_BEGINLABELEDIT
listhWnd = *nmh\hwndFrom
;Retrieve the address of the LIEdit structure.
*liedit = GetProp_(listhWnd, "_LIEdit")
If *liedit ;Good to go!
*liedit\editHwnd=0
;Get the handle of the edit control used to edit the label.
edithWnd = SendMessage_(listhWnd, #LVM_GETEDITCONTROL,0,0)
;Subclass the edit control.
SetProp_(edithWnd, "_LIEditOldProc", SetWindowLong_(edithWnd, #GWL_WNDPROC, @_LIEeditProc()))
;Set text.
celltext$=GetGadgetItemText(*nmh\idFrom, *liedit\item, *liedit\subitem)
SendMessage_(edithWnd, #WM_SETTEXT, 0, celltext$)
SetGadgetItemText(*nmh\idFrom, *liedit\item, "",*liedit\subitem)
;Get bounding rectangle.
rc\top = *liedit\subitem
rc\left = #LVIR_BOUNDS
SendMessage_(listhWnd, #LVM_GETSUBITEMRECT, *liedit\item, rc)
*liedit\x=rc\left
*liedit\y=rc\top
*liedit\cx=SendMessage_(listhWnd, #LVM_GETCOLUMNWIDTH, *liedit\subitem,0)
*liedit\cy=rc\bottom-rc\top
EndIf
Case #LVN_ENDLABELEDIT
listhWnd = *nmh\hwndFrom
;Retrieve the address of the LIEdit structure.
*liedit = GetProp_(listhWnd, "_LIEdit")
If *liedit ;Good to go!
*lvd = lParam
If *lvd\item\pszText
SetGadgetItemText(*nmh\idFrom, *liedit\item, PeekS(*lvd\item\pszText), *liedit\subitem)
Else
SetGadgetItemText(*nmh\idFrom, *liedit\item, celltext$, *liedit\subitem)
EndIf
InvalidateRect_(listhWnd,0,1)
UpdateWindow_(listhWnd)
SetWindowLong_(listhWnd, #GWL_STYLE, GetWindowLong_(listhWnd, #GWL_STYLE)&~#LVS_EDITLABELS)
EndIf
Default
result=CallWindowProc_(oldwinproc, hWnd, uMsg, wParam, lParam)
EndSelect
Case #WM_NCDESTROY
result=CallWindowProc_(oldwinproc, hWnd, uMsg, wParam, lParam)
RemoveProp_(hWnd, "_LIEditOldProc")
Default
result=CallWindowProc_(oldwinproc, hWnd, uMsg, wParam, lParam)
EndSelect
ProcedureReturn result
EndProcedure
Procedure.l _LIEListProc(hWnd, uMsg, wParam, lParam) ; ListIcon editable (Window proc of the ListIcon)
Protected result, *liedit._LIEdit, PInfo.LVHITTESTINFO, *nmHEADER.HD_NOTIFY
;Retrieve the address of the LIEdit structure.
*liedit = GetProp_(hWnd, "_LIEdit")
Select uMsg
Case #WM_NOTIFY
*nmHEADER = lParam
Select *nmHEADER\hdr\code
Case #HDN_BEGINTRACK, #HDN_BEGINTRACKW ;Prevent column 0 from being resized.
If *nmHEADER\iItem=0
result=1
EndIf
Default
result=CallWindowProc_(*liedit\listOldProc, hWnd, uMsg, wParam, lParam)
EndSelect
Case #WM_LBUTTONDBLCLK
;Identify the clicked item
PInfo\pt\x = lParam&$ffff
PInfo\pt\y = (lParam>>16)&$ffff
SendMessage_(hwnd, #LVM_SUBITEMHITTEST, 0, PInfo)
If PInfo\iItem <> -1 ;A valid cell was clicked.
*liedit\item = PInfo\iItem
*liedit\subitem = PInfo\iSubItem
;*****IF YOU WISH TO RESTRICT WHICH CELLS CAN BE EDITED, THEN PERFORM THE NECESSARY CHECKS HERE
;*****ON THE VALUES OF *liedit\item and *liedit\subitem (WHICH INDICATE WHICH CELL IS ABOUT
;*****TO BE EDITED) AND RUN THE FOLLOWING 2 LINES FOR THOSE CELLS WHICH ARE TO BE EDITED.
If CaseEditable(PInfo\iSubItem, PInfo\iItem) And Not TabloColonneNonEditables(PInfo\iSubItem)
SetWindowLong_(hWnd, #GWL_STYLE, GetWindowLong_(hWnd, #GWL_STYLE)|#LVS_EDITLABELS)
SendMessage_(hWnd, #LVM_EDITLABEL, PInfo\iItem, 0)
EndIf
;*****************************************************************************************
EndIf
Case #WM_NCDESTROY
result=CallWindowProc_(*liedit\listOldProc, hWnd, uMsg, wParam, lParam)
RemoveProp_(hWnd, "_LIEdit")
FreeMemory(*liedit)
Default
result=CallWindowProc_(*liedit\listOldProc, hWnd, uMsg, wParam, lParam)
EndSelect
ProcedureReturn result
EndProcedure
Procedure.l _LIEeditProc(hWnd, uMsg, wParam, lParam) ; ListIcon editable (Window proc of the edit control)
Protected result, oldwinproc, *liedit._LIEdit, *wpos.WINDOWPOS
;Retrieve the address of the old proc.
oldwinproc = GetProp_(hWnd, "_LIEditOldProc")
;Retrieve the address of the LIEdit structure.
*liedit = GetProp_(GetParent_(hWnd), "_LIEdit")
Select uMsg
Case #WM_ERASEBKGND
;A hack in order to clear the default selection of characters.
result=CallWindowProc_(oldwinproc, hWnd, uMsg, wParam, lParam)
If *liedit\editHwnd=0
*liedit\editHwnd = hWnd
;Set margins.
SendMessage_(hWnd, #EM_SETMARGINS, #EC_LEFTMARGIN|#EC_RIGHTMARGIN, 4)
SendMessage_(hWnd, #EM_SETSEL, -1,0)
EndIf
Case #WM_WINDOWPOSCHANGING
*wpos=lParam
;*wpos\cx=*liedit\cx ;Comment this line to get an edit control which grows with the text.
*wpos\cy=*liedit\cy+3
*wpos\x=*liedit\x
*wpos\y=*liedit\y-2
result=CallWindowProc_(oldwinproc, hWnd, uMsg, wParam, lParam)
Case #WM_NCDESTROY
result=CallWindowProc_(oldwinproc, hWnd, uMsg, wParam, lParam)
RemoveProp_(hWnd, "_LIEditOldProc")
Default
result=CallWindowProc_(oldwinproc, hWnd, uMsg, wParam, lParam)
EndSelect
ProcedureReturn result
EndProcedure
Procedure UnSetListIconEditable(listID)
Protected hWnd, *mem._LIEdit
If IsGadget(listID) And GadgetType(listID)=#PB_GadgetType_ListIcon
hWnd = GadgetID(listID)
*mem = GetProp_(hWnd, "_LIEdit")
If *mem
SendMessage_(hWnd, #LVM_EDITLABEL, 0, 0)
SetWindowLongPtr_(hWnd, #GWL_WNDPROC, *mem\listOldProc)
FreeMemory(*mem)
RemoveProp_(hWnd, "_LIEdit")
EndIf
EndIf
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
#ListIcon = 1
OpenWindow(0, 100, 100, 600, 600, "ListIcon Example", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ListIconGadget(#ListIcon, 5, 5, 490, 390, "", 0, #PB_ListIcon_GridLines)
; Creation des colonnes
For i = 1 To 5
AddGadgetColumn(#ListIcon, i, "Col " + Str(i), 100)
Next
; Ecriture dans les cellules
For row = 1 To 2
AddGadgetItem(#ListIcon, -1, "")
For col = 1 To 5
SetGadgetItemText(#ListIcon, row - 1, "row " + Str(row - 1) + ", col " + Str(col), col)
Next
Next
; Rendre les cellules editables sans ecrire (Juste ajouter une ligne vide)
For row = 3 To 20
AddGadgetItem(#ListIcon, -1, "")
Next
SetListIconEditable(#ListIcon)
; Donner le focus à une cellule
EditCell(#ListIcon, 1,3)
; Retourne le numero de la ligne sélectionnée
Debug LigneSelection(#ListIcon)
; Rendre une cellule non editable
Debug CaseEditable(1, 1)
CaseEditable(1, 1, #False) ; N'est plus éditable
Debug CaseEditable(1, 1)
CaseEditable(1, 1, #True) ; Redevient editable
Debug CaseEditable(1, 1)
; Rendre la ListIcon non editable (Plante)
UnSetListIconEditable(#ListIcon)
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
CompilerEndIf