1. Robert Sawyer
  2. PowerBuilder
  3. Monday, 17 June 2024 15:25 PM UTC

I'm creating a custom visual user object. It does not contain a clicked event. I'm putting several picture buttons on the uo. When I put the UO on a window, how can I tell what button was clicked on on the UO? I just need a container for the buttons - like a menu header for example. I don't have to use a custom visual - just something that I can make look like a header bar w / button and have multiple instances of the UO on the window.

John Fauss Accepted Answer Pending Moderation
  1. Tuesday, 18 June 2024 19:02 PM UTC
  2. PowerBuilder
  3. # 1

One possible way to accomplish this is by using the DYNAMIC keyword when triggering an event in the parent window.

Attached is a simple custom visual user object (CVUO) I threw together to illustrate. I used command buttons instead of picture buttons:

The CVUO contains a single instance variable:

Protected:
Window iw_parent   // Reference to the parent window (populated in this object's Constructor event).

It also contains a function named of_GetParentWindow:

// Public Function of_GetParentWindow(REF Window aw_Parent) Returns Integer

// Finds a reference to this object's parent window.

// Argument(s):
// Window  aw_Parent [by ref]  This parameter will be assigned a reference to
//                              the parent window.
//
// Returns:  Integer  1 -> Success.
//                   -1 -> Failure.

// Usage notes:
// 1. If no parent window can be found, aw_parent gets set to NULL.

// Attribution:  The logic is taken from the PowerBuilder Foundation Class (PFC) objects.

PowerObject lpo_parent

// Obtain a reference to this object's immediate parent.
lpo_parent = This.GetParent()

// Do we have a reference to a window object?
Do While IsValid(lpo_parent)
   If lpo_parent.TypeOf() = window! Then Exit
   // No - Continue up the parent hierarchy until a window is found.
   lpo_parent = lpo_parent.GetParent()
Loop

// Do we have a valid window reference?
If IsNull(lpo_parent) Or Not IsValid(lpo_parent) Then
   SetNull(aw_parent)
   Return -1
End If

// Assign parent window reference to the argument parameter.
aw_parent = lpo_parent
Return 1

and code in the Constructor event script to call the function to save the reference to the parent window in the instance variable:

// Constructor event.

// Obtains and saves a reference to this object's parent window (for use by the command buttons).

Integer li_rc

li_rc = This.of_GetParentWindow(This.iw_parent)
Return 0

For the menu (command) buttons, the code triggers an event in the parent window. Here's the code from the "sideways" menu button:

// Clicked event.

// Trigger an event in the parent window.
If IsValid(iw_parent) Then
   iw_parent.EVENT DYNAMIC ue_sideways()
End If

Return 0

The clicked event in the other buttons are similar.

Take special note of the "DYNAMIC" keyword (it does not have to be in uppercase). This tells the compiler to defer binding this function call to the referenced object until execution time. If the referenced object (the parent window, in this case) does not contain the specified event, the event call fails silently. Without the DYNAMIC keyword, the code in the clicked event could not be compiled.

Unzip the source for the CVUO and import it, then add it to a window. Add any/all of the user events called by the menu bar's buttons (ue_save, ue_addrow, ue_deleterow, ue_up, ue_down, ue_sideways) to the window. I tested by coding a MessageBox function call in the ue_sideways event.

I don't know if this technique will work for you, but I hope it helps.

Best regards, John

Attachments (1)
Comment
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Monday, 17 June 2024 17:32 PM UTC
  2. PowerBuilder
  3. # 2

 

Are your clickable objects on a datawindow?

In that case you already have an event called ue_clicked which receives a dwobject. I'm supposing that that event is on the userobject, not on the datawindow. So just check dwo.name to know which object has been clicked.

If that's NOT the case, then you can create your own ue_clicked2 event on the userobject and when you click on a button you call that ue_clicked2 event passing in the clicked object.

 

Comment
  1. Robert Sawyer
  2. Monday, 17 June 2024 18:01 PM UTC
"you can create your own ue_clicked2 event" mapped to what PB event?
  1. Helpful
  1. Miguel Leeuwe
  2. Monday, 17 June 2024 19:50 PM UTC
No mapping, just create the event and call it from the clicked of .... You haven't answered the question if the buttons are on a datawindow or not ... If they are, like I said, you already have a ue_clicked event.
  1. Helpful
There are no comments made yet.
Robert Sawyer Accepted Answer Pending Moderation
  1. Monday, 17 June 2024 17:11 PM UTC
  2. PowerBuilder
  3. # 3

I have a user object like the black bar below. It has picture objects. The picture objects have a clicked event. 

 

But, when I put the user object on a window, how can I tell what button was clicked? The button click events are not present at that level, nor is a clicked event for the user object.

Comment
  1. John Fauss
  2. Monday, 17 June 2024 18:03 PM UTC
IF you need to place code in the Clicked event of the picture button(s), then you need to perform this coding in the User Object Painter instead of waiting until the user object has been instantiated on a window. A custom visual user object works differently than, say, a tab control when you insert (default) tab pages into the tab control and then can "drill down" (tab_1.tabpage_1.pb_save, for example). This allows the visual control AND the code to be reused across multiple instantiations, if needed. This is the way a custom visual user object has always worked... there is no alternative... no "container-only" type of user object.
  1. Helpful 1
  1. Benjamin Gaesslein
  2. Tuesday, 18 June 2024 07:00 AM UTC
I would use an nvo to handle the clicks. Think Model-View-Controller pattern.

Create an nvo with an event like uo_clicked ( long index ) and have the clickable userobjects forward their clicked event to the nvo's uo_clicked() event with a unique index. In uo_clicked you can call the corresponding code.
  1. Helpful 1
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Monday, 17 June 2024 16:14 PM UTC
  2. PowerBuilder
  3. # 4

Hi, Robert -

I'm not confident I understand what you are asking about. Each picture button will have a Clicked event that can be scripted. Are you asking how you can invoke an event or function in the window that the user object is eventually placed in/on?

When you say "... how can I tell what button was clicked on the UO?", are you really asking "how can the window be notified that a (picture) button on the user object was clicked"?

Please clarify.

Best regards, John

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.