Somewhere - I think it's in the Wiki - there is a PROCsecaretpos(dlg%,ic%) which enables you to set the caret to a specified list box within the dialog box. I need to *read* that position, but the SYS"GetCaretPos" appears to return the coordinates of the caret in graphic units. Is that the best that can be done or is there some clever call that will return the same information as used to set the caret position?
Surely someone else must have had this same problem, so any help would be appreciated.
GetCaretPos
-
- Posts: 78
- Joined: Sat 23 Jun 2018, 15:51
Re: GetCaretPos
Can't you use LBItemFromPt function from that point or am I misunderstanding the problem?
Z
Z
-
- Posts: 327
- Joined: Wed 04 Apr 2018, 06:36
Re: GetCaretPos
Er - is that something available from BB4W? I've not come across it before.
-
- Posts: 327
- Joined: Wed 04 Apr 2018, 06:36
Re: GetCaretPos
And also, stupid me, I meant "Edit box", not "List box".
I have a dialog with a column of static boxes "Name", "Street", "Town" and so on. Next to it is a column of edit boxes into which the user can type the required information. For various reasons I need to know the position of the cursor (caret) and clicking on an edit box does not return that information. The only way would be to somehow acquire the information via a system call or polling the entire column or something.
I have a dialog with a column of static boxes "Name", "Street", "Town" and so on. Next to it is a column of edit boxes into which the user can type the required information. For various reasons I need to know the position of the cursor (caret) and clicking on an edit box does not return that information. The only way would be to somehow acquire the information via a system call or polling the entire column or something.
Re: GetCaretPos
I'm now a little unsure what you are trying to get. Do you simply need to know which edit box has the focus (i.e. the caret is in it, and it will get any keyboard entry)? You should be able to do that with SYS GetFocus, though that returns the window *handle* not the *ID*. You'd need to look up the window handles relating to the edit boxes with SYS GetDlgItem (presumably holding them in an array), and then check against your list.
Or do you want to know the location of the caret within the text string in the edit box? I don't know a way to do that directly. With clever use of the kind of text selection techniques Richard suggested for SETTING the cursor position it might be possible...
Best wishes,
D
Or do you want to know the location of the caret within the text string in the edit box? I don't know a way to do that directly. With clever use of the kind of text selection techniques Richard suggested for SETTING the cursor position it might be possible...
Best wishes,
D
-
- Posts: 327
- Joined: Wed 04 Apr 2018, 06:36
Re: GetCaretPos
Again, sorry for the delay in replying. I'm not getting notifications, despite having the "Notify me" ticked!
I have a column of edit boxes in a dialog box. I also have a text edit window which contains a list of hymn titles. When I click on one of the titles it is typed into one of the edit boxes. You'll see it in "Tools=>Service outline" in my Display program. (See the ScreenSave thread.)
If I click in one of the edit boxes the cursor appears in that box, but I presume that clicking in the edit window sets the cursor to that, so the location of the cursor in the edit boxes is lost. My solution has been to put a column of pushbuttons beside the edit boxes and clicking on one of them sets a variable which is used in the type routine to position the text. What I *want* is for that variable to be set when I click in the edit box.
Annoyingly, if you experiment, you will find that clicking in an edit box *does* return a value, but there is no guarantee what the value will be. It may be of the previous edit box you clicked, it may be the handle of one you clicked several clicks ago, but it is *never* the value of the box you clicked unless that is the only edit box in the dialog!
I have a column of edit boxes in a dialog box. I also have a text edit window which contains a list of hymn titles. When I click on one of the titles it is typed into one of the edit boxes. You'll see it in "Tools=>Service outline" in my Display program. (See the ScreenSave thread.)
If I click in one of the edit boxes the cursor appears in that box, but I presume that clicking in the edit window sets the cursor to that, so the location of the cursor in the edit boxes is lost. My solution has been to put a column of pushbuttons beside the edit boxes and clicking on one of them sets a variable which is used in the type routine to position the text. What I *want* is for that variable to be set when I click in the edit box.
Annoyingly, if you experiment, you will find that clicking in an edit box *does* return a value, but there is no guarantee what the value will be. It may be of the previous edit box you clicked, it may be the handle of one you clicked several clicks ago, but it is *never* the value of the box you clicked unless that is the only edit box in the dialog!
-
- Posts: 78
- Joined: Sat 23 Jun 2018, 15:51
Re: GetCaretPos
If you click on an Edit control or tab into it you will get a EN_SETFOCUS notification for that control. If you are getting strange results it may be that your interrupt routines don't have a buffer and you are missing that particular notification. It will be very close on the heals of the notification of the exiting of the previous control and perhaps other notifications so if your interrupt handling isn't fast enough you could be missing stuff.
The solutions to that if it is the issue are in the wiki http://www.bbcbasic.co.uk/wiki/doku.php ... interrupts
One thing the wiki doesn't mention is that you can add the mouse clicks to that queue by putting !404=!400 after the ON SYS statement and it keeps the relative timing of mouse events correct.
Z
The solutions to that if it is the issue are in the wiki http://www.bbcbasic.co.uk/wiki/doku.php ... interrupts
One thing the wiki doesn't mention is that you can add the mouse clicks to that queue by putting !404=!400 after the ON SYS statement and it keeps the relative timing of mouse events correct.
Z
-
- Posts: 327
- Joined: Wed 04 Apr 2018, 06:36
Re: GetCaretPos
I hope the below is short enough not to cause problems. Move the dialog box out of the way to reveal the BASIC window beneath, then click on the edit boxes. For convenience each one contains its handle. Click on 221 and nothing happens. Click on 222 and "221" appears. Click back on 221 and "222" appears. This happens whether or not !404=!400 is put after ON SYS (either in the next line or just before RETURN).
debug%=TRUE
PROCinit
*SYS 1
click%=0
ON SYS click%=FNsys(@msg%,@wparam%,@lparam%):RETURN
SYS"DragAcceptFiles",@hwnd%,1
REPEAT
PRINTTAB(0,0)click%
pause%=INKEY(1)
CASEclick%OF
WHEN301:click%=0
PROC_closedialog(warn%)
ENDCASE
UNTIL!dialog%=0
PROC_closedialog(dialog%)
END
:
DEFFNsys(M%,W%,L%)
CASEM%OF
WHEN273:click%=W%AND&FFF
WHEN563:PROCdrag(W%,L%):click%=0
ENDCASE
=click%
:
DEFPROCdrag(W%,L%)
SYS"DragQueryFile",W%,-1,0,0TON%
IFN%=0ENDPROC
SYS"DragQueryFile",W%,I%,K%,255
PROCopen($$K%)
ENDPROC
:
REM ===== Initialisation routines =====
:
DEFPROCinit
INSTALL @lib$+"WINLIB2"
REM ----- Centre window on screen -----
REM Set the text that appears at the top of the window
SYS"SetWindowText",@hwnd%,"U3A"
REM These two calls set up the SystemMetrics
SYS"GetWindowLong",@hwnd%,-16TOws%
SYS"SetWindowLong",@hwnd%,-16,ws%AND&FFFBFFFF AND&FFFEFFFF
REM These calls give you the screen dimensions in graphics units, not Windows units
SYS"GetSystemMetrics",0TOscreenx%
SYS"GetSystemMetrics",1TOscreeny%
winwide%=288*2+12:REM The width of your main dialog box*2+12 to allow for the window borders
winhigh%=174*2+58:REM The height of your main dialog box*2+58 to allow for borders and menu bar
sx%=(screenx%-winwide%)DIV2
sy%=(screeny%-winhigh%)DIV2-30
SYS"SetWindowPos",@hwnd%,0,sx%,sy%,winwide%,winhigh%,0
REM Design the dialog box for your program
REM The second line (IFNOTdebug%) removes the side, top and bottom bars from the box
REM The final line (also IFNOTdebug%) sets the program window to be the same size as your dialog box
dialog%=FN_newdialog("Dialog",0,0,288,174,10,80*50)
IFNOTdebug%dialog%!16=&508800C4
PROC_groupbox(dialog%,"Slides",200,4,0,280,170,0)
PROC_static(dialog%,"Record no:",201,10,12,40,14,0)
PROC_editbox(dialog%,"221",221,45,10,28,12,0)
PROC_editbox(dialog%,"222",222,45,24,28,12,0)
PROC_pushbutton(dialog%,"OK",232,215,44,45,16,1)
PROC_showdialog(dialog%)
IFNOTdebug%PROCresizewindow(dialog%)
DIMK%255:REM Used for various purposes by the WIMP. Do not use or overwrite
DIMtext%255:REM Used for reading the text in dialog boxes. Increase size if required
ENDPROC
:
DEFPROCresizewindow(handle%)
DIM rc{l%,t%,r%,b%}
SYS"GetWindowRect",!handle%,rc{}
SYS"GetWindowLong",@hwnd%,-16TOstyle%
SYS"SetWindowLong",@hwnd%,-16,style%ANDNOT&50000
SYS"AdjustWindowRect",rc{},style%ANDNOT&50000,0
SYS"SetWindowPos",@hwnd%,0,0,0,rc.r%-rc.l%,rc.b%-rc.t%+20,102
ENDPROC
Incidentally, implementing the first of the suggestions in the interrupts article you referenced resulted in the following:
ON SYS PROCsys(@msg%,@wparam%,@lparam%,click%):RETURN
DEFPROCsys(M%,W%,L%,RETURN click%) - instead of DEFFNsys() with a corresponding ENDPROC instead of =click%
It made no difference to the behaviour.
debug%=TRUE
PROCinit
*SYS 1
click%=0
ON SYS click%=FNsys(@msg%,@wparam%,@lparam%):RETURN
SYS"DragAcceptFiles",@hwnd%,1
REPEAT
PRINTTAB(0,0)click%
pause%=INKEY(1)
CASEclick%OF
WHEN301:click%=0
PROC_closedialog(warn%)
ENDCASE
UNTIL!dialog%=0
PROC_closedialog(dialog%)
END
:
DEFFNsys(M%,W%,L%)
CASEM%OF
WHEN273:click%=W%AND&FFF
WHEN563:PROCdrag(W%,L%):click%=0
ENDCASE
=click%
:
DEFPROCdrag(W%,L%)
SYS"DragQueryFile",W%,-1,0,0TON%
IFN%=0ENDPROC
SYS"DragQueryFile",W%,I%,K%,255
PROCopen($$K%)
ENDPROC
:
REM ===== Initialisation routines =====
:
DEFPROCinit
INSTALL @lib$+"WINLIB2"
REM ----- Centre window on screen -----
REM Set the text that appears at the top of the window
SYS"SetWindowText",@hwnd%,"U3A"
REM These two calls set up the SystemMetrics
SYS"GetWindowLong",@hwnd%,-16TOws%
SYS"SetWindowLong",@hwnd%,-16,ws%AND&FFFBFFFF AND&FFFEFFFF
REM These calls give you the screen dimensions in graphics units, not Windows units
SYS"GetSystemMetrics",0TOscreenx%
SYS"GetSystemMetrics",1TOscreeny%
winwide%=288*2+12:REM The width of your main dialog box*2+12 to allow for the window borders
winhigh%=174*2+58:REM The height of your main dialog box*2+58 to allow for borders and menu bar
sx%=(screenx%-winwide%)DIV2
sy%=(screeny%-winhigh%)DIV2-30
SYS"SetWindowPos",@hwnd%,0,sx%,sy%,winwide%,winhigh%,0
REM Design the dialog box for your program
REM The second line (IFNOTdebug%) removes the side, top and bottom bars from the box
REM The final line (also IFNOTdebug%) sets the program window to be the same size as your dialog box
dialog%=FN_newdialog("Dialog",0,0,288,174,10,80*50)
IFNOTdebug%dialog%!16=&508800C4
PROC_groupbox(dialog%,"Slides",200,4,0,280,170,0)
PROC_static(dialog%,"Record no:",201,10,12,40,14,0)
PROC_editbox(dialog%,"221",221,45,10,28,12,0)
PROC_editbox(dialog%,"222",222,45,24,28,12,0)
PROC_pushbutton(dialog%,"OK",232,215,44,45,16,1)
PROC_showdialog(dialog%)
IFNOTdebug%PROCresizewindow(dialog%)
DIMK%255:REM Used for various purposes by the WIMP. Do not use or overwrite
DIMtext%255:REM Used for reading the text in dialog boxes. Increase size if required
ENDPROC
:
DEFPROCresizewindow(handle%)
DIM rc{l%,t%,r%,b%}
SYS"GetWindowRect",!handle%,rc{}
SYS"GetWindowLong",@hwnd%,-16TOstyle%
SYS"SetWindowLong",@hwnd%,-16,style%ANDNOT&50000
SYS"AdjustWindowRect",rc{},style%ANDNOT&50000,0
SYS"SetWindowPos",@hwnd%,0,0,0,rc.r%-rc.l%,rc.b%-rc.t%+20,102
ENDPROC
Incidentally, implementing the first of the suggestions in the interrupts article you referenced resulted in the following:
ON SYS PROCsys(@msg%,@wparam%,@lparam%,click%):RETURN
DEFPROCsys(M%,W%,L%,RETURN click%) - instead of DEFFNsys() with a corresponding ENDPROC instead of =click%
It made no difference to the behaviour.
-
- Posts: 327
- Joined: Wed 04 Apr 2018, 06:36
Re: GetCaretPos
Hmmmm. I've now just tried
ON SYS !404=!400:click%=FNsys(@msg%,@wparam%,@lparam%):RETURN
Click on 221 as soon as the program starts and you get no change. However from then on clicking on 221 or 222 produces the correct output. This may be useful, so thanks.
ON SYS !404=!400:click%=FNsys(@msg%,@wparam%,@lparam%):RETURN
Click on 221 as soon as the program starts and you get no change. However from then on clicking on 221 or 222 produces the correct output. This may be useful, so thanks.
-
- Posts: 327
- Joined: Wed 04 Apr 2018, 06:36
Re: GetCaretPos
In fact, trying it out in the program appears to have solved the problem. Brilliant! Many many thanks.