1. Berka Frenfert
  2. PowerBuilder
  3. Wednesday, 26 April 2023 13:38 PM UTC

Something is wrong either with code or PB and have no idea why when window height and width is not bigger enough, the code where i check TypeOf() objects in control array of a window, TypeOf function fails.

And if i increase width and height then TypeOf function start working again.

Please see code and attached debugger image to figure out reason

_errorLog("::: " + ClassName() + ": w_parent_sheet :  Constructor: " +  String(Now(), "HH:MM:SSSS") + ":" +  "AUT:TRIG:YES-EX")

OrgTitle = Trim(st_tool_title.Text)

st_tool_title.Visible = FALSE
st_tool_title.Text = ""
Title = ""

Event Post _Constructor()



Integer win_object
StaticText st
w_parent_sheet TheParentWin

Parent.Win = Parent
TheParentWin = Parent.Win

Tab TheTab, TheChildTab
Uo_DataWindow DW
Integer control_counter
Integer Tabpage, TabPageChild, TabPageOfChildTab


FOR control_counter = 1 TO upperbound(TheParentWin.control)

	/// folowwing line has unknown error because .TypeOf() returns nothing
	/// This happens even at very first object in control array
		
	CHOOSE CASE TheParentWin.control[control_counter].Typeof()
		CASE DataWindow!
			
				
			///_errorLog("DataWindow!" + TheParentWin.control[control_counter].Classname())
			TRY
				dw = TheParentWin.control[control_counter]
				AllDW[UpperBound(AllDW) + 1] = DW
				dw.Win = TheParentWin.Win
				
				/// InView boolean value is set
				IF DW.X < TheParentWin.Width AND DW.Y < TheParentWin.Height THEN
					DW.InView = TRUE
				ELSE
					/// outsider
					DW.InView = FALSE
				END IF
			CATCH(RuntimeError rte88101)
			END TRY
	
		/*This portion changes the label of the tabpages */
		CASE Tab!
			
			TheTab = TheParentWin.control[control_counter]

			FOR Tabpage = 1 TO UpperBound(TheTab.control[])
				
				/// going inside a tabpage
				FOR TabPageChild = 1 TO UpperBound(TheTab.control[Tabpage].control)
					CHOOSE CASE TheTab.control[Tabpage].control[TabPageChild].Typeof()
						CASE DataWindow!
							///_errorLog("DataWindow! inside tab " + TheTab.control[Tabpage].control[TabPageChild].Classname() )
							TRY
								dw = TheTab.control[Tabpage].control[TabPageChild]
								AllDW[UpperBound(AllDW) + 1] = DW
								dw.Win = TheParentWin.Win
								
								/// InView boolean value is set for DWs inside a tab control
								/// if tab control itself is inside view area then DW is consider InView
								IF TheTab.X < TheParentWin.Width AND TheTab.Y < TheParentWin.Height THEN
									DW.InView = TRUE
								ELSE
									/// outsider
									DW.InView = FALSE
								END IF
							CATCH(RuntimeError rte8811)
							END TRY
					END CHOOSE
				NEXT
			NEXT
	END CHOOSE
NEXT



 

 

Regards,

Berka

 

 

 

 

Attachments (1)
References
  1. https://postimg.cc/Lq4LbpV1
Accepted Answer
Benjamin Gaesslein Accepted Answer Pending Moderation
  1. Wednesday, 3 May 2023 17:50 PM UTC
  2. PowerBuilder
  3. # Permalink
I doubt that TypeOf() fails here. The Debugger cannot show you a result when you set a "watch" for TypeOf(), presumably because the debugger can't show you enumerated types. That's a fault in the debugger but not TypeOf() failing. Try setting a watch for "control[control_counter].TypeOf() = DataWindow!" and the watch view should show either "true!" or "false!" So whatever throws an error here, the TypeOf() line is unlikely to be at fault. I strongly suspect this: Parent.Win = Parent TheParentWin = Parent.Win (...) dw.Win = TheParentWin.Win I'm assuming "Win" is some kind of window reference you have for every base class? Why is Parent.Win set to Parent itself? And why is dw.Win set to TheParentWin.Win, which resolves to Parent.Win.Win wich is just a reference to a reference to Parent itself? There's some serious circular referencing going on here. I tried it with 2019 and it works but it might throw PB 12.5 off. But this is just a guess.
Comment
  1. Berka Frenfert
  2. Wednesday, 3 May 2023 18:08 PM UTC
Hi Benjamin,

That was very helpful. TypeOf() did not fail but debugger was not showing enumerated datatypes.

New script worked nicely on PB2019 and on PB12.5.

Thank you.



True Regards,

Berka







  1. Helpful
There are no comments made yet.
John Raghanti Accepted Answer Pending Moderation
  1. Thursday, 27 April 2023 11:58 AM UTC
  2. PowerBuilder
  3. # 1

I see that this is in the constructor. The constructor of what? Is it possible that the objects aren't actually available yet?

Could you move this code to another event and do a post() call from the constructor to see if that may be the case?

Comment
  1. Berka Frenfert
  2. Friday, 28 April 2023 12:00 PM UTC
The constructor you asked about is of a static text. It could be any constructor of all available controls in the parent . window but the code you see do some very preliminary initialization required before any inherited child can perform any action correctly. For example uo_dw is a user object that has no parent but uo_dw is used in all those child windows that are inherited from w_parent_sheet. uo_dw do need one important thing before it can complete any task. It need the reference of the window it will be used in. That means the code i wrote in uo_dw does not know which window will use the uo_dw. So, The constructor in question sets that window variable defined as instance variable. That is way the code in constructor must set that instance variable in uo_dw. That was needed because uo_dw does not know what is Parent.
  1. Helpful
  1. Berka Frenfert
  2. Friday, 28 April 2023 12:48 PM UTC
Hi Andreas,

That is apparently true but i am not sure why. You can see that the loop on control array is actually inside constructor of multilineEdit and the output include even the mle_1 itself. That sound like window has create event somewhere but not listed in windows events list. Though it is quite simple to test that the typeof() perfectly works on control array in constructor event. When i was writing code in the static text control of my w_parent i made it sure i picked the very first object in control array because i was thinking the same. Please suggest something that i may have overlooked.

True Regards,

Berka
  1. Helpful
  1. Berka Frenfert
  2. Saturday, 29 April 2023 00:46 AM UTC
I could not find any reason why typeof() failed for me in constructor of a static text that exist in parent window. The only reason i can think of is that when i am writing script in ancestor window and running loop on control[] array in ancestor windows and expecting that i will get types of objects from control array of descendant window then typeof() will fail. I really have no clue if there is any difference between control array of ancestor and control array of descendant. Loop on control array of a window which has no descendant then typeof() will not fail even in constructor event of a control.

One thing the Visibility of MDI sheet actually opened many holes to fix because visible property of MDI sheet cannot be changed neither hide() function works.
  1. Helpful
There are no comments made yet.
Berka Frenfert Accepted Answer Pending Moderation
  1. Saturday, 29 April 2023 01:07 AM UTC
  2. PowerBuilder
  3. # 2

The height and width of a window has nothing to do with TypeOf()  function. That was logical problem with my code that i fixed later.

But:

TypeOf function do have some problems because it works when window is not descendant neither ancestor.

In my app the parent window has loop on control array in constructor event of a control and right there typeof() fails. Actual reason is still unclear.

Comment
  1. John Fauss
  2. Saturday, 29 April 2023 01:43 AM UTC
The TypeOf() PowerScript function is valid for EVERY type of object or control, and yes, it works even if an object is not an ancestor or a descendant.

Do you verify the object reference is valid before using the TypeOf() function?
  1. Helpful 1
  1. Berka Frenfert
  2. Saturday, 29 April 2023 01:47 AM UTC
Do you mean Isvalid() ?

I did not check Isvalid() but debugger shows correct classname(). Please see the attached image.

  1. Helpful
  1. Berka Frenfert
  2. Wednesday, 3 May 2023 11:55 AM UTC
Hi Benjamin,

I am trying to recheck everything including PB19. hopefully, i will come up with working code.

You debugger tips was nice. It helped me a lot.

Oh, the



Parent.Win = Parent

TheParentWin = Parent.Win



The Win instance variable of w_parent is reference to itself so that all other control in descendant windows can access parent window without going through a reverse loop to reach window they reside in. Parent keyword easy way but those for example on Tab pages can easily access parent with Win. The variable name Win is not clearly stating what win but descendant windows used it already. TheParentWin a little better name with same reference to w_parent. It cannot be invalid reference neither circular reference and readily available in all descendants.
  1. Helpful
There are no comments made yet.
Berka Frenfert Accepted Answer Pending Moderation
  1. Monday, 1 May 2023 13:52 PM UTC
  2. PowerBuilder
  3. # 3

There is alternate way to avoid use of TypeOf()

The Error line:

TheParentWin.control[control_counter].Typeof()

I used variables to assign objects in control[] to avoid use of TypeOf() function.

DataWindow TheDW

Tab TheTab

If I don't use  TRY CATCH app will crash

/// when expecting a DW in the control array
TRY
  TheDW = TheParentWin.control[control_counter]
CATCH(RuntimeError RT012)
  SetNull(TheDW)
END TRY

/// when expecting a tab control in the control[] array
TRY
  TheTab = TheParentWin.control[control_counter]
CATCH(RuntimeError RT014)
  SetNull(TheTab)
END TRY

Then i check if the variable hold a valid object by using IsValid()

IF IsValid(TheDW) THEN
  TheDW.ClassNmae()
END IF

That is how i can check how many DWs are there in the  window and how many DWs are in tabpages. All this is done in constructor event.

That means TypeOf() is failing for no reason in my previous code.

Comment
There are no comments made yet.
Berka Frenfert Accepted Answer Pending Moderation
  1. Wednesday, 3 May 2023 18:41 PM UTC
  2. PowerBuilder
  3. # 4

There was no need to replace TypeOf() with type casting operator '='

Real problem started when debugger was not showing enumerated datatype that TypeOf() was returning. I thought null was returned every time.

Someone suggested to try same script in PB2019 and this step took me sometime. Good thing is i completed script in PB 2019 and when tested it on PB12.5 it worked nicely without any problem.

just in case someone interested to see what changes were made in script

w_parent TheParentWin
TheParentWin = Parent

uo_tab TheChildTab
uo_dw DW
Integer control_counter
Integer Tabpage, TabPageChild, TabPageOfChildTab

Tab TheTab

/// Main loop on window control[]
FOR control_counter = 1 TO UpperBound(TheParentWin.control)
 	SetNull(DW)
	CHOOSE CASE TheParentWin.control[control_counter].TypeOf()
		CASE DataWindow!
			_errorLog("Window control[] DW :" + TheParentWin.control[control_counter].ClassName() )
			AllDW[UpperBound(AllDW) + 1] = TheParentWin.control[control_counter]
			
			/// Win is instance of w_parent (refer to parent win). uo_dw has another 
			// instance var Win of type w_parent. InView is boolean var of uo_dw.
			/// Either crashing on DW.Win or on DW.InView means that the
			/// datawindow control used in a descendant window is not a uo_dw.
			TRY
				DW = TheParentWin.control[control_counter]
				DW.Win = TheParentWin
				IF DW.X < TheParentWin.Width AND DW.Y < TheParentWin.Height THEN
					DW.InView = TRUE
				ELSE
					/// outsider
					DW.InView = FALSE
				END IF
			CATCH (RuntimeError RTE0011)
				_errorLog("Simple dw <> uo_dw: " + DW.ClassName() + " In window: " + TheParentWin.ClassName())
			END TRY
			/// go for next in control[]
			Continue
		CASE Tab!
			
	END CHOOSE
	
	/// =============== TAB control[] =========================
	/// Object if not a DW, could be a Tab control
	CHOOSE CASE TheParentWin.control[control_counter].TypeOf()
		CASE Tab!
			TheTab = TheParentWin.control[control_counter]
			_errorLog("Wondow control[] Tab:" + TheParentWin.control[control_counter].ClassName() )

			/// How many tabpages?
			FOR Tabpage = 1 TO UpperBound(TheTab.control)
				/// going inside a tabpage
				/// how many controls on each tabpage?
				FOR TabPageChild = 1 TO UpperBound(TheTab.control[Tabpage].control)
					CHOOSE CASE TheTab.control[Tabpage].control[TabPageChild].TypeOf()
					CASE DataWindow!			
						_errorLog("Valid TABDW :" + TheTab.control[Tabpage].control[TabPageChild].ClassName()) 
							AllDW[UpperBound(AllDW) + 1] = TheTab.control[Tabpage].control[TabPageChild]
							TRY
								DW = TheTab.control[Tabpage].control[TabPageChild]
								DW.Win = TheParentWin
								IF DW.X < TheParentWin.Width AND DW.Y < TheParentWin.Height THEN
									DW.InView = TRUE
								ELSE
									/// outsider
									DW.InView = FALSE
								END IF
							CATCH (RuntimeError RTE0111)
								_errorLog("Simple dw <> uo_dw: " + DW.ClassName() + " In Tab: " + TheTab.control[Tabpage].ClassName())
							END TRY					
					END CHOOSE
				NEXT /// TABPage
			NEXT ///TAB
	END CHOOSE
NEXT




 

 

 

 

Comment
  1. Berka Frenfert
  2. Wednesday, 3 May 2023 18:52 PM UTC
I am impressed to find that PB12.5 is not as buggy as I had initially believed, which is a really positive aspect.
  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.