Is there anyway to set things up so a a vb program and a vb script can interact? I'm attempting to create a graphical interface for a MUSH system, however, I'm trying to figure out how to get the information obtaine by the script to the program. Any help would be appreciated, thanks
Accessing Other Programs
Posted by Jamal on Wed 31 Dec 2003 10:49 PM — 17 posts, 84,540 views.
Run a search on this forum for "super health bar" or something to that effect. This is something Nick Gammon (I believe) did to show proof of concept; it IS possible to have MUSHclient talk to an external VB program (via VBscript). In this case, the external program was a graphical health bar that was updated from the prompt.
I believe Shadowfyr also made some form of fireworks display, but since I don't play the MUD he did it for and don't have a server-side implementation anyways, I didn't look at it. But I believe it does the same thing: MUSHclient talks to the VB app via VBscript.
Hope that helps. :)
I believe Shadowfyr also made some form of fireworks display, but since I don't play the MUD he did it for and don't have a server-side implementation anyways, I didn't look at it. But I believe it does the same thing: MUSHclient talks to the VB app via VBscript.
Hope that helps. :)
Ok, I tried to get the Healthbar to work and had little help. I saw in that example, and in another external program project the use of createobject(), however, when I tried to use it I keep getting:
ActiveX component can't create object: 'TextDisplay.DTXT'
Anyone know why?
ActiveX component can't create object: 'TextDisplay.DTXT'
Anyone know why?
Either that isn't its exact name, or the external program is not registered (ie. is not in the Registry properly).
I think its that lasy problem, through I'm not exactly sure what your talking about with registry property.
Basically Windows creates ActiveX components by looking in the system registry for a key, this key in turn provides information about the 'objects' in the file and the file itself. In this case DTXT is an 'object' in your TextDisplay file.
Now.. If you are using VB, then the important thing to remember is that the VB compiler can create *two* different types of objects. If you attempt to test an object like you would a program, using "Run" it makes a temporary object, that only exists in memory and an equally temporary key. As long as the object is being *Run* in the editor Windows can find it, but the moment you close the editor or you hit "Stop" the object disappears and Windows can't find it anymore. This is actually warned about in the documentation, which says that this is definitely the *wrong* way to test ActiveX exe or dll files.
The *right* way is to use the option under the File menu for Make. This will either show "Make TextDisplay.exe" or maybe "Make TextDisplay.dll", depending on which one you are creating. This will create a *real* object and a *real* key in the registry, so that when you use createobject, Windows will be able to find the information it needs to create it. But always remember to use Make, never Run, since every time you use Run Windows will lose track of the *real* copy you previosly made and won't be able to find it again. ;)
Now.. If you are using VB, then the important thing to remember is that the VB compiler can create *two* different types of objects. If you attempt to test an object like you would a program, using "Run" it makes a temporary object, that only exists in memory and an equally temporary key. As long as the object is being *Run* in the editor Windows can find it, but the moment you close the editor or you hit "Stop" the object disappears and Windows can't find it anymore. This is actually warned about in the documentation, which says that this is definitely the *wrong* way to test ActiveX exe or dll files.
The *right* way is to use the option under the File menu for Make. This will either show "Make TextDisplay.exe" or maybe "Make TextDisplay.dll", depending on which one you are creating. This will create a *real* object and a *real* key in the registry, so that when you use createobject, Windows will be able to find the information it needs to create it. But always remember to use Make, never Run, since every time you use Run Windows will lose track of the *real* copy you previosly made and won't be able to find it again. ;)
Ok, after some trial and error I got things to work, thanks. However, how do I access the object created in the script from inside the program. Right now I have a variable inside the class which stores the world its dealing with. I want the Form I wrote to retrieve the data from the class created by the script, but I don't know how to refer to it.
The world variable? Did you look at the super health bar plugin? I think you basically have to tell VBscript about MUSHclient (ie. register the .tlb file) and then it knows how to interpret the world object.
From what I can tell, in the Super Health Bar, you have the class updating the display on the form, so the class is sending it all the needed information. I was wondering if this is the only way, or is there some way to refer the created class instead of having the class send the form the info?
Assuming I understand the question correctly, there is probably a way, however I don't know what it is.
The simplest thing is probably to have a method in the class that the script can call.
The simplest thing is probably to have a method in the class that the script can call.
I assume he means something like:
Class.Form.Text = "yadda"
Good question, but I doubt it. The Form is an object of its own and not part of the class used to communicate with it. The closest you can do is create a property in the class:
I believe this is about the only way you can get it to work. You don't have to have both Get and Let, often just Get is useful by itself.
Personally I find this a lot less annoying than the fact that the so called Active Scripts Microsoft puts out are not event driven, so you can't use programs or controls that generate events. I.e. You have a list of songs in Winamp, one ends and the next starts, so the Winamp ActiveX plugin fires a SongChange event. In true VB or other event driven languages you just drop something like this in:
However, the briliant minds an MS decided you shouldn't be able to do this in scripts... :( It simply gets ignored. One of these days I hope I can track down some code for how IE handles completely unknown objects.. A C++ class that creates the object and correctly identified and passed events on to the script would be a god send, especially if we can convince Nick to impliment it in the client. It drives me nuts that, other than the CallPlugin command, ActiveX controls and programs must me almost totally passive in their interaction with the scripts that called them. :p This is fine if you code your own, but using something that wasn't designed with Mushclient or some bloody web browser correctly can be completely impossible. Python may be the only one that can do this. But that is a big 'maybe'.
And yeah. I know this was one of those 'security' issues, but you would think some option would exist to deal with this for applications that are not used for the internet.
Class.Form.Text = "yadda"
Good question, but I doubt it. The Form is an object of its own and not part of the class used to communicate with it. The closest you can do is create a property in the class:
Property Let MyText(Text As String)
MyForm.text = Text
End Property
Property Get MyText() As String
MyText = MyForm.text
End PropertyI believe this is about the only way you can get it to work. You don't have to have both Get and Let, often just Get is useful by itself.
Personally I find this a lot less annoying than the fact that the so called Active Scripts Microsoft puts out are not event driven, so you can't use programs or controls that generate events. I.e. You have a list of songs in Winamp, one ends and the next starts, so the Winamp ActiveX plugin fires a SongChange event. In true VB or other event driven languages you just drop something like this in:
sub SongChange (SongName As String)
'Do stuff
end subHowever, the briliant minds an MS decided you shouldn't be able to do this in scripts... :( It simply gets ignored. One of these days I hope I can track down some code for how IE handles completely unknown objects.. A C++ class that creates the object and correctly identified and passed events on to the script would be a god send, especially if we can convince Nick to impliment it in the client. It drives me nuts that, other than the CallPlugin command, ActiveX controls and programs must me almost totally passive in their interaction with the scripts that called them. :p This is fine if you code your own, but using something that wasn't designed with Mushclient or some bloody web browser correctly can be completely impossible. Python may be the only one that can do this. But that is a big 'maybe'.
And yeah. I know this was one of those 'security' issues, but you would think some option would exist to deal with this for applications that are not used for the internet.
Quote:
sub SongChange (SongName As String)
'Do stuff
end sub
sub SongChange (SongName As String)
'Do stuff
end sub
Are you sure this won't work? Assuming that in your VB program you have saved the world variable, can't you do this ...
sub SongChange (SongName As String)
myworld.Note "Song has changed to " & SongName
end sub
If not, what happens exactly?
I tried it. VBScript isn't event driven. It can't recieve them as near as I can tell. I suppose it 'may' be possible I screwed up and had the wrong sub name, but I asked about in on several forums and was told it doesn't work. In web browsers, where scripting is normally used, the scripts either use their own custom objects (i.e. built into the browser) or in the case of IE, a special declaration that tell the browser, not the script, what the ID key is and what things you want to use with it.
As near as I can figure, the script engine itself lacks any direct means to do this, unless there is some command or option you need to optionally enable when you start it and is normally disabled. I admit that after the first time I tried I didn't check to see if something else would work. However, one good clue that this is true is that vbscript has no object collection class, so it relies on the client to figure out which of several identical objects is referred to by something like Buttom1_OnClick.
I may be wrong, but if so, then I haven't a clue why the one thing I tried using didn't do anything. Some like Python are different and support real events, but they also support internal declarations of windows, buttons, etc. directly as part of the language.
As near as I can figure, the script engine itself lacks any direct means to do this, unless there is some command or option you need to optionally enable when you start it and is normally disabled. I admit that after the first time I tried I didn't check to see if something else would work. However, one good clue that this is true is that vbscript has no object collection class, so it relies on the client to figure out which of several identical objects is referred to by something like Buttom1_OnClick.
I may be wrong, but if so, then I haven't a clue why the one thing I tried using didn't do anything. Some like Python are different and support real events, but they also support internal declarations of windows, buttons, etc. directly as part of the language.
I tried this:
Project: Project1
Class: EventTest
It didn't do anything. Also tried making it ab_Repeat. If VBScript is recieving the event, then I haven't a clue what it is actually getting or what name it needs. It definitely doesn't respond. Normally in scripting the objects 'Name' gets defined in the script, so you get EventTest1, EventTest2, etc. But the code to set that name is IE specific and not supported anyplace else.
Hmm. There is something in the docs for Windows scripting though under 'event binding', like:
Set <object>.<event> = GetRef("Procedure")
The exact example is:
However, when I attempted this with both the stuff I made above and with the gen_com.dll plugin for Winamp I tried before I got:
Object doesn't support this property of method 'winamp.SongChange'
This makes no sense, but they are the only two COM functions I have tried, so... The gen_com.dll for winamp does have 1-2 glitches and I have no idea if the basic one I made even works. Its possible something is just wrong with them. However, the rest of the references to events in the docs for VB are all for the WSH scripting host, not normal VBScript. :(
==============
==============
Umm. I also just noticed your example. You missed the point, I am trying to make the 'script' respond to an event from 'my' program, not have my program act as an intermediary. I have the song name show up on the info bar. But it also needs to have 1) how long I have given myself to play, 2) how much of that time I have spent, 3) A envolope symbol that appears if I have unread mudmail, 4) My current EXP/Minute and 'then' the song name, if Winamp is playing.
Now placing my program in between would look like this:
Mushclient <---> My Program <---> Winamp Control DLL <---> Winamp
All my program would end up doing is adding more potential bugs (since I would now be talking through 2 COM programs). This is rediculous, since there is no real reason why the script itself can't respond to these events (in theory). Now that I know it 'should' work, I'll keep looking around to see why it won't. :(
Found the reason... - It only works with events from the *client*, such as DHTML objects in a browser. It doesn't know how to use it with objects it creates itself apparently.
Project: Project1
Class: EventTest
Public Event Repeat(str As String)
Public Sub RepeatMe(str As String)
RaiseEvent Repeat(str)
End Sub
----
VBScript>
sub Repeat(str)
note str
end sub
----
Commands executed>
/set ab = createobject("Project1.EventTest")
/ab.RepeatMe "Test Test"
----It didn't do anything. Also tried making it ab_Repeat. If VBScript is recieving the event, then I haven't a clue what it is actually getting or what name it needs. It definitely doesn't respond. Normally in scripting the objects 'Name' gets defined in the script, so you get EventTest1, EventTest2, etc. But the code to set that name is IE specific and not supported anyplace else.
Hmm. There is something in the docs for Windows scripting though under 'event binding', like:
Set <object>.<event> = GetRef("Procedure")
The exact example is:
<SCRIPT LANGUAGE="VBScript">
Function GetRefTest()
Dim Splash
Splash = "GetRefTest Version 1.0" & vbCrLf
Splash = Splash & Chr(169) & " YourCompany 1999 "
MsgBox Splash
End Function
Set Window.Onload = GetRef("GetRefTest")
</SCRIPT>However, when I attempted this with both the stuff I made above and with the gen_com.dll plugin for Winamp I tried before I got:
Object doesn't support this property of method 'winamp.SongChange'
This makes no sense, but they are the only two COM functions I have tried, so... The gen_com.dll for winamp does have 1-2 glitches and I have no idea if the basic one I made even works. Its possible something is just wrong with them. However, the rest of the references to events in the docs for VB are all for the WSH scripting host, not normal VBScript. :(
==============
==============
Umm. I also just noticed your example. You missed the point, I am trying to make the 'script' respond to an event from 'my' program, not have my program act as an intermediary. I have the song name show up on the info bar. But it also needs to have 1) how long I have given myself to play, 2) how much of that time I have spent, 3) A envolope symbol that appears if I have unread mudmail, 4) My current EXP/Minute and 'then' the song name, if Winamp is playing.
Now placing my program in between would look like this:
Mushclient <---> My Program <---> Winamp Control DLL <---> Winamp
All my program would end up doing is adding more potential bugs (since I would now be talking through 2 COM programs). This is rediculous, since there is no real reason why the script itself can't respond to these events (in theory). Now that I know it 'should' work, I'll keep looking around to see why it won't. :(
Found the reason... - It only works with events from the *client*, such as DHTML objects in a browser. It doesn't know how to use it with objects it creates itself apparently.
If you want to callback from your external program into your plugin, can't you use CallPlugin?
Say your external program has a world object somewhere, then doing this could notify your script that something has happened ...
world.CallPlugin "80cc18937a2aca27079567f0", "OnSongChange", "New Song Name"
Say your external program has a world object somewhere, then doing this could notify your script that something has happened ...
world.CallPlugin "80cc18937a2aca27079567f0", "OnSongChange", "New Song Name"
That is sort of the point Nick. The event fired isn't from *my* program. Someone else designed the control I am using and it generates the event. In other words.. Right now I call all of the functions in that control, but not make the script respond to the one event that the control generates. If I had to create a program to handle this event and pass it to CallPlugin, then I would also have to reimpliment my own version of every single function in the control. This is rediculous. It is also not practical to create a new version of some programs and controls that support CallPlugin.
For example, lets say some existing program like an FTP client can be created as an object and fires a "I am finished" type event. What if it is more complex and can fire 20-30 events? Designing my own program or DLL to sit in between and baby sit the events, because the script can't handle them directly could become almost as complicated as writing the original program.
Imho, this is just silly, since scripts can have objects linked to them the same way that you link world events to it. IE does this by letting you register a name with the engine that references the object and the events that it is expected to fire. Unfortunately IE does this by handling the object creation itself and pulling a list of events from the DLL or EXE file's event list.
For example, lets say some existing program like an FTP client can be created as an object and fires a "I am finished" type event. What if it is more complex and can fire 20-30 events? Designing my own program or DLL to sit in between and baby sit the events, because the script can't handle them directly could become almost as complicated as writing the original program.
Imho, this is just silly, since scripts can have objects linked to them the same way that you link world events to it. IE does this by letting you register a name with the engine that references the object and the events that it is expected to fire. Unfortunately IE does this by handling the object creation itself and pulling a list of events from the DLL or EXE file's event list.