September 26, 2020, 10:06:47 pm

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


How can I change the contents of a ListBox control?

Started by Egil, May 05, 2017, 04:10:50 am

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Egil

Hi,

I'm working on a program showing three Controls.

1- A dropdown ComboBox, listing subfolders (Projects).
2- A ListBox showing a list of files in the subfolder selected in the ComboBox. (Project Items)
3- An Edit Control to show and edit the textfiles selected in the ListBox.

Not yet finished the routines for managing the Edit Control.

Populating the system by adding new Projectnames to the ComboBox (creating new subfolders) works fine. And creating items (new textfiles in the subdirectories) also works without problems.

But when selecting another Project from the list in the ComboBox, the contents of the ListBox is not updated till a mousebutton is clicked with the mousepointer in another control.

The code for the change of contents is shown below. I'll be greatful for any suggestions that can help me back on track.


Egil

Code Select

' Control ID 11 = ComboBox contains a list of project names
' Control ID 12 = Listbox  contains a list of project items
' When selecting a new project from the list with code below,
' the new list of items are not shown till another control or the window is clicked.


case 11
selectedproject = GETCONTROLTEXT(win,11)
if selectedproject <> oldproject then SendMessage(win,LB_RESETCONTENT,0,0,12)
ListItems(win,12,selectedproject)



PS
Two more Eddit controls are added in the picture below. They are for adding new projects and project items. This part is working ok.
Support Amateur Radio  -  Have a ham  for dinner!

Andy

Hi Egil,

Think you need some kind of timer in there, you would also need to detect what is selected and store it.

After that, in the timer you need to keep checking what was selected, and what is selected now - if they are different then you do the update.

So, when the screen opens, set the selected to the first item in the list and store it, then keep checking the selected (getselected command) and compare them.

If different, update the listbox and save the new selection in case another gets selected.

Andy
:)
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Egil

Quote from: Andy on May 05, 2017, 06:34:22 am
After that, in the timer you need to keep checking what was selected, and what is selected now - if they are different then you do the update.


That's exactly what I do here, without a timer though:
Code Select
if selectedproject <> oldproject then SendMessage(win,LB_RESETCONTENT,0,0,12)

And I know that the list is updated, as the new selection is shown correctly, but not before I click inside another control. That is what  bugs me.
Reckon I'll be able to rectify this by using SENDMESSAGE, but have to find out the  what parameters to send.


Egil
Support Amateur Radio  -  Have a ham  for dinner!

LarryMc

Can I see the contents of this:
Code Select
ListItems(win,12,selectedproject)
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Egil

Quote from: LarryMc on May 05, 2017, 08:10:12 pm
Can I see the contents of this:
Code Select
ListItems(win,12,selectedproject)


Hi Larry,

I should have posted the full code at once, but since I had not finished all the planned tasks yet, I did'nt... sorry. But here it is attached.
Attached is also a partly populated collection of items, so you have something to start with. If you delete the PROJECTS folder, the program will make a new, empty, one, so you can add your own contents (enter project names first, and then itemnames into the selected project)
I have tried many options, but the result was always the same; the list of items for the selected project does not show until clicking in one of the controls...

BTW, it was almost strange to start coding again after almost a year. So feeling a little rusty. Had almost forgotten how much fun it was. But think I needed this exercise before taking up my two large, resting projects again..


Egil

EDIT:
Amost forgot to mention that the subs ListItems and ListProjects are identical. And it does not matter whether the expression ADDSTRING wnd,ID,fname or
if CONTROLEXISTS(wnd,ID) then ADDSTRING wnd,ID,fname is used, since they both produce the same result.

Support Amateur Radio  -  Have a ham  for dinner!

LarryMc

I just can't get my mind to work, especially in CB for some reason. Plus I've been down with some sort of bug ever since I come back from visiting my brother.  That 8hr one-way drive is getting tougher and tougher.

Best I remember I've run into this problem before in IWB.  Seems like the solution is to force the system to redraw the control using either

InvalidateRect(HWND hWnd, pointer lpRect, BOOL bErase),BOOL

or

RedrawWindow(HWND hWnd, pointer lprcUpdate, HRGN hrgnUpdate, UINT flags),BOOL

but I just can't remember.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Egil

No problem Larry!

At an early stage I converted the code into IWB code, just to see if the far better error trapping could give me a hint. But after  compilation the program behaves in exactly the same way, exept for listing the ListBox contest twice, but that should be easy to rectify.
The IWB code is, except for the window and control declarations pluss added ENDSUBs, identical to the CB code, and it is posted below.

This project was abandoned by my young "assistants", as they ran out of time to get their project accepted by the school. So they discarded the control boxes and used the usual way for filebrowsing instead, and the only control left was the editbox for inputting text.

But please do not put too much effort into this, as it is really no big deal. I just felt that they had put so much effort into this code that it deserved a second try...
And I'll see if I can find info on how to use the API functions you mention later today.


Egil



EDIT: Was in a hurry this morning so wrote added RETURNs instead of  added ENDSUBs.
          I am still convinced that faking a mouseclick by using SENDMESSAGE will end the problems, but I'm not able to figure out what parameters should be sent.
Support Amateur Radio  -  Have a ham  for dinner!

LarryMc

Egil

It took me a while to get my head back on straight.
As it was I didn't need the two commands I suggested previously.

Attached is your IWB source file with my corrections and I noted where I made changes/additions.
It's pretty easy to follow.

The MAJOR flaw we were all missing in the beginning is that you never ever never use GETCONTROLTEXT with a COMBOBOX.  It sort of puts you a 1/2 lap behind in things.  You have to get the index of the selected item and then get the string located at that index location.
Once you recognize that then my othe code adjustments fall right into place.
Taking that into account, you should be able to fix the CB code up for your little troopers.

LarryMc

LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Egil

Quote from: LarryMc on May 11, 2017, 10:03:55 pmThe MAJOR flaw we were all missing in the beginning is that you never ever never use GETCONTROLTEXT with a COMBOBOX.  It sort of puts you a 1/2 lap behind in things.  You have to get the index of the selected item and then get the string located at that index location.


Thanks Larry!

At one point I actually tried using GETSELECTED myself, whithout realizing that the string index is zero-based....

The main differences between CB and IWB are definitions  for Windows/Dialog and Controls, plus the ENDSUB statements that are not used in CB. 99% of all other code is exactly the same in both languages, so converting this code to CB will be easy.

I had a phone call from the kid's teacher last night. He was surprised to see what "my" kids had achieved, and that they produced working code examples in just a fraction of time, compared to those using Python. Tomorrow (saturday) I expect to see them here, by then I have translated your comments into norwegian so I'll pass on your corrected code.


Egil
Support Amateur Radio  -  Have a ham  for dinner!

Egil

Finally got around to convert Larry's IWB code. Now it works like a dream with CB.
My young prodigies told me on the phone the other day that they had started working with a different way doing the same job. So now they can choose between two different ways to finish their project. CB version of Larry's code is posted below.


Egil


Code Select
'
'-------------------------------------------------------------------------------------
' MockUp.cba
'-------------------------------------------------------------------------------------
AutoDefine "Off"

'--------------------------------------------------
' Defines for catching ENTER key in edit controls:
'--------------------------------------------------
SETID "ENMKEYEVENTS",0x10000
SETID "ENMSGFILTER",0x700

TYPE MSGFILTER
def hwndFrom:INT
def idFrom:INT
def code:INT
def msg:INT
def wparam:INT
def lparam:INT
ENDTYPE
DEF mf:MSGFILTER
DEF mem:MEMORY
'*********************************

DECLARE AddProject(wnd:window, projectname:string, ID:int)
DECLARE ListProjects(wnd:window,ID:int)
DECLARE AddItem(wnd:window,path:string,itemname:string)
DECLARE ListItems(wnd:window,ID:int, projectname:string)

def LB_RESETCONTENT:int 
CONST LB_RESETCONTENT = 0x184

DEF answer:INT
def wstyle:int
wstyle = @SIZE|@MINBOX|@MAXBOX
def win:window 
def cleft,ctop,cwidth,cheight:int :'Clientarea
def run,pcount:int
def itempath,myitem,newitem,selectedproject,newproject,oldproject:string

Window win,-640,0,680,480,wstyle,0,"  CB MockUp",MainLoop
GETCLIENTSIZE win,cleft,ctop,cwidth,cheight
SETWINDOWCOLOR win,RGB(121,150,222)
drawmode win,@TRANSPARENT

'-------------------------------------------------------------------------------------
' SETTING UP
'-------------------------------------------------------------------------------------
RECT win,33,13,173,56, RGB(96,96,96),RGB(248,216,136)
RECT win,223,13,173,56,RGB(96,96,96),RGB(248,216,136)
RECT win,412,13,173,56,RGB(96,96,96),RGB(248,216,136)

CONTROL win,"M,Select,40,40,160,202,@CTCOMBODROPDOWN|@VSCROLL,11" :' ComboBox Control
SETCONTROLTEXT win,11,"Select:"   

CONTROL win,"L,,10,85,160,cheight-(10+85),@CTLISTNOTIFY,12" :' ListBox Control
CONTROL win,"E,,180,85,cwidth-190,cheight-(10+85),@CTEDITMULTI|@CTEDITRETURN|@VSCROLL,13" :' Edit Control

RECT win,230,40,158,23,0,RGB(102,102,102) :' Make fake EDIT Control appearance
RECT win,231,41,158,23,0,RGB(255,255,255) :' Make fake EDIT Control appearance
CONTROL win,"RE,proj,232,43,150,18,@CTEDITLEFT,14"
CONTROLCMD win,14,@RTSETEVENTMASK,@ENMKEYEVENTS

RECT win,419,40,158,22,0,RGB(102,102,102) :' Make fake EDIT Control appearance
RECT win,420,41,158,22,0,RGB(255,255,255) :' Make fake EDIT Control appearance
CONTROL win,"RE,item,423,43,150,18,@CTEDITLEFT,15"
CONTROLCMD win,15,@RTSETEVENTMASK,@ENMKEYEVENTS

move win,80,20
FRONTPEN win,RGB(121,150,222)
print win,"PROJECT"
move win,270,20
print win,"NEW  ITEM"
move win,445,20
print win,"NEW  PROJECT"

CONTROL win,"B,,600,18,49,49,@CTLBTNBITMAP,16"
SETCONTROLTEXT win,16,GETSTARTPATH + "info.bmp" 
 
CREATEDIR(GETSTARTPATH + "PROJECTS")  :' Creates Projectfolder if not found
ListProjects(win,11)

run = 1

WAITUNTIL run = 0
FREEMEM mem
CLOSEWINDOW win 
END   


'
SUB MainLoop()
'-------------------------------------------------------------------------------------
' Main Loop
'-------------------------------------------------------------------------------------
'
DEF key:int

SELECT @CLASS

CASE @IDCONTROL

SELECT @CONTROLID

case 11
if @NOTIFYCODE = @CBNSELCHANGE :' /* added */
selectedproject = GETSTRING (win, 11,GETSELECTED (win,11)) :' /* changed  GETCONTROLTEXT is BIG NONO for combobox*/
if selectedproject <> oldproject :' /* changed */
SendMessage(win,LB_RESETCONTENT,0,0,12)
oldproject = selectedproject :' /* added */
ListItems(win,12,selectedproject)
endif :' /* added */
endif :' /* added */


'case 12 :' load selected file for editing


'case 13 :' check for changes in EditControl


case 14 :' New Item is Entered
IF @NOTIFYCODE = @ENMSGFILTER
                  'read in the MSGFILTER structure
mem = @QUAL
READMEM mem,1,mf
                    'at this point the keyboard event
                    'is in mf.msg and the keyboard code is in mf.wparam
                    'the event can be things like @IDCHAR
IF mf.msg = @IDCHAR
key = mf.wparam
IF (key = 13)   :' ENTER KEY PRESSED
selectedproject = GETCONTROLTEXT(win,11)
newitem = GETCONTROLTEXT(win,14)

if newitem <> ""
itempath = GETSTARTPATH + "PROJECTS\" + selectedproject + "\"
AddItem(win,itempath,newitem)
ADDSTRING win,12,newitem + ".txt"
SETCONTROLTEXT(win,14,"")
newitem = ""
SETFOCUS win,14 :' Send focus back to the window
endif

                     ENDIF
ENDIF
ENDIF


case 15 :' New project is entered
IF @NOTIFYCODE = @ENMSGFILTER
                    'read in the MSGFILTER structure
mem = @QUAL
READMEM mem,1,mf
                    'at this point the keyboard event
                    'is in mf.msg and the keyboard code is in mf.wparam
                    'the event can be things like @IDCHAR
IF mf.msg = @IDCHAR
key = mf.wparam
IF (key = 13)   :' ENTER KEY PRESSED
newproject = GETCONTROLTEXT(win,15)
if newproject<>"" then AddProject(win,newproject,11)
SETCONTROLTEXT(win,15,"")
pcount = GETSTRINGCOUNT(win,11)
SETSELECTED win,11,pcount-1
'SETFOCUS win :' Send focus back to the window
oldproject = newproject
newproject = ""
endif
                     ENDIF
ENDIF
ENDIF

case 16
system GETSTARTPATH + "info.txt"

ENDSELECT


CASE @IDSIZE                                                              :' Window size has been changed
GETCLIENTSIZE win,cleft,ctop,cwidth,cheight                            :' Retreive new window size
if CONTROLEXISTS(win,12) then SETSIZE win,10,85,160,cheight-(10+85),12 :' Resize ListBox Control
if CONTROLEXISTS(win,13) then SETSIZE win,180,85,cwidth-190,cheight-(10+85),13  :' Resize Edit Control


CASE @IDCREATE 
CENTERWINDOW win

CASE @IDCLOSEWINDOW 
run = 0 

ENDSELECT 
RETURN
'-------------------------------------------------------------------------------------

'
SUB ListProjects(wnd:window,ID:int)
'-------------------------------------------------------------------------------------
' Find existing project folders and add them to ComboBox list
'-------------------------------------------------------------------------------------
DEF dir:INT
DEF fname:STRING
def fdir:string
fdir = "PROJECTS\"

dir = FINDOPEN(GETSTARTPATH + fdir + "*.*")
IF(dir)
DO
fname = FINDNEXT(dir)
if (fname <> ".") & (fname <> "..") &(fname <> "")
if CONTROLEXISTS(wnd,ID) then ADDSTRING wnd,ID,fname
endif
UNTIL fname = ""
FINDCLOSE dir
ENDIF

RETURN
'-------------------------------------------------------------------------------------

'
SUB AddProject(wnd:window, projectname:string, ID:int)
'-------------------------------------------------------------------------------------
' Create new project
'-------------------------------------------------------------------------------------
DEF err:int

err = CREATEDIR(GETSTARTPATH + "PROJECTS\" + projectname)
if (err=1) & CONTROLEXISTS(wnd,ID)
ADDSTRING wnd,ID,projectname
else
if err = 0 then MessageBox(wnd,"Project already exists!", "",0x30)
endif

RETURN
'-------------------------------------------------------------------------------------

'
SUB AddItem(wnd:window,path:string,itemname:string)
'-------------------------------------------------------------------------------------
' Creates new, empty, Item File for editing later
'-------------------------------------------------------------------------------------
DEF myfile:FILE
'DEF err:int
DEF myfilename:string

myfilename = path + itemname + ".txt"

IF(OPENFILE(myfile,myfilename,"W") = 0)
    WRITE myfile,"EMPTY "
    CLOSEFILE myfile
ELSE
MessageBox(wnd, "Could not create file","WARNING!",0x30)
ENDIF
RETURN
'-------------------------------------------------------------------------------------

'
SUB ListItems(wnd:window,ID:int, projectname:string)
'-------------------------------------------------------------------------------------
' List items in selected project in ListBox Control
'-------------------------------------------------------------------------------------
DEF dir:INT
DEF fname:STRING
def fdir:string
fdir = "PROJECTS\" + projectname + "\"

dir = FINDOPEN(GETSTARTPATH + fdir + "*.*")
IF(dir)
DO
fname = FINDNEXT(dir)
if (fname <> ".") & (fname <> "..") &(fname <> "")
if CONTROLEXISTS(wnd,ID) then ADDSTRING wnd,ID,fname
endif
UNTIL fname = ""
FINDCLOSE dir
ENDIF

RETURN

RETURN
'-------------------------------------------------------------------------------------

Support Amateur Radio  -  Have a ham  for dinner!