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
' 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.
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
:)
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:
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
Can I see the contents of this:
ListItems(win,12,selectedproject)
Quote from: LarryMc on May 05, 2017, 08:10:12 PM
Can I see the contents of this:
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.
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.
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.
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
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
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
'
'-------------------------------------------------------------------------------------
' 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
'-------------------------------------------------------------------------------------