Posted: Thu Nov 13, 2008 11:45 pm
Ok, I've finally found the source of the problem. The Windows drivers for my touchpad assumes that the window beneath the cursor has the highest z-order. It searches for all windows beneath the cursor and sends the WM_VSCROLL message to the first window that has the WS_VSCROLL style set, even if it is hidden.
When PureBasic creates gadgets it displays them on top of each other in the order they were created. However, this is the opposite of the actual z-order. freak has said in the past:
http://www.purebasic.fr/english/viewtopic.php?t=33465
http://www.purebasic.fr/english/viewtopic.php?t=28802
So, freak, if you would please try setting the Scintilla gadget associated with the current tab at the top of the z-order this should, in theory, solve the problem.
Here is an example with a Sintilla gadget setup identical (I believe) to the PureBasic IDE and an example program that reports the gadget with the topmost z-depth and the WS_VSCROLL style. Use the hotkey "Q" while the mouse is hovering over the Scintilla gadget to see which gadget is below the cursor and which is the topmost window with a vertical scrollbar. I've also included two methods (one preemptive one post) that will solve the problem.
Because of the changes with gadget lists use 4.30 to compile.
wm_vscroll_hotkey.pb
scintilla_panel.pb
Part of the problem is that the Scintilla gadgets in the PureBasic IDE aren't actually inside the tab panel. If they were the z-order is correct. So this is actually a two-way bug. The drivers should have used GetWindowFromPoint but it couldn't predict that the IDE would have hidden gadgets with scroll bars layered on top of each other.
I hope this helps! It's been a really difficult bug to track down.
When PureBasic creates gadgets it displays them on top of each other in the order they were created. However, this is the opposite of the actual z-order. freak has said in the past:
This makes sense because actual gadget creation and z-depth isn't being handled by a visual designer so there is no way for the PureBasic compiler to know which order you want them to display and the actual z-order. I think what's most misleading is that gadgets are drawn by PB in the order that they were created and not their actual z-order.freak wrote:PB has no support for overlapping gadgets (and z-order) at all.
http://www.purebasic.fr/english/viewtopic.php?t=33465
http://www.purebasic.fr/english/viewtopic.php?t=28802
So, freak, if you would please try setting the Scintilla gadget associated with the current tab at the top of the z-order this should, in theory, solve the problem.

Here is an example with a Sintilla gadget setup identical (I believe) to the PureBasic IDE and an example program that reports the gadget with the topmost z-depth and the WS_VSCROLL style. Use the hotkey "Q" while the mouse is hovering over the Scintilla gadget to see which gadget is below the cursor and which is the topmost window with a vertical scrollbar. I've also included two methods (one preemptive one post) that will solve the problem.
Because of the changes with gadget lists use 4.30 to compile.
wm_vscroll_hotkey.pb
Code: Select all
Procedure EnumChildProc(hWnd, *lParam.LONG)
If GetWindowLong_(hWnd,#GWL_STYLE)&#WS_VSCROLL
*lParam\l=hWnd
ProcedureReturn 0
EndIf
ProcedureReturn 1
EndProcedure
RegisterHotKey_(0,1,0,#VK_Q)
RegisterHotKey_(0,2,0,#VK_P)
Repeat: Delay(20)
GetMessage_(@Msg.MSG,0,0,0)
If Msg\message=#WM_HOTKEY
x.q=DesktopMouseX()
y.q=DesktopMouseY()
POINT.q=y<<32+x
Select Msg\wParam
Case 1 ; #VK_Q
hWnd=WindowFromPoint_(POINT.q)
ParenthWnd=GetParent_(hWnd)
If ParenthWnd
EnumChildWindows_(ParenthWnd,@EnumChildProc(),@VScrollChild.LONG)
EndIf
VScrollTitle.s=Space(200)
GlobalGetAtomName_(GetProp_(VScrollChild\l,"GadgetTitle"),VScrollTitle.s,200)
VScrollTitle.s=Trim(VScrollTitle.s)
WFPTitle.s=Space(200)
GlobalGetAtomName_(GetProp_(hWnd,"GadgetTitle"),@WFPTitle.s,200)
WFPTitle.s=Trim(WFPTitle.s)
If VScrollTitle.s And WFPTitle.s
Debug "VScrollChild "+VScrollTitle.s+" "+"WFP "+WFPTitle.s
Else
Debug "VScrollChild "+Str(VScrollChild\l)+" "+"WFP "+Str(hWnd)
EndIf
Case 2 ; #VK_P
End
EndSelect
EndIf
ForEver
Code: Select all
Procedure ScintillaCallBack(Gadget, *scinotify.SCNotification)
EndProcedure
Procedure ForceGadgetZOrder(hGadget)
;/ Flip the gadget draw order and force
;/ the topmost gadget to recieve focus
;/ first for overlapping gadgets
SetWindowLong_(hGadget,#GWL_STYLE,GetWindowLong_(hGadget,#GWL_STYLE)|#WS_CLIPSIBLINGS)
SetWindowPos_(hGadget,#HWND_TOP,0,0,0,0,#SWP_NOSIZE|#SWP_NOMOVE)
ProcedureReturn hGadget
EndProcedure
InitScintilla("Scintilla.dll")
OpenWindow(0,0,0,320,240,"Scintilla Scroll Test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
PanelID=PanelGadget(#PB_Any,0,0,320,23)
AddGadgetItem(PanelID, -1, "Panel 1")
AddGadgetItem(PanelID, -1, "Panel 2")
CloseGadgetList()
UseGadgetList(WindowID(0))
ScintillaID1=ScintillaGadget(#PB_Any,0,21,320,200,@ScintillaCallBack())
ScintillaID2=ScintillaGadget(#PB_Any,0,21,320,200,@ScintillaCallBack())
;/ Setup prop strings for debugging with wm_vscroll_hotkey.pb
Atom_ScintillaID1_Title=GlobalAddAtom_(@"ScintillaID1")
Atom_ScintillaID2_Title=GlobalAddAtom_(@"ScintillaID2")
SetProp_(GadgetID(ScintillaID1),@"GadgetTitle",Atom_ScintillaID1_Title)
SetProp_(GadgetID(ScintillaID2),@"GadgetTitle",Atom_ScintillaID2_Title)
;/ Correct the gadget draw order
; ForceGadgetZOrder(GadgetID(ScintillaID1))
; ForceGadgetZOrder(GadgetID(ScintillaID2))
HideGadget(ScintillaID2,1)
For i=1 To 100 ; 500 lines
Tab1.s+RSet(Str(i),3,"0")+" Panel1"+#CRLF$
Tab2.s+RSet(Str(i),3,"0")+" Panel2"+#CRLF$
Next i
ScintillaSendMessage(ScintillaID1,#SCI_SETTEXT,0,@Tab1.s)
ScintillaSendMessage(ScintillaID2,#SCI_SETTEXT,0,@Tab2.s)
Repeat
Select EventGadget()
Case PanelID
Select EventType()
Case #PB_EventType_LeftClick
Select GetGadgetState(PanelID)
Case 0 ; panel 0
HideGadget(ScintillaID1,0)
HideGadget(ScintillaID2,1)
;/ Uncomment to create a "fix" without ForceGadgetZOrder
;BringWindowToTop_(GadgetID(ScintillaID1))
Case 1 ; panel 1
HideGadget(ScintillaID2,0)
HideGadget(ScintillaID1,1)
;/ Uncomment to create a "fix" without ForceGadgetZOrder
;BringWindowToTop_(GadgetID(ScintillaID2))
EndSelect
EndSelect
EndSelect
Until WaitWindowEvent()=#WM_CLOSE
;/ Cleanup
DeleteAtom_(Atom_ScintillaID1_Title)
DeleteAtom_(Atom_ScintillaID2_Title)
RemoveProp_(GadgetID(ScintillaID1),"GadgetTitle")
RemoveProp_(GadgetID(ScintillaID2),"GadgetTitle")
I hope this helps! It's been a really difficult bug to track down.