1. Berka Frenfert
  2. PowerBuilder
  3. Tuesday, 2 May 2023 12:07 PM UTC

As you can see my previous questions were about failure of TypoeOf() function

I used a different way to get specific controls picked from control array without using TypeOf()

Only to pick Datawindow controls and save them in a DataWindow AllDW[] array, i used PowerBuilder's internal Type Casting Operator '=' equal sign.

Declared DataWindow type variable and assigned it each control in a loop

DataWindow TheDW, AllDW[]

But there are only two places in a window where a datawindow control can be found or can be placed.

1- Window itself

2- TabPage of a Tab Control


When i run loop on Windows control array and ignore Tab controls just to pick those datawindows first that are there in window and not on a tab control, the type casting operator ('=' equal sign) works fine. Because we know powerbuilder runtime crashes when statictext control is assigned to a datawindow variable. Which is obvious as default behavior of PB. To avoid crash we use TRY and after TRY if IsValid() function is used to see if DW is a valid datawindow then in case when loop was inspecting statictext in the window control [] array, the DW is not valid and IsValid() function verify that. So this how all other controls are ignored and picked only datawindow controls.

Things are pretty much in good shape so far because loop is ignoring Tab controls.

FOR control_counter = 1 TO UpperBound(TheParentWin.control)
	TRY
		TheDW = TheParentWin.control[control_counter]
	CATCH(RuntimeError RT012)
	END TRY
	
	IF IsValid(TheDW) THEN
		TheDW
		AllDW[UpperBound(AllDW) + 1] = TheDW

 

Now problem starts when inner loop runs through each control on a tabpage.

The type casting idea with = failed because all of the controls on tabpage were valid as datawindow. What that means is, if there is a static text control on tabpage and i set that to the TheDW variable the assignment becomes valid and IsValid function sees it valid to assign a picture, statictext, groupbox, ole etc. to a datawindow variable.

FOR TabPageChild = 1 TO UpperBound(TheTab.control[Tabpage].control)
	TRY
		TheDW = TheTab.control[Tabpage].control[TabPageChild]
	CATCH(RuntimeError RTE0014)
		_errorLog("Crashed In Tab @ " + TheTab.control[Tabpage].control[TabPageChild].ClassName())
	END TRY

Note: the CATCH block of code is triggered but assignment is also completed as valid statement.

IF IsValid(TheDW) THEN
	AllDW[UpperBound(AllDW) + 1] = TheDW
	_errorLog("Valid TABDW :" + TheDw.ClassName())

Output includes both _errorlogs for every picture, text, ole, dw groupbox etc.
    "Crashed In Tab @ "
    "Valid TABDW :"
    
That is absolutely wrong and seems tabpage control[] array is handled different way than window control[] array internally. No idea what went wrong where.

The full script:

w_parent TheParentWin

/// the parent is a valid window reference
TheParentWin = Parent

/// variables
Tab TheTab, TheChildTab
Uo_DW TheDW
Integer control_counter
Integer Tabpage, TabPageChild, TabPageOfChildTab

/// just a log of how many controls are there in control array[]
_errorLog("Start : The object " + TheParentWin.ClassName() + " has total " + String(UpperBound(TheParentWin.control)) + " controls")

/// going through window array ( The main outer loop)
FOR control_counter = 1 TO UpperBound(TheParentWin.control)
 	SetNull(TheDW)
	SetNull(TheTab)

	/// either one of the following variables will be valid
	/// both cannot be valid at the same time TheDW & TheTab
	TRY
		TheDW = TheParentWin.control[control_counter]
	CATCH(RuntimeError RT012)
		SetNull(TheDW)
		_errorLog("Crashed In Window @ " + TheParentWin.control[control_counter].ClassName())
	END TRY

	/// Q: What to do when TheDW is valid? 
	/// A: DataWindow control goes to an array of type datawindow
	/// and also log classname and other things.
	IF IsValid(TheDW) THEN
		_errorLog("Valid DW :" + TheDW.ClassName() )
		SetNull(TheTab)
	
			AllDW[UpperBound(AllDW) + 1] = TheDW

		/// get next object
		Continue
	END IF	

	/// Object if not a DW, could be a Tab control
	TRY
		TheTab = TheParentWin.control[control_counter]
	CATCH(RuntimeError RT014)
		SetNull(TheTab)
	END TRY
	
	IF IsValid(TheTab) THEN
		/// 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)
				SetNull(TheDW)
				TRY
					TheDW = TheTab.control[Tabpage].control[TabPageChild]
				CATCH(RuntimeError RTE0014)
					_errorLog("Crashed In Tab @ " + TheTab.control[Tabpage].control[TabPageChild].ClassName())
				END TRY
	
				IF IsValid(TheDW) THEN
					_errorLog("Valid TABDW :" + TheDw.ClassName()) 
						AllDW[UpperBound(AllDW) + 1] = TheDW
//						END TRY
				END IF
			NEXT /// TABPage
		NEXT ///TAB
	END IF
NEXT




 

 

 

 

 

 

Accepted Answer
Benjamin Gaesslein Accepted Answer Pending Moderation
  1. Tuesday, 2 May 2023 14:41 PM UTC
  2. PowerBuilder
  3. # Permalink

I tried this in PB2019 and you can pretty much "successfully" cast any kind of windowobject to any other kind of windowobject using the Control-Array. "Successfully" meaning that a RuntimeError will be thrown but if you catch and ignore that, you can have a variable of type singlelineedit that seems to hold a valid reference to a datawindow, commandbutton, multilineedit etc.

This works with any control array, regardless if it belongs to a window or tabpage.

Comment
  1. Berka Frenfert
  2. Tuesday, 2 May 2023 15:37 PM UTC
Thanks a lot for checking that in PB2019. Is it possible for you to check TypeOf() function as well? I want to make sure before i can try my code on PB2019. I think TypeOf() if works then i don't have to rely on equal sign.
  1. Helpful
  1. Benjamin Gaesslein
  2. Wednesday, 3 May 2023 06:37 AM UTC
I'm having no issues with TypeOf().
  1. Helpful
  1. Berka Frenfert
  2. Thursday, 11 May 2023 10:04 AM UTC
This type casting was needed when my code had issues with TypeOf() which is the best way to check types of objects. I did not test it further to find out if the new reference is giving proper results. Actually, my other question posted earlier was about TypeOf() which was solved and i completely ignored this type casting question. TypeOf returned valid value but debugger was showing null/empty. Problem is resolved already. I am sorry i got busy in other things not related to my work so could not respond back in few days. Thanks a lot for the great help solved my problem.

  1. Helpful
There are no comments made yet.
Andreas Mykonios Accepted Answer Pending Moderation
  1. Tuesday, 2 May 2023 12:29 PM UTC
  2. PowerBuilder
  3. # 1

Hi.

I've read your question. Haven't had time to experiment. Just a comment. Datawindows can exist on windows, tabpages and user objects. Maybe you aren't using user objects, but generally speaking they could be placed to a user object. And of course tabpages and user objects are mostly related...

Andreas.

Comment
  1. Berka Frenfert
  2. Tuesday, 2 May 2023 12:38 PM UTC
Thanks for a quick review of the question. yes, you know that tabpages and userobjects are related. The loop on control array should be same for both.
  1. Helpful
There are no comments made yet.
Andreas Mykonios Accepted Answer Pending Moderation
  1. Tuesday, 2 May 2023 12:45 PM UTC
  2. PowerBuilder
  3. # 2

This may be some kind of workaround.

long ll_i
boolean lb_isdw = false
datawindow ldw_tmp

for ll_i = 1 to upperbound(uo_1.control)
	try
		lb_isdw = false
		ldw_tmp = uo_1.control[ll_i]
		lb_isdw = true
	catch (runtimeerror exc2)
//		messagebox("", exc2.text)
	catch (throwable exc1)
//		messagebox("", exc1.text)
	end try
	
	if lb_isdw then
		messagebox("", ldw_tmp.dataobject)
	end if
next

But I will make more testings with your concept later.

Andreas.

Comment
  1. Berka Frenfert
  2. Tuesday, 2 May 2023 13:12 PM UTC
My PB crashes ignoring TRY CATCH. just a quick check on Dataobject line, PB crashes. My script is running in constructor and most of my windows do not assign dataobject untill open event and in some cases a posted _open event is not done. I checked this dataobject check 2 days ago too but to make sure it cause crash on object like st_, cb_ etc. i checked it in my code few minutes ago.



TRY

IF Trim(TheDW.DataObject) <> "" THEN

_errorLog("Valid DW by Dataobject :" + TheDw.ClassName())

END IF

CATCH(RuntimeError rt0001)

END TRY
  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.