Nested #Button('Parent'), Multi(%list,%field) - is there some sort of hidden parent child linking taking place?

#Application
#Button('Parent'),Multi(%ParentList,%ParentField)
#Prompt('ParentField',@s255),%ParentField,Req
#Button('Child'),Multi(%ChildList,%ChildField)
#Prompt('ChildField',@s255),%ChildField,Req
#Prompt('ParentField',@s255),%ChildParentField,Req,Default(%ParentField)
#EndButton
#EndButton

In the below example the Prompt (Child) “range limited” to the parent doesnt display the right fields.

#Procedure
#Prompt('Parent',From(%ParentList,,%ParentField),%ProcParentField
#Prompt('Child',From(%ChildList,%ChildParentField = %ProcParentField ,%ChildField),%ProcParentField

So is there some sort of internal linkage taking place when I have nested #Button Multi’s like in the example above?

TIA

Edit

The TXA values look alright.

%iscwInterfaceList MULTI LONG  (1, 2)
%iscwInterfaceName DEPEND %iscwInterfaceList DEFAULT TIMES 2
WHEN  (1) ('MyInterface1')
WHEN  (2) ('MyInterface2')

%iscwInterfaceParent DEPEND %iscwInterfaceList DEFAULT TIMES 0

%iscwInterfaceType DEPEND %iscwInterfaceList LONG TIMES 0

%iscwInterfaceCOM DEPEND %iscwInterfaceList LONG TIMES 0

%iscwInterfaceProcedureList DEPEND %iscwInterfaceList MULTI LONG TIMES 2
WHEN  (1) (1, |
  2)
WHEN  (2) (1, |
  2)

%iscwInterfaceProcedureName DEPEND %iscwInterfaceProcedureList DEFAULT TIMES 2
WHEN  (1)TIMES 2
WHEN  (1) ('MyInterface1ProcedureName')
WHEN  (2) ('MyInterface1OtherProcedureName')
WHEN  (2)TIMES 2
WHEN  (1) ('MyInterface2MyProcedureName')
WHEN  (2) ('MyInterface2MyOtherProcedureName')

You don’t need the %ChildParentField at the child level. Those children will automatically be nested within the parent, and you do this:

#FOR(%ParentList)
  #FOR(%ChildList)
    #ERROR('ParentList='& %ParentList &'; ChildList='& %ChildList)
  #ENDFOR
#ENDFOR

As you can see, the Children are not all sitting in a flat table, but rather in a sub list. You can’t access them without first #FIXing the Parent in some manner.

What I do in this type of situation is use local multi-valued symbols or hidden multi-valued #PROMPTs. Then experiment with #PREPARE and WHENACCEPTED(…) to fill those local lists for use in the #PROMPT statements.

Unfortunately I don’t have a similar example to share with you. It will take a fair bit of fiddling, but you should be able to get it to work.

I did wonder this, originally I didnt have the %ChildParentField but because I couldnt get Fix, Find or Select to work, I added the %ChildParentField and tried Fix, Find and Select again and still no joy.

Its because the #Button(‘’),Multi is a instance number when most of the examples in the help docs are using multisymbols with text.

I didnt know if
#Prompt('Parent',From(%ParentList,,%ParentField),%ProcParentField
was some sort of undocumented feature because normally for multisymbol
#Prompt('Parent',From(%ParentList),%ProcParentField
would be enough, but in #Button Multi’s they are instance numbers.

The last attempt was
#Prompt('Parent',From(%ParentList,,%ParentField),%ProcParentField,WhenAccepted(%MyFix)

#Group(%MyFix)
#Declare(%InstanceNumber)
#For(%ChildList)
    #IF(%ChildParentField = %ParentField)
        #Break
    #EndIF
#EndFor

Even that didnt work.

Anyway I’ll give the error a go at seeing whats going on behind the scenes.

Thanks!

It’s a bit of a tightrope. WHENACCEPTED fires only when it’s actually accepted. #PREPARE happens a bit more consistently, so you want to use #PREPARE as much as possible, because it represents the current state of affairs. Sprinkle in WHENACCEPTED to adjust things as the state of affairs changes.

This is all tied in with my other post
Error: SAVE’d variables only allowed in the #Application section - but they are! - ClarionHub

I’m refactoring the template at the moment as its getting a little on the large side, my tpl file is now just these few lines, which is much more manageable. :grinning: It is a case of getting the right code in the right place though.

#TEMPLATE(IS_ClassWriter,'IS_Class_Writer'),Family('IS_ClassWriter')
#!
#!
#Include('IS_AnEmbedEditorSourceButton.tpw')
#!
#Include('IS_ClassWriter_TODO.TPW')
#Include('IS_ClassWriter_Declarations.TPW')             
#Include('IS_ClassWriter_Wizard.TPW')
#Include('IS_ClassWriter_Notes.TPW')

#!
#Include('IS_ClassWriter_Application.TPW')
#Include('IS_ClassWriter_Program.TPW')
#Include('IS_ClassWriter_Module.TPW')
#Include('IS_ClassWriter_Procedure.TPW')

It might be firing but here its not doing anything.

I got some code which is supposed to clear a @s255 prompt and its not clearing it.
#Set(%field,‘’) doesnt clear the symbol either.
#Clear(%field) doesnt clear the symbol either.

The thing I’m finding with this computer is some days it works, and other days the same code doesnt work, and it could be clarion code or template code thats not working, there is no pattern to it or anything, which is annoying because I cant write a program to make this windows computer secure, because windows is insecure by design, 10years I’ve been trying to secure various computers, very annoying.

All I can say is that templates are quirky. I don’t think I’ve ever been able to clear a #PROMPT, except possibly with #ENABLE(…),CLEAR. Even with that, I see that I’ve often coded pessimistically, so I wouldn’t trust that either.

The templates are astonishingly flexible, but they are also difficult to get working the way you want. Additionally, no one really knows how they work (including SoftVelocity). It think this is why they didn’t recode the generation engine when they changed to the new IDE, because they couldn’t reverse engineer the code. If they recoded it from scratch, it would have broken everyone’s templates, and Clarion’s priority is to ensure people’s code keeps working, as much as possible.

Understatement! :grinning:

I might peek at it using Ghidra to see what I can find out. :male_detective:

Did you ever meet Veronica Chapman over here, she used to come round my house and teach me stuff in clarion, assembler, and things. She very succinctly summed up programming.

Its all just Longs and Cstrings

and it is in a way. :grinning:

Edit.

Interesting person.
Anders Hejlsberg - Wikipedia

Clarion and Delphi - delphi (delphigroups.info)

It is my understanding that Anders wrote the Turbo Pascal compiler and that
a couple of other people who subsequently went to work for Neils at TopSpeed
wrote the editor and various other bits and bobs. Whether Neils himself
wrote an earlier, pre-release version of TP I have no idea…

Edit2
https://clarionhub.com/uploads/default/original/1X/77559724d5888058dc89110c7aa9d634c2f9eab7.pdf
Page 59 Suggests the Clarion pragma’s are actually ADA pragma’s because they are the definition of the language.

Edit3
The compiler directives/project defines appear to fit
Pragmas (adaic.org)

I dont know how much more this fits with the project system though, but I wonder if this might explain the template system esoterism

1 Like

This error is a bit of a dark horse! I didnt realise it pops up in the AppGen window, I’ve only ever seen it display messages in the compiler window, this has certainly made things a little easier.

1 Like

Just keep at it. I’ve had as much or more experience with templates than anyone out there, and it would still take me few hours of fiddling to get what you’re trying to do work reliably. Once you’re done, you’ll have a much better insight into how that all works.

This will guarantee a C6 32bit server crash (C60srvx.exe)!

#Declare(%DbgVwMsg)
#Set(%DbgVwMsg,'6 '  & %Module &' '& %Procedure)
#Error(%DbgVwMsg)
#RunDll('Kernel32.dll', 'OutputDebugStringA',%DbgVwMsg), release, win32

#RunDll must be using the Topspeed and not the Pascal calling convention. :wink:

1 Like

I suppose you could create a Clarion wrapper DLL to do it instead.

This is one of the things I’ve been trying to get working since last year but it refuses to work so I’m now going through the map and exp files to work out whats going on.

I dont know whether the side channel mitigations that are set in the bios are affecting this, but the #Rundll with a clarion wrapper to outputdebugstringa just refuses to work and I dont know if its some of the MS anti virus exploit protection stuff causing problems or what.

Finally got the clarion wrapper to work, it was a path error that was stopping it!
So we can do this
#RunDll(‘drive:\path\filename.dll’, ‘MAIN@FRsc’, %DbgVwMsg), release, win32
and not just
#RunDll(‘filename.dll’, ‘MAIN@FRsc’, %DbgVwMsg), release, win32

Thing is though, I did have the path added to the redir so I think the #RunDll does not use the redir file which will explain alot. So obvious with hindsight.

I can finish off my language translator which is rewriting the templates adding a group call to pertinent lines in the template either before or after which sends the output to debugview so I can see the value of symbols etc. But I only ever work on the original template , the language translator processes the template and puts the modified version in the IDE folders.

Cool.
Fist bump! (imgflip.com)

1 Like

LONGPATH should do the trick:

#RunDll(LONGPATH(‘filename.dll’), ‘MAIN@FRsc’, %DbgVwMsg), release, win32

1 Like

LOL that just causes the 16bit sub system (NTVDM.exe) to crash.

All these cause crashes:

#Set(DbgVwMsg,‘LONGPATH(’‘filename.dll’’) = ’ & LONGPATH(‘filename.dll’) )
#RunDll(‘drive:\path\filename.dll’, ‘MAIN@FRsc’, %DbgVwMsg), release, win32

Even these cause a crash surprisingly!
#Set(DbgVwMsg,‘Path() = ’ & Path() )
#RunDll(‘drive:\path\filename.dll’, ‘MAIN@FRsc’, %DbgVwMsg), release, win32

#Set(DbgVwMsg,'LongPath(Path()) = ’ & LongPath(Path()) )
#RunDll(‘drive:\path\filename.dll’, ‘MAIN@FRsc’, %DbgVwMsg), release, win32

I did wonder if there was some special variation of Longpath(‘filename.dll’) which only worked when called from within the template, but the path() doesnt work nor does the Longpath(path()), yet I have Longpath(path()) working inside a #Set in other templates.

Something has obviously changed on this computer again! :roll_eyes:

I meant LONGPATH(‘filename.dll’) expands to ‘drive:\path\filename.dll’

For some strange reason path() and longpath are not working in this template but I have them working in other templates so I dont know if its the test code I have here which is causing the problem, the template needs tidying up which might make Longpath and path work on this machine here.

I dont even need to do that, I can either place the dll in one of the search folders as discussed here
Dynamic-Link Library Search Order - Win32 apps | Microsoft Docs

Or just add ALL the Clarion folders & subfolders to the System Path, which I think I must of missed out when I reinstalled the OS.
How to set the path and environment variables in Windows (computerhope.com)
Windows: Set Environment Variable - CMD & PowerShell - ShellHacks

Anyway this now works when the DLL is in the correct folder and the system path is updated to reflect clarion folder layout changes I’ve made.

#RunDll(‘filename.dll’, ‘MAIN@FRsc’, %DbgVwMsg), release, win32

Finally getting the debugview output I wanted from the Templates. Its not finished yet, but its interesting seeing the orders stuff gets called in and how often some of the template commands get called, #Tabs get called alot when in them.

Went into the Global Properties template here and all the Tab’s fire.

[1596] #Tab('&1 Include Files')
[1596] #Tab 2
[1596] #Tab('&1 Include Files')
[1596] #Tab 2
[1596] #Tab('&1 Include Files')
[1596] #Tab('&1 Include Files')
[1596] #Tab 2
[1596] #Tab('&1 Include Files')
[1596] #Tab 2
[1596] #Tab('&1 Include Files')
[1596] #Tab 2
[1596] #Tab('&1 Include Files')
[1596] #Tab 2
[1596] #Validate 1
[1596] #Validate 2
[1596] #Tab('&1 Include Files')
[1596] #Tab 2
[1596] #Tab('&1 Include Files')
[1596] #Tab 2
[1596] #Tab('&1 Include Files')
[1596] #Tab 2
[1596] #Tab('&1 Include Files')
[1596] #Tab 2
[1596] #Tab('&1 Include Files')
[1596] #Tab 2
[1596] #Tab('&1 Include Files')
[1596] #Validate 3
[1596] #Tab 2

Pressed Make button here, but at least I can see the value’s in %symbols now like %module in this example.

[1596] #Application
[1596] #Prepare
[1596] #EndPrepare
[1596] #Sheet,HScroll
[1596] #EndSheet
[1596] Before #FOR(%Module), WHERE (%Module <> %Program)
[1596] #FOR(%Module=), WHERE (%Module= <> %Program=SimpleApp.clw)
[1596] #GENERATE(%Module=Simpl001.clw)
[1596] After #ENDFOR - (%Module), WHERE (%Module <> %Program)

Now I just need to automate adding the debugview group to all templates.

Its surprising how many messages debugview can handle in 1 second, like just over 8,000 messages which is surprising, but I suspect its probably machine dependent.

1 Like