AllowLVEdits Version 2.2
-
- Always Here
- Posts: 6425
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: AllowLVEdits Version 2.0
....Nothing to apologise for! Thank you for sharing the pbi file, I will study the methods carefully, my own efforts were reliable but way too slow with huge lists.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
- electrochrisso
- Addict
- Posts: 980
- Joined: Mon May 14, 2007 2:13 am
- Location: Darling River
-
- Addict
- Posts: 1654
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: AllowLVEdits Version 2.0
Wow this is a pretty neat .pbi !
I wonder if I could use this.
I wonder if I could use this.
- netmaestro
- PureBasic Bullfrog
- Posts: 8425
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: AllowLVEdits Version 2.2
Update today, current version is 2.20.
While using the cashflow sample provided in the first post, I noticed that there was a delay in the edit box coming up. I traced it to too many recalcs being done, and this turned out to be happening because the library was sending #PB_EventType_Change to the calling program when a cell was edited. I had assumed that #PB_EventType_Change for the ListIcon meant cell contents were changed. I was wrong, it turns out that event type means only that the currently selected item is changed. Since there is no event type for cell changes, I had to make a custom one for this library. Also, I added three new commands useful to the programmer for when edits happen. Upon receiving the message #PB_Event_Gadget with EventType() = #Ale_Cellcontents_Changed, these commands are available:
Ale_ColumnChanged()
Ale_RowChanged()
Ale_OriginalText()
Details are in the preamble to the code in the first post, code is updated and the cashflow example is updated with undo/redo demonstration.
While using the cashflow sample provided in the first post, I noticed that there was a delay in the edit box coming up. I traced it to too many recalcs being done, and this turned out to be happening because the library was sending #PB_EventType_Change to the calling program when a cell was edited. I had assumed that #PB_EventType_Change for the ListIcon meant cell contents were changed. I was wrong, it turns out that event type means only that the currently selected item is changed. Since there is no event type for cell changes, I had to make a custom one for this library. Also, I added three new commands useful to the programmer for when edits happen. Upon receiving the message #PB_Event_Gadget with EventType() = #Ale_Cellcontents_Changed, these commands are available:
Ale_ColumnChanged()
Ale_RowChanged()
Ale_OriginalText()
Details are in the preamble to the code in the first post, code is updated and the cashflow example is updated with undo/redo demonstration.
BERESHEIT
- electrochrisso
- Addict
- Posts: 980
- Joined: Mon May 14, 2007 2:13 am
- Location: Darling River
Re: AllowLVEdits Version 2.2
I noticed that too NM, I thought it was happening with updating the file, but still I only had a quick look at the code.
Those extra commands are a great edition.
Anyway thanks for the code to play with.
Those extra commands are a great edition.
Anyway thanks for the code to play with.
PureBasic! Purely one of the best
- netmaestro
- PureBasic Bullfrog
- Posts: 8425
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: AllowLVEdits Version 2.2
You are on the mark with that observation, that was half of the problem. I reworked it so that it only saves to the file if you click the save toolbar icon and on exit. All these years I've been misunderstanding #PB_EventType_Change for the listicon, it makes me wonder if I'm losing my mind Thanks for the testing and feedback, it's appreciated!I thought it was happening with updating the file
BERESHEIT
Re: AllowLVEdits Version 2.2
Very good job ...
If I had one suggestion it would be able to create multiple line for each date if necessary ... This would be a perfect time to log movements household budget.
But hey, it's just an idea ...
If I had one suggestion it would be able to create multiple line for each date if necessary ... This would be a perfect time to log movements household budget.
But hey, it's just an idea ...
Sorry for my english ! (Windows Xp, Vista and Windows 7, Windows 10)
Re: AllowLVEdits Version 2.2
Thanks for update, very useful
please me if maybe it and you find a bit free^free time:
if i paste from clipboard into a cell and then click on other cell , i need my pasted things remain into cell and don't remove in event, sorry for my bad English
please me if maybe it and you find a bit free^free time:
if i paste from clipboard into a cell and then click on other cell , i need my pasted things remain into cell and don't remove in event, sorry for my bad English
- netmaestro
- PureBasic Bullfrog
- Posts: 8425
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: AllowLVEdits Version 2.2
@Tomi: If you hit <Enter> after the paste the data will stay.
-Left doubleclick a date and a duplicate is inserted below it
-Right doubleclick a duplicated date and the row is deleted.
Right-doubleclicks for deletions are bulletproof because they are only executed if the date in the row above is identical. This way you can't accidentally remove a date altogether or remove the wrong date.
Thanks for the suggestion, it makes the program much more usable as a cashflow worksheet
Excellent suggestion. I had been trying to keep the demo code as simple as possible but this idea is too good not to implement. Cashflow demo is now updated as follows:GeBonet wrote:If I had one suggestion it would be able to create multiple line for each date if necessary ... This would be a perfect time to log movements household budget.
-Left doubleclick a date and a duplicate is inserted below it
-Right doubleclick a duplicated date and the row is deleted.
Right-doubleclicks for deletions are bulletproof because they are only executed if the date in the row above is identical. This way you can't accidentally remove a date altogether or remove the wrong date.
Thanks for the suggestion, it makes the program much more usable as a cashflow worksheet
BERESHEIT
Re: AllowLVEdits Version 2.2
Well now, I am glad it is useful ... And thank you!
A thousand apologies if this shows the reality of balances
Very good job.
A thousand apologies if this shows the reality of balances
Very good job.
Sorry for my english ! (Windows Xp, Vista and Windows 7, Windows 10)
- electrochrisso
- Addict
- Posts: 980
- Joined: Mon May 14, 2007 2:13 am
- Location: Darling River
Re: AllowLVEdits Version 2.2
Nah, I think PB getting many new features on each update to have time to test every option in every situation.All these years I've been misunderstanding #PB_EventType_Change for the listicon, it makes me wonder if I'm losing my mind Thanks for the testing and feedback, it's appreciated!
PureBasic! Purely one of the best
- netmaestro
- PureBasic Bullfrog
- Posts: 8425
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: AllowLVEdits Version 2.2
This program is updated to use the new module library. Here's the code:
I should mention that this version I pulled from a project and it has special processing for window# 2 and column# 2, it pops up a menu to make a choice from. You won't need this so just find SaveAndExitDesc() and use SaveAndExit() for everything.
Code: Select all
;======================================================================================================================
; Library: AllowLVEdits 3.0
; Author: netmaestro
; Date: June 19, 2007 last update July 7, 2013
; Target OS: Microsoft Windows All
; Target Compiler: PureBasic version 5.20+
; License: Free, unrestricted, no warranty
;
; This library allows the user to edit the contents of ListIcon cells
; by right-clicking on them.
;
; EXPORTED COMMANDS:
;
; StartEditing(WindowNumber, GadgetNumber); Make ListIcon gadget cells editable
;
; StopEditing(); Take ListIcon gadget out of editable mode
;
; SetMoneyColumn(Column, Width) ; Width is number of digits before the decimal place
;
; DecimalMask(char) ; Char is the character you wish to use for decimal point, usually '.' or ',' (46 or 44)
;
; MaskColumn(Column) ; Disallows edits for the passed column
;
; Ale_RowChanged() ; Returns the row of the last-edited item
;
; Ale_ColumnChanged() ; Returns the column of the last-edited item
;
; Ale_OriginalText() ; Returns a string containing the original item text before the edit
;
; DETECTING CHANGES:
;
; When this library detects an edit to a listicon cell, it will send a #PB_Event_Gadget message
; to your WaitWindowEvent() loop with the EventType() of #Ale_Cellcontents_Changed. When you receive
; this message, three commands are available to you:
;
; - Ale_RowChanged()
; - Ale_ColumnChanged()
; - Ale_OriginalText()
;
; These commands may only be called after receiving #PB_Event_Gadget with event type = #Ale_Cellcontents_Changed.
; Additionally, they may only be called once as calling them clears their contents. So if you need them later you
; must save their return values in a variable of your own.
;
; Using these three commands and a linked-list or array of stored changes, you can easily provide a user with
; the option of cancelling all changes or stepping through an undo list.
;
; This version of the program is contstructed using the Module library which is available beginning with v5.20
;
; Include this file in your program and if it's the only module you'll be using in your project you can do:
;
; Usemodule LVEdit
; ... call the commands as needed
; Unusemodule LVEdit
;
; If you are using other modules in your project the commands must be qualified with the module name like so:
;
; LVEdit::StartEditing(<window>, <listicon>)
;
;
;======================================================================================================================
DeclareModule LVEdit
Enumeration #PB_Event_FirstCustomValue
#Ale_Cellcontents_Changed
EndEnumeration
Declare Ale_ColumnChanged(cell = -1)
Declare Ale_RowChanged(Item = -1)
Declare.s Ale_OriginalText(orig$ = "")
Declare SaveAndExit()
Declare SaveAndExit_Desc(newtext$)
Declare SubClass_String(hwnd, Message, wparam, lparam)
Declare.s GetNewText()
Declare ResizeEdit(hwnd)
Declare hookproc(nCode, wparam, lparam)
Declare SubClass_LV(hwnd, Message, wparam, lparam)
Declare StopEditing(); Take ListIcon gadget out of editable mode
Declare StartEditing(WindowNumber, GadgetNumber); Make ListIcon gadget editable
Declare SetMoneyColumn(Column, Width) ; Width is number of digits before the decimal place
Declare DecimalMask(char) ;Char is the symbol to use For decimal point, usually '.' Or ',' (46 Or 44)
Declare MaskColumn(Column) ; Disallows edits for the passed column, the lib will gray it out
EndDeclareModule
Module LVEdit
Import ""
PB_Gadget_SendGadgetCommand(hWnd, EventType)
EndImport
Structure EDITDATA
Array MoneyColumn.i(100)
Array Masked.i(100)
_edits210_oldlist.i
_edits210_EditActive.i
_edits210_oldstring.i
_edits210_string.i
_edits210_decimal.i
_edits210_container.i
_edits210_window.i
_edits210_item.i
_edits210_subitem.i
_edits210_gadget.i
_edits210_itemrect.RECT
_edits210_menuhook.i
EndStructure
Global descpopup = CreatePopupMenu(#PB_Any) ; Scope is limited to the module
MenuItem(10, "Opening Balance")
MenuItem(11, "Deposit")
MenuItem(12, "Campsite Fees")
MenuItem(13, "Firewood Sales")
MenuBar()
MenuItem(14, "Fuel Receipt")
MenuItem(15, "Propane Receipt")
MenuItem(16, "Tools/Supplies Receipt")
MenuItem(17, "Withdrawal")
MenuBar()
MenuItem(18, "<leave blank>")
*LVEdits.EDITDATA = AllocateMemory(SizeOf(EDITDATA))
InitializeStructure(*LVEdits, EDITDATA)
Procedure Ale_ColumnChanged(cell = -1)
Static cellchanged
If cell<> -1
cellchanged = cell
ProcedureReturn
Else
result = cellchanged
cellchanged = -1
ProcedureReturn result
EndIf
EndProcedure
Procedure Ale_RowChanged(Item = -1)
Static Itemchanged
If Item<> -1
Itemchanged = Item
ProcedureReturn
Else
result = Itemchanged
Itemchanged = -1
ProcedureReturn result
EndIf
EndProcedure
Procedure.s Ale_OriginalText(orig$ = "")
Static originaltext$
If orig$ <> ""
originaltext$ = orig$
ProcedureReturn
Else
result$ = originaltext$
originaltext$ = ""
ProcedureReturn result$
EndIf
EndProcedure
Procedure SaveAndExit()
Shared *LVEdits.EDITDATA
tmp$ = GetGadgetText(*LVEdits\_edits210_string)
orig$ = GetGadgetItemText(*LVEdits\_edits210_gadget,*LVEdits\_edits210_item,*LVEdits\_edits210_subitem)
If Trim(tmp$) <> Trim(orig$)
SendChange = #True
Ale_OriginalText(orig$)
Else
SendChange = #False
EndIf
If *LVEdits\_edits210_item >= 0
SetGadgetState(*LVEdits\_edits210_gadget, *LVEdits\_edits210_item)
EndIf
crlf = FindString(tmp$, #CRLF$, 1)
If crlf
SetGadgetText(*LVEdits\_edits210_string,ReplaceString(tmp$,#CRLF$,""))
SendMessage_(sg,#EM_SETSEL,crlf-1,crlf-1)
EndIf
If *LVEdits\MoneyColumn(*LVEdits\_edits210_subitem)
tmpout.s = Trim(GetGadgetText(*LVEdits\_edits210_string))
ploc = FindString(tmpout,Chr(*LVEdits\_edits210_decimal),1)
If ploc
If ploc = 1
tmpout = "0" + tmpout
EndIf
While Len(tmpout) - FindString(tmpout,Chr(*LVEdits\_edits210_decimal),1) < 2
tmpout+"0"
SetGadgetText(*LVEdits\_edits210_string, tmpout)
Wend
Else
If tmpout <> ""
tmpout + Chr(*LVEdits\_edits210_decimal) + "00"
SetGadgetText(*LVEdits\_edits210_string, tmpout)
EndIf
EndIf
If Val(tmpout) = 0
tmpout= ""
EndIf
SetGadgetItemText(*LVEdits\_edits210_gadget,*LVEdits\_edits210_item, RSet(Trim(tmpout),*LVEdits\MoneyColumn(*LVEdits\_edits210_subitem)+3," "), *LVEdits\_edits210_subitem)
Else
SetGadgetItemText(*LVEdits\_edits210_gadget,*LVEdits\_edits210_item, GetGadgetText(*LVEdits\_edits210_string), *LVEdits\_edits210_subitem)
EndIf
FreeGadget(*LVEdits\_edits210_string)
FreeGadget(*LVEdits\_edits210_container)
*LVEdits\_edits210_EditActive = #False
If SendChange
Ale_ColumnChanged(*LVEdits\_edits210_subitem)
Ale_RowChanged(*LVEdits\_edits210_item)
PB_Gadget_SendGadgetCommand(GadgetID(*LVEdits\_edits210_gadget), #Ale_Cellcontents_Changed)
EndIf
;UnhookWindowsHookEx_(*LVEdits\_edits210_menuhook)
EndProcedure
Procedure SaveAndExit_Desc(newtext$)
Shared *LVEdits.EDITDATA
tmp$ = newtext$
orig$ = GetGadgetItemText(*LVEdits\_edits210_gadget,*LVEdits\_edits210_item,*LVEdits\_edits210_subitem)
If Trim(tmp$) <> Trim(orig$)
SendChange = #True
Ale_OriginalText(orig$)
Else
SendChange = #False
EndIf
SetGadgetItemText(*LVEdits\_edits210_gadget,*LVEdits\_edits210_item, newtext$, *LVEdits\_edits210_subitem)
If SendChange
Ale_ColumnChanged(*LVEdits\_edits210_subitem)
Ale_RowChanged(*LVEdits\_edits210_item)
PB_Gadget_SendGadgetCommand(GadgetID(*LVEdits\_edits210_gadget), #Ale_Cellcontents_Changed)
EndIf
EndProcedure
Procedure.s GetNewDescription()
Shared *LVEdits.EDITDATA
DisplayPopupMenu(descpopup, WindowID(*LVEdits\_edits210_window))
EndProcedure
Procedure SubClass_String(hwnd, Message, wparam, lparam)
Shared *LVEdits.EDITDATA
Protected blocking=0, ploc, tmpout.s
result = CallWindowProc_(*LVEdits\_edits210_oldlist, hwnd, Message, wparam, lparam)
Select Message
Case #WM_RBUTTONDOWN
*LVEdits\_edits210_menuhook = SetWindowsHookEx_(#WH_MOUSE, @hookproc(), 0, GetCurrentThreadId_())
Case #WM_DESTROY
UnhookWindowsHookEx_(*LVEdits\_edits210_menuhook)
Case #WM_KEYDOWN
Select wparam
Case #VK_RETURN
SaveAndExit()
If *LVEdits\_edits210_window <> 1 ; <------ Change for Summit
*LVEdits\_edits210_item + 1
If *LVEdits\_edits210_item < CountGadgetItems(*LVEdits\_edits210_gadget)
RtlZeroMemory_(@*LVEdits\_edits210_itemrect,SizeOf(RECT))
*LVEdits\_edits210_itemrect\top = *LVEdits\_edits210_subitem
SendMessage_(GadgetID(*LVEdits\_edits210_gadget), #LVM_GETSUBITEMRECT, *LVEdits\_edits210_item, @*LVEdits\_edits210_itemrect)
GetNewText()
EndIf
EndIf
Case #VK_ESCAPE
FreeGadget(*LVEdits\_edits210_string)
FreeGadget(*LVEdits\_edits210_container)
*LVEdits\_edits210_EditActive = #False
Case #VK_LEFT
SendMessage_(hwnd, #EM_GETSEL, @first.l, @last.l)
If first = 0
SaveAndExit()
currentsubitem = *LVEdits\_edits210_subitem
*LVEdits\_edits210_subitem - 1
If *LVEdits\_edits210_subitem >= 1
While *LVEdits\Masked(*LVEdits\_edits210_subitem) And *LVEdits\_edits210_subitem >= 0
*LVEdits\_edits210_subitem - 1
If *LVEdits\_edits210_subitem < 1
*LVEdits\_edits210_subitem = currentsubitem
EndIf
Wend
Else
*LVEdits\_edits210_subitem + 1
EndIf
RtlZeroMemory_(@*LVEdits\_edits210_itemrect,SizeOf(RECT))
*LVEdits\_edits210_itemrect\top = *LVEdits\_edits210_subitem
SendMessage_(GadgetID(*LVEdits\_edits210_gadget), #LVM_GETSUBITEMRECT, *LVEdits\_edits210_item, @*LVEdits\_edits210_itemrect)
GetNewText()
EndIf
Case #VK_RIGHT
SendMessage_(hwnd, #EM_GETSEL, @first.l, @last.l)
If Len(GetGadgetText(*LVEdits\_edits210_string)) = last
headerhWnd=SendMessage_(GadgetID(*LVEdits\_edits210_gadget),#LVM_GETHEADER,0,0)
numcolumns = SendMessage_(headerhWnd, #HDM_GETITEMCOUNT,0,0)
If *LVEdits\_edits210_subitem < numcolumns-1
SaveAndExit()
currentsubitem = *LVEdits\_edits210_subitem
*LVEdits\_edits210_subitem + 1
If *LVEdits\_edits210_subitem < numcolumns
While *LVEdits\Masked(*LVEdits\_edits210_subitem) And *LVEdits\_edits210_subitem <= numcolumns
*LVEdits\_edits210_subitem + 1
If *LVEdits\_edits210_subitem >= numcolumns
*LVEdits\_edits210_subitem = currentsubitem
EndIf
Wend
Else
*LVEdits\_edits210_subitem -1
EndIf
RtlZeroMemory_(@*LVEdits\_edits210_itemrect,SizeOf(RECT))
*LVEdits\_edits210_itemrect\top = *LVEdits\_edits210_subitem
SendMessage_(GadgetID(*LVEdits\_edits210_gadget), #LVM_GETSUBITEMRECT, *LVEdits\_edits210_item, @*LVEdits\_edits210_itemrect)
GetNewText()
EndIf
EndIf
Case #VK_UP
SaveAndExit()
*LVEdits\_edits210_item - 1 : If *LVEdits\_edits210_item <= 0 : *LVEdits\_edits210_item = 0 : EndIf
RtlZeroMemory_(@*LVEdits\_edits210_itemrect,SizeOf(RECT))
*LVEdits\_edits210_itemrect\top = *LVEdits\_edits210_subitem
SendMessage_(GadgetID(*LVEdits\_edits210_gadget), #LVM_GETSUBITEMRECT, *LVEdits\_edits210_item, @*LVEdits\_edits210_itemrect)
GetNewText()
Case #VK_DOWN
SaveAndExit()
*LVEdits\_edits210_item + 1:If *LVEdits\_edits210_item >= CountGadgetItems(*LVEdits\_edits210_gadget):*LVEdits\_edits210_item - 1 : EndIf
RtlZeroMemory_(@*LVEdits\_edits210_itemrect,SizeOf(RECT))
*LVEdits\_edits210_itemrect\top = *LVEdits\_edits210_subitem
SendMessage_(GadgetID(*LVEdits\_edits210_gadget), #LVM_GETSUBITEMRECT, *LVEdits\_edits210_item, @*LVEdits\_edits210_itemrect)
GetNewText()
EndSelect
Case #WM_CHAR
If *LVEdits\MoneyColumn(*LVEdits\_edits210_subitem)
blocking = 1
Select wparam
Case *LVEdits\_edits210_decimal, 48 To 57
tmpout.s = GetGadgetText(*LVEdits\_edits210_string)
If FindString(tmpout, Chr(*LVEdits\_edits210_decimal), 1) = 0
If Len(tmpout) > *LVEdits\MoneyColumn(*LVEdits\_edits210_subitem)
If wparam <> *LVEdits\_edits210_decimal
SendMessage_(hwnd, #EM_GETSEL, 0, @pos)
SetGadgetText(*LVEdits\_edits210_string, Left(tmpout,Len(tmpout)-1))
SendMessage_(hwnd, #EM_SETSEL, pos-1, pos-1)
EndIf
EndIf
EndIf
If wparam = *LVEdits\_edits210_decimal
If CountString(tmpout, Chr(*LVEdits\_edits210_decimal)) > 1
SendMessage_(hwnd, #EM_GETSEL, 0, @pos)
SetGadgetText(*LVEdits\_edits210_string, Left(tmpout,Len(tmpout)-1))
SendMessage_(hwnd, #EM_SETSEL, pos-1, pos-1)
EndIf
EndIf
If FindString(tmpout,Chr(*LVEdits\_edits210_decimal),1)
If Len(tmpout) - FindString(tmpout,Chr(*LVEdits\_edits210_decimal),1) > 2
SendMessage_(hwnd, #EM_GETSEL, 0, @pos)
SetGadgetText(*LVEdits\_edits210_string, Left(tmpout,Len(tmpout)-1))
SendMessage_(hwnd, #EM_SETSEL, pos-1, pos-1)
EndIf
EndIf
Default
If wparam <> 8 And wparam <> 13
tmpout.s = GetGadgetText(*LVEdits\_edits210_string)
SendMessage_(hwnd, #EM_GETSEL, 0, @pos)
SetGadgetText(*LVEdits\_edits210_string, Left(tmpout,Len(tmpout)-1))
SendMessage_(hwnd, #EM_SETSEL, pos-1, pos-1)
EndIf
EndSelect
EndIf
Case #WM_PASTE
If *LVEdits\MoneyColumn(*LVEdits\_edits210_subitem)
tmpout.s = GetGadgetText(*LVEdits\_edits210_string)
If FindString(tmpout,Chr(*LVEdits\_edits210_decimal),1)
validlength = *LVEdits\MoneyColumn(*LVEdits\_edits210_subitem)+3
Else
validlength = *LVEdits\MoneyColumn(*LVEdits\_edits210_subitem)
EndIf
If Len(tmpout)<=validlength
ok = #True
*cc.CHARACTER = @tmpout
While *cc\c
Select *cc\c
Case '0' To '9', *LVEdits\_edits210_decimal
Default
ok = #False
EndSelect
*cc+1
Wend
Else
ok = #False
EndIf
If Not ok
SetGadgetText(*LVEdits\_edits210_string, "")
EndIf
EndIf
EndSelect
ProcedureReturn result
EndProcedure
Procedure hookproc(ncode, wparam, lparam)
Shared *LVEdits.EDITDATA
If ncode<0 Or IsGadget(*LVEdits\_edits210_string) = 0
result = CallNextHookEx_(*LVEdits\_edits210_menuhook, ncode, wparam, lparam)
ProcedureReturn result
EndIf
If wparam = #WM_RBUTTONUP
If IsGadget(*LVEdits\_edits210_string)
*mhs.MOUSEHOOKSTRUCT = lparam
If *mhs\hwnd = GadgetID(*LVEdits\_edits210_string)
ProcedureReturn #True
EndIf
EndIf
EndIf
ProcedureReturn CallNextHookEx_(*LVEdits\_edits210_menuhook, ncode, wparam, lparam)
EndProcedure
Procedure.s GetNewText()
Shared *LVEdits.EDITDATA
*LVEdits\_edits210_EditActive = #True
Protected grect.rect
twleft = *LVEdits\_edits210_itemrect\left+6
twtop = *LVEdits\_edits210_itemrect\top
winwidth = *LVEdits\_edits210_itemrect\right-*LVEdits\_edits210_itemrect\left-8
winheight = *LVEdits\_edits210_itemrect\bottom-*LVEdits\_edits210_itemrect\top-1
oldgadgetlist = UseGadgetList(GadgetID(*LVEdits\_edits210_gadget))
*LVEdits\_edits210_container = ContainerGadget(#PB_Any, twleft-2,twtop-2,winwidth+4,winheight+4)
HideGadget(*LVEdits\_edits210_container, 1)
SetGadgetColor(*LVEdits\_edits210_container,#PB_Gadget_BackColor, #Black)
If *LVEdits\MoneyColumn(*LVEdits\_edits210_subitem)
*LVEdits\_edits210_string = StringGadget(#PB_Any,2,2,winwidth,winheight,RemoveString(GetGadgetItemText(*LVEdits\_edits210_gadget,*LVEdits\_edits210_item,*LVEdits\_edits210_subitem)," "),#PB_String_BorderLess|#ES_MULTILINE|#ES_AUTOVSCROLL)
Else
*LVEdits\_edits210_string = StringGadget(#PB_Any,2,2,winwidth,winheight,GetGadgetItemText(*LVEdits\_edits210_gadget,*LVEdits\_edits210_item,*LVEdits\_edits210_subitem),#PB_String_BorderLess|#ES_MULTILINE|#ES_AUTOVSCROLL|#PB_String_UpperCase)
EndIf
CloseGadgetList()
SetGadgetFont(*LVEdits\_edits210_string, GetGadgetFont(*LVEdits\_edits210_gadget))
UseGadgetList(oldgadgetlist)
SetActiveGadget(*LVEdits\_edits210_string)
*LVEdits\_edits210_oldstring=SetWindowLong_(GadgetID(*LVEdits\_edits210_string), #GWL_WNDPROC, @SubClass_String())
SetWindowLong_(GadgetID(*LVEdits\_edits210_string), #GWL_EXSTYLE, GetWindowLong_(GadgetID(*LVEdits\_edits210_string), #GWL_EXSTYLE) &~ #WS_EX_CONTEXTHELP)
SendMessage_(GadgetID(*LVEdits\_edits210_string),#EM_SETSEL,0,-1)
HideGadget(*LVEdits\_edits210_container, 0)
GetWindowRect_(GadgetID(*LVEdits\_edits210_gadget), @gr.RECT)
GetWindowRect_(GadgetID(*LVEdits\_edits210_container), @cr.RECT)
GetClientRect_(GadgetID(*LVEdits\_edits210_gadget), @grc.RECT)
If cr\top - gr\top < winheight
SendMessage_(GadgetID(*LVEdits\_edits210_gadget), #WM_VSCROLL, #SB_LINEUP ,0)
ElseIf cr\top - gr\top > grc\bottom-grc\top-winheight
SendMessage_(GadgetID(*LVEdits\_edits210_gadget), #WM_VSCROLL, #SB_LINEDOWN ,0)
EndIf
If GadgetWidth(*LVEdits\_edits210_gadget)-twleft < winwidth
SendMessage_(GadgetID(*LVEdits\_edits210_gadget), #WM_HSCROLL, #SB_RIGHT, 0)
ElseIf twleft<0
SendMessage_(GadgetID(*LVEdits\_edits210_gadget), #WM_HSCROLL, #SB_LEFT, 0)
EndIf
EndProcedure
Procedure ResizeEdit(hwnd)
Shared *LVEdits.EDITDATA
RtlZeroMemory_(@*LVEdits\_edits210_itemrect,SizeOf(RECT))
*LVEdits\_edits210_itemrect\top = *LVEdits\_edits210_subitem
SendMessage_(hwnd, #LVM_GETSUBITEMRECT, *LVEdits\_edits210_item, @*LVEdits\_edits210_itemrect)
twleft = *LVEdits\_edits210_itemrect\left+6
twtop = *LVEdits\_edits210_itemrect\top
winwidth = *LVEdits\_edits210_itemrect\right-*LVEdits\_edits210_itemrect\left-8
winheight = *LVEdits\_edits210_itemrect\bottom-*LVEdits\_edits210_itemrect\top-1
ResizeGadget(*LVEdits\_edits210_container,twleft-2,twtop-2,winwidth+4,winheight+4)
ResizeGadget(*LVEdits\_edits210_string, 2,2, GadgetWidth(*LVEdits\_edits210_container)-4, GadgetHeight(*LVEdits\_edits210_container)-4)
InvalidateRect_(GadgetID(*LVEdits\_edits210_container),0,1)
If GadgetY(*LVEdits\_edits210_container) < winheight
HideGadget(*LVEdits\_edits210_container, 1)
Else
HideGadget(*LVEdits\_edits210_container, 0)
SetActiveGadget(*LVEdits\_edits210_string)
EndIf
EndProcedure
Procedure SubClass_LV(hwnd, Message, wparam, lparam)
Shared *LVEdits.EDITDATA
result = CallWindowProc_(*LVEdits\_edits210_oldlist, hwnd, Message, wparam, lparam)
If message = #WM_KEYUP
If wparam = #VK_TAB
If GetAsyncKeyState_(#VK_SHIFT) & 32768
SaveAndExit()
currentsubitem = *LVEdits\_edits210_subitem
*LVEdits\_edits210_subitem - 1
If *LVEdits\_edits210_subitem >= 1
While *LVEdits\Masked(*LVEdits\_edits210_subitem) And *LVEdits\_edits210_subitem >= 0
*LVEdits\_edits210_subitem - 1
If *LVEdits\_edits210_subitem < 1
*LVEdits\_edits210_subitem = currentsubitem
EndIf
Wend
Else
*LVEdits\_edits210_subitem + 1
EndIf
RtlZeroMemory_(@*LVEdits\_edits210_itemrect,SizeOf(RECT))
*LVEdits\_edits210_itemrect\top = *LVEdits\_edits210_subitem
SendMessage_(GadgetID(*LVEdits\_edits210_gadget), #LVM_GETSUBITEMRECT, *LVEdits\_edits210_item, @*LVEdits\_edits210_itemrect)
GetNewText()
Else
If IsGadget(*LVEdits\_edits210_string)
headerhWnd=SendMessage_(GadgetID(*LVEdits\_edits210_gadget),#LVM_GETHEADER,0,0)
numcolumns = SendMessage_(headerhWnd, #HDM_GETITEMCOUNT,0,0)
SaveAndExit()
currentsubitem = *LVEdits\_edits210_subitem
*LVEdits\_edits210_subitem + 1
If *LVEdits\_edits210_subitem < numcolumns
While *LVEdits\Masked(*LVEdits\_edits210_subitem) And *LVEdits\_edits210_subitem <= numcolumns
*LVEdits\_edits210_subitem + 1
If *LVEdits\_edits210_subitem >= numcolumns
*LVEdits\_edits210_subitem = currentsubitem
EndIf
Wend
Else
*LVEdits\_edits210_subitem -1
EndIf
RtlZeroMemory_(@*LVEdits\_edits210_itemrect,SizeOf(RECT))
*LVEdits\_edits210_itemrect\top = *LVEdits\_edits210_subitem
SendMessage_(GadgetID(*LVEdits\_edits210_gadget), #LVM_GETSUBITEMRECT, *LVEdits\_edits210_item, @*LVEdits\_edits210_itemrect)
GetNewText()
EndIf
EndIf
EndIf
EndIf
If message = #WM_VSCROLL Or message = #WM_HSCROLL
If IsGadget(*LVEdits\_edits210_container) And *LVEdits\_edits210_container <> 0
ResizeEdit(hwnd)
EndIf
EndIf
If message=#WM_NOTIFY
If IsGadget(*LVEdits\_edits210_container) And *LVEdits\_edits210_container <> 0
*nmHEADER.HD_NOTIFY = lParam
Select *nmHEADER\hdr\code
Case #HDN_ITEMCHANGING
ResizeEdit(hwnd)
EndSelect
EndIf
EndIf
If Message = #WM_RBUTTONDOWN
If Not *LVEdits\_edits210_EditActive
GetCursorPos_(@cp.POINT)
MapWindowPoints_(0,hwnd,@cp,1)
HitInfo.LVHITTESTINFO
Hitinfo\pt\x = cp\x
HitInfo\pt\y = cp\y
SendMessage_(hwnd,#LVM_SUBITEMHITTEST ,0,@HitInfo)
SetGadgetState(*LVEdits\_edits210_gadget, hitinfo\iitem)
If hitinfo\isubitem > 0 And HitInfo\iItem >= 0
RtlZeroMemory_(@*LVEdits\_edits210_itemrect,SizeOf(RECT))
*LVEdits\_edits210_itemrect\top = hitinfo\iSubItem
SendMessage_(hwnd,#LVM_GETSUBITEMRECT, hitinfo\iitem, @*LVEdits\_edits210_itemrect)
*LVEdits\_edits210_item = hitinfo\iitem
*LVEdits\_edits210_subitem = hitinfo\iSubItem
If Not *LVEdits\Masked(*LVEdits\_edits210_subitem)
If *LVEdits\_edits210_subitem = 2 And *LVEdits\_edits210_window = 2
GetNewDescription()
Else
GetNewText()
EndIf
EndIf
EndIf
Else
FreeGadget(*LVEdits\_edits210_string)
FreeGadget(*LVEdits\_edits210_container)
*LVEdits\_edits210_EditActive = #False
EndIf
EndIf
If Message = #WM_LBUTTONDOWN
If *LVEdits\_edits210_EditActive
FreeGadget(*LVEdits\_edits210_string)
FreeGadget(*LVEdits\_edits210_container)
*LVEdits\_edits210_EditActive = #False
EndIf
EndIf
ProcedureReturn result
EndProcedure
Procedure StopEditing(); Take ListIcon gadget out of editable mode
Shared *LVEdits.EDITDATA
*LVEdits\_edits210_editactive = #False
If *LVEdits\_edits210_string
If IsGadget(*LVEdits\_edits210_string) : FreeGadget(*LVEdits\_edits210_string) : EndIf
EndIf
If *LVEdits\_edits210_container
If IsGadget(*LVEdits\_edits210_container) : FreeGadget(*LVEdits\_edits210_container) : EndIf
EndIf
If *LVEdits\_edits210_oldlist
If IsGadget(*LVEdits\_edits210_gadget)
SetWindowLong_(GadgetID(*LVEdits\_edits210_gadget), #GWL_WNDPROC, *LVEdits\_edits210_oldlist)
*LVEdits\_edits210_oldlist = 0
EndIf
EndIf
EndProcedure
Procedure StartEditing(WindowNumber, GadgetNumber); Make ListIcon gadget cells editable
Shared *LVEdits.EDITDATA
StopEditing()
*LVEdits\_edits210_window=WindowNumber
Protected cn$ = Space(100)
GetClassName_(GadgetID(GadgetNumber),@cn$,99)
If UCase(Trim(cn$)) = "SYSLISTVIEW32" And *LVEdits\_edits210_oldlist = 0
*LVEdits\_edits210_oldlist=SetWindowLong_(GadgetID(GadgetNumber), #GWL_WNDPROC, @SubClass_LV())
*LVEdits\_edits210_gadget = GadgetNumber
*LVEdits\_edits210_decimal = 46
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure SetMoneyColumn(Column, Width) ; Width is number of digits before the decimal place
Shared *LVEdits.EDITDATA
If *LVEdits\_edits210_oldlist
With lvc.LV_COLUMN
\Mask = #LVCF_FMT
\fmt=#LVCFMT_RIGHT
EndWith
SendMessage_(GadgetID(*LVEdits\_edits210_gadget),#LVM_SETCOLUMN,column,@lvc)
If width >= 1
*LVEdits\MoneyColumn(Column) = width
Else
*LVEdits\MoneyColumn(Column) = 1
EndIf
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure DecimalMask(char) ; Char is the character you wish to use for decimal point, usually '.' or ',' (46 or 44)
Shared *LVEdits.EDITDATA
*LVEdits\_edits210_decimal = char
EndProcedure
Procedure MaskColumn(Column) ; Disallows edits for the passed column
Shared *LVEdits.EDITDATA
If *LVEdits\_edits210_oldlist
*LVEdits\Masked(Column) = 1
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
EndModule
BERESHEIT
- Zebuddi123
- Enthusiast
- Posts: 794
- Joined: Wed Feb 01, 2012 3:30 pm
- Location: Nottinghamshire UK
- Contact:
Re: AllowLVEdits Version 2.2 Updated for V3.0
Updated this example cause i needed the Pbi. Hope I`ve got it correct (this new fangle Module stuff) my poor little brain hurts
Big Thanks for the V3.0 Update netmaestro
Zebuddi
Big Thanks for the V3.0 Update netmaestro
Code: Select all
;=======================================================
; Program: AllowLVEdits 3.0 Demo program
; Author: netmaestro
;=======================================================
;
IncludeFile "allowlveditsV3.pbi"
UseModule LVEdit
Structure editrecord
row.i
col.i
newtext$
oldtext$
EndStructure
Global NewList edits.editrecord()
AddElement(edits())
Procedure$ DayStr(day)
ProcedureReturn Mid("SunMonTueWedThuFriSat", day*3+1, 3)
EndProcedure
Procedure Recalc()
runningtotal.d = 0
For i = 0 To CountGadgetItems(0)-1
tmp$ = GetGadgetItemText(0,i,2)
If tmp$<>"" : runningtotal+ValD(tmp$) : EndIf
tmp$ = GetGadgetItemText(0,i,3)
If tmp$<>"" : runningtotal-ValD(tmp$) : EndIf
If runningtotal < 0
txtout.s="("+StrD(runningtotal,2)+")"
Else
txtout.s = StrD(runningtotal,2)
EndIf
SetGadgetItemText(0,i,txtout,4)
If runningtotal < 0
SetGadgetItemColor(0,i,#PB_Gadget_FrontColor, #Red, 4)
EndIf
Next
EndProcedure
Procedure Load()
If ReadFile(0, "cashflow.dat")
SendMessage_(GadgetID(0), #WM_SETREDRAW, 0,0)
While Not Eof(0)
AddGadgetItem(0, -1, ReplaceString(ReadString(0),"|",Chr(10)))
Wend
CloseFile(0)
SendMessage_(GadgetID(0), #WM_SETREDRAW, 1, 0)
Else
SendMessage_(GadgetID(0), #WM_SETREDRAW, 0,0)
For i=0 To 365*5
date = AddDate(ParseDate("%mm/%dd/%yyyy","11/01/2011") , #PB_Date_Day, i)
date$ = DayStr(DayOfWeek(date))+FormatDate("%mm/%dd/%yyyy", date)
AddGadgetItem(0, -1, Chr(10)+RSet(date$,14," ")+Chr(10)+Space(0)+Chr(10)+Space(0)+Chr(10)+Space(0)+Chr(10)+Space(0)+Chr(10))
Next
SendMessage_(GadgetID(0), #WM_SETREDRAW, 1,0)
EndIf
For i=0 To CountGadgetItems(0)-1
SetGadgetItemColor(0,i,#PB_Gadget_BackColor,RGB(240,240,240),1)
If FindString(GetGadgetItemText(0,i,4), "(", 1)
SetGadgetItemColor(0,i,#PB_Gadget_FrontColor,#Red,4)
EndIf
SetGadgetItemColor(0,i,#PB_Gadget_BackColor,RGB(240,240,240),4)
Next
EndProcedure
Procedure Save()
Dim t.s(5)
If CreateFile(0, "CashFlow.dat")
For i = 0 To CountGadgetItems(0)-1
For j=1 To 5
t(j) = GetGadgetItemText(0,i,j)
Next
WriteStringN(0, "|"+t(1)+"|"+t(2)+"|"+t(3)+"|"+t(4)+"|"+t(5)+"|" )
Next
CloseFile(0)
EndIf
EndProcedure
LoadFont(0, "Courier New",9)
w = OpenWindow(0,0,0,840,700,"Cash Flow Budget",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
CreateToolBar(0, WindowID(0))
ToolBarStandardButton(0, #PB_ToolBarIcon_Save)
ToolBarStandardButton(1, #PB_ToolBarIcon_Undo)
ToolBarStandardButton(2, #PB_ToolBarIcon_Redo)
ListIconGadget(0,0,ToolBarHeight(0),840,700-ToolBarHeight(0),"",0,#PB_ListIcon_GridLines)
SetGadgetColor(0, #PB_Gadget_LineColor, RGB(210,210,210))
AddGadgetColumn(0,1,"Date", 150)
AddGadgetColumn(0,2,"Income", 130)
AddGadgetColumn(0,3,"Expense", 130)
AddGadgetColumn(0,4,"Balance", 130)
AddGadgetColumn(0,5,"Description", 275)
SetGadgetFont(0,FontID(0))
LVEdit::StartEditing(0,0)
LVEdit::SetMoneyColumn(2,12)
LVEdit::SetMoneyColumn(3,12)
LVEdit::SetMoneyColumn(4,12)
LVEdit::MaskColumn(1)
LVEdit::MaskColumn(4)
Load()
Repeat
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_Gadget
If EventGadget() = 0
Select EventType()
Case #Ale_Cellcontents_Changed
; store undo infos
AddElement(edits())
With edits()
\col = Ale_ColumnChanged()
\row = Ale_RowChanged()
\oldtext$ = Ale_OriginalText()
\newtext$ = GetGadgetItemText(0, edits()\row, edits()\col)
EndWith
current=ListIndex(edits())
LastElement(edits())
While ListIndex(edits())<>current
DeleteElement(edits())
Wend
; recalculate the worksheet
Recalc()
Case #PB_EventType_LeftDoubleClick
GetCursorPos_(@cp.POINT)
MapWindowPoints_(0,GadgetID(0),@cp.POINT,1)
HitInfo.LVHITTESTINFO\pt = cp.POINT
SendMessage_(GadgetID(0),#LVM_SUBITEMHITTEST ,0,@HitInfo)
If hitinfo\isubitem = 1
AddGadgetItem(0, hitinfo\iItem+1, Chr(10)+GetGadgetItemText(0,hitinfo\iItem,1))
SetGadgetItemColor(0, hitinfo\iItem+1, #PB_Gadget_BackColor, RGB(240,240,240), 1)
SetGadgetItemColor(0, hitinfo\iItem+1, #PB_Gadget_BackColor, RGB(240,240,240), 4)
recalc()
EndIf
Case #PB_EventType_RightDoubleClick
GetCursorPos_(@cp.POINT)
MapWindowPoints_(0,GadgetID(0),@cp.POINT,1)
HitInfo.LVHITTESTINFO\pt = cp.POINT
SendMessage_(GadgetID(0),#LVM_SUBITEMHITTEST ,0,@HitInfo)
If hitinfo\isubitem = 1
If GetGadgetItemText(0, hitinfo\iItem, 1) = GetGadgetItemText(0, hitinfo\iItem-1, 1)
RemoveGadgetItem(0, hitinfo\iItem)
recalc()
EndIf
EndIf
EndSelect
EndIf
Case #PB_Event_Menu
Select EventMenu()
Case 0
Save()
Case 1
If ListIndex(edits())>0
SetGadgetItemText(0, edits()\row, edits()\oldtext$, edits()\col)
PreviousElement(edits())
recalc()
EndIf
Case 2
NextElement(edits())
SetGadgetItemText(0, edits()\row, edits()\newtext$, edits()\col)
recalc()
EndSelect
EndSelect
Until EventID = #WM_CLOSE
Save()
LVEdit::StopEditing()
malleo, caput, bang. Ego, comprehendunt in tempore
Re: AllowLVEdits Version 2.2
It seems that allowedit consume a lot of memeory ? Is there a way to avoid that
Thanks in advance
Thanks in advance
Re: AllowLVEdits Version 2.2
hum
why the function: LVEdit::StartEditing()
edite the Listicon only In capital letters ??
why the function: LVEdit::StartEditing()
edite the Listicon only In capital letters ??