Mr. Cluey
: How To ...? : Unique WindowsFor simple operations, you can use an order modifier to keep track of which is which. For example, if you have two notepad sessions running, you can use *Notepad[1] to refer to the one on top and *Notepad[2] to refer to the one underneith. Unfortunately, this isn't all that helpful - because when you set 2 to be active, it suddenly becomes number 1. Oops. If you are going to be switching back and forth between two windows, you need to create smarter windows, that can remember who they are when you move them around on the screen.
This is the way that I did it.
const NON_EXISTANT_TAG = Desktop.WndTag + "[2]" ;
winclass CUniqueWin : MainWin
{
tag this.MyTag() ;
string sCmdLine ;
integer MyAppId ;
WNDTAG MyGenericTag ;
WNDTAG MyTag ()
{
window w ;
WNDTAG wtag = NON_EXISTANT_TAG ;
for each w in Desktop.GetChildren()
{
if w.GetAppId() == this.MyAppId
{
wtag = w.WndTag ;
break ;
}
}
return (wtag) ;
}
Invoke ()
{
this.InvokeNewInstance () ;
this.MyAppId = Desktop.GetActive().GetAppId () ;
}
InvokeNewInstance ()
{
integer NewId=0 ;
window w ;
boolean bWindowExists = true ;
while bWindowExists
{
NewId++ ;
w = MainWin(this.MyGenericTag+"[{NewId}]") ;
bWindowExists = w.Exists() ;
}
w.Start( this.sCmdLine ) ;
}
}
You can never inherit a CUniqueWin that is already running, you have to invoke a new one for yourself. Each time a new one is invoked, it grabs the AppID and saves it away. When you request the tag (be it directly or indirectly), the window searches through the entire list of windows on the Desktop, looking for the one with the matching App ID.
The NON_EXISTANT_TAG constant is used to ensure that, if there are no windows with the correct AppId in the list, the result is a non-existant window, rather than a bad tag. I had hoped that I could use a truly impossible tag, like "#0", but partner helpfully (!) prevents you from doing that. You can customize your own non tag, but I figure that most people are only going to have one desktop at any given time....
Here's an example of the code in action, using a CUniqueNotepad class that is derived from the CUniqueWin class
winclass CUniqueNotepad : CUniqueWin
{
WNDTAG MyGenericTag = "*Notepad" ;
string sCmdLine = "notepad" ;
}
main ()
{
print ( Desktop.WndTag ) ;
window A = CUniqueNotepad() ;
window B = CUniqueNotepad() ;
window w ;
for each w in { A,B}
{
w.Invoke() ;
print (w.Exists() ) ;
}
A.Close () ;
for each w in { A,B}
{
print (w.Exists() ) ;
}
B.Close () ;
}
This was put together off the cuff. Really, the MyGenericTag of your class should be an window id using the application name. Of course, you could write declarations for A and B rather than working with them on the fly, and if the CUniqueNotepad class is too much of a bother you can declare the windows as CUniqueWin and move the customizations into the declaration itself.
If you already have a non Unique version of the window declared, you can reference the sCmdLine from that directly, and use the WndTag of the non unique version everyplace you see this.MyGenericTag, which makes for much less of a maintenance headache.
| Mr. Cluey : How To ...? : Unique Windows |