Author |
Topic: A solution to the old FN_setproc problem. (Read 599 times) |
|
sveinioslo
Developer
member is offline


Posts: 64
|
 |
A solution to the old FN_setproc problem.
« Thread started on: Aug 16th, 2014, 10:54am » |
|
Just got an idea about the old FN_setproc hijacking ON SYS problem. This appears to be working. Any comments ?
Svein Still V.5 user :)
Code: WM_COMMAND = 273
INSTALL @lib$+"WINLIB5"
ON SYS : PROCa(@wparam%) : RETURN
a%=FN_button("on sys",300,50,100,30,100,0)
b%=FN_button("setproc",300,100,100,30,FN_setproc(PROCb),0)
c%=FN_button("setproc( )",300,150,100,30,FN_setproc(PROCc()),0)
REPEAT WAIT 0
UNTIL 0
DEF PROCa(w%): PRINT "on sys "; w%: ENDPROC
DEF PROCb: PRINT "setproc": ENDPROC
DEF PROCc(w%,l%): PRINT "setproc() ";w%,l%: ENDPROC
DEF FN_setproc(RETURN F%)
PRIVATE D%,T%,lp%
IF T% = 0 THEN
LOCAL L%, P%, W%, S%, U%, O%, wp%, code%, pass%, pr%
DIM code% NOTEND AND 2047, code% 2300, L% -1
SYS "GetWindowLong", @hwnd%, -4 TO O%
FOR pass% = 8 TO 10 STEP 2
P% = code%
[OPT pass%
.pr% DD 0
.wp% DD 0
.lp% DD 0
;REM proc addresses
]
P% = (P% + 2047) AND -2048
[OPT pass%
.U%
pop eax
push O%
push eax
jmp "CallWindowProc"
.S% ; subclass
mov eax,[esp+8] ; msg
cmp eax,WM_COMMAND
jnz U%
mov eax,[esp+12] ; wparam
and eax,&FFFFFF00
cmp eax,&0000FF00
jnz U%
mov eax,[esp+16] ; lparam
mov [lp%],eax
mov eax,[esp+12] ; wparam
mov [wp%],eax
not eax
and eax,&000000FF
jz U%
mov ebx,lp%
mov eax,[ebx+eax*4]
or eax,eax
jz U%
mov [pr%],eax
jnz T%
.W%
push 0
call "Sleep"
.T%
mov al,[@vdu%+205]
add al,8
cmp al,[@vdu%+206]
jz W%
call "csenter"
mov edx,[@vdu%-144]
mov dl,[@vdu%+205]
mov dword [edx+4],pr% ; to @msg%
mov dword [edx+260],!^PROC_@sys
add dl,8
mov [@vdu%+205],dl
call "csleave"
or byte [^@flags%+3],&20
ret 20
]
NEXT pass%
SYS "SetWindowLong", @hwnd%, -4, S%
ENDIF
D%+=1 : lp%!(D%*4)=F%
=NOTD%AND&FFFF
DEF PROC_@sys: IF ?!@msg%=&28 PROC(@msg%)(@msg%!4,@msg%!8) ELSE PROC(@msg%)
RETURN
|
|
Logged
|
|
|
|
rtr
Guest
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #1 on: Aug 16th, 2014, 12:40pm » |
|
on Aug 16th, 2014, 10:54am, sveinioslo wrote:Just got an idea about the old FN_setproc hijacking ON SYS problem. This appears to be working. Any comments ? |
|
It seems to work, but I'm unsure what the "problem" is that you are trying to solve.
In my programs I use FN_setproc alone when the only ON SYS events I am interested in are menu selections and/or button clicks (or other simple WM_COMMAND events) and FN_setproc in conjunction with EVENTLIB when I need more flexibility (typically when I use *SYS 1 to enable additional events, which EVENTLIB does automatically):
Code: WM_NOTIFY = 78
INSTALL @lib$+"WINLIB5"
INSTALL @lib$+"EVENTLIB"
b%=FN_button("setproc",300,100,100,30,FN_setproc(PROCb),0)
c%=FN_button("setproc( )",300,150,100,30,FN_setproc(PROCc()),0)
PROC_eventinit
PROC_eventregister(WM_NOTIFY, PROCa())
REPEAT WAIT 0
PROC_eventpoll
UNTIL 0
DEF PROCa(m%,w%,l%): PRINT "notification "; m%,w%,l%: ENDPROC
DEF PROCb: PRINT "setproc": ENDPROC
DEF PROCc(w%,l%): PRINT "setproc() ";w%,l%: ENDPROC So long as you call FN_setproc before PROC_eventinit no "hijacking" takes place: it's one of the main things EVENTLIB was written to achieve (it automatically 'forwards' an unregistered event to the original handler).
Admittedly the use of EVENTLIB forces events to be synchronous (you must call PROC_eventpoll) but in my opinion that's no bad thing.
Richard.
|
|
Logged
|
|
|
|
sveinioslo
Developer
member is offline


Posts: 64
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #2 on: Aug 16th, 2014, 7:59pm » |
|
Quote: but I'm unsure what the "problem" is that you are trying to solve |
|
I was referring to the old pre eventlib problem. In this post https://groups.yahoo.com/neo/groups/bb4w/conversations/topics/16863 you wrote: Quote:The snag with the approach WINLIB5 adopts is that it hijacks ON SYS; if you're using FN_setproc() in your program you can't use ON SYS for anything else |
|
and Quote: I would welcome any ideas people might have |
|
I am mostly using eventlib myself, but recently i ran into a problem with it. While considering options and workarounds, i remembered the old FN_setproc issue, and simply had to try it out. Pre eventlib we had re-entrant considerations. Now we have to consider positive feedback instead. This is obvious when one is aware of the problem. You probably knew this, but i hadn't thought of it before. This code shows it clearly. Code: SWP_NOMOVE = 2
SWP_NOZORDER = 4
WM_SIZE = 5
INSTALL @lib$+"eventlib"
PROC_eventinit
PROC_eventregister(WM_SIZE, PROCstuck())
SYS "SendMessage",@hwnd%,WM_SIZE,0,0
PROC_eventpoll
END
DEF PROCstuck(m%,w%,l%)
PRIVATE X% : X%+=1 : IF X%>400 X%=0
SYS "SetWindowPos", @hwnd%, 0, 0, 0, 200+X%, 200+X%, SWP_NOMOVE + SWP_NOZORDER
WAIT 1: ENDPROC
Now that i know, i can fix it by as in this example removing the last WM_SIZE message immediately after SetWindowPos. Code: FOR A%=1 TO Q@%(0) STEP 3
IF Q@%(A%)=WM_SIZE THEN Q@%(A%)=0 : EXIT FOR
NEXT A%
Not saying that there is something wrong with eventlib, just that one needs to be aware of the danger of feedback. Luckily, my problem was of a visual nature.
Svein
|
|
Logged
|
|
|
|
rtr
Guest
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #3 on: Aug 16th, 2014, 8:39pm » |
|
on Aug 16th, 2014, 7:59pm, sveinioslo wrote: As you say, that was pre-EVENTLIB. Indeed, in the message in which I announced the release of EVENTLIB (more than two years ago!) I explicitly said that one of its objectives was to address that specific issue:
on Mar 10th, 2012, 10:17am, admin wrote: http://bb4w.conforums.com/index.cgi?board=libraries&action=display&num=1331378257
So, naturally, I have not considered it to be a "problem" since! Your 'solution' is a valid alternative approach, which one can use if asynchronous interrupts are wanted, but for my applications I have been happy to use the EVENTLIB method.
Richard.
|
« Last Edit: Aug 16th, 2014, 8:46pm by rtr » |
Logged
|
|
|
|
sveinioslo
Developer
member is offline


Posts: 64
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #4 on: Aug 18th, 2014, 2:06pm » |
|
Just checked if your original program had the same problem as mine, and it does.! Quote: This is only true if the canvas is bigger than the screen. As you can see in this video: http://fix24.net/bb4w/Scroll.bbc.mp4 The only changes i have done, is to make the canvas smaller than my screen. Code: CanvasX% = 800
CanvasY% = 800
I also inserted this line into PROCmove() to slow down the oscillations by pressing the shift key. Code: What i wanted to do, was to modify your scroll.bbc to add automatic scrollbars to the default bb4w output window. But they should not be visible until they where needed, as when the window was resized smaller than the canvas. And to limit resizing up to the canvas size. Then hide scrollbars again. Sounds very straightforward, right? Still can't get it to work reliably, there always seems to be an unstable combination of variables.
Can this be one situation where eventlib is not the best choice ?
Svein
|
|
Logged
|
|
|
|
rtr
Guest
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #5 on: Aug 18th, 2014, 2:58pm » |
|
on Aug 18th, 2014, 2:06pm, sveinioslo wrote:Just checked if your original program had the same problem as mine, and it does! |
|
I cannot reproduce the problem here (Windows 8.1, Intel Core i7 1.90 GHz). If I reduce the canvas size to 800x600 SCROLL.BBC appears still to work perfectly.
Quote:I also inserted this line into PROCmove() to slow down the oscillations by pressing the shift key. |
|
Adding that code causes resizing and scrolling to happen slowly, but I don't observe any 'oscillatory' effect.
Quote:But they should not be visible until they where needed, as when the window was resized smaller than the canvas. |
|
That is the automatic behaviour of Windows scrollbars - you don't need to take any special measures to achieve it. Indeed, if I reduce the canvas to 800x600 and then drag the window to a larger size, the scroll bars disappear.
Quote:Can this be one situation where eventlib is not the best choice ? |
|
Since I am unable to reproduce the problem I cannot comment. Can you tell us something about your setup, such as the version of Windows, CPU type and speed etc. If I have a more similar machine I will try it on that.
Richard.
|
|
Logged
|
|
|
|
sveinioslo
Developer
member is offline


Posts: 64
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #6 on: Aug 18th, 2014, 6:05pm » |
|
Quote:I cannot reproduce the problem here |
|
Yes, it can sometimes be hard to get the 'oscillatory' effect started. Especially when one wants to. It will never happend while the mouse button is pressed, for some reason. It seems to be a matter of releasing the mousebutton at the right time at the right spot. And both x and y edges of the window must be 'at' or very close to the canvas x y.
Don't think this is pc-specific, tried it on: Win7 pro 32bit core i7 3.4gHz stationary bbc 5.95a Win7 home 64bit core i7 ?gHz laptop new bbc 5.95a Win7 pro dual core 1.6gHz laptop old bbc 5.93a
Quote:Quote:
I also inserted this line into PROCmove() to slow down the oscillations by pressing the shift key.
Adding that code causes resizing and scrolling to happen slowly, but I don't observe any 'oscillatory' effect |
|
Oscillation can be so quick that one can hardly see it, unless one know or expect it to happend, pressing shiftkey when the display seems to flicker, will reveal the oscillation. It is not always the same pattern or frequency. Quote:That is the automatic behaviour of Windows scrollbars - you don't need to take any special measures to achieve it. Indeed, if I reduce the canvas to 800x600 and then drag the window to a larger size, the scroll bars disappear |
|
Yes. If window<canvas we get and want bars If window>canvas we have no bars and we don't need them If window=canvas we will get bars, but they are not needed If we resize window larger than canvas, we get visible empty unusable areas to the bottom or left of the active window area. To have window=canvas with no bars we need make six.nPage%=canvas+1 Trying to adjust the window with SYS "SetWindowPos" will make it very much easier to get the 'oscillatory' effect. It seems both "SetScrollInfo" and "SetWindowPos" sends the WM_SIZE message, and that will get stored in the eventqueue before PROCmove returns to the inner loop of PROC_eventpoll, which picks up the messages and calls PROCmove again, indefinitely sometimes. One can put say: CNT%+=1 in the inner loop of PROC_eventpoll and open variable viewer to monitor that value. When it starts to rush away, we have the oscillation going. Svein
|
|
Logged
|
|
|
|
sveinioslo
Developer
member is offline


Posts: 64
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #7 on: Aug 18th, 2014, 6:12pm » |
|
Try this one, you will see all kind of malfunctions. A disaster really. Code: SWP_NOMOVE = 2
SWP_NOZORDER = 4
WHITENESS = &FF0062
WM_SIZE = 5
WM_HSCROLL = &114
WM_VSCROLL = &115
WS_HSCROLL = &100000
WS_VSCROLL = &200000
CanvasX% = 800
CanvasY% = 800
WindowX% = 700
WindowY% = 700
IF WindowX%=0 THEN WindowX%=@vdu%!208
IF WindowY%=0 THEN WindowY%=@vdu%!212
IF CanvasX%=0 THEN CanvasX%=WindowX%
IF CanvasY%=0 THEN CanvasY%=WindowY%
SYS "SetWindowPos", @hwnd%, 0, 0, 0, WindowX%, WindowY%, SWP_NOMOVE + SWP_NOZORDER
DIM BITMAPINFOHEADER{Size%, Width%, Height%, Planes{l&,h&}, BitCount{l&,h&}, \
\ Compression%, SizeImage%, XPelsPerMeter%, YPelsPerMeter%, \
\ ClrUsed%, ClrImportant%}
DIM bmi{Header{} = BITMAPINFOHEADER{}}
bmi.Header.Size% = DIM(BITMAPINFOHEADER{})
bmi.Header.Width% = CanvasX%
bmi.Header.Height% = CanvasY%
bmi.Header.Planes.l& = 1
bmi.Header.BitCount.l& = 24
SYS "CreateDIBSection", @memhdc%, bmi{}, 0, ^Bits%, 0, 0 TO hbitmap%
IF hbitmap% = 0 ERROR 100, "Couldn't create DIBSection"
SYS "SelectObject", @memhdc%, hbitmap% TO oldhbm%
SYS "DeleteObject", oldhbm%
INSTALL @lib$+"EVENTLIB"
PROC_eventinit
PROC_eventregister(WM_SIZE, PROCmove())
PROC_eventregister(WM_HSCROLL, PROCmove())
PROC_eventregister(WM_VSCROLL, PROCmove())
REM SYS "GetWindowLong", @hwnd%, -16 TO ws%
REM SYS "SetWindowLong", @hwnd%, -16, ws% OR WS_HSCROLL OR WS_VSCROLL
VDU 23,22,WindowX%;WindowY%;8,16,16,128
ORIGIN 0,2*(@vdu%!212-CanvasY%)
VDU 24,0;0;CanvasX%*2-2;CanvasY%*2-2;
CLG
LINE 0,0,CanvasX%*2-2,CanvasY%*2-2
LINE 0,CanvasY%*2-2,CanvasX%*2-2,0
VDU 23,23,2;0;0;0;
OFF : VDU 5 : VDU 30
MOVE 0,CanvasY%*2-200
REPEAT
WAIT 10
cx% = RND(CanvasX%*2)
cy% = RND(CanvasY%*2)
cr% = RND(200)
GCOL RND(15)
CIRCLE FILL cx%, cy%, cr%
GCOL 0
CIRCLE cx%, cy%, cr%
GCOL 4,0
MOVE cx%-8*INTLOG(cr%)-8,cy%+16
IF cr% > 24 PRINT ;cr%;
PROC_eventpoll
PROCscroll(-1)
UNTIL FALSE
END
DEF PROCscroll(Y%)
PRIVATE S%
IF S% THEN ENDPROC
S%=TRUE
LOCAL rc{}
DIM rc{l%,t%,r%,b%}
SYS "GetRgnBox", @vdu.hr%, rc{}
SYS "ScrollDC", @memhdc%, 0, Y%, rc{}, 0, 0, 0
SYS "ScrollWindow", @hwnd%, 0, Y%, 0, 0
IF Y%<0 THEN
SYS "PatBlt", @memhdc%, 0, CanvasY%-ABS(Y%), CanvasX%, ABS(Y%), WHITENESS
ELSE
SYS "PatBlt", @memhdc%, 0, 0, CanvasX%, ABS(Y%), WHITENESS
ENDIF
REM PROCclr(Bits%,CanvasX%*ABS(Y%),255)
S%=FALSE
ENDPROC
DEF FNTAB(X%,Y%) : X% = X%*16 : Y% = 2*CanvasY%-Y%*24
= CHR$25+CHR$4+CHR$(X%)+CHR$(X%DIV256)+CHR$(Y%)+CHR$(Y%DIV256)
DEF PROCclr(B%,C%,A%) : REM b=start c=len a=value
PRIVATE E%
CASE bmi.Header.BitCount.l& OF
WHEN 24 : C%*=3
WHEN 32 : C%*=4
ENDCASE
IF E%=0 THEN
LOCAL F%,G%,H%,I%,L%
DIM E% 45 : L%=E%+45
FOR I%=8 TO 10 STEP 2
P%=E%
[OPT I%
mov edx,eax
shl edx,8
or eax,edx
mov edx,eax
shl edx,16
or eax,edx
mov edx,eax
.H%
mov al,cl
and al,3
jz G%
mov [ebx+ecx],dl
dec ecx
jmp short H%
.G%
mov eax,edx
mov edx,4
shr ecx,2
.F%
mov [ebx],eax
add ebx,edx
loop F%
ret
]
NEXT I%
ENDIF
CALL E%
ENDPROC
DEF PROCmove(msg%,wp%,lp%) : REM ENDPROC
REM PRINT msg%,wp%,lp%
PRIVATE sih{}, siv{}
LOCAL flag%
DIM sih{cbSize%, fMask%, nMin%, nMax%, nPage%, nPos%, nTrackPos%}
DIM siv{cbSize%, fMask%, nMin%, nMax%, nPage%, nPos%, nTrackPos%}
sih.cbSize% = DIM(sih{})
siv.cbSize% = DIM(siv{})
sih.fMask% = 7
siv.fMask% = 7
sih.nMax% = CanvasX%
siv.nMax% = CanvasY%
CASE msg% OF
WHEN WM_SIZE:
sih.nPage% = lp% AND &FFFF
siv.nPage% = lp% >>> 16
LOCAL rc{},xs%,ys%,xmax%,ymax%,flag%,sx%,sy%,hbar%,vbar%
DIM rc{l%,t%,r%,b%}
SYS "GetSystemMetrics", 0 TO xs% : xs%-=20 :REM screen
SYS "GetSystemMetrics", 1 TO ys% : ys%-=20
SYS "GetSystemMetrics", 2 TO sx% : REM scrollbar
SYS "GetSystemMetrics", 3 TO sy%
IF sih.nPage%<CanvasX% THEN hbar%=1 ELSE hbar%=0 : sih.nPage%=CanvasX%+1
IF siv.nPage%<CanvasY% THEN vbar%=1 ELSE vbar%=0 : siv.nPage%=CanvasY%+1
IF CanvasX%>xs% THEN xmax%=xs% ELSE xmax%=CanvasX%+vbar%*sx%
IF CanvasY%>ys% THEN ymax%=ys% ELSE ymax%=CanvasY%+hbar%*sy%
REM IF sih.nPage%=CanvasX% THEN ymax%=ymax%-sy% ELSE ymax%=ymax%+sy%
REM IF siv.nPage%=CanvasY% THEN xmax%=xmax%-sx% ELSE xmax%=xmax%+sx%
rc.r%=xmax% : rc.b%=ymax%
SYS "GetWindowLong", @hwnd%, -16 TO style%
SYS "AdjustWindowRect", rc{}, style%, 0 : REM menu or not ??? , taskbar ??????
xmax%=rc.r%-rc.l% : IF xmax%>xs% THEN xmax%=xs%
ymax%=rc.b%-rc.t% : IF ymax%>ys% THEN ymax%=ys%
SYS "GetWindowRect", @hwnd%, rc{}
rc.r%=rc.r%-rc.l%
rc.b%=rc.b%-rc.t%
IF rc.r% > xmax% THEN
WindowX%=xmax%+vbar%*sx%
flag%=1
ELSE
WindowX%=rc.r%+vbar%*sx%: REM no need to "setwindowpos" unless Y needs
ENDIF
IF rc.b% > ymax% THEN
WindowY%=ymax%+hbar%*sy%
flag%=1
ELSE
WindowY%=rc.b%+hbar%*sy%
ENDIF
IF INKEY(-1) THEN TRACE STEP ON
WHEN WM_HSCROLL:
CASE wp% AND &FFFF OF
WHEN 0: sih.nPos% -= 1
WHEN 1: sih.nPos% += 1
WHEN 2: sih.nPos% -= sih.nPage%
WHEN 3: sih.nPos% += sih.nPage%
WHEN 5: sih.nPos% = wp% >> 16
ENDCASE
WHEN WM_VSCROLL:
CASE wp% AND &FFFF OF
WHEN 0: siv.nPos% -= 1
WHEN 1: siv.nPos% += 1
WHEN 2: siv.nPos% -= siv.nPage%
WHEN 3: siv.nPos% += siv.nPage%
WHEN 5: siv.nPos% = wp% >> 16
ENDCASE
ENDCASE
IF sih.nPos% > sih.nMax%-sih.nPage% sih.nPos% = sih.nMax%-sih.nPage%
IF siv.nPos% > siv.nMax%-siv.nPage% siv.nPos% = siv.nMax%-siv.nPage%
IF sih.nPos% < sih.nMin% sih.nPos% = sih.nMin%
IF siv.nPos% < siv.nMin% siv.nPos% = siv.nMin%
SYS "SetScrollInfo", @hwnd%, 0, sih{}, 1
SYS "SetScrollInfo", @hwnd%, 1, siv{}, 1
@ox% = sih.nPos%
@oy% = siv.nPos%
SYS "InvalidateRect", @hwnd%, 0, 0
*REFRESH
IF flag% THEN SYS "SetWindowPos", @hwnd%, 0, 0, 0, WindowX%, WindowY%, SWP_NOMOVE + SWP_NOZORDER
ENDPROC
|
|
Logged
|
|
|
|
sveinioslo
Developer
member is offline


Posts: 64
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #8 on: Aug 18th, 2014, 6:15pm » |
|
In my coding, that is.!
svein
|
|
Logged
|
|
|
|
rtr
Guest
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #9 on: Aug 18th, 2014, 9:54pm » |
|
on Aug 18th, 2014, 6:05pm, sveinioslo wrote:Yes, it can sometimes be hard to get the 'oscillatory' effect started. Especially when one wants to. |
|
I've never managed it. All the systems you listed run Windows 7, so it may be associated with that specific version. If you get an opportunity, try it on Windows 8 or 8.1.
Quote:It seems both "SetScrollInfo" and "SetWindowPos" sends the WM_SIZE message |
|
My expectation would be that SetScrollInfo would send a WM_SIZE message only if it results in a scrollbar appearing (in which case the client size decreases) or a scrollbar disappearing (in which case the client size increases). In those specific cases it is obviously correct to send a WM_SIZE message.
However if, as a result of the SetScrollInfo, a scrollbar neither appears nor disappears, the client size doesn't change and I would not expect a WM_SIZE to be generated. This program confirms that to be the case (on Windows 8.1 at least) since no ON MOVE occurs:
Code: ON MOVE PRINT "ON MOVE received" : RETURN
DIM sih{cbSize%, fMask%, nMin%, nMax%, nPage%, nPos%, nTrackPos%}
DIM siv{cbSize%, fMask%, nMin%, nMax%, nPage%, nPos%, nTrackPos%}
sih.cbSize% = DIM(sih{})
siv.cbSize% = DIM(siv{})
sih.fMask% = 7
siv.fMask% = 7
sih.nMax% = @vdu%!208
siv.nMax% = @vdu%!212
sih.nPage% = sih.nMax%+1
siv.nPage% = siv.nMax%+1
SYS "SetScrollInfo", @hwnd%, 0, sih{}, 1
SYS "SetScrollInfo", @hwnd%, 1, siv{}, 1
REPEAT
WAIT 1
UNTIL FALSE
END That being the case, I do not understand how an 'oscillatory' effect can result, and I do not see one here.
Whatever is going on, EVENTLIB is not to blame because all it does is effectively to lengthen the event queue from 32 to 64 events. Even if you eliminate EVENTLIB's queue entirely, you are still left with the 32-event queue built into BB4W; so the same effect is likely to occur.
Richard.
Edit: I've just tried the above code in Windows 7 - no ON MOVE happens there either. So, if you gradually increase the size of the Window, at one point the scrollbar will disappear. This will result in the client size increasing and a WM_SIZE message being sent - but only one. The increase in the client size cannot result in another WM_SIZE - the scrollbar is still absent.
Similarly, if you gradually decrease the size of the Window, at one point the scrollbar will appear. This will result in the client size decreasing and a WM_SIZE message being sent, but again only one. The decrease in the client size cannot result in another WM_SIZE - the scrollbar is still present.
So how can any kind of 'oscillation' happen? If anything what you have is hysteresis - which is what you want to prevent oscillation! I simply don't understand the mechanism behind what you observe.
|
« Last Edit: Aug 18th, 2014, 10:45pm by rtr » |
Logged
|
|
|
|
sveinioslo
Developer
member is offline


Posts: 64
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #10 on: Aug 18th, 2014, 11:56pm » |
|
Hmm !?
Just to be clear if this is a windows problem or not. Are you saying that you ran this code on a windows 8 machine, and it just ended. you didn't see a slowly pulsating window ??
Code:SWP_NOMOVE = 2
SWP_NOZORDER = 4
WM_SIZE = 5
INSTALL @lib$+"eventlib"
PROC_eventinit
PROC_eventregister(WM_SIZE, PROCstuck())
SYS "SendMessage",@hwnd%,WM_SIZE,0,0
PROC_eventpoll
END
DEF PROCstuck(m%,w%,l%)
PRIVATE X% : X%+=1 : IF X%>400 X%=0
SYS "SetWindowPos", @hwnd%, 0, 0, 0, 200+X%, 200+X%, SWP_NOMOVE + SWP_NOZORDER
WAIT 1: ENDPROC
Are you also saying that on a windows 8 machine, this code will also just end ??
Code: INSTALL @lib$+"eventlib"
PROC_eventinit
PROC_eventregister(123, PROCstuck())
SYS "SendMessage",@hwnd%,123,0,0
PROC_eventpoll
END
DEF PROCstuck(m%,w%,l%)
SYS "SendMessage",@hwnd%,123,0,0
ENDPROC
If so, then yes, there is a difference between win7 and win8.
Svein
|
|
Logged
|
|
|
|
rtr
Guest
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #11 on: Aug 19th, 2014, 08:42am » |
|
on Aug 18th, 2014, 11:56pm, sveinioslo wrote:Are you saying that you ran this code on a windows 8 machine, and it just ended. you didn't see a slowly pulsating window ?? |
|
Those programs are not relevant to the issue under discussion. The first sends a SetWindowPos message every time a WM_SIZE message is received, so of course you have deliberately created a feedback mechanism. The second program sends another WM_CONTEXTMENU message every time one is received, so again you have created a feedback mechanism.
If you deliberately create feedback, you can expect unwanted things to happen. Exactly what happens will be difficult to predict, but depending on the system dynamics an oscillatory behaviour is entirely reasonable. For example simply adding delay in the feedback path can dramatically change the system dynamics (in servo-system theory this would be equivalent to changing the phase of the feedback signal).
You may end up with a system which exhibits damped oscillation, which eventually dies down, or a system which exhibits oscillation which builds up until it is limited by a non-linearity. Often the optimum solution is considered to be 'critical damping', which is a non-oscillatory transition to a new steady-state. The mathematics of such systems is well understood, and as an electronics engineer I have plenty of experience of them!
If you are interested in understanding more about servo theory and how to control a system's dynamics, there is plenty of information available online such as:
http://en.wikipedia.org/wiki/Damping
But none of this has any relevance to SCROLL.BBC, which is the program you were reporting problems with. SCROLL.BBC does not contain such a feedback mechanism. When a WM_SIZE message is received, another WM_SIZE message is generated only very rarely - specifically when the SetScrollInfo causes a scrollbar to appear or to disappear. I would not expect SCROLL.BBC to exhibit oscillatory behaviour, and I see no trace of it doing so here.
Richard.
|
|
Logged
|
|
|
|
sveinioslo
Developer
member is offline


Posts: 64
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #12 on: Aug 19th, 2014, 11:56am » |
|
Quote:Those programs are not relevant to the issue under discussion |
|
They were made specifically to pinpoint IF there is a feedback mechanism, and WHERE it occurs. That is: 'can it be the combination of PROCmove and PROC_eventpoll ?' The answer is a definite yes. Quote:If you are interested in understanding more about servo theory |
|
We are on the same page here. I worked as an electronics system designer/programmer in the eighties. Not been working with anything remotely close, ever since. Quote:SCROLL.BBC does not contain such a feedback mechanism. |
|
No, not in it self, but in combination with eventlib it does. You may have missed that there is two consecutive "SetScrollInfo" in PROCmove. They can both send a WM_SIZE. So every WM_SIZE can result in 0,1 or 2 new WM_SIZE.
I am not putting any 'blame' on eventlib, this is just an unfortunate combination that can result in oscillation. The solution is clear: Keep canvas larger than the screen and find another way of dealing with the window resizing And/or Use asynchronous interrupt with a busy flag.
I have made a new video for you, which will provide 'beyond shadow of a doubt' proof. http://fix24.net/bb4w/New_Scroll.bbc.mp4
It is for sure the WM_SIZE message. Svein
|
|
Logged
|
|
|
|
rtr
Guest
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #13 on: Aug 19th, 2014, 1:22pm » |
|
on Aug 19th, 2014, 11:56am, sveinioslo wrote:That is: 'can it be the combination of PROCmove and PROC_eventpoll ?' The answer is a definite yes. |
|
No. If you create feedback, you can end up with an oscillatory system. That's it. It is irrelevant and unhelpful to refer to specific elements of the system such as PROCmove and PROC_eventpoll. They are no more 'responsible' for the oscillation than, for example, a single resistor or capacitor can be said to be 'responsible' for the oscillation of a hardware circuit.
It is the system as a whole which oscillates. Change any single element within that system and it is likely to change the behaviour.
Quote:The solution is clear: Keep canvas larger than the screen and find another way of dealing with the window resizing And/or Use asynchronous interrupt with a busy flag. |
|
As far as SCROLL.BBC is concerned there is no requirement for a "solution" because there isn't a problem!
Your videos purport to demonstrate a failure mode, but even if that is the case (and I cannot reproduce it here, however hard I try) it happens only over a very narrow range of conditions and it is of trivial significance.
I WILL NOT REPLY TO ANY FURTHER COMMENTS YOU MAY MAKE.
Richard.
|
|
Logged
|
|
|
|
sveinioslo
Developer
member is offline


Posts: 64
|
 |
Re: A solution to the old FN_setproc problem.
« Reply #14 on: Aug 19th, 2014, 2:18pm » |
|
Let's agree to disagree then.  Have a good day.
Svein
|
|
Logged
|
|
|
|
|