Page 1 of 2

Processing WM_SYSCOMMAND without callback?

Posted: Sat May 23, 2015 5:50 pm
by bbanelli
Greetings to all,

here's the code:

Code: Select all

Procedure WinProc(hWnd, msg, wParam, lParam) 
  Protected.i result
  result = #PB_ProcessPureBasicEvents 
  If msg = #WM_SYSCOMMAND
    If wparam = #SC_MINIMIZE
      Debug "Minimized"
      result = 0
    ElseIf wParam = #SC_CLOSE
      Debug "Closed"
      result = 0
    ElseIf wparam = #SC_RESTORE
      Debug "Restored"
      result = 0
    EndIf 
  EndIf 
  ProcedureReturn result 
EndProcedure 

If OpenWindow(0, 0, 0, 320, 240, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
  ;SetWindowCallback(@WinProc())
  Repeat
    
    Event = WaitWindowEvent()
    
    Select Event
      Case #WM_SYSCOMMAND
        Select EventwParam()
          Case #SC_CLOSE
            Debug "Close"
          Case #SC_MINIMIZE
            Debug "Minimize"
          Case #SC_RESTORE
            Debug "Restore"
        EndSelect
    EndSelect
    
  Until Event = #PB_Event_CloseWindow
EndIf
Unfortunately, only triggered event appears to be SC_RESTORE. All others are not reported in the loop. Naturally, callback works perfectly, but I was wandering, what's wrong with the approach in WaitWindowEvent()?

With my best,

Bruno

Re: Processing WM_SYSCOMMAND without callback?

Posted: Sat May 23, 2015 7:28 pm
by luis
The fact WindowEvent() is not legally bound to return Windows messages.
Can replace them with corresponding #PB events and return those instead, can ignore some of them, etc.
It has only to return the documented #PB events, for everything else OS specific you have to use a callback.

Also it may return some Windows messages today, and stop to do it tomorrow -> http://www.purebasic.fr/english/viewtop ... 13&t=54124

Re: Processing WM_SYSCOMMAND without callback?

Posted: Sat May 23, 2015 7:42 pm
by bbanelli
luis wrote:The fact WindowEvent() is not legally bound to return Windows messages.
Can replace them with corresponding #PB events and return those instead, can ignore some of them, etc.
It has only to return the documented #PB events, for everything else OS specific you have to use a callback.

Also it may return some Windows messages today, and stop to do it tomorrow -> http://www.purebasic.fr/english/viewtop ... 13&t=54124
Thank you, luis, for, as usual, precise and informative answers! :)

I can only guess that there is no mutual exclusivity in using callback and WaitWindowEvent(), that is, there should be no issues there if both are used (for different purposes, naturally!)? Basically, callback should be "the right way", right?

BTW, I was really not aware that Eventl/w were deprecated functions. Why are they not reported by compiler as CreateGadgetList(), for example?

Re: Processing WM_SYSCOMMAND without callback?

Posted: Sat May 23, 2015 7:52 pm
by luis
bbanelli wrote: I can only guess that there is no mutual exclusivity in using callback and WaitWindowEvent(), that is, there should be no issues there if both are used (for different purposes, naturally!)? Basically, callback should be "the right way", right?
You can mix them. You can process the #PB events in the main loop, and the extra OS specific events in the callback.
In the callback you can also "transform" the Windows messages in your own custom user messages and PostEvent them in the original main loop to keep all the event processing there in one place, if you like.
bbanelli wrote: BTW, I was really not aware that Eventl/w were deprecated functions. Why are they not reported by compiler as CreateGadgetList(), for example?
I don't know :?

Re: Processing WM_SYSCOMMAND without callback?

Posted: Sun May 24, 2015 1:46 am
by Little John
bbanelli wrote:BTW, I was really not aware that Eventl/w were deprecated functions. Why are they not reported by compiler as CreateGadgetList(), for example?
I also don't know why they are not reported by the compiler.
However, it is documented:
Help for EventwParam() wrote:This function is not supported anymore and shouldn't used in new project. Use a callback to get full control over Windows message with SetWindowCallback().

Re: Processing WM_SYSCOMMAND without callback?

Posted: Sun May 24, 2015 6:36 am
by TI-994A
bbanelli wrote:...I can only guess that there is no mutual exclusivity in using callback and WaitWindowEvent(), that is, there should be no issues there if both are used (for different purposes, naturally!)? Basically, callback should be "the right way", right?
Hi bbanelli. Yes; you can safely use them both together, but you can't use callbacks exclusively without the PureBasic event loop. Callbacks are only meant as handlers of additional, low-level messages.
bbanelli wrote:...I was really not aware that Eventl/w were deprecated functions. Why are they not reported by compiler as CreateGadgetList(), for example?
Perhaps because they were never official functions to begin with (according to Fred).
Fred wrote:...these two commands aren't 'officials' but it would probably hurt if we remove it as we can't replace it with something else. So it's still here..
I read somewhere (can't seem to find that post though) that this function pair was originally implemented to assist the development team, but their use unintentionally proliferated among the early adopters.

Re: Processing WM_SYSCOMMAND without callback?

Posted: Sun May 24, 2015 1:47 pm
by bbanelli
Hi guys,

thanks for the heads up about the functions and callback! :) It's all much clearer now. While we are at it, I guess it is only legal to post events to call for requesters from callback, right? Just the way it is supposed to be done from threads?

Re: Processing WM_SYSCOMMAND without callback?

Posted: Sun May 24, 2015 3:18 pm
by TI-994A
bbanelli wrote:... it is only legal to post events to call for requesters from callback, right?
Hello again. It should be pretty safe to implement requesters from just about anywhere within the main thread; and that includes procedures and callbacks:

Code: Select all

Procedure WndProc(hWnd, uMsg, wParam, lParam)
  result = #PB_ProcessPureBasicEvents
  If uMsg = #WM_LBUTTONDOWN
    Debug (OpenFileRequester("Opened from Callback:", "", "", 0))
  EndIf
  ProcedureReturn result
EndProcedure

wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered 
OpenWindow(0, #PB_Any, #PB_Any, 300, 150, "Requesters in Callbacks", wFlags)
SetWindowCallback(@WndProc())
While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
The only known exception is calling them from threads.

Please, correct me if I'm wrong.

Re: Processing WM_SYSCOMMAND without callback?

Posted: Sun May 24, 2015 3:35 pm
by bbanelli
TI-994A wrote:The only known exception is calling them from threads.

Please, correct me if I'm wrong.
I was just unsure whether callback counts as a thread, but according to ProcessExplorer, there are equal amount of threads with or without SetWindowCallback() function.

Re: Processing WM_SYSCOMMAND without callback?

Posted: Sun May 24, 2015 4:30 pm
by TI-994A
bbanelli wrote:...just unsure whether callback counts as a thread...
Callbacks are nothing more than procedures that execute within the same thread.

However, it bears noting that some languages do have the capability of asynchronous callbacks, which technically run in separate threads.

Again, please correct me if I'm wrong. :lol:

Re: Processing WM_SYSCOMMAND without callback?

Posted: Sun May 24, 2015 4:43 pm
by luis
bbanelli wrote:I was just unsure whether callback counts as a thread, but according to ProcessExplorer, there are equal amount of threads with or without SetWindowCallback() function.
Sure, it's part of the same thread. That's why generally is important to not spend too much time inside a callback.

TI-994A wrote: It's so childish to get defensive about principles that are clearly beyond you.
Ahahahahah ! Yeah ! Right ! It's plain to see.

:lol:

Re: Processing WM_SYSCOMMAND without callback?

Posted: Sun May 24, 2015 5:13 pm
by TI-994A
luis wrote:That's why (it is) generally important (not to) spend too much time inside a callback.
There's simply no logic to support that. Being procedures themselves, callbacks function in the same manner, and are accordingly subject to the same rules of execution.


It's so childish to get defensive about principles that are clearly beyond you. And throwing tantrums in your signatures isn't helping either. :lol:

Re: Processing WM_SYSCOMMAND without callback?

Posted: Mon Jun 01, 2015 4:21 pm
by fromVB
TI-994A wrote:
luis wrote:That's why (it is) generally important (not to) spend too much time inside a callback.
There's simply no logic to support that. Being procedures themselves, callbacks function in the same manner, and are accordingly subject to the same rules of execution.
Are you sure?

Re: Processing WM_SYSCOMMAND without callback?

Posted: Tue Jun 02, 2015 8:32 pm
by TI-994A
fromVB wrote:Are you sure?
Yes; pretty much. :wink:

Re: Processing WM_SYSCOMMAND without callback?

Posted: Wed Jun 03, 2015 5:35 am
by Danilo
TI-994A wrote:
luis wrote:That's why (it is) generally important (not to) spend too much time inside a callback.
There's simply no logic to support that. Being procedures themselves, callbacks function in the same manner, and are accordingly subject to the same rules of execution.
There is no more event processing, while Windows is within your callback.

Code: Select all

Procedure MyWindowCallback(WindowID, Message, WParam, LParam)
    Delay(50)
    ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Procedure Timer()
    Static Value : Value + 1
    SetGadgetText(0,StrU(Value,#PB_Integer))
EndProcedure

If OpenWindow(0, 0, 0, 400, 100, "Timer Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    TextGadget(0,10,10,100,25,"")
    AddWindowTimer(0, 123, 50)
    BindEvent(#PB_Event_Timer,@Timer())

    ;
    ; ACTIVATE THE CALLBACK FOR TESTING, THEN MOVE THE WINDOW AROUND
    ;    
    ;SetWindowCallback(@MyWindowCallback())
    
    Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
The event processing is blocked as long as you are within the callback, that's why luis said
codes within callbacks should be as fast as possible.
Of course it's the same with all other procedures within the same thread. If your procedures
process something for 10 seconds, there is no event handling for 10 seconds - if you don't continue
to call WindowEvent() from time to time.

The main GUI thread should be non-blocking, and procedures that take long time to process
should be better executed in other threads.

That's meant to be a general thing to have in mind, not specific to your OpenFileRequester() example.