Page 1 of 1
Keyboard Focus and Threads
Posted: Thu Jun 18, 2009 2:20 pm
by Polly
Does anybody have an idea why window/gadget 0 does not get the keyboard focus, whatever I do?
Code: Select all
Procedure test(x)
hwnd=OpenWindow(1, 0, 0, 256, 99, "", #PB_Window_ScreenCentered )
If hwnd
TextGadget(#PB_Any, 50, 10, 170, 70, "xxx", #PB_Text_Center)
EndIf
While WindowEvent() : Wend
Delay(1500)
CloseWindow(1)
EndProcedure
test=CreateThread(@test(),0)
While IsThread(test) : Delay(100) : Wend
If OpenWindow(0, 0, 0, 322, 35, "StringGadget Flags", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
StringGadget(0, 8, 10, 306, 20, "Normal StringGadget...")
StickyWindow(0,1)
StickyWindow(0,0)
SetActiveWindow(0)
Debug WindowID(0)
Debug SetFocus_(WindowID(0))
Debug GetFocus_()
SetActiveGadget(0)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Keyborad focus has ... the debugger! (XP, 4.31, x86)
Posted: Thu Jun 18, 2009 4:20 pm
by srod
Curious. Remove all debugs and we are still left with the problem.
Using Purebasic event loops in a thread is perhaps not such a great idea. However, I can see no immediate reason why this should fail to work as expected. If you move the 'While IsThread(...)...' after the OpenWindow() then I can get it to work easily enough.
A better workaround perhaps :
Code: Select all
Procedure test(x)
hwnd=OpenWindow(1, 0, 0, 256, 99, "", #PB_Window_ScreenCentered )
If hwnd
TextGadget(#PB_Any, 50, 10, 170, 70, "xxx", #PB_Text_Center)
EndIf
While WindowEvent() : Wend
Delay(1500)
CloseWindow(1)
EndProcedure
test=CreateThread(@test(),0)
While IsThread(test) : Delay(100) : Wend
hWnd = OpenWindow(0, 0, 0, 322, 35, "StringGadget Flags", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_Invisible)
If hWnd
ShowWindow_(hWnd, #SW_MINIMIZE)
ShowWindow_(hWnd, #SW_RESTORE)
StringGadget(0, 8, 10, 306, 20, "Normal StringGadget...")
SetActiveGadget(0)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Posted: Thu Jun 18, 2009 4:38 pm
by ABBKlaus
or use SetWindowState()
Code: Select all
SetWindowState(0,#PB_Window_Minimize)
SetWindowState(0,#PB_Window_Normal)
Posted: Thu Jun 18, 2009 4:43 pm
by srod
ABBKlaus wrote:or use SetWindowState()
Code: Select all
SetWindowState(0,#PB_Window_Minimize)
SetWindowState(0,#PB_Window_Normal)
Good point!

Posted: Thu Jun 18, 2009 5:01 pm
by netmaestro
Fine but the question of why the window needs restored remains. Not only is it not getting activated, when the second window opens, if you don't use StickyWindow, it comes out behind the ide.
Posted: Thu Jun 18, 2009 5:15 pm
by srod
netmaestro wrote:Fine but the question of why the window needs restored remains. Not only is it not getting activated, when the second window opens, if you don't use StickyWindow, it comes out behind the ide.
Not here on Vista. Comes up on top.
Posted: Thu Jun 18, 2009 5:18 pm
by netmaestro
I'm currently test-driving Win7 RC and if I comment out the StickyWindow code it's coming out behind the ide.
Posted: Thu Jun 18, 2009 5:32 pm
by netmaestro
The thread is gone and so is the window it created, so isn't this a bug? Sure seems like one at this point unless I'm missing something.
Posted: Thu Jun 18, 2009 5:39 pm
by srod
Hard to say if this constitutes a PB bug in this case. Personally I wouldn't attempt such things with threads anyhow as this is just asking for trouble!

Re: Keyboard Focus and Threads
Posted: Thu Jun 18, 2009 9:50 pm
by PB
> why window/gadget 0 does not get the keyboard focus
It gets the focus here just fine (Win XP + SP2).
Posted: Thu Jun 18, 2009 10:10 pm
by srod
When I run the original code on XP here, the string gadget doesn't get the focus. You should be able to type directly into the string gadget without first clicking it.
Posted: Thu Jun 18, 2009 11:08 pm
by idle
Don't really know what's going on there at all. This works though
Code: Select all
Procedure test(x)
hwnd=OpenWindow(1, 0, 0, 256, 99, "", #PB_Window_ScreenCentered,x)
If hwnd
TextGadget(#PB_Any, 50, 10, 170, 70, "xxx", #PB_Text_Center)
EndIf
While WindowEvent()
Delay(0)
Wend
Delay(300)
CloseWindow(1)
tID1 = 0
EndProcedure
Procedure test2(x)
OpenWindow(2, 0, 0, 322, 35, "StringGadget Flags", #PB_Window_SystemMenu | #PB_Window_ScreenCentered,x)
StringGadget(0, 8, 10, 306, 20, "Normal StringGadget...")
SetActiveGadget(0)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
tID2 = 0
EndProcedure
Global tID1,tID2
If OpenWindow(0, 0, 0, 322, 35, "StringGadget Flags", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Repeat
ev = WaitWindowEvent()
If ev = #WM_LBUTTONDOWN
If Not IsThread(tID1)
tID1 = CreateThread(@test(),WindowID(0))
EndIf
ElseIf ev = #WM_RBUTTONDOWN
If Not IsThread(tID2)
tID2 = CreateThread(@test2(),WindowID(0))
EndIf
EndIf
Until ev = #PB_Event_CloseWindow
EndIf
[/code]
Posted: Fri Jun 19, 2009 8:54 am
by Polly
Thanks all for your support. For my purpose the Minimize workaround is sufficient, using Stickywindow to force the window opening on top, which is required on XP too.
But generally speaking I would also consider it as a bug as there is no reasonable explanation to be seen. When the second window opens only the main thread is running - and so it should work as usual.
Posted: Fri Jun 19, 2009 9:04 am
by Polly
With Minimize the StickyWindow is not neccessary of course.