|
Castaway GURU
Joined: 10 Oct 2000 Posts: 793 Location: Swindon, England
|
Posted: Wed Aug 10, 2005 6:13 am
Changing properties at runtime |
Heyho,
In my playing around, I'm attempting now to change properties of a window at runtime, eg I have a window with a button on it, and clicking the button should change the colour (background ?) of the window:
Code: |
<window name='wbuttons' caption='Button Demonstration' width='250' height='300'>
<panel name='mainview' align='client'>
<label align='top'>
If you click on any of the four buttons below, the background of the button area
will change to the color indicated in the button. You can press Tab to move am
ong the buttons, then press Space to invoke the current button.
</label>
<panel align='client'>
<button name='peach' caption='PeachPuff1'>
<script language='PerlScript'>
$wbuttons->Color('#FFDAB9');
</script>
</button>
</panel>
</panel>
</window>
|
That PerlScript should be the equivalent of: wbuttons.Color('#FFDAB9')
Should this work? Am I just missing something? (an update call?)
Lady C. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Aug 10, 2005 3:16 pm |
The Window doesn't have a "color" property. The Window colors are controlled by your current theme. You need to color the panel "mainview" that you have rather than the window itself.
|
|
|
|
Castaway GURU
Joined: 10 Oct 2000 Posts: 793 Location: Swindon, England
|
Posted: Wed Aug 10, 2005 3:53 pm |
Oops.. unfortunately that doesnt work either..
btwi discovered that to use include files you need to actually call the entity somewheres..(ie &AboutBox; somewhere in the main section)
Lady C. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Aug 11, 2005 2:16 am |
Well, not sure about PerlScript syntax, but it works in VBScript. In VBScript the syntax is:
Code: |
mainview.color = "#FFDAB9" |
It looks like you are trying to call a method called "Color" rather than setting the value of a property. Have you tried something like:
Code: |
$mainview->color = '#FFDAB9' |
|
|
|
|
Castaway GURU
Joined: 10 Oct 2000 Posts: 793 Location: Swindon, England
|
Posted: Thu Aug 11, 2005 4:21 am |
Ah.. hmm.. good idea..
Is there a way to debug this stuff? That should produce an error in Perl, if there wasnt a method called "Color"..
(I figured it was a get/set method)
"Doesnt work" in this case, just means I click my button and nothing happens, nothing at all.. :(
Lady C. |
|
|
|
Castaway GURU
Joined: 10 Oct 2000 Posts: 793 Location: Swindon, England
|
Posted: Thu Aug 11, 2005 9:52 am |
Ok, after much much playing around..
The objects (ie windows, statusbars, panels etc) are not "just visible" to Perl as $Status, $bmainview and so on, not anywhere that I can see. After lots of fiddling about, I noticed the Core.FindControl method, which DOES give me the objects.. but means I'll have to use it everytime I want to manipulate one inside a script..
Code: |
my $bmainview = $core->FindControl('bmainview');
$bmainview->{Color}='#FFDAB9';
|
works..
Hmm, I wonder if I create a <var> called bmainview, whether that would fix it.. they're supposed to be global, right? (the panels etc)
Update: Nope, that didnt work..
Lady C. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Aug 11, 2005 11:40 pm |
Hmm, that's a bad sign. Is this ActivePerl? I could have sworn that I tested ActivePerl, but it's been a while so I'll give it another try. But zMUD is calling the routine in the Microsoft Active Scripting system to make these variables available, so I'm not sure why it wouldn't work unless the scripting engine side of things wasn't handling objects.
|
|
|
|
theNerd Adept
Joined: 01 Mar 2005 Posts: 277
|
Posted: Fri Aug 12, 2005 12:45 am |
Zugg wrote: |
But zMUD is calling the routine in the Microsoft Active Scripting system to make these variables available, so I'm not sure why it wouldn't work... |
You mean zApp, right? You sure have zMUD on your mind lately. |
|
|
|
Krule Adept
Joined: 12 Nov 2000 Posts: 268 Location: Canada
|
Posted: Fri Aug 12, 2005 1:34 am |
I swear I was going to do it, but decided against it :p
|
|
|
|
Castaway GURU
Joined: 10 Oct 2000 Posts: 793 Location: Swindon, England
|
Posted: Fri Aug 12, 2005 4:05 am |
Yup, this is ActivePerl, latest version (ActivePerl-5.8.7.813-MSWin32-x86-148120.zip), I even trawled through %main:: which should hold all visible variables, and found there a MainObj, which appears to be a visible object, but no idea what it is (it's a Win32::OLE object), and Core, which already worked (as $core). I could have missed something though..
Would you like the code? (I was planning to let you have it at some point anyway, but its a work in progress ,)
Lady C. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Fri Aug 12, 2005 4:09 pm |
I should be able to test it with what I have. The "MainObj" is the master zApp object that is used to access all other components. You might try using
$MainObj->mainview->Color = '#FFDAB9'
and see if that does anything. One of the Active Script routines from Microsoft allows you to add an OLE Object and make all of it's properties and methods available without using the primary object name. For example, if you have a function library called "func" you can add it to the scripting engine and call the functions in the library directly without putting "func." or "func->" in front of each call.
It's possible that ActivePerl doesn't support this for some reason. So give it a try, but I'll also try to play with it when I get a chance. Right now I'm up to my ears in the new ecommerce and copy protection system that is replacing eLicense, so I won't be able to test this zApp stuff until next week.
And yes, I've had my mind on zMUD a lot lately. Seems that after ten years my fingers just automatically want to type zMUD instead of zApp ;) |
|
|
|
Castaway GURU
Joined: 10 Oct 2000 Posts: 793 Location: Swindon, England
|
Posted: Fri Aug 12, 2005 6:01 pm |
Ah, yup, that works too.. thats somewhat better.
I've not tried PerlScript in anything else, so I cant say if its normal.. Except the tutorials/examples I've found seem to show Perl using global objects like that. (But no idea how they were created..)
I'll battle on.. good luck with the licensing stuff!
Lady C. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Sep 29, 2005 9:45 pm |
Well, bad news for ActivePerl users
Perl does not handle dynamic COM objects properly. The way zApp works is that it creates a global object called 'MainObj' and then implements the COM GetIDsOfNames and Invoke methods to dynamically check the current zApp objects list and return any object that is found. Then, MainObj is added to the script system with the GLOBALMEMBERS flag, which tells the scripting host that the properties and methods of MainObj can be accessed directly without specifying the MainObj name.
So, when you access "MyButton.Caption", MyButton is actually a dynamic COM property of the MainObj global object. The scripting host is supposed to query the MainObj interface for the "MyButton" method. zApp checks the global object table for the current value of the MyButton component and returns that particular object.
The problem with ActivePerl is that it tries to be "smart" and instead of calling GetIDsOfNames each time, it loads the TypeLibrary for the COM object and creates it's own internal table of property and method names. Since the MainObj global object doesn't have a TypeLibrary (because it's list of properties methods is dynamic) Perl decides that there are no properties of MainObj so it doesn't add anything to it's internal list of available properties and methods.
You *can* call MainObj.MyButton directly, as Castaway found, but when you try to reference just MyButton, it fails to find anything with this name because when Perl was initialized, the MainObj object didn't have any property called MyButton at that time.
In order to make this a bit easier to deal with, I have renamed the "MainObj" object to just "Obj" in the next 2.33 release of zApp. So then you can access zApp objects using the Perl syntax:
$obj->MyButton
which is a bit cleaner than the previous $MainObj->MyButton syntax.
If I find a way to get around all of this, I'll let you know. But for now it looks like it's just going to be more of a pain to use Perl than the VBScript or JScript languages that implement dynamic COM objects correctly. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Sep 29, 2005 10:27 pm |
Yep, just verified this problem with ActivePerl. Seems that ActivePerl has a *very* basic implementation of the Microsoft Scripting Engine. Using ActivePerl with zApp just isn't ever going to work very well because of this.
I tried another trick just to be sure. I implemented the TypeLibrary stuff and checked to see how ActivePerl uses Type Libraries. The problem is that it *caches* the information from the type library internally, and only calls the ITypeInfo routines once. It's presumeably loading the type library initially, then looping through it and copying stuff like property and method names to some internal table. It does this when the script engine is initialized, and then never again.
So, even if I implemented a dynamic type library system, it still wouldn't work since it only queries the type library details once.
This is very sad and seems to be yet another case where programmers just don't understand how to use COM. Rather than reading in the type library and copying the information to some internal table, you are supposed to keep a reference to the ITypeInfo object itself and always query it. This isn't slow. Or, at least, it's no slower than looking up something in an internal table. Maybe they felt that putting it into some sort of hash table of properties and methods would be better, but it defeats the purpose of using a standard interface or making assumptions about it (like it being static).
Oh well, I did what I could with this. Can't do anything else about it.
Oh, and I also learned that ActivePerl doesn't seem to implement any of the Scripting Host debugging interfaces, so Perl will also never work with any fancy debugging system that gets implemented in zApp Pro.
Too bad they did such a minimal implemenation job. And with Active Scripting going away in .NET, I'm not seeing a lot of new support for it. Which is also sad that Microsoft feels the need to abandon a technology that works just fine and is relatively easy to implement. Sigh. |
|
|
|
Castaway GURU
Joined: 10 Oct 2000 Posts: 793 Location: Swindon, England
|
Posted: Fri Sep 30, 2005 6:13 am |
Hmm, apart from having to access objects via MainObj or FindControl, using ActivePerl with zApp has worked very well for me so far. Please don't shoot down a whole language just because it seems somewhat simpler than you are used to. Yeah, the debugging stuff is more annoying..
I'm going to try out 2.33, thanks very much for that!
And I will go see if I can't find whomever is responsible for ActivePerl, and ask them if better support would be possible. Did you actually ask them, or just confirm it for yourself?
Out of curiosity, what is replacing Active Scripting in .NET.. And have you seen the stuff about gadgets in Vista?
Lady C. |
|
|
|
Castaway GURU
Joined: 10 Oct 2000 Posts: 793 Location: Swindon, England
|
Posted: Fri Sep 30, 2005 7:56 am |
Hmm, having searched around a bit, I see others using PerlScript also have similar problems. *sigh*..
Anyway, one article I came across seems to imply that using/registering a global base object "Application" will cause all unknown objects to be looked for there, and thus eliminate the need to write $obj-> everywhere:
http://www.ddj.com/documents/s=1520/ddj0110as/0110as001.htm
Is that true or am I just misreading it?
Lady C. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Sat Oct 01, 2005 4:47 pm |
That's what zApp already does...the MainObj (or Obj as it's now called) *is* a global "application" object. The problem is that PerlScript queries this object for it's properties and methods when the script engine is first initialized and then it never queries again.
So, for example, if you later create a BUTTON component with the name "MyButton", this component cannot be accessed because it didn't exist when the script engine was initialized.
I have contacted the people at PerlScript (with the help of Castaway :) to explain this situation and see if they can modify their scripting engine so that instead of declaring an identifier as "unknown" that it should re-check the interface of global objects to see if the identifier is part of one of these objects.
Technically they aren't doing anything wrong, since 99.9% of all COM objects are static. But nothing in the COM spec forces a COM object to be static, and by not calling the GetIDsOfName method of the global COM objects at later times they are preventing any sort of dynamic COM object from working. It should be a very easy change in their code to support this, but we'll have to wait and see if they are willing.
The other bug that is mentioned on sites like DDJ.COM is that PerlScript only handles a *single* global Application object. According to the Scripting Host documentation you can have any number of global objects, but PerlScript only handles one. That's not a problem for zApp since MainObj/Obj is the only global object that is used, but it's something else that it would be nice to see fixed in PerlScript eventually. |
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|