Adding window with info about character

Posted by Zuurstof on Fri 20 Feb 2004 12:30 PM — 25 posts, 94,065 views.

#0
Hello

I would like to try and create the following, I have no idea if it's possible though. But at my mud all the info about your character is in different commands.
vb:

score:
Draven of Cuiviénen the silvan Highlord (Bane of Angband)
HP: 230/230 END: 221/230 Exp: 2100188 Avg. Stats: 100
Strength: 100 Agility: 100 Charisma: 100
Constitution: 100 Coordination: 100 Intelligence: 100
Level 20 warrior, 24d 6h 57m 36s old.

skills:
Common Skills:
Aim : 100 Attack : 100 Awareness : 100
Defense : 100 Dodge : 100
Fire building : 100
Riding : 100

Professional Skills: Other Skills:
Blind fighting : 100 Deception : 60
Blocking : 100 Disguise : 2
Combat arms : 100 Wilderness : 60
Tactics : 100

Languages:
You are 100% fluent in variag.
You are 100% fluent in adunaic.
You speak khuzdul very well.
You are 100% fluent in sindarin.
You can speak easterling a little bit.
You speak black passably.
You are 100% fluent in westron.
You are 100% fluent in rohirric.
You are 100% fluent in orcish.
You are 100% fluent in silvan.


Now it would be nice to create an extra little window inside mushclient that constantly shows and updates this data.

I was thinking about writing a dll and calling it from mushclient. filling the new window with the data send by mushclient somehow. I have no real idea how to do this though, and if it's even possible. The same idea goes when trying to create an extra window to show your equipment.
With extra window I mean a window created in vb or something that I call from mushclient. So the new window will be only visible when mushclient is not minimised.

I'm not sure if anybody understand what I mean, but I hope so. Let me know if you think you know how to do this.

Greetings Zuurstof

#1
Hmm, well I discovered how to call a dll, give a msgbox and show a form, the only problem with that is that the form has to be modal, which would make me unable to type anything while the form from my dll is open. Can't I make it a mdi-child form of the application somehow. I guessing no, but maybe somebody out there knows a solution.
USA #2
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.
Amended on Fri 20 Feb 2004 08:25 PM by Shadowfyr
USA #3
Oh.. BTW. Three things to remember.

1. Make sure that the class is set to allow multi-use.

2. Always use the File menus option to create the complete DLL or EXE and use Mushclient itself to test the result. Using Run means it will not create either a permanent file or a permanent Registry entry, so you can't use it 'except' in the VB editor.

3. Exe is generally better, since one feature of VB ActiveX Exe files is that you can usually run them like a normal program the first time in order to make them available to the user.

This means that you can send someone a copy of the file, without an installer and they can just double-click the program, then immediately start using it. In theory you could even make you script do:

on error resume
set a = createobject("MyWindow.NewWindow")
on error goto 0
if typename(a) <> "MyWindow" then
... 'Add code to run the Exe or here.
end if

I am not sure about the 'type' returned. I believe it will be the name of your object. For instance the Winamp COM control gadget shows: IApplication when typename is used.

You may be able to use Rundll32.exe this way as well to register a DLL file. I haven't actually tried this, but it *should* work in theory and doesn't require the guy installing the plugin to do anything with the EXE or DLL except unzip the files into the plugins directory set their world to load the plugin.
Australia Forum Administrator #4
I was going to suggest capturing the output and sending to a notepad window, but a separate program would probably be neater, if a lot more work. :)
#5
Thanks for the quick reply, I've understand most of your messages. It's still a bit fuzzy but i'll probably get it when i'm programming it. Anyways I still have a couple of questions though.

1:
You say: As of 3.43 and 3.44 you can now request a handle for Mushclient's main window.

I only have version 3.42, and I can't find the versions you are talking about on the website. Is the explanation you give based on these newers version??


2:
1. Make sure that the class is set to allow multi-use.
What you mean with this?:)

3:
I still haven't really heared how I would show the form.
Cuz now I have the following code:

Project name: Arda
Class name: cMain

class code:
Public Sub setParameters()

MsgBox "test"
frm.Show vbModal
End Sub

in script:
Sub start(thename, theoutput, thewildcards)
set obj = createobject("Arda.cMain")
obj.setParameters
End Sub


Now this creates the object, and shows the messagebox alright. Then it shows the form, but it's modal. So I can't type anywhere. If you know another way of calling the form without it being modal and it will work in mushclient, that would solve a lot of my problems. Mushclient should be the parent of an mdi-child I show. Well that's the same principle at least..

Greetings
Zuurstof



USA #6
3.44 Can be found here...

http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=3772&page=1

Nick tends to release new versions, and then only once stable, etc post it on the main site.
USA #7
1. These are new versions just released. Maybe the links are not updated yet. Check this thread:

http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=3772&page=999999

Included in 3.43 (which was buggy) was a new command 'world.GetFrame' that returns a handle to Mushclient's main frame. 3.44 also has it of course. The only other way to get the handle is to do:

In the .BAS module:

Declare Function EnumWindows Lib "user32" _
 (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
Declare Function GetWindowText Lib "user32" _
 Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, _
 ByVal ccs As Long) As Long
Declare Function GetWindowTextLength Lib "user32" _
 Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long

dim DockWindow = "MUSHClient"

Public Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) _
  As Boolean
  Dim sSave As String, Ret As Long
  Ret = GetWindowTextLength(hwnd)
  sSave = Space(Ret)
  GetWindowText hwnd, sSave, Ret + 1
  If InStr(sSave, DockWindow) Then
    Winhndl = hwnd
    EnumWindowProc = False
  End If
  EnumWindowsProc = True
End Function

In your main code:
EnumWindows AddressOf EnumWindowsProc, ByVal 0&


This is what I used for a gadget that produces a firework display, in order to let me find the Mushclient window and resize the fireworks to fit snuggly next to it. Now if I where to recode the program, I would use the GetFrame technique instead, since it is a lot easier to have Mushclient tell me what the internal ID for its window is than to use all the above API junk to find it myself. Basically, the above code has to look through *every* window that has the system Desktop as a parent. That is all open programs, all system tasks, all tray icon based applications, etc., just to find the Mushclient window.

If you used it with a program whos title bar contained changing text or you could open multiple copies, forget even trying. Imagine for instance three copies of Notepad open. The above code only finds the 'first' one. You could maybe adjust it to find all of them, but then which one is the *right* one? I pestered Nick for a while about this before he caved and provided a better way. ;)

2. Actually I meant the project. There are several settings you can employ:

a. Multiple copies used by several different programs. This is the one you want. In think it is also the default.

b. A single copy of the object, but usable by more than one program. This is like most system services or databases, but is more complicated to manage, since you have to directly keep track of how many applications are connected, since the object cannot be destroyed until 'all' programs release it. If you do it like (a), then the first program to release a connection would destroy the object and every other program that thought it still existed would crash.

c. One instance, one use. I think... Only one program can use it at a time. This is probably for DLLs that are used by only your own programs. The expectation is that only one copy of your program will be running and that the DLL will not be used by anything except that program.

At least I think that is the options available. I am not 100% sure about (c) and there may be a fourth option as well.

3. Umm.. Why exactly are you using vbModal?? Just use 'frm.Show' without any other parameter. It defaults automatically to non-Modal. The only time 'anyone' uses the vbModal flag is in critical system applications that must 'lock' the machine until completed. It is bad practice to use it in your own programs, unless you absolutely need it. Even then, I think it is only Modal to the 'parent', though I am not positive. You may be able to make child windows Modal and not effect the OS, but in this case you are making the Top-Level window (the one whos only parent is the system Desktop) Modal and that locks all other programs, except the Taskmanager and 'maybe' system service applications. Best bet is just don't use vbModal. ;)

---

Oh, BTW. I just realized SetForegroundWindow is also an API call. You need to declare it in the .BAS module with the rest like:

Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Imho these things should all be built into VB, but like most MS products, they simplified the language to the point where even *basic* things you can do in pretty much any other language are unavailable to VB programmers. Bloody stupid.

The one that annoys me the most is that all controls (like buttons and stuff) have by default a 'design-time' mode. This is the same thing you see when building a form. The control lets you use the mouse to move them, resize them and you can change some settings like mutli-line in textboxes. If you code in C++ this mode is available to you in your own programs. In VB these functions are completely disabled at run-time, so you can't use/change them at all. But then who would want to design a VB application that let you design or change the layout of a form? **Me, you bloody idiots!!!!** lol
Amended on Mon 23 Feb 2004 12:08 AM by Nick Gammon
Greece #8
You could use drag-and-drop to set the control position on the form...
USA #9
Yes. You can 'fake' design time control, within limits. However, in the case of a textbox, you have to impliment both the multi-line and single-line version and then hide one and make the other visible to 'fake' it. Same with any other controls that have options that are only evailable in design time. Nothing like wasting memory on 20 object you are never going to use, just because you can't change one minor setting at runtime. With C++ you can simply switch the entire form into desing mode by changing the UserMode attribute and alter anything you want. If you want to be able to resize the control with the mouse, then you have to create fake drag box that fits over it, with control points and impliment a rediculous mess of code to resize the real control based on the fake drag box. This is imho rediculously complicated and stupidly redundant when all existing controls already impliment functions to do this already.

The form designer in VB and other programs don't impliment these things, they are *built-in* to the function of the controls themselves, so they know how to drag and drop, resize, etc. when in the correct user mode. A form designer is little more than a program that shows a form, provides a mess of options to add existing objects, links those things to the control array in the form you are using and lets you switch the whole thing in and out of design mode. If VB supported design mode at runtime, you could code an entire form designer in probably 100-200 lines of code. Instead they disable the ability to even use controls or forms in that mode and short of using 4-5 times as many lines of code in C++ to build a COM control that allows it, you have to spend 4-5 times as much code to fake 50% of the function that such a designer allows.

Its just another one of those 'features' of VB that make it inconvenient to design programs that actually work as well as something written in any other language.
Greece #10
Isn't it possible to get the control to think it's in design mode? Maybe you couldn't change it back and forth though... Yeah, it's stupid if the controls already have the functionality :/
USA #11
It is possible with a single line of code, *in C++*, but VB doesn't provide access to that function. It may be possible through an API call or some other indirect means, but I have lost track of the one example I saw that used it. Six hours of Googling yesterday failed to rediscover the article. :( I plan to keep looking though. It may be possible to impliment the option in a DLL written in C++ and use that class to manipulate the objects. However, at the moment it is only a working theory.

I am also trying to find out how IE impliments its feature for doing:

<OBJECT ID="Grid1" WIDTH=100 HEIGHT=51
 CLASSID="CLSID:A8C3B720-0B5A-101B-B22E-00AA0037B2FC">
    <PARAM NAME="_Version" VALUE="65536">
    <PARAM NAME="_ExtentX" VALUE="2646">
    <PARAM NAME="_ExtentY" VALUE="1323">
    <PARAM NAME="_StockProps" VALUE="77">
    <PARAM NAME="BackColor" VALUE="16777215">
</OBJECT>

I don't need the overhead of imbedded IE, which expects events from such controls to be handled by script anyway. I just need it, so I can add generic controls into a form within an XML definition file, so you can load a custom window with something like:

set a = createobject("MC_Companion.NewWindow")
a.loadform "forms\ObjectBrowser.xml"

of something of the sort.

There are roughly 232 such controls on my computer. Some of them are tied to other programs like 3D Canvas or RealPlayer, but even if you ignore all the ones that don't appear on everyone's machine, you still end up with at least 150 or more. It is real stupid to have to waste resources by pre-linking all these things into your program, just so they are available when you need them. Some people may also design their own controls to do some special thing and then what? They can't 'ever' use it in your program.

What I needed is a way to edit the layout in design time mode, then export the result to XML and reload it later. Finding an example of this that isn't precompiled and proprietary is proving very frustrating. :(
Australia Forum Administrator #12
Quote:

Nick tends to release new versions, and then only once stable, etc post it on the main site.


Does anyone who has been using version 3.44 had any problems with it, or can it become the official release?
USA #13
No problems I have found.
#14
Well I still have the same problem. I'm not sure if anybody tried this or not but I try to open a form from my dll and it's non-modal then it just will crash.


error nr: -2146827882
error:
Non-modal forms cannot be displayed in this host application from an ActiveX DLL, ActiveX Control, or Property Page.


I can create a seperate program and send the data there I guess, but I want to screen to be inside mushclient. So that mushclient is a parent to my screen, if that is at all possible. If somebody could give a real simple example of how I can open a form(non-modal) from within a dll that is called from muchclient vbscript that would solve all my problems. I know how to ship data to it, I just can't open a form.


ps:

this code produced the error

project: Arda
class: cMain
Public Sub setParameters()
frm.Show
End Sub


vbscript in mushclient:
Sub start(thename, theoutput, thewildcards)
set obj = createobject("Arda.cMain")
obj.setParameters
End Sub


I have an alias that calls sub Start and that's it.
Let me know if you need any more information




Btw thanks for all the quick replies!

Greetings Zuurstof.
#15
I have had some problems, namely if I change my target I sometimes got a message telling me that PCRE doesnt support a certain character (or something sound like that, I press enter right after I change my target which remove the error message and I cant reproduce the error).

But still, with PartialLine plugin and the other upgrades, it rocks !
#16
The message is :

Failed : PCRE does not support \L, \I,\N, \P, \p,\U,\u or \X at offset 2
#17
Well I did some looking around, now I use this workaround to open the form. It seems it's some kind of bug.

now I use an api call to open the form and that works

Declare Function ShowWindow& Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long)

in the class

Load frm
lres = ShowWindow(frm.hwnd, SW_SHOWNORMAL)

Then I use another api to make sure it remains on the top all of the time. Now it's just matter of figuring out how I can handle lostfocus events from the client to make sure my window dissapears when somebody goes to another application and that is reappears when mushclient gets the focus again.

Thanks for all your help people!

Greetings Zuurstof
USA #18
Hmm. Ok. I think I see your problem... I had a similar crash trying to get around this limitation when fiddling with Python. A non-modal window *must* have a parent. The problem is your DLL does not have a 'main' window. Don't ask me why it isn't considered a main window, but it isn't. Thus when you attempt to open the window from the script, there is no primary window for it to identify as a parent and it crashes with an error.

Now, two prossible solutions: Use an EXE instead of a DLL, so that your main form becomes the primary window. This may still be possible with a DLL, but I haven't a clue why it won't work. This won't place it *inside* Mushclient, but I am confused as to why it needs to be. My fireworks gadget uses this method and works perfectly, it also automatically closes the moment you close mushclient or you directly destroy the scripts instance of the object.

Second option: *Before* creating the window, use world.GetFrame to send Mushclient's main window handle to your DLL and then when you create the form, set its parent to this handle, *then* show it. I have no idea if this will actually work or not, but that would make it a true child of Mushclient's primary window. This may be a really bad idea though, which is why I haven't attempted it. The results could be unpredictable and could generate a crash when you attempt to close Mushclient. On the other hand, it could turn out to work perfectly, which would open up the ability to use the wxPython extensions to do a mess of stuff that currently won't work at all in that script language, unless it runs in the Python GUI, instead of the scripting engine.

The fact of the matter is that VBScript, JavaScript, etc. *are not designed* to create instances of new windows inside the client running them. The reason for this is very simple, they don't have access to that client's address space, objects, windows or anything else. The only access they have to the program they are running in is through the calls that the client itself 'links' into the script engine when it starts. Programs like IE or Word, that do allow such things use their own methods to create the objects and their own methods to link the events and other features of that window or control into the engine, so that the script becomes aware of them.

What you are trying to do is get the script to create and object and suddenly have the client know that it exists and belongs to the client. Even if you managed to attach the new window to the client, it probably won't have a clue that this window belongs to it, what to do with it if something goes wrong or how to properly handle any messages related to it. The only way to do this is if a method existing like I mentioned earlier in this thread (for IE) that lets the client create the object and merely provides the script with the needed calls and references to use it. Any object created *by* the script itself *must* provide its own container (primary window) to display controls, including child windows.
Russia #19
"Second option: *Before* creating the window, use world.GetFrame to send Mushclient's main window handle to your DLL and then when you create the form, set its parent to this handle, *then* show it. I have no idea if this will actually work or not, but that would make it a true child of Mushclient's primary window. This may be a really bad idea though, which is why I haven't attempted it. The results could be unpredictable and could generate a crash when you attempt to close Mushclient. On the other hand, it could turn out to work perfectly, which would open up the ability to use the wxPython extensions to do a mess of stuff that currently won't work at all in that script language, unless it runs in the Python GUI, instead of the scripting engine.
"

I tried that with wxPython (well, using a LocalServer component instead of an Inproc DLL) and it didn't do much aside from causing type errors. Perhaps some sort of a cast is needed to get an appropriate object using the result of world.GetFrame. However, as I have a very faint idea of what exactly it is that world.GetFrame returns, and docking windows isn't among my priorities right now, I decided to let it rest. I find creating stand-alone toplevel applications in wxPython to be easier than trying to fit an extra process into Mushclient, and it's a pretty safe way of doing things too if not for a couple of problems. One is with wxPython's threading problem - needs to run in the main thread, which is impossible since COM needs to reside there, but a solution to this must exist. I've managed to get it to the point of being able to shut down and relaunch the application several times in a row without a single crash, though it still crashes sometimes. Another problem is getting the messages through to Mushclient from your stand-alone. Using callbacks provides a solution, but it is a very limited one. Another solution might be COM events, through pythoncom's DispatchWithEvents method, which lets you specify an event handling class in the script that launches the application and pass that class to the application when it is launched. However, the problem with that is the same as above - I don't know how events work in COM and haven't had the time to dig up anything substantial on the matter yet. Still, I remain convinced that wxPython is the best solution to the problem of spawning windows for Mushclient.
USA #20
If you have Spy++ some place (It comes with VC++), then the 'handle' returned by GetFrame will appear in the list of windows like this:

--------vvvvvvvv--------
Window 0000063A "MUSHclient - [Some Mud Name [Closed]]" Afx:400000:8:14B6:0:6337

The first Hex number is the handle from GetFrame, the second part is obviously the title bar text and the last is a class name:

Afx - Referes to the Afx base class I think, all windows share this.
400000 - The instance of this window.
8:14B6:0:6337 - I have no idea, but 14B6 is always the number for Mushclient and 6337 may be somehow related to it being a child of Desktop. I can't remember what I read about it some place.

Anyway.. Handles to objects are 32-bit integers, so the value returned by things like FindWindow or Object.hwnd is the same identical number that GetFrame returns, or should be anyway. I checked the number shown using 'note hex(GetFrame)' against the value returned by Spy++ for the main window. This is not a direct object reference though, so the program may simply refuse to take the integer value and treat it as a valid reference, which would be really inconvenient. Also, Python may instead be seeing a variant and expecting a 32-bit integer (Long for VB, Int for C++). I have no idea.

In theory the number is correct. The issue is if you can convince the damn programs to use it.
Amended on Tue 24 Feb 2004 06:33 AM by Shadowfyr
Australia Forum Administrator #21
It is an HWND (window handle). I doubt it is a COM object.
USA #22
Which is what I said Nick. Apparently Python is somehow refusing to treat it as a valid hWnd though or something. Either that or the command he tried to use expected something else. Some of these languages are pickier than others about the 'type'. For instance.. Since it is passed to Python as a variant type, it needs to convert it into a known Python type. If the value is under the maximum for a 16-bit integer is may be seeing it as a 16-bit integer and failing because the calls that use an hWnd 'require' a 32-bit integer (Long type in VB and maybe Python).
Amended on Tue 24 Feb 2004 04:39 PM by Shadowfyr
Australia Forum Administrator #23
Quote:

The message is :

Failed : PCRE does not support \L, \I,\N, \P, \p,\U,\u or \X at offset 2


Er, is this my bug or yours? Sounds like an escape sequence has made its way into the regular expression, (eg. \L).

Have you in fact put one there, or is "offset 2" a variable being expanded (eg. @target ...).

If so, perhaps the variable expansion should be escaping them.
Russia #24
Actually I tried passing GetFrame result to a frame (wxMiniFrame) object as a parent argument. I didn't check the type on this result, but I'll do that as soon as I get back to my computer whcih has all the needed stuff installed.