1. Christopher Craft
  2. PowerBuilder
  3. Saturday, 18 February 2023 20:19 PM UTC

PB 2019 R3

I don't know if this is possible but I am trying to get the width and height of a UserObject as it was designed (in the PBL). When creating a window we insert multipe UserObjects as TabPages and I need them all to size to the tab. When the UserObject constructs I only have what the current size is for the tabpage. If I can get the original size I can adjust all the objects within so they all look like they were designed for this window.

Thanks,

Chris Craft

Accepted Answer
John Fauss Accepted Answer Pending Moderation
  1. Saturday, 18 February 2023 23:20 PM UTC
  2. PowerBuilder
  3. # Permalink

Hi, Chris -

See if the following code does what you are looking for:

Integer         li_num_properties, li_index, li_width, li_height
String          ls_class_name = "tabpg_test"
ClassDefinition lcd_tabpage

// Obtain the Class Definition for the desired tabpage user object.
lcd_tabpage = FindClassDefinition(ls_class_name)
If Not IsValid(lcd_tabpage) Then
   MessageBox("Oops","Unable to obtain class definition of tabpg_test user object.")
   Return 0
End If

// Invalid values, so we now when we have found their original values.
li_width  = -1
li_height = -1

// The properties for an object class can be inspected by examining the
// contents of the ClassDefinition's array of VariableDefintion objects,
// contained in its VariableList property.
li_num_properties = UpperBound(lcd_tabpage.VariableList)

For li_index = 1 To li_num_properties
   // We are interested in only the "width" and "height" properties...
   Choose Case lcd_tabpage.VariableList[li_index].Name
      Case "width"
         // Get the initial value for the width.
         li_width = lcd_tabpage.VariableList[li_index].InitialValue
      Case "height"
         // Get the initial value for the height.
         li_height = lcd_tabpage.VariableList[li_index].InitialValue
   End Choose
   If li_width <> -1 And li_height <> -1 Then Exit
Next

// Any luck?
If li_width <> -1 And li_height <> -1 Then
   MessageBox("Eureka!","The tabpg_test user object's original width is " + &
      	String(li_width) + " and its original height is " + String(li_height) + ".")
Else
   MessageBox("Rats!","Unable to find the tabpg_test user object's original width & height.")
End If

Return 0

Best regards, John

Comment
  1. Christopher Craft
  2. Wednesday, 22 March 2023 18:47 PM UTC
Just ran into an issue that I wanted to post the solution for. If you create tabs on the fly using OpenTab() then there is no Tabpage object so the ancestor will put you back to your base object (ie. u_container). In order to support OpenTab() just add this check before going back to your ancestor class:



// Only use the ancestor if we have a parent class - this supports OpenTab()

IF NOT IsNull(lClassDef.ParentClass) THEN

IF IsValid(lClassDef.Ancestor) THEN

lClassDef = lClassDef.Ancestor

END IF

END IF

...Rest of code
  1. Helpful
  1. Chris Pollach @Appeon
  2. Wednesday, 22 March 2023 20:21 PM UTC
Hi Chris;

Thank you for that insight into your solution! Very interesting.

FWIW: In my STD Framework, it's designed to send a "Resize" Event to ALL nested objects. For example: TC => each TP => each UO ... then if nested furher => each TP => each UO .. etc - down the *entire* Parent / Child chain. That way, each object is encapsulated resize wise and the resize logic is very simplex..Plus, you can nest objects indefinitely without worrying about nested object resizes from high level parents they are all independent of the "immediate" parent that controls them. Food for thought (in the big long term picture). I always wondered why PB or the PFC for that matter never implements this. ;-)

Regards ... Chris
  1. Helpful
  1. Christopher Craft
  2. Thursday, 30 March 2023 14:59 PM UTC
Yes - we do the same. The issue here is I have UO's that are created as tabpages on the fly across different windows which all have different Tab sizes. I needed just this UO to get sized to the Tab it is on BEFORE the window does any resizing. This logic then makes the UO fit perfectly on any tab it is created on. Once that is sized then the normal Window resize will do its work - firing resize to all nested objects.
  1. Helpful
There are no comments made yet.
Patrice Domange Accepted Answer Pending Moderation
  1. Wednesday, 22 February 2023 11:14 AM UTC
  2. PowerBuilder
  3. # 1

Hello,

You could also simply declare instances variables called ii_originalWidth & ii_originalHeight and initialise them in the constructor event:

ii_originalWidth = this.width
ii_originalHeight = this.height

Then recall these values when needed using adequate getter method you will have defined.

If using the PFC, you can extends the class u_base in that way to have best performance comparing to use the of_GetInfo method instead.

Regards.

Comment
  1. Miguel Leeuwe
  2. Wednesday, 22 February 2023 18:33 PM UTC
Hi Patrice, that's also what I thought like 2 years ago, until I ran into problems:

See https://community.appeon.com/index.php/qna/q-a/how-to-determine-the-original-width-and-height-of-an-mdi-sheet-window

and

https://community.appeon.com/index.php/qna/q-a/window-width-height-values-in-edit-source?limitstart=0#reply-30745

Maybe it's not completely the same situation though, so you method could work depending on what you need.

regards.
  1. Helpful
There are no comments made yet.
Kevin Ridley Accepted Answer Pending Moderation
  1. Monday, 20 February 2023 13:11 PM UTC
  2. PowerBuilder
  3. # 2

You should take a look at my Elevate 2020 presentation on using the PFC resize service without the PFC.  I think you might find it very useful for this scenario.

 

https://www.youtube.com/watch?v=zPAnRMC-12c&t=14s

Comment
  1. Kevin Ridley
  2. Monday, 20 February 2023 13:14 PM UTC
The code is on CodeXchange and you are welcome to use it in any application.
  1. Helpful
  1. Christopher Craft
  2. Tuesday, 21 February 2023 18:05 PM UTC
Thanks Kevin. Our application does have a resize service. The issue here is I have base objects that can be used in multiple windows. These base objects are sized pretty small in order to handle the different tabpages that they might exist on in every window. The resize service will correctly size all the objects in the base object but it did not take up the tab pages full real estate in all the windows which I have never liked. The key is I needed to fire a resize for the tabpage before the windows resize service kicked in which is why I needed the original dimensions of the user object.



Are you saying the PFC has a way to do this already? I didn't see that in the presentation.
  1. Helpful
There are no comments made yet.
Christopher Craft Accepted Answer Pending Moderation
  1. Monday, 20 February 2023 04:34 AM UTC
  2. PowerBuilder
  3. # 3

Well, this is the constructor for the user object in the tabpage - the class definition name is showing the window name and not the object name?

Comment
  1. John Fauss
  2. Wednesday, 22 February 2023 04:40 AM UTC
I believe the Tab control was added to PB in version 5 (that was a monumental release that dramatically improved PB), after Windows added it to their set of common controls. Prior to that we had lower-functionality "simulated" tabs in DataWindows with user objects.
  1. Helpful 1
  1. Miguel Leeuwe
  2. Wednesday, 22 February 2023 08:56 AM UTC
Yes, I think you're right John!
  1. Helpful
  1. Christopher Craft
  2. Wednesday, 22 February 2023 16:14 PM UTC
That explains it - we started with PB3! I really should go back to these and make them inherit from the Tab control but there are so many other things to do...

Thanks everyone for your help on this.
  1. Helpful
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Sunday, 19 February 2023 22:41 PM UTC
  2. PowerBuilder
  3. # 4

Hi Christopher,

 

You don't have to use the tag to store your objectname.

I have this little code in my constructor of a common ancestor of my tabpages:

Look at the ls_temp variable in the image below:

The "name" property of the classdefinition, gives me information about both: the first part is the name of the tabpage object as saved in the pbl and the second part is the control name on the tab.

So the name of the control is "tabpage_collections" and the name of the physical object in the library is "u_combo_cq".

regards

Comment
  1. Miguel Leeuwe
  2. Sunday, 19 February 2023 22:54 PM UTC
Now that I come to think of it, if you have a common constructor for your tabpages, you would not even have to make use of the FindClassDefinition() function. ClassDefinition is a property, as you can see in my code above. For the rest you could apply all of John's code. Maybe the constructor event is not the best option in that case, but you could use some kind of "postconstructor" or even the SelectionChanged() event of the parent Tab control. (I'm thinking of tabpages that have "CreateOnDemand" activated. It really mixes up the sequence of constructors and not in a good way. It sometimes fires AFTER other events of the tabpage have fired, depending on which powerbuilder version you are using).
  1. Helpful
  1. John Fauss
  2. Sunday, 19 February 2023 23:16 PM UTC
Very nice, Miguel!
  1. Helpful 1
  1. Miguel Leeuwe
  2. Sunday, 19 February 2023 23:23 PM UTC
Ty John, the same code that you posted helped me in the past to figure out window sizes!
  1. Helpful
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.