Page 1 of 1

Why #PB_Event_SizeWindow is fired that often?

Posted: Thu Sep 18, 2014 11:30 am
by uwekel
Hi,

i just noticed, that the #PB_Event_SizeWindow event is fired very often after the mouse button is released, but the WindowWidth() and WindowHeight() are only updated once. I think, the event should only fired if the coordinates are really changed, otherwise relayouting the window is senseless.

Code: Select all

If OpenWindow(0, 0, 0, 300, 300, "Test", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
  ButtonGadget(0, 0, 0, 300, 300, "0")
  Repeat
    Select WaitWindowEvent()
    Case #PB_Event_SizeWindow
      ResizeGadget(0, 0, 0, WindowWidth(0), WindowHeight(0))
      n + 1
      SetGadgetText(0, Str(n))
    Case #PB_Event_CloseWindow
      Break
    EndSelect
  ForEver
EndIf
I tested this on Windows 7 x86.

Best regards
Uwe

Re: Why #PB_Event_SizeWindow is fired that often?

Posted: Thu Sep 18, 2014 11:35 am
by PB
> the event should only fired if the coordinates are really changed

No, because then we can't interact with a window that is potentially changing.

Re: Why #PB_Event_SizeWindow is fired that often?

Posted: Thu Sep 18, 2014 11:44 am
by uwekel
PB wrote:No, because then we can't interact with a window that is potentially changing.
You didn't catch the point. There are a lot of events AFTER releasing the mouse button, and WindowWidth() and WindowHeight() are always the same.

Re: Why #PB_Event_SizeWindow is fired that often?

Posted: Thu Sep 18, 2014 12:15 pm
by PB
You're right. I overlooked the word "after". Sorry about that. :oops:

Re: Why #PB_Event_SizeWindow is fired that often?

Posted: Thu Sep 18, 2014 12:33 pm
by RASHAD
Hi uwekel
I think what is being fired after releasing the mouse is #PB_Event_Repaint
And that is normal I think

Re: Why #PB_Event_SizeWindow is fired that often?

Posted: Thu Sep 18, 2014 4:08 pm
by uwekel
RASHAD wrote:I think what is being fired after releasing the mouse is #PB_Event_Repaint
And that is normal I think
No, it is #PB_Event_SizeWindow. Look the example code above. The Case statement exactly queries #PB_Event_SizeWindow.

Re: Why #PB_Event_SizeWindow is fired that often?

Posted: Thu Sep 18, 2014 4:26 pm
by majikeyric
With PB 5.30 now, the correct way to handle #PB_Event_SizeWindow shouldn't only be with a callback ?
e.g Like this :

Code: Select all

Global.i n

Procedure abc()
      ResizeGadget(0, 0, 0, WindowWidth(0), WindowHeight(0))
      n + 1
      SetGadgetText(0, Str(n))
EndProcedure


If OpenWindow(0, 0, 0, 300, 300, "Test", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
	ButtonGadget(0, 0, 0, 300, 300, "0")
	
	BindEvent(#PB_Event_SizeWindow,@abc(),0)
	
  Repeat
    Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    EndSelect
  ForEver
EndIf
results seem OK for me.

Re: Why #PB_Event_SizeWindow is fired that often?

Posted: Thu Sep 18, 2014 5:02 pm
by RASHAD
It is quit clear you are right

Code: Select all

If OpenWindow(0, 0, 0, 300, 300, "Test", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
  ButtonGadget(0, 0, 0, 300, 300, "0")
  Repeat
    Select WaitWindowEvent()

    Case #PB_Event_SizeWindow
      ResizeGadget(0, 0, 0, WindowWidth(0), WindowHeight(0))
      n + 1
      SetGadgetText(0, Str(n))
      
    Case #PB_Event_CloseWindow
      Break
      
    Default
         Debug WaitWindowEvent()
         
    EndSelect
  ForEver
EndIf
Edit :It is Window behavior not PB not #PB_Event_SizeWindow
not ResizeGadget()

Code: Select all

Global Appname.s,hMenu.l ,n

Procedure WndProc(Wnd,Message,wParam,lParam) 
  Returnval.l = DefWindowProc_(Wnd, Message, wParam, lParam) 
  Select Message 
    Case #WM_SIZE
           If IsGadget(100)
                 MoveWindow_(GadgetID(100), 10, 10, 200,200,1)
                 n + 1
                 SetGadgetText(100, Str(n))
           EndIf
    
    Case #WM_CLOSE
    UnregisterClass_(Appname,hInstance) 
    PostQuitMessage_(0) 
  EndSelect 
  ProcedureReturn Returnval 
EndProcedure 

Appname = "Main Window" 

wc.WNDCLASS 
wc\style          =  #CS_VREDRAW | #CS_HREDRAW 
wc\lpfnWndProc    =  @WndProc() 
wc\cbClsExtra     =  0 
wc\cbWndExtra     =  0 
wc\hInstance      =  hInstance 
wc\hIcon          =  LoadIcon_(hInstance, "#1") 
wc\hCursor        =  LoadCursor_(0, #IDC_ARROW) 
wc\hbrBackground  =  CreateSolidBrush_(GetSysColor_(15)) 
wc\lpszMenuName   =  0 
wc\lpszClassName  =  @Appname 
RegisterClass_(wc) 
hWnd = CreateWindowEx_(0,Appname,Caption$,#WS_OVERLAPPEDWINDOW|#WS_SIZEBOX,#CW_USEDEFAULT,0,#CW_USEDEFAULT,0,0,0,hInstance,0) 

UpdateWindow_(hWnd) 
ShowWindow_(hWnd,#SW_SHOWNORMAL) 
SetForegroundWindow_(hWnd) 

UseGadgetList(hWnd) 
ButtonGadget(100,10,10,100,100,"Test Button")

While GetMessage_(m.MSG, 0, 0, 0) 
  TranslateMessage_(m) 
  DispatchMessage_(m) 
Wend 


Re: Why #PB_Event_SizeWindow is fired that often?

Posted: Thu Sep 18, 2014 8:37 pm
by pjay
I reported this as a bug a few weeks ago as I don't believe that this was the intended behaviour: http://www.purebasic.fr/english/viewtop ... =4&t=60257

The real-time #PB_Event_MoveWindow event triggering was also removed in PB 5.30, and this only triggers once when you lift the mouse button, as expected.

Re: Why #PB_Event_SizeWindow is fired that often?

Posted: Thu Sep 18, 2014 8:44 pm
by uwekel
pjay wrote:I reported this as a bug a few weeks ago
Hi pjay, i looked before i wrote this post, but have not found anything similar.
Indeed, it seems to be a bug then.

Re: Why #PB_Event_SizeWindow is fired that often?

Posted: Fri Sep 19, 2014 6:57 am
by netmaestro
This event was removed from real-time processing in the event loop by the team, iirc to reduce flicker. The events get stored up and all of them hit the loop when the mousebutton is released. It's known behavior and I don't believe it's considered a bug. Handling #PB_Event_SizeWindow in the event loop is the old way of doing things anyway and really should be abandoned by PB coders. BindEvent() is a much cleaner, more structured, more maintainable approach, not to mention better performing. Every resize event hits the callback as it happens.

Re: Why #PB_Event_SizeWindow is fired that often?

Posted: Fri Sep 19, 2014 7:32 am
by Danilo
I think the non-realtime events within the main PB event loop should fire only once, after the resizing is finished.

Display both methods of re-sizing and moving the window:

Code: Select all

#PB_Event_SizeWindow2 = #PB_Event_FirstCustomValue
#PB_Event_MoveWindow2 = #PB_Event_FirstCustomValue + 1

Procedure WinProc(hWnd,msg,wParam,lParam)
    Static countMove, countResize, currentMode, in_WM_ENTERSIZEMOVE
    Select msg
        Case #WM_MOVE, #WM_MOVING
            currentMode = 1
            ; call real-time callback function, if set
        Case #WM_SIZE, #WM_SIZING
            currentMode = 2
            ; call real-time callback function, if set
        Case #WM_ENTERSIZEMOVE
            currentMode         = 0
            in_WM_ENTERSIZEMOVE = #True
            ;AddGadgetItem(1,-1,"Callback: Starting move/resize...")
        Case #WM_EXITSIZEMOVE
            If in_WM_ENTERSIZEMOVE = #True
                Select currentMode
                    Case 1 ; move
                        countMove + 1
                        ;AddGadgetItem(1,-1,"Callback: Window Moved - "+Str(countMove))
                        PostEvent(#PB_Event_MoveWindow2,1,hWnd)
                        currentMode = 0
                        ProcedureReturn 0
                    Case 2 ; resize
                        countResize + 1
                        ;AddGadgetItem(1,-1,"Callback: Window Resized - "+Str(countResize))
                        PostEvent(#PB_Event_SizeWindow2,1,hWnd)
                        currentMode = 0
                        ProcedureReturn 0
                EndSelect
                in_WM_ENTERSIZEMOVE = #False
            EndIf
    EndSelect
    ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Procedure OnMove()
    Static count
    count + 1
    AddGadgetItem(2,-1,"OnMove: Window Moved - "+Str(count))
    SetGadgetState(2,CountGadgetItems(2)-1)
EndProcedure

Procedure OnSize()
    Static count
    ResizeGadget(1,0,0,WindowWidth(1)*0.5,WindowHeight(1))
    ResizeGadget(2,WindowWidth(1)*0.5,0,WindowWidth(1)*0.5,WindowHeight(1))
    UpdateWindow_(WindowID(1))
    count + 1
    AddGadgetItem(2,-1,"OnSize: Window Resized - "+Str(count))
    SetGadgetState(2,CountGadgetItems(2)-1)
EndProcedure


OpenWindow(1,0,0,640,480,"Resize & Move - PB Event Loop vs. Event Procedures",#PB_Window_SizeGadget|#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
SetWindowCallback(@WinProc())

BindEvent(#PB_Event_MoveWindow, @OnMove())
BindEvent(#PB_Event_SizeWindow, @OnSize())

ListViewGadget(1, 0 ,0,WindowWidth(1)*0.5,WindowHeight(1))
ListViewGadget(2,WindowWidth(1)*0.5,0,WindowWidth(1)*0.5,WindowHeight(1))

Repeat
    Event = WaitWindowEvent(10)
    Select Event
        Case #PB_Event_SizeWindow2
            count1 + 1
            AddGadgetItem(1,-1,"Main Loop: Window Resized - "+Str(count1))
            SetGadgetState(1,CountGadgetItems(1)-1)
        Case #PB_Event_MoveWindow2
            count2 + 1
            AddGadgetItem(1,-1,"Main Loop: Window Moved - "+Str(count2))
            SetGadgetState(1,CountGadgetItems(1)-1)
    EndSelect
Until Event = #PB_Event_CloseWindow