Super Health Bar plugin with external VB program

Posted by Nick Gammon on Sat 16 Aug 2003 04:06 AM — 39 posts, 155,741 views.

Australia Forum Administrator #0
I have been mucking around trying to do a "super" health bar - one that uses an external program to display a fancier health bar. It is sort-of working, so I will present it here in the hope someone can make it work perfectly.

The general idea - which works on my development PC (Windows NT 4) - is to write a small VB program (not VBscript) which is invoked from MUSHclient and which draws a nice health bar with multiple lines. See the screen shot in the next post for the general idea.

However I am finding that when attempting to run it on other PCs I get strange behaviour, like missing VB DLLs, and other things. However you may be able to make it work, especially if you have VB installed.

First, the plugin which calls the health bar program - this is similar to the earlier health bar plugin, however it has the enhancement of the 1-second timer that will do a match on the last line, even if there is no newline, so it should work even if the prompt does not have a newline on it.

Super_Health_Bar.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE muclient [
  <!ENTITY trigger_match 
   "^\&lt;\-?(\d+)\/(\d+) hp \-?(\d+)\/(\d+) m \-?(\d+)\/(\d+) mv\&gt;(.*?)$" 
  > 
]>
<!-- Saved on Saturday, August 16, 2003, 7:11 AM -->
<!-- MuClient version 3.42 -->

<!-- Plugin "Super_Health_Bar" generated by Plugin Wizard -->
<!--
You will probably need to customise the trigger to match your MUD.

See ENTITY line near top of file. The above trigger will match on:

  <54/1000 hp 90/100 m 600/750 mv>

A simpler trigger would be:

  &lt;*/*hp */*m */*mv&gt;

-->

<muclient>
<plugin
   name="Super_Health_Bar"
   author="Nick Gammon"
   id="4637b3ca32d84f4b5ea6743b"
   language="VBscript"
   purpose="Health, Mana, Movement bar implemented with external VB program"
   date_written="2003-08-16 07:08:12"
   requires="3.42"
   version="1.0"
   save_state="y" 
   >
<description trim="y">
<![CDATA[
Uses a small Visual Basic program to display your current health, 
mana and movement points in a separate window.

You need your prompt line to display the appropriate information,
naturally. I used this in SMAUG:

prompt <%h/%H hp %m/%M m %v/%V mv>
fprompt <%h/%H hp %m/%M m %v/%V mv>

"prompt" sets the normal prompt, "fprompt" sets the fight prompt.

Customise the plugin if you want to match a different sort of prompt line.

]]>
</description>

</plugin>


<!--  Triggers  -->

<triggers>
  <trigger
   enabled="y"
   match="&trigger_match;"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>

On Error Resume Next

if not isempty (barobject) then
  if not (barobject is nothing) then
    barobject.SetMaxHP %2
    barobject.SetHP %1
    barobject.SetMaxMana %4
    barobject.SetMana %3
    barobject.SetMaxMove %6
    barobject.SetMove %5
  end if
end if

</send>
  </trigger>
</triggers>

<!--  Timers -->

<timers>
  <timer 
    script="CheckPrompt" 
    enabled="y" 
    second="1" 
  >
  </timer>
</timers>


<!--  Script  -->


<script>
<![CDATA[
'
' global variable which is the HP bar Visual Basic COM object
'
dim barobject

barobject = empty

'
'  Central spot for showing errors, so we can easily customise colours
'
sub ShowError (sMessage)
  world.ColourNote "white", "red", sMessage 
end sub


'
' This world has been connected (to the MUD)
'
sub OnPluginConnect
dim X, Y, width

if isempty (barobject) then
  set barobject = nothing
end if

if barobject is nothing then
  On Error Resume Next

  set barobject = createobject ("MUSHclient_bar.Bar")

  If Err.Number <> 0 Then
    ShowError Err.Description
    ShowError "Cannot execute bar display program"
    ShowError "Check it is installed."
    Exit Sub
  End If

  On Error GoTo 0

'
'  reposition it (from value saved last time)
'

  X = GetVariable ("X")
  Y = GetVariable ("Y")
  width = GetVariable ("width")

  if not IsEmpty (X) and not IsEmpty (Y) then
    barobject.SetPosition CInt (X), CInt (Y)
  else
    Note "First time used - using default screen position"
  end if

  if not IsEmpty (width) then
    barobject.SetWidth CInt (width)
  end if

  barobject.SetTitle world, world.WorldName
end if

end sub

'
' This world has been disconnected (from the MUD)
'
sub OnPluginDisconnect

On Error Resume Next

'
'  release bar window - remember position
'

if not isempty (barobject) then
  if not barobject is nothing then
    SetVariable "X", barobject.GetX
    SetVariable "Y", barobject.GetY
    SetVariable "width", barobject.GetWidth
    set barobject = nothing
  end if 
end if 

end sub

sub CheckPrompt (sName)
Dim regEx, Matches, Match, sLine, iNumber

'
'  Find line number of last line in buffer
'
  iNumber = world.GetLinesInBufferCount

' ignore lines with a newline at the end

  if world.GetLineInfo (iNumber, 3) then exit sub

' ignore world.note lines

  if world.GetLineInfo (iNumber, 4) then exit sub

' ignore player input lines

  if world.GetLineInfo (iNumber, 5) then exit sub

'
' So far we have a line that is MUD output (not note or command)
'  and it doesn't have a newline, so it is probably a prompt
'

' get text of line

  sLine = world.GetLineInfo (iNumber, 1)

'
' Make a regular expression to match on the line:
'
'  
  Set regEx = New RegExp

'
'  exit CDATA block so we can use the trigger entity
'
]]>

  regEx.Pattern = "&trigger_match;"

<![CDATA[

'
'  Execute regular expression
'

  Set Matches = regEx.Execute (sLine)

'
'  Exit if no match
'
 
  if Matches.Count = 0 then  exit sub


  Set Match = Matches.Item (0)

  Set regEx = Nothing
  Set Matches = Nothing

'
'  Update the bar
'

  On Error Resume Next

  if not isempty (barobject) then
    if not (barobject is nothing) then
      barobject.SetMaxHP CInt (Match.SubMatches (1))
      barobject.SetHP CInt (Match.SubMatches (0))
      barobject.SetMaxMana CInt (Match.SubMatches (3))
      barobject.SetMana CInt (Match.SubMatches (2))
      barobject.SetMaxMove CInt (Match.SubMatches (5))
      barobject.SetMove CInt (Match.SubMatches (4))
    end if
  end if

  Set Match = Nothing

end sub

'
'  Called if the user closes the bar window
'

sub barclosed (arg)
 OnPluginDisconnect
end sub

]]>


</script>


</muclient>



Next, the VB project.

There is a reference in it to the MUSHclient.tlb file (which comes with MUSHclient). You will probably need to change that to be where you actually have that file.

MUSHclient_bar.vbp


Type=OleExe
Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#C:\WINNT\System32\StdOle2.Tlb#OLE Automation
Reference=*\G{00025E01-0000-0000-C000-000000000046}#5.0#0#C:\Program Files\Common Files\Microsoft Shared\DAO\DAO360.DLL#Microsoft DAO 3.6 Object Library
Reference=*\G{11DFC5E7-AD6F-11D0-8EAE-00A0247B3BFD}#1.0#0#C:\Program Files\MUSHclient\scripts\MUSHclient.tlb#MUSHclient
Object={6B7E6392-850A-101B-AFC0-4210102A8DA7}#1.3#0; COMCTL32.OCX
Class=Bar; Bar.cls
Form=Gauge.frm
Module=Globals; Globals.bas
Startup="(None)"
ExeName32="MUSHclient_bar.exe"
Command32=""
Name="MUSHclient_bar"
HelpContextID="0"
CompatibleMode="0"
CompatibleEXE32="MUSHclient_bar.exe"
MajorVer=1
MinorVer=0
RevisionVer=0
AutoIncrementVer=0
ServerSupportFiles=0
VersionCompanyName="Gammon Software Solutions"
CompilationType=0
OptimizationType=0
FavorPentiumPro(tm)=0
CodeViewDebugInfo=0
NoAliasing=0
BoundsCheck=0
OverflowCheck=0
FlPointCheck=0
FDIVCheck=0
UnroundedFP=0
StartMode=1
Unattended=0
Retained=0
ThreadPerObject=0
MaxNumberOfThreads=1



Next, the "bar" class that is called from MUSHclient.

Bar.cls



VERSION 1.0 CLASS
BEGIN
  MultiUse = 0   'False
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "Bar"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True

Option Explicit

Sub SetHP(value As Integer)
  If value < 0 Then value = 0
  Gauge.HPbar.value = value
End Sub
Sub SetMaxHP(value As Integer)
  Gauge.HPbar.Max = value
End Sub
Sub SetMove(value As Integer)
  If value < 0 Then value = 0
  Gauge.Movebar.value = value
End Sub
Sub SetMaxMove(value As Integer)
  Gauge.Movebar.Max = value
End Sub
Sub SetMana(value As Integer)
  If value < 0 Then value = 0
  Gauge.Manabar.value = value
End Sub
Sub SetMaxMana(value As Integer)
  Gauge.Manabar.Max = value
End Sub
Sub SetPosition(X As Integer, Y As Integer)
  Gauge.Left = X
  Gauge.Top = Y
End Sub
Sub SetWidth(width As Integer)
  Gauge.width = width
End Sub
'
' remember calling world in case they close the bar window
'
Sub SetTitle(callingworld As Object, title As String)
  Gauge.Caption = title
  Set theworld = callingworld
End Sub
Function GetX()
  GetX = Gauge.Left
End Function
Function GetY()
  GetY = Gauge.Top
End Function
Function GetWidth()
  GetWidth = Gauge.width
End Function

Private Sub Class_Initialize()
  Gauge.Show
End Sub

Private Sub Class_Terminate()
  End
End Sub



Next, the form that you actually see with 3 progress bars on it...

Gauge.frm



VERSION 5.00
Object = "{6B7E6392-850A-101B-AFC0-4210102A8DA7}#1.3#0"; "COMCTL32.OCX"
Begin VB.Form Gauge 
   Caption         =   "Health Bar"
   ClientHeight    =   870
   ClientLeft      =   60
   ClientTop       =   345
   ClientWidth     =   9090
   LinkTopic       =   "Form1"
   ScaleHeight     =   870
   ScaleWidth      =   9090
   StartUpPosition =   3  'Windows Default
   Begin ComctlLib.ProgressBar HPbar 
      Height          =   255
      Left            =   720
      TabIndex        =   0
      Top             =   0
      Width           =   8295
      _ExtentX        =   14631
      _ExtentY        =   450
      _Version        =   327682
      Appearance      =   1
   End
   Begin ComctlLib.ProgressBar Movebar 
      Height          =   255
      Left            =   720
      TabIndex        =   2
      Top             =   600
      Width           =   8295
      _ExtentX        =   14631
      _ExtentY        =   450
      _Version        =   327682
      Appearance      =   1
   End
   Begin ComctlLib.ProgressBar Manabar 
      Height          =   255
      Left            =   720
      TabIndex        =   1
      Top             =   300
      Width           =   8295
      _ExtentX        =   14631
      _ExtentY        =   450
      _Version        =   327682
      Appearance      =   1
   End
   Begin VB.Label movement 
      Alignment       =   1  'Right Justify
      Caption         =   "Move"
      Height          =   255
      Left            =   0
      TabIndex        =   5
      Top             =   600
      Width           =   615
   End
   Begin VB.Label mana 
      Alignment       =   1  'Right Justify
      Caption         =   "Mana"
      Height          =   255
      Left            =   0
      TabIndex        =   4
      Top             =   300
      Width           =   615
   End
   Begin VB.Label HP 
      Alignment       =   1  'Right Justify
      Caption         =   "HP"
      Height          =   255
      Left            =   0
      TabIndex        =   3
      Top             =   0
      Width           =   615
   End
End
Attribute VB_Name = "Gauge"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

Private Sub Form_Resize()
  HPbar.width = width - 900
  Manabar.width = width - 900
  Movebar.width = width - 900
End Sub

Private Sub Form_Unload(Cancel As Integer)
 
  If Not IsEmpty(theworld) Then
    If Not theworld Is Nothing Then
      theworld.ColourNote "white", "red", "Health Bar has been closed"
      theworld.CallPlugin "4637b3ca32d84f4b5ea6743b", "barclosed", ""
    End If
  End If

End Sub





Finally a file with a single global variable in it.

Globals.bas



Attribute VB_Name = "Globals"
Public theworld As world




Save these 4 files to disk under the indicated names, and open the MUSHclient_bar.vbp file in Visual Basic, and then compile.

All of the above files - the plugin, the 4 files, and the compiled executable - are in the file:


http://www.gammon.com.au/mushclient/HealthBar.zip


What you could try to do is:

  • Get the above zip file
  • Put the plugin (Super_Health_Bar.xml) in your plugins directory
  • Execute the program (MUSHclient_bar.exe) - this will hopefully "register" it with Windows
  • Install the plugin into MUSHclient
  • Connect to your world - with luck, the health bar will appear




Features

The health bar displays 3 progress bars - health, mana, movement.

You can resize it and the progress bars will resize accordingly. The plugin will remember the width for next time.

You can move it and the location on the screen will be remembered by the plugin for next time.

You can use a trigger to individually set the HP, Max HP, movement, max movement, mana and max mana.

eg.

SetHP 22
SetMaxHP 100
SetMove 40
SetMaxMove 88
SetMana 1000
SetMaxMana 2000

You can move it and set its width:

SetPosition 500, 8080
SetWidth 1000

You can set the window title and tell it which world is calling it:

SetTitle world, "SMAUG"

You can get the X and Y coordinates, and with:

X = GetX
Y = GetY
width = GetWidth
Amended on Sat 16 Aug 2003 04:08 AM by Nick Gammon
Australia Forum Administrator #1

This is what the health bar looks like:

USA #2
Interesting. Too bad the gauges that VB uses are ugly and a predetermined color. To do anything real impressive you have to build your own control, kind of like with the 'fiddly' toolbars. On the other hand.. It would be fairly simple in the next version, once we have GetFrame, to use my docking idea to position this as though it was really part of the client.

It is fairly simple, you would simply use VB to GetWindowRect() from the Frame and set the top, left, right or bottom to the returned position +1 or -1, depending on where you are docking it. It would require periodic checks to make sure it stays docked on the edge, but that is no big deal.
Amended on Sat 16 Aug 2003 05:47 AM by Shadowfyr
Australia Forum Administrator #3
If you look at this link, it gives, in a rather complicated way, a more powerful progress bar in VB.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dninvb00/html/conserve.asp

However I decided against doing that, at this stage, as I really wanted to illustrate the basic idea, which all the extra stuff about colour drawing would have hidden.

However if you want to incorporate it, and do a more powerful VB program, by all means. :)
Greece #4
I hope that Microsoft site is not about subclassing... Anyway, I have code to make progress bars from simple VB picture controls, which are about 30 lines long. It's really simple, and the results are amazing. I will post some when I get back home... This project sounds interesting.
Greece #5
Would it be easy to zip everything up and put them in a .zip file? This is too tedious :/
Australia Forum Administrator #6
It is there - see near the bottom of my first post here.
#7
If you've got some version of Nero installed on your computer, you can use the LED control from their Wave editor as a progress bar-like control. Using the RedZone and YellowZone properties on it, you can get it tricolour, at least.
#8
Oh, and you might also want to use SetWindowPos to make it always on top, comme ça:

Add to the/a module:

Public Const HWND_TOPMOST = -1
Public Const HWND_NOTOPMOST = -2
Public Const SWP_NOMOVE = &H2
Public Const SWP_NOSIZE = &H1
Public Const SWP_SHOWWINDOW = &H40

Public Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long


And then have buttons or a menu that sets it to always on top or not using:

SetWindowPos Gauge.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE And SWP_NOSIZE And SWP_SHOWWINDOW


and

SetWindowPos Gauge.hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE And SWP_NOSIZE And SWP_SHOWWINDOW


to set and unset the Always on Top-ness respectively.

And maybe have it so it toggles the Title Bar on a double click event.

-Ian
#9
PS: If anyone can get the above title bar thing to work, I'd be most grateful to find out how. For some reason, BorderStyle is read-only at runtime... I could just create two seperate forms, but if anyone else knows a better way...

Thanks,

-Ian
Russia #10
Well, I've got it working in wxPython (with colours and all) but that doesn't help much, does it?
#11
On further testing, I think some of the SWP_ flags conflicted, so I took the former SetWindowPos calls out and did this instead:

Public AOTP as Boolean

Public Sub Form_DblClick()
  If AOTP = False Then
    Dump = SetWindowPos(frmBar.hwnd, HWND_TOPMOST, frmBar.Left / Screen.TwipsPerPixelX, frmBar.Top / Screen.TwipsPerPixelY, frmBar.width / Screen.TwipsPerPixelX, frmBar.Height / Screen.TwipsPerPixelY, SWP_SHOWWINDOW)
    frmBar.Caption = "Status Bar - AOTP"
    AOTP = True
  Else
    Dump = SetWindowPos(frmBar.hwnd, HWND_NOTOPMOST, frmBar.Left / Screen.TwipsPerPixelX, frmBar.Top / Screen.TwipsPerPixelY, frmBar.width / Screen.TwipsPerPixelX, frmBar.Height / Screen.TwipsPerPixelY, SWP_SHOWWINDOW)
    frmBar.Caption = "Status Bar"
    AOTP = False
  End If
End Sub


If you want to make the AOTP variable save, and check it when you start the status bar again, you could save it like the X, Y and size properties, and have a similar bit to the above in the Form_Load sub, assuming that the Class Module loads before the Form.

My bar currently looks like this: [img=http://phenix.rootshell.be/~ian/statusbar.jpg]

(No movement points on our MUD, no sirree!)

-Ian
#12
Any tips on getting this to 'register' with windows? I always get the "Cannot execute..." note.
USA #13
Well Ian, the problem is not conflicts between the setting you are trying to use. You need to "OR" the values not "AND" them. This also avoids the need to specify the 4 coordinates for the position, since 'SWP_NOMOVE OR SWP_NOSIZE' will cause the API to ignore those options.

The reason "And" doesn't work should be obvious:

&H1 = 00000001 'in binary'
&H2 = 00000010
--------------
AND = 00000000

&H1 = 00000001
&H2 = 00000010
--------------
OR = 00000011

As for registering the thing Johnathan.. If you have VB and do a 'Full Compile' it should automatically register. When you merely 'Run' it, the VB IDE creates a temporary registration that only works with the control as it runs in the debugger. I think there should also be an option under the file menu to generate the full DLL or EXE instead.

If you get a pre-compiled version from some one, then an EXE is ironically easier to use, since it apparently self registers when you run it the first time. For DLLs you have to use a RUNDLL32 command, I can't remember what the command line options are though. It is generally better to have the programs creator use the packaging wizard or some similar installer to create setup file that handles all the stuff needed to run it.

NOTE: There is a bug in all versions of VB before .NET.Depending on your system it will either automatically include or tell you it cannot find four automation files it thinks it needs. These are only supposed to be included when designing web based remote access controls, but the packager tries to add them even for basic ActiveX. Just tell it to ignore these files and continue when/if you make a package to distribute to people. ;)
#14
I don't have VB, I downloaded the zip file and put it in my plugins directory, installed the plugin, double clicked the .exe, and it didn't work. I've tried several variations to no avail.
USA #15
Very strange.. It registered properly for me... My guess would be that it needs an administration level access and you are using a normal user account. The bar will apparently install these keys:

--------------

REGEDIT4

[HKEY_CLASSES_ROOT\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}]
@="MUSHclient_bar.Bar"

[HKEY_CLASSES_ROOT\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\ProgID]
@="MUSHclient_bar.Bar"

[HKEY_CLASSES_ROOT\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\LocalServer32]
@="C:\\PROGRAM FILES\\MUSHCLIENT\\WORLDS\\PLUGINS\\MUSHCLIENT_BAR.EXE"

[HKEY_CLASSES_ROOT\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\TypeLib]
@="{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}"

[HKEY_CLASSES_ROOT\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\VERSION]
@="1.0"

[HKEY_CLASSES_ROOT\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\Implemented Categories]

[HKEY_CLASSES_ROOT\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\Implemented Categories\{40FC6ED5-2438-11CF-A3DB-080036F12502}]

[HKEY_CLASSES_ROOT\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\Programmable]

[HKEY_CLASSES_ROOT\MUSHclient_bar.Bar]
@="MUSHclient_bar.Bar"

[HKEY_CLASSES_ROOT\MUSHclient_bar.Bar\Clsid]
@="{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}"

[HKEY_CLASSES_ROOT\TypeLib\{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}]

[HKEY_CLASSES_ROOT\TypeLib\{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}\1.0]
@="MUSHclient_bar"

[HKEY_CLASSES_ROOT\TypeLib\{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}\1.0\FLAGS]
@="0"

[HKEY_CLASSES_ROOT\TypeLib\{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}\1.0\0]

[HKEY_CLASSES_ROOT\TypeLib\{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}\1.0\0\win32]
@="C:\\PROGRAM FILES\\MUSHCLIENT\\WORLDS\\PLUGINS\\MUSHCLIENT_BAR.EXE"

[HKEY_CLASSES_ROOT\TypeLib\{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}\1.0\HELPDIR]
@="C:\\PROGRAM FILES\\MUSHCLIENT\\WORLDS\\PLUGINS"

[HKEY_LOCAL_MACHINE\Software\CLASSES\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}]
@="MUSHclient_bar.Bar"

[HKEY_LOCAL_MACHINE\Software\CLASSES\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\ProgID]
@="MUSHclient_bar.Bar"

[HKEY_LOCAL_MACHINE\Software\CLASSES\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\LocalServer32]
@="C:\\PROGRAM FILES\\MUSHCLIENT\\WORLDS\\PLUGINS\\MUSHCLIENT_BAR.EXE"

[HKEY_LOCAL_MACHINE\Software\CLASSES\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\TypeLib]
@="{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}"

[HKEY_LOCAL_MACHINE\Software\CLASSES\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\VERSION]
@="1.0"

[HKEY_LOCAL_MACHINE\Software\CLASSES\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\Implemented Categories]

[HKEY_LOCAL_MACHINE\Software\CLASSES\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\Implemented Categories\{40FC6ED5-2438-11CF-A3DB-080036F12502}]

[HKEY_LOCAL_MACHINE\Software\CLASSES\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\Programmable]

[HKEY_LOCAL_MACHINE\Software\CLASSES\MUSHclient_bar.Bar]
@="MUSHclient_bar.Bar"

[HKEY_LOCAL_MACHINE\Software\CLASSES\MUSHclient_bar.Bar\Clsid]
@="{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}"

[HKEY_LOCAL_MACHINE\Software\CLASSES\TypeLib\{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}]

[HKEY_LOCAL_MACHINE\Software\CLASSES\TypeLib\{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}\1.0]
@="MUSHclient_bar"

[HKEY_LOCAL_MACHINE\Software\CLASSES\TypeLib\{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}\1.0\FLAGS]
@="0"

[HKEY_LOCAL_MACHINE\Software\CLASSES\TypeLib\{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}\1.0\0]

[HKEY_LOCAL_MACHINE\Software\CLASSES\TypeLib\{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}\1.0\0\win32]
@="C:\\PROGRAM FILES\\MUSHCLIENT\\WORLDS\\PLUGINS\\MUSHCLIENT_BAR.EXE"

[HKEY_LOCAL_MACHINE\Software\CLASSES\TypeLib\{3AF6B063-CF8D-11D7-A78D-0080AD7972EF}\1.0\HELPDIR]
@="C:\\PROGRAM FILES\\MUSHCLIENT\\WORLDS\\PLUGINS"

--------------

Now why if you are able to install other programs on your computer that adds to or changes HKEY_CLASS_ROOT, then I have no idea why this one is causing you problems, but it sounds like the OS is literally refusing to run the program. I assume that would only happen if the program attempted to register and you where in a restricted user account. This is however only a guess, I really haven't a clue if this is why.
Australia Forum Administrator #16
I had a similar problem when I tried running it on a different PC. I can only say that if you have VB and compile it, it should work, as that is how I developed it.

Using the precompiled one may or may not work. I released it in the hope that it would work for some people, as that is better than nothing.

My very first post in this thread says:

Quote:

However I am finding that when attempting to run it on other PCs I get strange behaviour, like missing VB DLLs, and other things. However you may be able to make it work, especially if you have VB installed.


I stand by that comment.
Australia Forum Administrator #17
BTW, this is what annoys me about VB. You should be able to develop an application without having to download megabytes of "supporting files", whatever they are.
#18
I do have admin access, and I manually changed my registry settings to those that you specified, Shadowfyr, and its loading and unloading fine. However, I am getting this:


Error number: -2146828275
Event:        Execution of line 58 column 3
Description:  Type mismatch
Called by:    Function/Sub: OnPluginConnect called by Plugin Super_Health_Bar
Reason: Executing plugin Super_Health_Bar sub OnPluginConnect


It seems to be failing somewhere withing the If barobject is nothing... and the final end if before the end sub. I dunno.
Amended on Sat 29 Nov 2003 11:22 PM by Johnathan Allen
USA #19
Hmm.. As I said in one of my posts Nick. It is better to use the package and deployment wizard to make and installer. If you don't, then you run into anything from missing dlls that are absolutely needed to incorrect versions of ones that are installed, and which thus don't work. It is true that this is one of VBs biggest pains and the reason why they moved to the .NET system. However, then you get stuck having to screw with installation if the .NET dlls, so same issue.

As for the error your getting Johnathan, this is why I hate having no debugger for some languages.. According to my count the line that is causing a problem would be:

barobject.SetTitle world, world.WorldName

which makes absolutely no sense at all....
#20
Indeed, that is the line, when I comment it out, the error goes away.
USA #21
Hmm.. Ok, I see what the problem is... The line should probably be:

barobject.SetTitle getworld(worldname), worldname

This line is supposed to pass an object and a string to the health bar, which sets the object that connects back to Mushclient and the title of the window. I have no idea how or why it works for me, 'world' by itself may be a valid object and seems to work without any apparent issues on mine, but may be failing in some rare cases. The only callbacks seem to appear in the Form_Unload, which activates when someone hits the close button on the form. Due to the way COM works, this kills the form, but doesn't release the object (a problem I have with my firework gadget as well).

It would probably be better if the close button was removed, since all it does is screw things up when used in cases like this. To use it you either need to inform the plugin that it closed, which you can't do with something like mine, where it may be used with something other than Mushclient, or you have to reload the form if some fool closed it. Neither case is all that helpful. In fact, due to the way that Nick's is coded, you can't even use it with a plugin that differs from the one it was designed for, since the callback to inform the plugin that it closed is hard coded to the ID for that plugin. This is one situation where having the script sleep is extremely inconvenient, a much better solution would have been to use an object event sub that would automatically be called when that happened. This is how most programs and script system would handle such things, but since Mushclient puts the script engine to sleep when not using it there is no way to respond to such events. :( Though... I wonder if the event is passed direct to the script or there might be some way for Mushclient to 'catch' the event so it knows to let the script wake up and respond..... With my luck, probably not..
Australia Forum Administrator #22
Quote:

... since Mushclient puts the script engine to sleep when not using it there is no way to respond to such events.


MUSHclient doesn't put the script engine "to sleep" any more than you put your subroutines to sleep when you aren't using them. They are called when they are supposed to be called and when they are not in use they are just sitting there.
USA #23
Hmm. Yes. From some things I have read, the script engine itself (for VBScript and JavaScript) may actually lack the ability to directly respond to events. I am not certain of this though. I do know that when I tried to use the On_SongChange event (or what ever it was called) for the WinAmp COM control, the script was unable to respond to it at all. It appears that clients which this does work in may be intercepting the createobject call and doing something like:

Script - CreatObject("Blah.Blah")
Client - Intercepts and executes its own CreateObject.
Client - Places new object into a control list and passes a reference to the script.
Script - Executes calls on the reference OK.
Event - Triggers the *client's* event handler, which identifies the event and calls the appropriate script.

I have no idea if this is actually the case, but I started nosing around in the articles at the MS news servers that relate specifically to script hosting and one said something to the effect that, "MS scripts are not event driven", which was in response to a near identical problem. I take that to mean that some construct like above is needed to actually handle events, otherwise the controls events are ignored. This is frustrating to say the least, since about 90% of the prebuilt programs that you could attempt to use with Mushclient probably use such events, since they haven't a clue what Mushclient is or what a plugin is. :(

I have been trying to find a way around this issue for a while and I think I am now at a dead end.
USA #24
I think the problem here is a misconception that scripts can do anything and can solve all the world's problems... the fact of the matter is that scripts are simply not all powerful and certainly won't solve all the world's problems. :)

About the events... It's true, if you nose around a bit in the VBA documentation you'll see indeed that the scripts aren't event driven. It's because of a fundamental difference in the way applications and scripts work, which I won't go into.

To have plugins or something respond to an event, you'd most likely need something like what you described, where the program hosting the scripts listens for events, and has a list of what plugins want to know about an event.
USA #25
I didn't think they did solve all the worlds problems, but having seen most of them in IE or other browsers, where they can and do respond to some events, finding that this wasn't a built in feature came as a nasty surprise. ;)
#26
I know it's usually not a good idea to mess around with the registry, but could you explain how to install the necessary keys to get the health bar to work?
Australia Forum Administrator #27
Well, at your own risk, copy what Shadowfyr said, between the hyphens.

Paste into a Notepad window, save as blah.reg.

Start regedit, go to Registry -> Import Registry File.

Select the blah.reg file.

All done!

If we don't hear from you again we'll know it corrupted your computer and you are spending all next week re-installing Window. ;)
#28
Bombs away! :)
#29
Registry survived alright, but I got this crytic error in a red background when I made a connection with the host:

Cannot execute bar display program
Check it is installed.
Australia Forum Administrator #30
That is in the plugin, to display if the CreateObject call fails.

Thus it was not able to find the MUSHclient_bar.Bar COM object. Why, it is hard to say.

However as you have used Shadowfyr's registry entries I would check they match what you have on your system. In particular:

[HKEY_CLASSES_ROOT\CLSID\{3AF6B065-CF8D-11D7-A78D-0080AD7972EF}\LocalServer32]
@="C:\\PROGRAM FILES\\MUSHCLIENT\\WORLDS\\PLUGINS\\MUSHCLIENT_BAR.EXE"


Does that path actually contain that file?
Amended on Tue 10 Feb 2004 03:11 AM by Nick Gammon
#31
It appears that all the keys are there. Am i going to end up needing a VB compiler after all?
Australia Forum Administrator #32
I was asking about the file that the key refers to, not the key itself.
#33
Fixed the problem: Whne I installed MUSH 3.42, I wanted to keep my old version so I called the new one mushclient342. When I created a plugins folder and put the bar.exe file, it compiled.

However, I'm having trouble getting it to customize- when I copy/paste the same trigger I want from the standard health bar plugin, the super bar still isn't responding- all 3 fields remain blank.
#34
nevermind, trigger was wrong.

Thanks for all the help guys!!
USA #35
I'd like to do something like this but with gossip/ooc channels. Using a window that can scroll and be placed always on top that way I can simply focus on the mud rather than what other people are saying. I've posted idea's about having output windows coded into mushclient in the past. This is very similar to what I'd like mushclient to do.
Greece #36
I have created a plugin to do that, it's an external window you can add colored text to, etc... It's posted somewhere in the forums.
Portugal #37
im considering to use this idea to build a sort of "external info bar" mainly to check up settings without spam myself to dead with world.notes...

what i wanted to know is if it is possible to "link" this window to the MUSHclient window, so when i minimize the MC window the "info window" would also minimize, and when i restore MC it would restore my window too.

thank you in advance
USA #38
Well.. Not really. There is no event trapping in Mushclient itself that lets you tell when/if it is minimized and the only other way requires trapping system events, which can, if done wrong, cause lethal results to the OS. In either case you would need to add functions to the bar that hide it when either the bar itself detected the change (with system event traps) or the script told it too (which would require Mushclient to tell the script something happened). You may be able to fake it using existing lose and gain focus functions that Mushclient does provide, but that would mean that merely switching to a seperate window would hide it. That may be OK in this case, but I can imagine some other tools where that is definitely not the right behaviour. However, using those functions still requires changes to the bar itself so you can tell it to hide/unhide. Hiding a window requires access to some commands in the User32.dll API, which is not an ActiveX object or something scripts allow access to normally. Python 'may' be able to, but not any of the other and then not without at least as much effort and redesigning the bar in the first place.

So yes, it is possible, just not exactly with the existing bars features..