WaitWindowEvent / WindowEvent problem

Windows specific forum
Ramihyn_
Enthusiast
Enthusiast
Posts: 314
Joined: Fri Feb 24, 2006 9:40 am

WaitWindowEvent / WindowEvent problem

Post by Ramihyn_ »

For some Operations in Windows, it seems the functions WaitWindowEvent() and WindowEvent() are blocking. In the following example, the WaitWindowEvent() function doesnt timeout anymore if you drag the sliders, keep a button of the sliders clicked, move the window around, open the window system menu or click into the slider area. Using WindowEvent() instead, create basically the same problem. The function doesnt return anymore even though the manual states that it will always return immediately.

I checked the manual, purearea samples and the english forum but couldnt find a solution to this. Verified on two windows xp professional installations with the latest PB 4.10 version.

Code: Select all

;- Window Constants
Global Window_Form1


;- Gadget Constants
Enumeration 1
  ;Window_Form1
  Global Gadget_Form1_ScrollBar2
  Global Gadget_Form1_ScrollArea3
  Global Gadget_Form1_Area4
  Global Gadget_Form1_ScrollBar5
EndEnumeration


Procedure.l Window_Form1()
  Window_Form1=OpenWindow(#PB_Any,80,80,345,170,"Work Form1",#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Invisible)
  If Window_Form1
    If CreateGadgetList(WindowID(Window_Form1))
      Gadget_Form1_ScrollBar2=ScrollBarGadget(#PB_Any,10,10,300,15,0,500,100)
      Gadget_Form1_ScrollArea3=ScrollAreaGadget(#PB_Any,10,40,300,115,400,300,5)
      CloseGadgetList()
      Gadget_Form1_ScrollBar5=ScrollBarGadget(#PB_Any,320,10,15,145,0,500,100,#PB_ScrollBar_Vertical)
      HideWindow(Window_Form1,0)
      ProcedureReturn WindowID(Window_Form1)
    EndIf
  EndIf
EndProcedure





;- Main Loop
If Window_Form1()

  quitForm1=0
  Repeat
    EventID  =WaitWindowEvent(100)

;     Repeat
;       EventID = WindowEvent()
;       If (EventID = 0)
;         Debug "EV Timeout"
;         Delay(10)
;       EndIf
;     Until EventID


    If (EventID)
      Debug "Event : " + Str(EventID)

      MenuID   =EventMenu()
      GadgetID =EventGadget()
      WindowID =EventWindow()
  
      Select EventID
        Case #PB_Event_CloseWindow
          If WindowID=Window_Form1
            quitForm1=1
          EndIf
  
  
        Case #PB_Event_Gadget
          Select GadgetID
            Case Gadget_Form1_ScrollBar2
            Case Gadget_Form1_Area4
            Case Gadget_Form1_ScrollBar5
          EndSelect
  
      EndSelect
    Else
      Debug "Event timeout"
    EndIf

  Until quitForm1

  CloseWindow(Window_Form1)
EndIf

End

; IDE Options = PureBasic 4.10 (Windows - x86)
; CursorPosition = 81
; FirstLine = 34
; Folding = -
; EnableThread
; EnableXP
So my questions are:

- Do i miss something? Is this behaviour intended or a bug?

- if this behaviour is "intended" - how can i make realtime updates to gadgets/areas while the scrollbar is dragged?

- why doesnt the scrollbar give any event while its beeing dragged?

- is longcat really as long as people claim it is?


Using a second thread, the window callback function and a mutex "may" get around this problem, but it feels very dirty and definitely isnt portable.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Perfectly normal for Windows; at least perfectly normal as far as the Purebasic eventloop is concerned! :wink:

You must keep in mind that a Purebasic event-loop sits 'above' the various window procedures attached to all GUI elements in your application and that, for various reasons, is not sent all messages generated by those elements. This means that a PB event loop cannot trap all Windows messages, there are times when you need to use callbacks.

Now there are times when Windows itself takes over a thread's message queue and essentially blocks most messages from arriving. One of these instances is when you start to drag a window around the screen. At this point Windows itself captures the mouse and 'hijacks' your application and will only allow certain events to be processed; primarily painting and so on. Thus, whilst you are dragging your window around, your PB event loop will probably receive no events at all. Now this is not true of a Window callback. Try it. Add a callback to your window, add a #WM_PAINT handler which simply debugs "PAINTING!", run the prog and drag the window etc. You will see (if you drag off-screen) that the callback is still being sent #WM_PAINT messages. If it were not then your window would lose all of it's content whilst you dragged etc.
On the other hand you will see that your PB event loop does not receive #WM_PAINT messages whilst the window is being dragged.

So, what you have observed is simply a combination of a PB event loop's inability to receive all messages together with instances of Windows hijacking your application! :)
I may look like a mule, but I'm not a complete ass.
Ramihyn_
Enthusiast
Enthusiast
Posts: 314
Joined: Fri Feb 24, 2006 9:40 am

Post by Ramihyn_ »

I probably shouldnt have mentioned the window dragging as thats a completely different problem, but i am not sure which problem PB has about delivering a CHANGE event while a scrollbar is moved or why the event functions basically lock up while scrollbars are used (contrary to documented behavior).

Can somebody please look into this to see if its possible to change these three things:

- add an event for the scrollbar gadget which is send when the gadget value is changed
- check why WaitWindowEvent() doesnt timeout anymore if a scrollbar is used and a timeout value is given
- check why WindowEvent() doesnt return anymore while a scrollbar is in use

It would be much appreciated :)

ps: for my current application i fixed this by extending my windows callback function and using another mutex semaphore but soon my problem will be to port this to linux and mac os x.
freak
PureBasic Team
PureBasic Team
Posts: 5948
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

This is a windows specific weirdness. It basically stops sending any messages to the event queue
while the draging of the scrollbar is processed.

The only way to work around this is to write all the mouse handling code for
the scrollbar manually, which would be a nightmare to get right for every windows version.

You'll just have to live with the callback solution on Windows.
For Linux and OSX all this is no problem. The events come in as expected.
quidquid Latine dictum sit altum videtur
Post Reply