Yeah. I know exactly what you mean. Basically, the best bet is a plugin that calls the dll. You would do something like this:
1. Make new AvtiveX Exe or Dll project - MyWindow
2. Add a Richtext control to the main form.
3. Add a class module NewWindow, this will be what you 'create' with createobject("MyWindow.NewWindow").
4. Add a .BAS file (Module), add the API call code for retrieving the window size and some other stuff from a handle to this module. It must be in a regular module to work:
Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Declare Function SetWindowPos Lib "user32" (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
Public Const HWND_TOPMOST = -1
Public Const HWND_NOTTOPMOST = -2
Public Const SWP_NOACTIVATE = &H10
Public Const SWP_NOSIZE = &H1
Public Const SWP_NOMOVE = &H2
Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
GetWindowRect is used to get the current size of the Mushclient window. As of 3.43 and 3.44 you can now request a handle for Mushclient's main window. There are also callbacks from plugins that identify when the world has gained or lost focus. To detect if Mushclient has minimized all you do is check the size of the main Mushclient window, since it should then be something like 0,0,0,0. So basically your plugin would do:
set Mywindow = createobject("MyWindow.NewWindow")
sub OnPluginLoseFocus
Mywindow.CheckSize(GetFrame)
end sub
sub OnPluginGetFocus
Mywindow.CheckSize(GetFrame)
end sub
Then in your VB program you would do (in the class module):
sub CheckSize (hwnd AS long)
dim TRect as RECT
GetWindowRect hwnd, TRect
if TRect.Left = 0 and TRect.Right = 0 then
MyWindowFrm.windowstate = 1
else
MyWindowFrm.windowstate = 0
SetForegroundWindow hwnd 'Return control to Mushclient.
end if
end sub
Note: I may have the window state backwards there..
SetWindowPos is used to make it always-on-top, you would use: HWND_TOPMOST along with 'SWP_NOACTIVATE OR SWP_NOSIZE OR SWP_NOMOVE' to make it on top, but not change any other settings. This means that if minimized it will remain so and you can use 0,0,0,0 for the X,Y,Cx,Cy values. If you left off the flags, it would resize the window to those values and give it focus.
You can also use the command (note I added it above too):
SetForegroundWindow hwnd
to return the focus to Mushclient (in the class module):
sub Return_Focus (hwnd AS LONG)
SetForegroundWindow hwnd
end sub
There is unfortunately no way to do this when the class is initialized, since even if you linked the mushclient.tbl file into the project, it has no connection to the world file until *after* the object already exists. Unless you want to send stuff to the mud from the project, it is just as easy to pass the window handle from the plugin each time, instead of using the linked .tbl file to ask for it internally to your project. In theory you could, once you have the handle the first time, save it in a global variable and reuse it (placed in the same .BAS module as the API declarations). This may or may not fail in some cases, so it is safer to make sure you have the right handle each time you need it.
However, other values you may need global are best placed in that same .BAS module, since that way 'all' parts of the program can use them. ;)
4. Finally, add in some code to display your text. Since you used a RichText control, you could in theory take appart the entire captured line and rebuild it in the output. Or you can do it the easy way and just paste more text into the window.
It may also be a good idea to add code to check if you intentionally minimized the window and leave it that way, since any time you leave the Mushclient window for 'any' reason it will cause a LoseFocus event and then a GetFocus when returning. If you intentionally minimized the window, then it will immediately pop back up as soon as this happens using the simple code above.
Anyway.. This is the basics. Anything accessible to the plugin needs to be part of the class module. Attributes (things you set or retrieve with Mywindow.value = 0 and the like) use Property Let and Property Get to make them accessable. This should hopefully give you a good start.
---
Heh Nick.
My only real complaint now is that dragging the Mushclient window smaller or larger still doesn't create an event that can be trapped, so if you want a window that resizes with Mushclient, you still have to periodically get the window rectangle and check to see if it changed from the prior time you checked. Something like an OnPluginFrameResize event (and the same main world event) would be quite a bit nicer. The only alternative is a nasty trick for trapping window events (by inserting a filter into the OS) and if you screw that up in any way it will freeze the computer. :(
It may be useful to have WorldResize events too, since you way change the number of available columns that a script can use for output and their is no existing way for the script to know this. You need both events though, since the Frame could change without effecting the size of the world and the other way round. |