|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
silicondale
Joined: 15 Mar 2007 Posts: 252 Location: Matlock, Derbyshire, UK
|
Posted: Tue Sep 03, 2013 2:20 pm Post subject: |
|
|
Now tested with %ob[thin_margin] and it's a definite improvement, though as you say, Paul, it doesn't go all the way!
However, for my application this is perfectly liveable with. Now to look at the accelerators...Thanks for the suggestions, Eddie and others. On the actual application I had already numbered the boxes using the SET callback (i.e. '+','SET',nbox,k,mycallback where k is the box number computed from row and column and nbox is in common, accessed by mycallback) and this is working fine, but I think the handle solution is perhaps more elegant. It's probably also more flexible.
-Steve |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2390 Location: Yateley, Hants, UK
|
Posted: Tue Sep 03, 2013 3:00 pm Post subject: |
|
|
Steve,
I was hoping that you would admit to a forehead-slapping "Doh!" moment with the single precision ... It's things like that I understand, not the language Jalih and Paul use to communicate.
Eddie |
|
Back to top |
|
|
silicondale
Joined: 15 Mar 2007 Posts: 252 Location: Matlock, Derbyshire, UK
|
Posted: Tue Sep 03, 2013 3:59 pm Post subject: |
|
|
Sorry Eddie -- I was too embarrassed. Doh, indeed! |
|
Back to top |
|
|
jalih
Joined: 30 Jul 2012 Posts: 196
|
Posted: Wed Sep 04, 2013 8:18 am Post subject: |
|
|
Paul,
Since validating input for the %lv seems to be the biggest issue for most people here, I have some ideas for improvement.
How about letting people define allowed characters for the %lv labels as character array?
You only need a handle for the edit control working as a label editor to be able to subclass it. Reserve space for the old window procedure and for 256 keys mask buffer. Go through the user supplied character array and set the correct character keys into the mask buffer. Inside subclassed window procedure for edit control, handle the WM_NCDESTROY message to free the allocated storage and WM_CHAR message to test character against mask buffer.
Another improvement would be to allow user defined validator function for the %lv label editor.
Validator function should return one of the four states: empty, valid, valid but not complete and error. Validator function should be called from window procedure of the edit control working as a label editor when it's contents change. Color of the edit control could be changed to reflect the returned status and user message could be send for the parent window to let rest of the program know about it.
Validator function itself could be a simple FSM. Basic idea is to go through the character array and test it against pre-defined states. Long variable could be used: upper word = state and lower word = character. Long variable can be constructed from the state word and the character word using MAKELONG macro. Now, rest is just a series of tests and state changes.
I can write a simple validator function for floating point data as an example if needed. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7933 Location: Salford, UK
|
Posted: Wed Sep 04, 2013 11:46 am Post subject: |
|
|
Jalih
Thanks for the suggestions.
In a minimal sense %lv already allows validation of edit cell input.
You can get the key pressed from clearwin_info@('KEYBOARD_KEY') and the return value of from the callback function specifies if the key is to be accepted etc.
I will make a note of your suggestions for when I come back to this issue on the wish list. |
|
Back to top |
|
|
jalih
Joined: 30 Jul 2012 Posts: 196
|
Posted: Wed Sep 04, 2013 12:14 pm Post subject: |
|
|
I made a little FTN95 callable DLL demonstrating some of the things I suggested in my previous post.
functions contained inside the DLL:
STDCALL validate_real 'validate_real' (INSTRING):integer*4
function validates string for a valid floating point value.
possible return values:
1 = EMPTY
2 = PARTIAL
3 = OK
4 = ERROR
Also included is a MaskEditControl function, defined in MiniBASIC syntax as:
MaskEditControl(HWND hwndEdit,string szMask,DWORD nOptions),BOOL
So, it takes a handle to the edit control, character string for defining valid characters and zero or no-zero value depending on whether we allow or reject characters in mask string.
I call it in MiniBASIC as:
MaskEditControl(hEdit, "0123456789.eE+-\x08", TRUE)
Available here |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2390 Location: Yateley, Hants, UK
|
Posted: Wed Sep 04, 2013 12:29 pm Post subject: |
|
|
Hi Paul,
That sense is rather minimal, as, not to put too fine a point on it, getting key by key doesn't work properly! (And probably hasn't since the thread started back in 2006 and before). Some keys are not reported at all, and some are reported inconsistently.
By 'properly' I don't mean it doesn't do what Clearwin+ intends it to do, I mean in a way that 'a reasonably competent Fortran user, exhibiting average levels of knowledge, skill and care' can get it to work so that users can pick it up! [i.e. exactly the target user for Clearwin+, like me].
Remember that no matter how quick a hack a program might be to the programmer, users see that it is a Windows program, and automatically assume that (a) it works as reliably as (say) MS Office, and (b) will immediately look and feel familiar. Any grid type input will immediately be compared to Excel by a Windows-hardened user. Matters have got worse since users have discovered that they can get a highly-polished app on their phone for 99p or less!
Most Clearwin+ things work extremely well and consistently, including the use of %lv for some purposes - just that it is in the range of difficult to impossible to use it for inputting and editing columns of real numbers. Silicondale's grid of boxes is a very viable alternative.
This one too is something that I regret is getting in the way of your other plans.
Eddie |
|
Back to top |
|
|
jalih
Joined: 30 Jul 2012 Posts: 196
|
Posted: Thu Sep 05, 2013 10:21 am Post subject: |
|
|
Here is a simple binary showing MaskEditControl() and validate_real() functions in action.
MaskEditControl() is used to set allowed characters for the edit control. Validate_real() is called on a response for edit controls update notification and color of the control is changed based on a validator result.
Below is a MiniBASIC source for the demo program:
Code: |
##ifndef WIN32
##define WIN32
##endif
##ifdef WIN32
##define WIN32_LEAN_AND_MEAN
##endif
##include "winsdk\windef.mbi"
##include "winsdk\winbase.mbi"
##include "winsdk\wingdi.mbi"
##include "winsdk\winuser.mbi"
##USES "edit.lib"
##NOCONSOLE
@API validate_real(string s),int
@API MaskEditControl(HWND hwndEdit,string szMask, DWORD nOptions),BOOL
WINDOW win
win.Open(0,0,295,199,WS_OVERLAPPED|WS_VISIBLE|WS_SYSMENU,0,"Input real",0,&handler)
win.AddControl(CT_EDIT,"",83,39,124,27,0x50800000|CS_EDITAUTOH,0,5)
win.SetWindowColor(GetSysColor(Color_BTNFACE))
HWND hEdit = win.GetControlHandle(5)
MaskEditControl(hEdit, "0123456789.eE+-\x08", TRUE)
win.setcontrolcolor(5,RGB(0,0,0), RGB(255,255,255))
win.SetFocus(5)
do
ProcessMessages
until win.GetHandle()=NULL
func handler(WINDOW win),int
select win.message
case WM_CREATE
win.CenterWindow()
case ID_CONTROL
select win.ControlID
case 5
if win.NotifyCode = EN_UPDATE
int status = validate_real(win.GetControlText(5))
select status
case 1
win.SetControlColor(5,RGB(0,0,0), RGB(255,255,255))
case 2
win.SetControlColor(5,RGB(0,0,0), RGB(255,255,0))
case 3
win.SetControlColor(5,RGB(0,0,0), RGB(0,255,0))
case 4
win.SetControlColor(5,RGB(0,0,0), RGB(255,0,0))
endselect
endif
endselect
case ID_CLOSE
win.Close()
endselect
return 0
endf
|
|
|
Back to top |
|
|
jalih
Joined: 30 Jul 2012 Posts: 196
|
Posted: Fri Sep 06, 2013 4:51 pm Post subject: |
|
|
I have made some progress adding automatic validation for the Win32 listview control labels. As edit control supports balloon tip, giving feedback to user is easy.
List-view picture |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2390 Location: Yateley, Hants, UK
|
Posted: Sun Sep 08, 2013 12:20 pm Post subject: |
|
|
Hi Jalih,
When you started posting, I thought you were a novice (until maybe your 3rd post!). Now that it is very clear that you eat this stuff for breakfast, I hesitate before offering you any advice!
The problem with editing REALs in a listview, apart from the fact it doesn't work yet in Clearwin+, is that it must work similarly to editing in a %rf box, responding to all the keypresses in the same way, in order to give users confidence; or failing that, in the same way as in-cell editing in Excel, again for the same reason. Anyone programming for themselves can accept non-standard behaviour (although in a while, it irritates even the programmer), but those programming for others need to stick to things that users find familiar.
Quite a lot of the "standards" are not described in places like the MS user experience guidelines, and you only realise what they are when you use a well-crafted piece of commercial software.
In the case of editing errors for REALs, the default in Excel seems to not only be an error message, but also the offer of the most likely fix. Even Excel isn't always right, but it tries.
Eddie |
|
Back to top |
|
|
jalih
Joined: 30 Jul 2012 Posts: 196
|
Posted: Mon Sep 09, 2013 6:46 am Post subject: Re: |
|
|
LitusSaxonicum wrote: |
In the case of editing errors for REALs, the default in Excel seems to not only be an error message, but also the offer of the most likely fix. Even Excel isn't always right, but it tries.
|
As the validator is finite state machine based, this should be quite easy modification. The easiest probably would be to keep the last good state in memory and on error state, return the last valid character index. |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2390 Location: Yateley, Hants, UK
|
Posted: Thu Sep 16, 2021 10:08 am Post subject: |
|
|
Eight years on, and I think that I may have cracked it! It will take multiple posts:
Code: | WINAPP
OPTIONS (INTL, DREAL)
PROGRAM LV_EXAMPLE
C ------------------
INCLUDE <WINDOWS.INS>
CHARACTER*(80) ROWS(11)
COMMON /INPUT_GRID/ ROWS, X(10), Y(10), Z(10), ISEL(10)
INTEGER, EXTERNAL:: KB_FOR_LV_GRID
NROWS = 11
iSEL = 0 ! initialise the array
iSEL(1) = 1
iVIEW = 1
ROWS = '| | | | '
DO 10 I=2,11
ROWS(I) = '|'//CHAR(I+63)//'| | | '
10 CONTINUE
ROWS(1) = '|Station_+65|Easting (m)_+105|Northing (m)_+105|'
& //'Altitude (m)_+75'
IW = WINIO@ ('%ca[ListView example]&')
IW = WINIO@ ('%^lv[edit_cells,go_down_on_return,'//
& 'single_selection]&',
& 420, 200, ROWS, NROWS,
& iSEL, iVIEW, KB_FOR_LV_GRID)
IW = WINIO@ ('%lw%ff%nl%16bn[text=OK,notes="Cor Blimey!"]', LW)
END |
|
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2390 Location: Yateley, Hants, UK
|
Posted: Thu Sep 16, 2021 10:11 am Post subject: |
|
|
Post 2 of 3:
Code: | INTEGER FUNCTION KB_FOR_LV_GRID()
C ---------------------------------
CHARACTER*(80) ROWS(11), BAND
COMMON /INPUT_GRID/ ROWS, X(10), Y(10), Z(10), ISEL(10)
CHARACTER*(80) CBR, CBE
CHARACTER*(2) CBK
CHARACTER*(1) KHAR
CHARACTER*(20) TEXT
DIMENSION INDEX(11)
INCLUDE <WINDOWS.INS>
KB_FOR_LV_GRID = 2
irow = clearwin_info@('ROW_NUMBER')
icol = clearwin_info@('COLUMN_NUMBER')
CBE = CLEARWIN_STRING@ ('EDITED_TEXT')
CBR = CLEARWIN_STRING@ ('CALLBACK_REASON')
C WRITE(*,*) IROW, ICOL, ' ', CBE(1:LEN_TRIM(CBE)), '... ',
C & CBR(1:LEN_TRIM(CBR))
IF (iCOL .EQ. 1) RETURN
IF (CBR .EQ. 'BEGIN_EDIT') THEN
RETURN
ELSE IF (CBR .EQ. 'EDIT_KEY_DOWN') THEN
NK = clearwin_info@('KEYBOARD_KEY')
C write(*,*) ' NK= ', NK
KB_FOR_LV_GRID = 2
L = LEN_TRIM (CBE)
K = 0
DO 10 M=1,L
IF (CBE(M:M) .EQ. '.') K=1 ! decimal point exists
10 CONTINUE
IF (NK .GE. 48 .AND. NK .LE. 57) RETURN
IF (NK .EQ. 46 .AND. K .EQ. 0) RETURN
KB_FOR_LV_GRID = 4
RETURN |
|
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2390 Location: Yateley, Hants, UK
|
Posted: Thu Sep 16, 2021 10:12 am Post subject: |
|
|
Post 3 of 3:
Code: | ELSE IF (CBR .EQ. 'END_EDIT') THEN
L = LEN_TRIM (ROWS(IROW+1))
INDEX = L
BAND = ROWS (IROW + 1)
KHAR = BAND(1:1)
INDEX(1) = 1
K = 2
DO 20 M=2,L
IF (BAND(M:M) .EQ. KHAR) THEN
INDEX(K) = M
K = K + 1
ENDIF
20 CONTINUE
IF (CBE .EQ. '') THEN
TEXT = ' '
GO TO 30
ENDIF
READ (CBE,*) VALUE
C write(*,*) cbe, value
WRITE (TEXT,'(F12.3)') VALUE
ELSE IF (CBR .EQ. 'KEY_DOWN') THEN
CALL BEEP@
RETURN
ENDIF
30 CONTINUE
ROWS(IROW + 1) = BAND(1:INDEX(ICOL))//TEXT//BAND(INDEX(ICOL+1):L)
CALL WINDOW_UPDATE@ (ROWS)
KB_FOR_LV_GRID = 2
RETURN
END
RESOURCES
1 24 default.manifest |
A bit clumsy, but explicit.
Eddie |
|
Back to top |
|
|
silicondale
Joined: 15 Mar 2007 Posts: 252 Location: Matlock, Derbyshire, UK
|
Posted: Thu Sep 16, 2021 12:26 pm Post subject: |
|
|
Hi Eddie-
Wow! You've been puzzling over this for 8 years? I guess I'm duty-bound to try it out, if I can find the place in my coding that needed it. I'm not even working on the same project any more, and it's a several months since I last did any Fortran coding. Now working on a couple of EU-funded submersible-robotics projects.
Actually, I did some Fortran last year for image processing. Addressing the "in-betweening" problem for successive frames in an underwater video, each frame containing clouds of silt grains. Needed first to find 3 or 4 matching points in each frame, then an affine transformation to rotate and stretch to match the pixels, and a majority-vote algorithm on 3 successive frames to remove the noise. Worked like a dream. JPG import and export are amazingly powerful! I generated a few clean images for colleagues to publish.
- Steve _________________ (Steve Henley) |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|