Processing WM_SYSCOMMAND without callback?

Windows specific forum
User avatar
TI-994A
Addict
Addict
Posts: 2741
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Processing WM_SYSCOMMAND without callback?

Post by TI-994A »

luis wrote:That's why (it is) generally important (not to) spend too much time inside a callback.
Danilo wrote:The event processing is blocked as long as you are within the callback...
Of course it's the same with all other procedures within the same thread...
Thank you for illustrating my point clearly.

Bottom line: the blocking behaviour is not exclusive to callbacks, as luis implied. :wink:
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
Little John
Addict
Addict
Posts: 4789
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Processing WM_SYSCOMMAND without callback?

Post by Little John »

Very good explanation, Danilo.
Thank you!
Little John
Addict
Addict
Posts: 4789
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Processing WM_SYSCOMMAND without callback?

Post by Little John »

TI-994A wrote:Bottom line: the blocking behaviour is not exclusive to callbacks, as luis implied. :wink:
No, luis did not imply that.
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.
Danilo just illustrated the logic behind luis' statement.
User avatar
TI-994A
Addict
Addict
Posts: 2741
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Processing WM_SYSCOMMAND without callback?

Post by TI-994A »

Hi Little John.
Little John wrote:Danilo just illustrated the logic behind luis' statement.
Not exactly. Danilo reiterated my point that callbacks are simply procedures. Although he went on to caution on the evils of blocking-routines, that rule-of-thumb applies to anywhere in the code, and not just within callbacks and procedures.

There is no logic behind luis' statement, because it is simply illogical to say that it's important not to spend too much time inside a procedure.

Where would you do all your processing then. :wink:
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: Processing WM_SYSCOMMAND without callback?

Post by bbanelli »

Hi guys, what about DefWindowProc function, is it needed when using callback in PB or is it done automatically? When is it even appropriate to use that function?

http://blogs.msdn.com/b/oldnewthing/arc ... 83093.aspx
https://msdn.microsoft.com/en-us/librar ... 85%29.aspx
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Processing WM_SYSCOMMAND without callback?

Post by Danilo »

@bbanelli:
When returning #PB_ProcessPureBasicEvents to PB, it continues with it's own internal event handling.
That includes calling DefWindowProc_() for messages that it does not process.

If you return any different value, it goes directly back to Windows. And if you want Windows' default processing
for a specific message, you can also do ProcedureReturn DefWindowProc_(...).
Just be aware that PB can't do it's own processing, if you don't return #PB_ProcessPureBasicEvents -
and that can lead to unwanted behaviour, if you "steal" a message that PB needs to process.

See also MSDN:
Window Procedures >> About Window Procedures >> Structure of a Window Procedure:
Because it is possible to call a window procedure recursively, it is important to minimize the number of local variables that it uses.
When processing individual messages, an application should call functions outside the window procedure to avoid excessive use of local variables,
possibly causing the stack to overflow during deep recursion.
And:
Messages and Message Queues >> About Messages and Message Queues >> Message Deadlocks

You see, there are some things to consider when working with window callbacks.

DefWindowProc_() is required when doing plain WinAPI GUI coding, without using PB's event system. [Example 1] [Example 2]
User avatar
TI-994A
Addict
Addict
Posts: 2741
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Processing WM_SYSCOMMAND without callback?

Post by TI-994A »

bbanelli wrote:...what about DefWindowProc function, is it needed when using callback in PB or is it done automatically? When is it even appropriate to use that function?
Hi bbanelli. The short and simple answer would be, it's not a function to be concerned with. :D

In PureBasic (Windows), the DefWindowProc API function is wrapped in the #PB_ProcessPureBasicEvents directive.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
Little John
Addict
Addict
Posts: 4789
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Processing WM_SYSCOMMAND without callback?

Post by Little John »

TI-994A wrote:Hi Little John.
Little John wrote:Danilo just illustrated the logic behind luis' statement.
Not exactly. Danilo reiterated my point that callbacks are simply procedures.
No, he didn't.
He actually wrote that callbacks are different from normal procedures. What he wrote is pretty clear, and I'm not going to waste my time anymore with trying to help you understanding some clear sentences.
TI-994A wrote:There is no logic behind luis' statement, because it is simply illogical to say that it's important not to spend too much time inside a procedure.
Luis did not write that. You keep trying to put words into Luis mouth which he never said/wrote. Sorry, but by doing so you are disqualifying yourself for a serious discussion.
It seems to me that you might have a personal problem with Luis. If this is the case, write him a PM or whatever, but please leave the forum alone with that.
User avatar
TI-994A
Addict
Addict
Posts: 2741
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Processing WM_SYSCOMMAND without callback?

Post by TI-994A »

Hello again Little John.
Little John wrote:He actually wrote that callbacks are different from normal procedures.
If your position is that callbacks are different from normal procedures, I clearly understand how my statements are confusing you.

Callbacks are no different from normal procedures, and that's the point I've been trying to make. And that is why it is illogical to say that it's important not to spend too much time inside callbacks or procedures (because they're the same). :wink:

And to address your other concern, I take no issues with anyone; just their erroneous statements. :lol:
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
Little John
Addict
Addict
Posts: 4789
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Processing WM_SYSCOMMAND without callback?

Post by Little John »

Aha.
User avatar
Demivec
Addict
Addict
Posts: 4270
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Processing WM_SYSCOMMAND without callback?

Post by Demivec »

TI-994A wrote:Callbacks are no different from normal procedures, and that's the point I've been trying to make. And that is why it is illogical to say that it's important not to spend too much time inside callbacks or procedures (because they're the same). :wink:
@TI-994A: I think the important point isn't that a callback is a procedure, it is that a callback is called for every event (when using a general window callback).

Because it is highly likely that it will be called frequently it is a good idea not to spend too much time inside the callback procedure. A callback that takes too long to execute can lead to a backlog of events as events are created faster than they are being dealt with. Making a user interface more responsive and leaving as much time for procedures and code that is not part of the user interface to execute and to actually get something accomplished is a very logical idea. :wink:
User avatar
TI-994A
Addict
Addict
Posts: 2741
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Processing WM_SYSCOMMAND without callback?

Post by TI-994A »

Hi Demivec. Some excellent points, but based on some wrong premises.
Demivec wrote:...a callback is called for every event.

A callback that takes too long to execute can lead to a backlog of events...
True, but the events that it handles would invariably trigger some action. Here is where the logic collapses.

In PureBasic, unless a separate thread is spawned to handle these actions, the triggered code would execute synchronously. This means that until it completes, all event processing is essentially suspended; regardless of whether it is running in the callback or anywhere else.

Here's a modification of Danilo's code to illustrate this:

Code: Select all

Procedure.q Ackermann(m, n)
  If m = 0
    ProcedureReturn n + 1
  ElseIf  n = 0
    ProcedureReturn Ackermann(m - 1, 1)
  Else
    ProcedureReturn Ackermann(m - 1, Ackermann(m, n - 1))
  EndIf
EndProcedure

Procedure windowCallback(hWnd, uMsg, WParam, LParam) 
  Select uMsg  
    Case #WM_COMMAND
      Select (wParam >> 16) & $ffff
        Case #BN_CLICKED           
          Select (wParam & $ffff)  
            Case 2
              SetGadgetText(0, "calculating...")
              Ackermann(3, 9)
          EndSelect
      EndSelect  
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure 

Procedure normalProcedure()
  SetGadgetText(0, "calculating...")
  Ackermann(3, 9)
EndProcedure  

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

wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
If OpenWindow(0, 0, 0, 400, 100, "Callback Example", wFlags)
  TextGadget(0, 150, 15, 100, 25, "", #PB_Text_Center)
  ButtonGadget(1, 10, 50, 180, 30, "click handled by procedure")
  ButtonGadget(2, 210, 50, 180, 30, "click handled by callback")
  AddWindowTimer(0, 123, 50)
  BindEvent(#PB_Event_Timer, @Timer())
  SetWindowCallback(@windowCallback())
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        appQuit = 1
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 1
            normalProcedure()
          Case 2
            ;handled by windowCallback
        EndSelect
    EndSelect
  Until appQuit = 1 
EndIf
Should we avoid blocking routines? Ideally - yes. Practically - not always possible. But that purely boils down to coding quality; not just because it is executed within a callback.
Demivec wrote:Making a user interface more responsive and leaving as much time for procedures and code that is not part of the user interface to execute and to actually get something accomplished is a very logical idea.
That statement sounds great, but does not quite meld.

These procedures and code that you mentioned are almost always triggered by some UI action, which is usually nothing more than a key stroke or a mouse click. Ultimately, in a synchronous environment, UI responsiveness hinges directly on these procedures and code themselves, regardless of where they may be executed. In this respect, the two are not exclusive.

So, unfortunately, the logic of the original statement in question still does not stand. :wink:
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
Post Reply