coda
Junior Member
Posts: 74
|
Post by coda on Mar 15, 2022 4:44:29 GMT -5
Is there a known issue using the "!locate" command with statictext? It seems to partially work only and produces random results. Sometimes it behaves and relocates all text. Sometimes text positions are only partially updated. Which text and when seems completely random. If so, how do I work around this? Any help great appreciated.
|
|
coda
Junior Member
Posts: 74
|
Post by coda on Mar 15, 2022 4:50:41 GMT -5
Ok... I may have solved this one, myself, just after uploading the question. It seems there is some kind potential glitch where order matters. If I issue all relocation commands to the statictext items PRIOR to relocating my combobox items I have NO issue but if I do it the other way around chaos ensues. I'm not sure why that would be (if anyone does pls let me know) but it seems at least to be working in that order.
|
|
coda
Junior Member
Posts: 74
|
Post by coda on Mar 15, 2022 4:59:54 GMT -5
I spoke too soon, by the looks of it. I'm still plagued by chaos and random positionings... Help
|
|
coda
Junior Member
Posts: 74
|
Post by coda on Mar 15, 2022 5:09:13 GMT -5
Ok. I seem to be able to stop the randomness occurring if I hide the window prior to relocating the statictext objects and then show it again afterwards. Hope this helps someone.
|
|
|
Post by Walt Decker on Mar 15, 2022 9:24:24 GMT -5
I do not see a problem. Code below is Rod's code modified. ' nomainwin a$(1) = "one" a$(2) = "two" a$(3) = "three" a$(4) = "four" combobox #win.combo1, a$(),[doCombo1],10,10,120,200 combobox #win.combo2, a$(),[doCombo2],10,30,120,200 combobox #win.combo3, a$(),[doCombo3],10,50,120,200 STATICTEXT #win.Stat1, "combo1", 135, 10, 120, 15 STATICTEXT #win.Stat2, "combo2", 135, 30, 120, 15 STATICTEXT #win.Stat3, "combo3", 135, 50, 120, 15 open "Combobox Demo" for window as #win #win "trapclose [quit]" ' #win.combo1 "selectindex 1" ' #win.combo2 "selectindex 1" #win.combo3 "selectindex 3" PRINT #win.combo3, "setfocus" timer 2000,[locate] wait
[locate] timer 0 'PRINT #win.Stat3, "!locate 135 100, 120 15" #win.combo3 "locate 10 100 120 200" PRINT #win.Stat3, "!locate 135 100, 120 15" #win "refresh" ' #win.combo1 "selectindex 1" ' #win.combo2 "selectindex 1" ' #win.combo3 "selectindex 1" wait
[quit] close #win end
[doCombo1] #win.combo1 "selection? sel$" notice "You chose ";sel$ wait
[doCombo2] #win.combo2 "selection? sel$" notice "You chose ";sel$ wait
[doCombo3] #win.combo3 "selection? sel$" notice "You chose ";sel$ wait '
|
|
coda
Junior Member
Posts: 74
|
Post by coda on Mar 15, 2022 10:18:08 GMT -5
Thanks for your reply, Walt. The problem seems to be random in nature. I can have the program move the text items 13 times or more flawlessly and then for no apparent reason the same code doesn't move them and they appear to have overwritten themselves. It doesn't happen after 13 cycles, it happens randomly and it works more often than not. You may need to get groupboxes involved (which are known to cause other problems that a hide/show on the window fixes) and repeat moving them several times for the problem to show itself. I'm not exactly sure why the problem shows up or doesn't show up but I'm fairly confident it is a bug because executing a 'hide' then 'show' on the window fixes it 100%. In other words, nothing was actually wrong with the code. The text is is where it should be, the window just hasn't always drawn properly for some reason.
|
|
|
Post by Walt Decker on Mar 15, 2022 10:30:38 GMT -5
Are you using a group button (box)? If so, remove it and see what happens.
I will modify the code a little more later today in an attempt to duplicate the problem. Now I have some rose bushes to trim.
|
|
|
Post by Rod on Mar 15, 2022 10:35:16 GMT -5
Are you using literal values or variables to locate the controls? I think if there were a bug we would know about it by now but you never know. It seems that Windows can fix the error by redrawing the screen. Refresh actually causes Windows to redraw the screen. Try a second refresh or put refresh on a button to see if it fixes the screen. If it does and the screen drawing is broken I suspect the culprit might be your display drivers / graphic card. Are they up to date? Fairly easy to check on Windows.
|
|
coda
Junior Member
Posts: 74
|
Post by coda on Mar 15, 2022 11:05:19 GMT -5
Yes, there are multiple groupboxes containing radio buttons and similar on my window. I am very aware of the bug surrounding groupboxes causing misdrawing and how to fix it which is why I have been wondering if their presence is the culprit.
Yes, a second refresh also fixes the problem, same as hiding and showing the window. Yes, my computer is brand new. Yes, I've just double checked my driver status and it is up-to-date.
Perhaps either Windows 10 or my graphics driver is the thing containing the bug and not LB but it is a bug in something because it is not my code.
|
|
|
Post by Walt Decker on Mar 15, 2022 17:48:20 GMT -5
Even with a group button and using variables to change the location of combo boxes and static controls I see no problem: ' 'nomainwin a$(1) = "one" a$(2) = "two" a$(3) = "three" a$(4) = "four"
MoveCount = 0
combobox #win.combo1, a$(), doCombo1,10,10,120,200 combobox #win.combo2, a$(), doCombo1,10,30,120,200 combobox #win.combo3, a$(), doCombo1,10,50,120,200
STATICTEXT #win.Stat1, "combo1", 135, 10, 50, 15 STATICTEXT #win.Stat2, "combo2", 135, 30, 50, 15 STATICTEXT #win.Stat3, "combo3", 135, 50, 50, 15
GROUPBOX #win.GRP, "DMY", 5, 100, 185, 210
open "Combobox Demo" for window as #win #win "trapclose [quit]"
[SET.TIMER] TIMER 2000, [CHANGE.CTL.LOC] wait
'------------------------------------------------------- '------------------------------------------------------- [quit] close #win end
[CHANGE.CTL.LOC]
TIMER 0 Ctl = 0 RetVal = 0
Ctl = INT(RND(0) * 3) + 1
SELECT CASE Ctl CASE 1 RetVal = FN.MoveCtrls("#win.combo1", "#win.Stat1")
CASE 2 RetVal = FN.MoveCtrls("#win.combo2", "#win.Stat2") CASE 3 RetVal = FN.MoveCtrls("#win.combo3", "#win.Stat3") END SELECT
TIMER 5000, [RESET.CTL] WAIT
[RESET.CTL] TIMER 0
SELECT CASE Ctl CASE 1 PRINT #win.combo1, "locate 10 10 120 200" PRINT #win.Stat1, "!locate 135 10 50 15"
CASE 2 PRINT #win.combo2, "locate 10 30 120 200" PRINT #win.Stat2, "!locate 135 30 50 15"
CASE 3 PRINT #win.combo3, "locate 10 50 120 200" PRINT #win.Stat3, "!locate 135 50 50 15" END SELECT
PRINT #win, "REFRESH" MoveCount = MoveCount + 2 PRINT MoveCount GOTO [SET.TIMER] [END.CHANGE]
SUB doCombo1 CmboHndl$
'SELECT CASE CmboHndl$ ' CASE "#win.combo1" ' PRINT #CmboHndl$, "locate ";100;" ";25;" ";120;" ";200 ' CASE "#win.combo2" + ' PRINT #CmboHndl$, "locate ";185;" ";100;" ";120;" ";200 ' PRINT #win.Stat2, "!locate ";310;" ";100;" ";50;" ";15 ' CASE "#win.combo3" ' PRINT #win.Stat3, "!locate ";10;" ";100;" ";50;" ";15 ' PRINT #CmboHndl$, "locate ";60;" ";100;" ";120;" ";200 'END SELECT
'PRINT #win, "REFRESH"
END SUB
'-------------------------------------------------------- '--------------------------------------------------------
FUNCTION FN.MoveCtrls(CmbTag$, StatTag$)
RetVal = 0
Ulx = 0 Uly = 0 Brx = 0 Bry = 0
I = 0
PrntTag$ = ""
I = INSTR(CmbTag$, ".")
PrntTag$ = LEFT$(CmbTag$, I - 1) RetVal = FN.ClientSize(PrntTag$, Brx, Bry)
Ulx = INT(RND(I) * Brx) - 1 Uly = INT(RND(Ulx) * Bry) - 1 PRINT #CmbTag$, "locate ";Ulx;" ";Uly;" ";120;" ";200 Ulx = Ulx + 125 PRINT #StatTag$, "!locate ";Ulx;" ";Uly;" ";50;" ";15 PRINT #PrntTag$, "REFRESH" END FUNCTION
'--------------------------------------------------------- '---------------------------------------------------------
FUNCTION FN.ClientSize(WinTag$, BYREF WinWide, BYREF WinHigh)
STRUCT tRect, _ X AS LONG, _ Y AS LONG, _ X1 AS LONG, _ Y1 AS LONG
WinHndl = 0 RetVal = 0
WinHndl = FN.GetHandle(WinTag$) CALLDLL #user32, "GetClientRect", WinHndl AS ULONG, tRect AS STRUCT, _ RetVal AS VOID
WinWide = tRect.X1.struct WinHigh = tRect.Y1.struct
END FUNCTION
'--------------------------------------------------------- '---------------------------------------------------------
FUNCTION FN.GetHandle(WinTag$)
WinHndl = 0 WinTag$ = FN.CheckTag$(WinTag$)
WinHndl = HWND(#WinTag$) FN.GetHandle = WinHndl END FUNCTION
'--------------------------------------------------------- '---------------------------------------------------------
FUNCTION FN.CheckTag$(WinTag$)
IF LEFT$(WinTag$, 1) <> "#" THEN WinTag$ = "#" + WinTag$
FN.CheckTag$ = WinTag$ END FUNCTION
'
|
|
|
Post by Brandon Parker on Mar 15, 2022 20:48:48 GMT -5
Coda, Can you supply a short snippet that reliably produces the issue you are observing?
{:0)
Brandon Parker
|
|
coda
Junior Member
Posts: 74
|
Post by coda on Mar 16, 2022 2:25:43 GMT -5
Thankyou for your efforts, Walt. You are worthy of knighthood. Yes, I see that your code is working. It also appears to work flawlessly on my machine. The problem is that it could be any number of things. It could be because my statictext is inside the group box. It could be because I have a graphicbox open in the same window. It could be, it could be, it could be... I just don't know as I have never used the locate/!locate command before in any of my programs so, I have no frame of reference as to what is different that has made it not work or appear not to work. I'm not doing anything different to you guys, trust me. ...and the text HAS moved, as evidenced by either hiding and showing the window or double refreshing as Rod suggested. It just isn't drawing properly without these further steps. Truthfully, I'm not sure if I CAN reproduce it outside my full code but in any case, I'm happy with the hide/show or double refresh solution to fix it. I know it's a band aid fix... a bit of a "bodge" but sometimes, I've learnt, you just have to accept bodges in order to move forward in life. It is invisible to the user, so I don't care. I have also commented the second refresh reminding myself that it isn't a typo and why it is there so that future me won't remove it. If the problem rears it's ugly head again. I'll try to create a code snippet. Thanks everyone for your amazing support as always. You guys rock!
|
|
|
Post by Rod on Mar 16, 2022 3:17:28 GMT -5
I did ask if we are using literals or variables to move the controls? If so print out the move to double check the variables are in scope and have values you expect. Also are we using resize at any point? Is there a timer running? Issuing a resize command has issues as it is only actioned when the window is actually resized. A timer can interfere with program flow.
But we are really at the stage of needing code that displays the error. Not sure you should move on without finding the culprit.
|
|
|
Post by Walt Decker on Mar 16, 2022 10:47:50 GMT -5
I have modified the code by moving the group button around the comboboxes and static controls and selecting an item in combobox1 and combobox3. I still see no problem. The items selected are hilited as they should be(that is a Windoz thing) and retain the hilighting on each move.
Instead of trying a work-around you should find the problem and fix it otherwise it might cause problems later.
' 'nomainwin a$(1) = "one" a$(2) = "two" a$(3) = "three" a$(4) = "four"
MoveCount = 0
CmbX = 0 CmbY = 0 CmbWide = 0 CmbHigh = 0
Lbx = 0 Lby = 0 LbWide = 0 LbHigh = 0
combobox #win.combo1, a$(), docombo,10,25,120,200 combobox #win.combo2, a$(), docombo,10,45,120,200 combobox #win.combo3, a$(), docombo,10,65,120,200
STATICTEXT #win.Stat1, "combo1", 135, 25, 50, 15 STATICTEXT #win.Stat2, "combo2", 135, 45, 50, 15 STATICTEXT #win.Stat3, "combo3", 135, 65, 50, 15
GROUPBOX #win.GRP, "DMY", 5, 5, 185, 210 'GROUPBOX #win.GRP, "DMY", 5, 100, 185, 210
open "Combobox Demo" for window as #win #win "trapclose [quit]" PRINT #win.combo1, "selectindex 1" PRINT #win.combo3, "selectindex 3"
[SET.TIMER] TIMER 2000, [CHANGE.CTL.LOC] wait
'------------------------------------------------------- '------------------------------------------------------- [quit] close #win end
[CHANGE.CTL.LOC]
TIMER 0
RetVal = 0 WinHndl = 0
Ctl = 0
Ctl = INT(RND(0) * 3) + 1 WinHndl = FN.GetHandle("#win") TRACE 2 SELECT CASE Ctl CASE 1 RetVal = FN.WindowSize("#win.combo1", CmbX, CmbY, CmbWide, CmbHigh) RetVal = FN.WindowSize("#win.Stat1", Lbx, Lby, LbWide, LbHigh) RetVal = FN.MoveCtrls("#win.combo1", "#win.Stat1")
CASE 2 RetVal = FN.WindowSize("#win.combo2", CmbX, CmbY, CmbWide, CmbHigh) RetVal = FN.WindowSize("#win.Stat2", Lbx, Lby, LbWide, LbHigh) RetVal = FN.MoveCtrls("#win.combo2", "#win.Stat2") CASE 3 RetVal = FN.WindowSize("#win.combo3", CmbX, CmbY, CmbWide, CmbHigh) RetVal = FN.WindowSize("#win.Stat3", Lbx, Lby, LbWide, LbHigh) RetVal = FN.MoveCtrls("#win.combo3", "#win.Stat3") END SELECT
TIMER 5000, [RESET.CTL] WAIT
[RESET.CTL] TIMER 0
SELECT CASE Ctl CASE 1 RetVal = FN.MapPoints(0, WinHndl, CmbX, CmbY, CmbWide, CmbHigh) RetVal = FN.MapPoints(0, WinHndl, Lbx, Lby, LbWide, LbHigh) CmbWide = CmbWide - CmbX CmbHigh = CmbHigh - CmbY LbWide = LbWide - Lbx LbHigh = LbHigh - Lby PRINT #win.combo1, "locate ";CmbX;" ";CmbY;" ";CmbWide;" ";CmbHigh PRINT #win.Stat1, "!locate ";Lbx;" ";Lby;" ";LbWide;" ";LbHigh
' PRINT #win.combo1, "locate 10 10 120 200" ' PRINT #win.Stat1, "!locate 135 10 50 15"
CASE 2 RetVal = FN.MapPoints(0, WinHndl, CmbX, CmbY, CmbWide, CmbHigh) RetVal = FN.MapPoints(0, WinHndl, Lbx, Lby, LbWide, LbHigh) CmbWide = CmbWide - CmbX CmbHigh = CmbHigh - CmbY LbWide = LbWide - Lbx LbHigh = LbHigh - Lby PRINT #win.combo2, "locate ";CmbX;" ";CmbY;" ";CmbWide;" ";CmbHigh PRINT #win.Stat2, "!locate ";Lbx;" ";Lby;" ";LbWide;" ";LbHigh ' PRINT #win.combo2, "locate 10 30 120 200" ' PRINT #win.Stat2, "!locate 135 30 50 15"
CASE 3 RetVal = FN.MapPoints(0, WinHndl, CmbX, CmbY, CmbWide, CmbHigh) RetVal = FN.MapPoints(0, WinHndl, Lbx, Lby, LbWide, LbHigh) CmbWide = CmbWide - CmbX CmbHigh = CmbHigh - CmbY LbWide = LbWide - Lbx LbHigh = LbHigh - Lby PRINT #win.combo3, "locate ";CmbX;" ";CmbY;" ";CmbWide;" ";CmbHigh PRINT #win.Stat3, "!locate ";Lbx;" ";Lby;" ";LbWide;" ";LbHigh
' PRINT #win.combo3, "locate 10 50 120 200" ' PRINT #win.Stat3, "!locate 135 50 50 15" END SELECT
PRINT #win, "REFRESH" MoveCount = MoveCount + 2 PRINT MoveCount GOTO [SET.TIMER] [END.CHANGE]
'-------------------------------------------------------- '--------------------------------------------------------
SUB docombo CmboHndl$
END SUB
'-------------------------------------------------------- '--------------------------------------------------------
FUNCTION FN.MoveCtrls(CmbTag$, StatTag$)
RetVal = 0
Ulx = 0 Uly = 0 Brx = 0 Bry = 0
I = 0
PrntTag$ = ""
I = INSTR(CmbTag$, ".")
PrntTag$ = LEFT$(CmbTag$, I - 1) RetVal = FN.ClientSize(PrntTag$, Brx, Bry)
Ulx = INT(RND(I) * Brx) - 1 Uly = INT(RND(Ulx) * Bry) - 1 PRINT #CmbTag$, "locate ";Ulx;" ";Uly;" ";120;" ";200 Ulx = Ulx + 125 PRINT #StatTag$, "!locate ";Ulx;" ";Uly;" ";50;" ";15 PRINT #PrntTag$, "REFRESH" END FUNCTION
'--------------------------------------------------------- '---------------------------------------------------------
FUNCTION FN.ClientSize(WinTag$, BYREF WinWide, BYREF WinHigh)
STRUCT tRect, _ X AS LONG, _ Y AS LONG, _ X1 AS LONG, _ Y1 AS LONG
WinHndl = 0 RetVal = 0
WinHndl = FN.GetHandle(WinTag$) CALLDLL #user32, "GetClientRect", WinHndl AS ULONG, tRect AS STRUCT, _ RetVal AS VOID
WinWide = tRect.X1.struct WinHigh = tRect.Y1.struct
END FUNCTION
'--------------------------------------------------------- '---------------------------------------------------------
FUNCTION FN.WindowSize(WinTag$, BYREF Ux, BYREF Uy,BYREF Bx, BYREF By)
STRUCT tRect, _ X AS LONG, _ Y AS LONG, _ X1 AS LONG, _ Y1 AS LONG
WinHndl = 0 RetVal = 0
WinHndl = FN.GetHandle(WinTag$) CALLDLL #user32, "GetWindowRect", WinHndl AS ULONG, tRect AS STRUCT, _ RetVal AS VOID
Ux = tRect.X.struct Uy = tRect.Y.struct Bx = tRect.X1.struct By = tRect.Y1.struct
END FUNCTION
'--------------------------------------------------------- '---------------------------------------------------------
FUNCTION FN.MapPoints(Wfrom, Wto, BYREF Ux, BYREF Uy,BYREF Bx, BYREF By)
STRUCT tRect, _ X AS LONG, _ Y AS LONG, _ X1 AS LONG, _ Y1 AS LONG
RetVal = 0 tRect.X.struct = Ux tRect.Y.struct = Uy tRect.X1.struct = Bx tRect.Y1.struct = By
CALLDLL #user32, "MapWindowPoints", Wfrom AS ULONG, Wto AS ULONG, _ tRect AS STRUCT, 2 AS LONG, RetVal AS VOID
Ux = tRect.X.struct Uy = tRect.Y.struct Bx = tRect.X1.struct By = tRect.Y1.struct
END FUNCTION
'--------------------------------------------------------- '---------------------------------------------------------
FUNCTION FN.GetHandle(WinTag$)
WinHndl = 0 WinTag$ = FN.CheckTag$(WinTag$)
WinHndl = HWND(#WinTag$) FN.GetHandle = WinHndl END FUNCTION
'--------------------------------------------------------- '---------------------------------------------------------
FUNCTION FN.CheckTag$(WinTag$)
IF LEFT$(WinTag$, 1) <> "#" THEN WinTag$ = "#" + WinTag$
FN.CheckTag$ = WinTag$ END FUNCTION
'
|
|
coda
Junior Member
Posts: 74
|
Post by coda on Mar 17, 2022 8:19:09 GMT -5
Literals. That's how I know that the same code can't produce different results and therefore there must be some kind of bug at play in either Windows 10, my graphics driver or LB. Honestly, if I had to guess, my money is on Windows 10 followed by LB. We know the actual code to move the controls in LB IS working. We know this because refreshing the window a second time would not result in the controls being in the right place if LB weren't positioning them correctly. What we don't know is why a single refresh is insufficient to always redraw the window properly.
Here's how my code works: I am literally checking and unchecking a checkbox that triggers a handler that uses literals to moves comboboxes and statictext elements into one position when the checkbox is checked and into another when the checkbox is unchecked and that's all the handler really does apart from triggering a flag and reversing some elements in a 2D array that has nothing to do with the repositioning. If I run my program, without the double refresh, I can sit there and toggle the checkbox back and forth, on and off and on and off... click, click, click, click... and if I do this about 20 or so times on average, one random time in that 20 will misdraw the window showing some of the the static text in the wrong spot.... however, if I include the second refresh. I can toggle it to my heart's content and the comboboxes and the statictext always just appear where they should, no matter how many times I check and uncheck the checkbox.
No. No resizing. No. No timer... and Walt's code DOES use a timer and works just fine.
I hear you. I love your enthusiasm for getting to the bottom of a problem. It's why you're such a great programmer and normally that's me too but if I had applied that logic to the well-known groupbox misdraw issue I would still be working on finding why my code was wrong when it isn't.
I am confident my code is not the culprit. I am confident a double refresh makes the issue go away. I am confident there is a glitch or bug in something I don't have access to recoding or redesigning, whatever that may be...
|
|