Message Router
\The Sandbox \PB Help \PFC Notes \Msg Router
15-Minute PFC
Learning Curve
Msg Router
LUW Service

When a window receives a message (usually from the menu), the PFC's message router on the window tries the following objects until it finds an object that will accept it:

  • the window itself
  • the control on the window that currently has focus
  • the DataWindow that currently has or last had focus

The problem with this approach is that it makes encapsulating difficult. For example, if I have a window with tabs, I may want to build a print routine either for each individual tabpage. The standard approach doesn't lend itself to encapsulating a print routine anywhere other than a window or DataWindow. The window would have to test for the active tabpage, and build a case statement that hard coded the names of the tabpage into it. The DataWindow would be wholly inappropriate, as the last active DataWindow may not reflect which tabpage is currently active. The solution I was after was to have the message router dig through the containing controls of the active control. For example, if focus were on a control within a tab control, my message router would search through (the additional steps highlighted):

  • the window itself
  • the tab object
  • the tabpage object
  • the control on the window that currently has focus
  • the DataWindow that currently has or last had focus

With a message router that works in this way, I can implement a print routine in either the tab or the tabpage, whichever is more appropriate, and achieve the potential of reuse. Similarly, functionality can be encapsulated into a custom visual user object and used in a non-tab situation.

To implement this approach, copy this code into your w_Master's pfc_MessageRouter event, overriding the ancestor event.


/////////////////////////////////////////////////////////////////////////// ///
//Event: pfc_messagerouter
//as_message  message (event notification) to send
//Returns: integer
// 1 = message successfully sent
// 0 = no receivers recognized the message
//-1 = error
//This event routes a message (event notification)
//to the appropriate object.
/////////////////////////////////////////////////////////////////////////// ///
//Revision History
//5.0  Initial version
// Techno-kitten: Extended to send messages to containing controls
/////////////////////////////////////////////////////////////////////////// ///
//Copyright © 1996-1997 Sybase, Inc. and its subsidiaries. All rights reserved.
//Any distribution of the PowerBuilder Foundation Classes (PFC)
//source code by other than Sybase, Inc. and its subsidiaries is prohibited.
/////////////////////////////////////////////////////////////////////////// ///

graphicobject lgo_Focus, lgo_Parent, lgo_ParentList[]
integer li_Index, li_ParentCount=0

// Check argument
IF IsNull (as_message) OR Len (Trim (as_message)) = 0 THEN

// Try sending the message to this window, if successful exit event.
IF This.TriggerEvent (as_message) = 1 THEN RETURN 1

lgo_Focus = GetFocus()
IF IsValid (lgo_Focus) THEN

  // Try sending message to object that contain the current control (e.g. tabpage, tab, userobject)
  lgo_Parent = lgo_Focus.GetParent ()
  DO WHILE IsValid (lgo_Parent) AND (lgo_Parent <> This)
   li_ParentCount ++
   lgo_ParentList[li_ParentCount] = lgo_Parent
   lgo_Parent = lgo_Parent.GetParent ()
  // Check containers from the top downwards
  FOR li_Index = li_ParentCount TO 1 STEP -1
   IF lgo_ParentList[li_Index].TriggerEvent (as_Message) = 1 THEN RETURN 1

  // Try sending the message to the current control, if successful exit event.
  IF lgo_Focus.TriggerEvent (as_message) = 1 THEN RETURN 1

// Try sending the message to the last active DataWindow, if successful exit event.
IF IsValid (idw_active) THEN
  IF idw_active.TriggerEvent (as_message) = 1 THEN RETURN 1

// No objects recognized the message


Document last updated Friday, June 26, 1999.

PBL Peeper PB Help PB History
& Future About Us Feedback Site Map