[Home] [Downloads] [Search] [Help/forum]


Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ General ➜ External MUClient text window

External MUClient text window

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1 2  3  4  

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Mon 15 Mar 2004 01:49 PM (UTC)
Message
OK, this is the thing... Right now we have billions of people shouting "WE WANT AN EXTERNAL WINDOW", so I figured, how hard can it be... I started to code it in VB, and it works nicely, you can create it, set it to topmost or not and add text. The rest is easy to add, but the problem is that I suck with RTF textboxes (I haven't used any), and I don't know how you go about adding color and stuff... So, if anyone would like to help me with the window thing, or have any ideas, please post here... I'll post the sources eventually, but right now it's like 10 lines of code :P Anyway, I just want to see the response it has, I'll get back to coding it now...

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Reply #1 on Mon 15 Mar 2004 06:15 PM (UTC)
Message
It's more or less working now, you can move it, resize it, print text in color and different fonts and sizes, set it to always on top or not, activate it, etc. I'll work on it a bit more and post it, when i find out how :p

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Reply #2 on Mon 15 Mar 2004 06:55 PM (UTC)
Message
It is now possible to have transparent and/or "click-through" windows, meaning that the click goes to the window behind that one. I still haven't found of an acceptable way to activate the windows (not in code, just normally), since they do not appear in the taskbar. Idealy, they would be added to MUClient's "Windows" menu, but I don't know if that can be done...

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Reply #3 on Mon 15 Mar 2004 06:56 PM (UTC)
Message
Oh, the transparency thing only works on XP/2k. Turns out it's just 2 API calls, I'm sure MUClient could be made to support that very easily...

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

Posted by Nick Gammon   Australia  (23,046 posts)  Bio   Forum Administrator
Date Reply #4 on Mon 15 Mar 2004 08:13 PM (UTC)
Message
Quote:

... and I don't know how you go about adding color and stuff...


The way MUSHclient does it is to draw each style as a separate operation. You can do that quite easily in your program, as it exposes the style runs, and the text to be drawn, as part of GetStyleInfo.

Thus you keep track of the X-Y coordinates on the window, start drawing (by going back a screenfull of lines, or by starting at the bottom and working up), draw each line from left to right, updating the X coordinate for each style run, and then updating the Y coordinate for each line.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Reply #5 on Mon 15 Mar 2004 08:42 PM (UTC)
Message
No, I was referring to the Rich Text box control, it has specific commands to do that... Anyway, it's working now, I just uploaded it to http://www.poromenos.org/MUClientWindow.exe. Download it, run it, and paste this alias:

<aliases>
  <alias
   match="DoDemo"
   enabled="y"
   send_to="12"
   ignore_case="y"
   sequence="100"
  >
  <send>
Dim WindowObject
WindowObject = Empty
Set WindowObject = CreateObject ("MUClientWindow.TextBox")
WindowObject.Topmost = True
WindowObject.SetTitle "Groovy MUClient Window"
WindowObject.SetPosition 300, 500, 12000, 3000
WindowObject.Opacity = 0.7
WindowObject.Transparent = True
WindowObject.Locked = True
WindowObject.BackgroundColor = vbBlack
WindowObject.Note "The ", "Times New Roman", 11, vbWhite
WindowObject.Note "quick ", "Times New Roman", 12, vbGreen
WindowObject.Note "fox ", "Times New Roman", 13, vbRed
WindowObject.Note "jumped ", "Times New Roman", 14, vbBlue
WindowObject.Note "over ", "Times New Roman", 15, vbYellow
WindowObject.Note "some ", "Times New Roman", 16, vbMagenta
WindowObject.Note "meaningless ", "Times New Roman", 17, vbCyan
WindowObject.Note "animal. " &amp; vbCrLf, "Times New Roman", 18, vbWhite
WindowObject.Note "This is just a demo."  &amp; vbCrLf, "Lucida Console", 8, vbRed
WindowObject.Note "Post stuff at the forum." &amp; vbCrLf, , , vbWhite
Dim WindowObject2
WindowObject2 = Empty
Set WindowObject2 = CreateObject ("MUClientWindow.TextBox")
WindowObject2.Note "Oh!" &amp; vbCrLf
WindowObject2.Note "You can have as many of these as you like (I think)"
</send>
  </alias>
</aliases>

Then, type DoDemo to see it working. Tell me what you think.

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

Posted by Shadowfyr   USA  (1,787 posts)  Bio
Date Reply #6 on Mon 15 Mar 2004 11:33 PM (UTC)
Message
Hmm. For those of us with Pre-2000/XP systems, do not use (delete) these options:

WindowObject.Opacity = 0.7
WindowObject.Transparent = True

The first one will fail and cause the script to terminate early. The second option will work, but since this floating window doesn't periodically update itself (under 98 at least, no idea about the others), unless you send text to it, the background will bleed through and completely obscure the window and anything in it.

A more reasonable thing would be to have your program check to see if it is running under 2000 pr XP and if not, then simply ignore these options completely. I.e., the user can supply them, but they won't do anything.
Top

Posted by Shadowfyr   USA  (1,787 posts)  Bio
Date Reply #7 on Tue 16 Mar 2004 12:52 AM (UTC)
Message
Ok... A few issues here.

First.. There is no way to clear the existing window contents, at least from the example you give.

Second and far more critical, when Mushclient executes a reload/recompile of a script, manually or otherwise, the script engine does not release existing instances of the control. If a reload automatically triggered a special "Release" sub that you could add to kill all instances of created objects this wouldn't be a big issue. Once Mushclient itself completely closes, then memory is freed, but I jumped to 90%+ system resources used in no time as a result of reloading my main script file while I fiddled with positioning the window and adding code to correctly capture the lines I needed. This is bad news...

However, it is the same situation I ran into with my fireworks gadget, so moving all the related code to a plugin would work, if I didn't need to make changes to it periodically and plugins didn't seem to occationally do the same thing to me. I get te feeling that the plugin/script in such case is released before the system has time to release the object.

I have no idea how to work around this frankly... Even if you make the program 'serve' up windows, so that it worked like a database and was 'multiple use, single instance', you still get extra references to the object that the script engine keeps, but can't use when the script reloads. The only real solution is to make sure these are released 'before' Mushclient reinstalls a plugin or reloads the script. I don't know if Nick can solve that problem somehow, but it means that all such script created objects are dangerous if not killed 'before' you reload the script. Closing the window does nothing.

You will notice that my fireworks program has the close button disabled. It 'cannot' kill the running instance, but only closed the form and gives you a false sense of security. I figured it was safer to disble the button, than let people think it is no longer running. Until the reference itself is released but the script, you can't *close* such a window for real.

The only interrum solution I can think of is the 'multiple use, single instance' trick. It doesn't actuall *fix* the problem, but you would do this instead:

WindowObject.NewWindow "My Window"
...
WindowObject.Note "You can have as many of these as you like (I think)"

This will work exactly the same, since internally you would keep track of *which* open window the script object is using. This should therefor only take the minimum resources needed to establish a link to the object and initially create the child window of your main program. Currently, each time the script reloads, and automatically opens a window, it creates a completely new window and the old one stays sitting in memory unused and swallowing up resources. We really need a better way to handle objects that doesn't have this problem imho...
Top

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Reply #8 on Tue 16 Mar 2004 08:24 AM (UTC)
Message
I see... Regarding the transparency problem, I read that it just wouldn't work in systems other than XP/2k... I'll do something about it... As for the way to clear the text, there is a WindowObject.Text property, that returns/sets the entire text, so you can do WindowObject.Text = "". I forgot to add that to the demo. Finally, about releasing objects, making new windows with a command would be too complicated both for me and the user :/ I would have to make form and control arrays, and the user would have to pass the number of the window with each operation... If I'm not mistaken though, plugins call OnPluginClose even when they reload, so they could be made to set the object to nothing until I find a better way.
Now that I think of it, why doesn't MUClient free the objects? Isn't the old scripting space released? That would cause the objects to be freed, unless I am (or Microsoft is :p) missing something.

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Reply #9 on Tue 16 Mar 2004 05:26 PM (UTC)
Message
It will now ignore transparency if the OS is less than 2k...

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

Posted by Shadowfyr   USA  (1,787 posts)  Bio
Date Reply #10 on Tue 16 Mar 2004 10:13 PM (UTC)

Amended on Tue 16 Mar 2004 10:17 PM (UTC) by Shadowfyr

Message
Hmm. Not as complicated as all that. I would suggest:

Public Function NewWindow (Name as String) As Boolean
  dim NewWin as MyBaseWindow
  dim TempWin as MyBaseWindow
  'I have no idea if the code between ***** is accurate.
  'I haven't used this type of control array before, so am
  'going by memory of what I think it was.
  '*****
  For Each TempWin In Me.Controls
    If TempWin.Name = Name then
      NewWindow = False
      Exit Function
    end if
  Next
  NewWin.Name = Name
  Me.Controls.Add NewWin
  '*****
  NewWin = Nothing
  NewWindow = True
End Sub

Then make the 'Note' command:

Public Function Note (Name as String, Text as String, Font As String, Size as Integer, Color as Integer) As Boolean

Then the user can direct text to the window they want and internally it would do:

Dim TempWin As MyBaseWindow
For Each TempWin In Me.Controls
  If TempWin.Name = Name then
    TempWin.Note Text, Font, Size, Color
    Note = True
    Exit Function
  end if
Next
Note = False


You would just move the existing window design and code into a seperate class you can make copies of, then add code like above to each of the current calls (making them functions too so the user can test to make sure the window exists). The basic window you already have doesn't change, you just use For Each to hunt down the specific window the user wants to send text to. This isn't really that much more complicated and the 'main' form can exist as a task tray item or even a hidden service. Since closing Mushclient will kill all connections to it, you don't need to worry about it being visible to the user.

Hmm. It does mean you have to make things like the .text also be accessed by name, with other things, but that is no big deal really.

----

As for Mushclient and plugins.. I think actually the problem was in my main script file, so plugins may correctly release the objects through OnPluginClose. However, I have:

sub Close_World
  set winamp = Nothing
end sub

In my main script and either this is not called when you reload the script or the previous instance of the script is killed before the system has time to actually release the object. In any case, it never releases the WinAmp COM control I was using if I do a reload. The issue I had may also have just been something to do with the odd nature of the WinAmp control. It is both ActiveX and a normal DLL, so closing winamp would *hang* the WinAmp program and occationally Mushclient. Releasing the object worked fine though, as long as you did that *first*, then closed WinAmp.

In any case, it may be possible to solve some of the odd quirks my just adding a delay to the Close function, so the script cannot exit until the system has had a chance to actually release the objects.

Top

Posted by Shadowfyr   USA  (1,787 posts)  Bio
Date Reply #11 on Tue 16 Mar 2004 10:20 PM (UTC)
Message
In fact, with this configuration you can actually make the close button on the window do something and add a WindowObject.Close <Name> type command, either of which will delete the object from the control array.
Top

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Reply #12 on Wed 17 Mar 2004 06:20 AM (UTC)
Message
I don't see how that is better than setting the variable to nothing, since that takes a line of code too, and the user could do a =nothing instead of a .close. The close button currently hides the window, and you can show it again with .Visible = True, without losing the contents... My point is that if you are going to free the windows anyway, you can free them with either way, either by having an array of objects, or by having one object with a .CloseAll function...

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Reply #13 on Wed 17 Mar 2004 06:21 AM (UTC)
Message
Also, I think that For ... Each In Me.Controls just enumerates the controls on a form, not the forms in a project, I'm not sure though.

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

Posted by Shadowfyr   USA  (1,787 posts)  Bio
Date Reply #14 on Wed 17 Mar 2004 07:17 AM (UTC)

Amended on Wed 17 Mar 2004 07:18 AM (UTC) by Shadowfyr

Message
Well, since the forms are children of the main form, they should be in the control area, either of the main form (though maybe that is only MDI, or in a seperate control array.

As for the difference between Close and = Nothing... 'Nothing' in this case won't work. You are not destorying your connection to the control, just killing one window. Example, your method does this to create two windows:

set Obj1 = createobject("MUClientWindow.TextBox")
set Obj2 = createobject("MUClientWindow.TextBox")

Mine does it this way:

set Obj = createobject("MUClientWindow.Server")
Obj.NewWindow("Window1")
Obj.NewWindow("Window2")

This is a 'major' difference, since if something causes the original script instance to die, like a reload and the object isn't released you can do this:

a = Obj.Exists("Window1")
if not a then
  Obj.NewWindow("Window1")
end if

More than one script, plugin or even world can talk to the same window through a link to the service, which could be an advantage in some cases. But more important, as long as you use the same name each time, the only extra resources taken up by a script reload or other nasty issue that fails to release the object is what provides the 'link'. With your current design, every time one fails to be released it takes up the memory needed for that link + the memory needed for a brand new window. After 6-7 reloads you are looking at literally MBs of unreleased memory that is taken up by inactive and inaccessable processes.

It may be possible to find a better solution, but imho this could significantly *limit* the damage caused each time someone messes up and doesn't properly release the object in WorldClosed and OnPluginClose, or some glitch prevents these functions from working, as happened to me.

Your version works fine, I am just suggesting a 'safer' way to do it while Nick works out why such objects fail to automatically release when the script is killed and reloaded anyway.
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


123,797 views.

This is page 1, subject is 4 pages long: 1 2  3  4  [Next page]

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]