Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Iterating over all powerbuild GUI objects

2,165 views
Skip to first unread message

frerichraabe

unread,
Aug 7, 2009, 10:54:00 AM8/7/09
to
Hi,

does anybody know whether it is possible to iterate over all
GUI objects in my PowerBuilder application, or at least my
powerbuilder GUI?

For example, I'd like to go recursively over all elements in
a dialog and toggle the Enabled property. Even better, I'd
like to go over all elements in my entire application and
inspect them (print their ClassName property).

I saw that window objects have a ParentWindow function, but
there doesn't seem to be a way to get the child windows for
a given window. Also, I didn't find a function to get all
toplevel windows.

Any comments would be much appreciated!

Paul Horan[Sybase]

unread,
Aug 7, 2009, 11:14:26 AM8/7/09
to
Are you talking about "design" time, or "runtime"? In other words, are you
looking for something like a global "search and replace" editor to change
the PB code in your PBLs, or do you just want to change the behavior that
the user experiences when they're using the application?

If it's design time, I would take a look at 3rd-party utilities like
PBLPeeper - www.techno-kitten.com
If it's runtime, you can iterate through the control[] array after the
window has opened.

--
Paul Horan[Sybase]
http://blogs.sybase.com/phoran/

<Frerich Raabe> wrote in message news:4a7c4008.3e5...@sybase.com...

frerichraabe

unread,
Aug 7, 2009, 11:31:49 AM8/7/09
to
Hi,

first of all, thanks for the quick reply!

> Are you talking about "design" time, or "runtime"? In
> other words, are you looking for something like a global
> "search and replace" editor to change the PB code in your
> PBLs, or do you just want to change the behavior that the
> user experiences when they're using the application?

I'm sorry for the imprecision, I was talking about runtime.
I'd like to write a PowerScript function which, when called
at runtime, recursively goes through all controls in my
application and does something with each control (like,
disabling it).

> If it's design time, I would take a look at 3rd-party
> utilities like PBLPeeper - www.techno-kitten.com
> If it's runtime, you can iterate through the control[]
> array after the window has opened.

Ah, the control[] array sounds great!

Do you know whether there's also a global function (or
object, on
which I could then retrieve the control[] property) which
gets
me a handle to the main window(s) of the application?
Something
which I could start with, and from there I could then use
the
control[] property to recurse.

Paul Horan[Sybase]

unread,
Aug 7, 2009, 1:06:48 PM8/7/09
to
Well, at runtime you can only operate on controls that have been
instantiated. IOW, that are in windows that are already open, or are in the
process of opening.

In the Open() event of your ancestor window and userobject classes, set up a
loop through the control[] array.
(I'd actually place it in the postOpen event so you can be sure the controls
are instantiated.)

The code would look something like this:

this.setRedraw( false ) // to stop the flicker
FOR lx = 1 to upperBound( this.control )
this.control[lx].disable()
NEXT
this.setRedraw( true )

--
Paul Horan[Sybase]
http://blogs.sybase.com/phoran/

<Frerich Raabe> wrote in message news:4a7c48e5.452...@sybase.com...

John Strano[Sybase]

unread,
Aug 7, 2009, 2:14:04 PM8/7/09
to
If what you're trying to accomplish is securing the GUI
according to user rights, have you considered 3rd party tools
like Visual Guard?

http://www.visual-guard.com/EN/powerbuilder-profile-security/identity-management-access-control-authentication-tool/pb.html

--
John Strano - Sybase Technology Evangelist

blog: http://powerbuilder.johnstrano.com/


<Frerich Raabe> wrote in message news:4a7c4008.3e5...@sybase.com...

Jerry Siegel [TeamSybase]

unread,
Aug 7, 2009, 2:30:47 PM8/7/09
to
PMJI -
The Open event fires after all the objects in the window have been
instantiated and their Constructor events have run, so the Control[ ] array
should be valid at that time.
Enable() and Disable() are methods of menu objects. Other controls need to
have their Enabled property set.
To do that, you will need to use TypeOf on each element in Control[ ] and
cast Control[lx] to a reference variable of the appropriate class since
WindowObject does not have an Enabled property (it is the ancestor of
DrawObject [line, rectangle...] as well as DragObject [datawindow,
userobject, SLE, ...])

commandbutton lcb_button
datawindow ldw_dw
...
CHOOSE CASE control[lx].TypeOf()
CASE 'commandbutton!'
lcb_button = control[lx]
lcb_button.Enabled = lb_enabled
CASE 'datawindow!'
ldw_dw = control[lx]
...

You will note that the Constructor of any userobject will have already fired
at this point. User objects don't have an Open event!
I would suggest declaring events in the user object, perhaps ue_enable and
ue_disable, and using TriggerEvent in the Window open event. That will be
safe for user objects that do not have those events [although I would have
put them the ancestor UO] because TriggerEvent fails silently if the event
does not exist. The event scripts would call an object function
of_enable(ab_enable) to iterate through the UO's Control[ ] array. [also
obviously in the ancestor UO]

And of course enabling/disabling every object in a datawindow is a whole
additional topic ;-)

--
Report Bugs: http://case-express.sybase.com/cx/welcome.do
Product Enhancement Requests:
http://my.isug.com/cgi-bin/1/c/submit_enhancement


"Paul Horan[Sybase]" <phoran_remove@remove_sybase.com> wrote in message
news:4a7c5f28$3...@forums-3-dub.sybase.com...

Scott Morris

unread,
Aug 7, 2009, 3:09:48 PM8/7/09
to
"Jerry Siegel [TeamSybase]" <jNOsSPAMsiegel@yahoo!.com> wrote in message
news:4a7c72d7$1...@forums-3-dub.sybase.com...

> PMJI -
> The Open event fires after all the objects in the window have been
> instantiated and their Constructor events have run, so the Control[ ]
> array should be valid at that time.

I would be very careful with tabs and tabpages that are set as <create on
demand>. Perhaps now would be a good time to highlight the fact that the
control array of a window can have controls that contain other objects
(i.e., have their own control arrays).

Jerry Siegel [TeamSybase]

unread,
Aug 7, 2009, 3:39:45 PM8/7/09
to
And of course OpenUserObject and Create Using.
I did mention UO control arrays, down at the bottom of the post, but it
can't hurt to mention it again :-)


"Scott Morris" <bo...@bogus.com> wrote in message
news:4a7c7bfc$3...@forums-3-dub.sybase.com...

Paul Horan[Sybase]

unread,
Aug 7, 2009, 3:57:03 PM8/7/09
to
We had Enable() and Disable() method prototypes defined in a powerobject
ancestor, and then implemented them in their specific descendents...

That way, each type of control knew how to enable and disable itself,
including tabpages and datawindows.

I guess I just got used to having that layer there!

"Jerry Siegel [TeamSybase]" <jNOsSPAMsiegel@yahoo!.com> wrote in message
news:4a7c72d7$1...@forums-3-dub.sybase.com...

Jerry Siegel [TeamSybase]

unread,
Aug 7, 2009, 4:01:35 PM8/7/09
to
<G> A good framework will do that for you!


"Paul Horan[Sybase]" <phoran_remove@remove_sybase.com> wrote in message

news:4a7c870f$3...@forums-3-dub.sybase.com...

frerichraabe

unread,
Aug 10, 2009, 3:58:33 AM8/10/09
to
Hi,

"John Strano[Sybase]" <nichtspa...@csi.com> wrote in
message news:4a7c6eec$4...@forums-3-dub.sybase.com...


> If what you're trying to accomplish is securing the GUI
> according to user rights, have you considered 3rd party
tools
> like Visual Guard?
>
>
http://www.visual-guard.com/EN/powerbuilder-profile-security/identity-management-access-control-authentication-tool/pb.html

Thanks, but no - I'm not trying to close down the GUI
depending
on user rights. What I'm trying to do is to create a
function
which gets me a 'dump' of the PowerBuilder GUI; the function
should recursively traverse the object hierarchy (i.e., walk
the
control[] arrays, as I've been taught :-)) and then, for
each
object, print the value of a few properties which are
interesting to me.

I'm not too familiar with PB or PowerScript yet, so I'm very
grateful for any pointers. I've been doing the same kind of
functionality for other GUI toolkits already though, so
maybe
I'm having an entirely wrong mindset. What I was trying to
do is
basically (pseudo-code ahead):

function dumpWindow ( w ) {
// print information for 'w' here, then descend
for ( child in w.control ) {
dumpWindow( w )
}
}

windows = getAllToplevelWindows()
for ( w in windows ) {
dumpWindow( w )
}

The control[] array is already a useful hin, what I'm
looking
for right now is a generic way to get the toplevel object(s)
(can there be multiple ones?) - which is basically the job
of
the 'getAllToplevelWindows' function above.

All this code is supposed to be called at runtime, so that I
can
get snapshots of the GUI state at various points during the
execution of the GUI. I'm trying to make it entirely
application-
agnostic so that I can reuse this function in other
PowerBuilder
applications - that's why I'd rather not directly reference
a
particular window object by name or the like.

- Frerich

Jeremy Lakeman

unread,
Aug 10, 2009, 9:04:00 AM8/10/09
to
On Aug 10, 4:58 pm, Frerich Raabe wrote:
> Hi,
>
> "John Strano[Sybase]" <nichtspamjstr...@csi.com> wrote in
> messagenews:4a7c6eec$4...@forums-3-dub.sybase.com...> If what you're trying to accomplish is securing the GUI

> > according to user rights, have you considered 3rd party
> tools
> > like Visual Guard?
>
> http://www.visual-guard.com/EN/powerbuilder-profile-security/identity...

You can use <frame window>.getfirstsheet(), <frame
window>.getnextsheet to find all sheet windows.
You can use getfocus() to get a handle to whatever control the cursor
is in, then getparent() until it returns an invalid object to find the
window it's on.
But the most reliable way to get a handle to all windows would be to
insert a line of code into a common ancestor's open event;

w_ancestor.open();
n_debug.of_add_ref(this)

When you're looping through the control array you'll need to assign
the control to a variable of the correct type to examine its
properties;

for ll_i = lowerbound(lw_window.control) to upperbound
(lw_window.control)
choose case typeof(lw_window.control[ll_i])
case commandbutton!
commandbutton lcb
lcb=lw_window.control[ll_i]
...lcb.text...

So you could write a portable of_debug(window) function, but you'd
need to write something application specific to call this method.

Jerry Siegel [TeamSybase]

unread,
Aug 10, 2009, 10:03:29 AM8/10/09
to
It is universal [for visual applications] for the first window to be opened
in the Open event of the Application object. Where things go after that is
unique to the application. It could open an MDI frame, which would then open
sheet windows depending on menu items. Or it could be like the venerable
PowerTOOL framework, and open cascading menu windows whose contents list the
sheet windows available to the specific user based on DB tables. Or myriad
other possibilities. It might be more useful to scan the PBLs for window
objects and proceed from there. Or rather than reinventing the wheel, see if
the reports from Pibble Peeper www.techno-kitten.com will serve.


<Frerich Raabe> wrote in message news:4a7fd329.6a1...@sybase.com...

Ivaylo Ivanov

unread,
Aug 10, 2009, 3:20:34 PM8/10/09
to
See the attached function source - it performs a recursive scan of a given
window, tab control or userobject and fills an array (the second argument)
with references to all the nested controls. Everything in this function is
passed and returned as graphicobject types which is the root class in
PowerBuilder. If you want to get a specific property you will have to make a
downcast.

Sample usage from the window OPEN event:

graphicobject lgr_controls[]
// Get a list of all possible controls in the UO, incl. those in tab
controls, user objects etc.
f_get_controls(this, lgr_controls)

Regards,
Ivaylo

<Frerich Raabe> wrote in message news:4a7c4008.3e5...@sybase.com...

f_get_controls.srf

john.o...@gmail.com

unread,
Dec 31, 2019, 4:09:48 AM12/31/19
to
Ivaylo... you literally saved me today!! thx
0 new messages