WinBatch® Technical Support Forum

All Things WinBatch => WinBatch => Topic started by: stevengraff on April 06, 2014, 11:11:20 AM

Title: WinIdGet - returns consistent pattern?
Post by: stevengraff on April 06, 2014, 11:11:20 AM
I'm trying to come up with a good way of producing unique trace log files for each of multiple instances of my script. I suppose I could just use a random number, but I've been looking at WinIdGet as well.

I notice that X=WinIdGet("") returns something like "#WIN$ID#02374D18" and I'm wondering if the pattern of the returned data is consistent enough to reliably use something like:

uid = winidget("")
uid = itemExtract( 3, uid, "#" )

tracefile = path : "goldsmstrace.log"
if fileExist( tracefile )
   tracefile = strReplace( tracefile, ".", "%uid%." )
   debugTrace(10 , fileRoot(tracefile) )
Endif

Title: Re: WinIdGet - returns consistent pattern?
Post by: snowsnowsnow on April 06, 2014, 11:33:10 AM
1) Instead of a "random" number,  you could just use a sequential number.  This would be the safest, albeit unglamorous, method.

2) Back to the subject of WinBatch "window ids": I think they are meant to be "opaque" - that is, you're not supposed to look at them, you are just supposed to use them.  That said, it is clear that they do follow a format, and it is pretty obvious what that format is.  I think it might even be documented somewhere, but I'm not sure about that.

Anyway, the format is obviously fixed up through the second #.  After that, is the Windows "window handle" of the specified window, expressed as an 8 digit hexadecimal number.  So, this is not guaranteed to be unique, since windows handles do get re-used, but in practice, it is likely to work.

There is a function in the Control Manager extender to convert back and forth between WinBatch "window ids" and (raw) Windows window handles.  But I often use my own version to convert from handle to id, because of a flaw in the  version in the Control Manager.  My version is:

#DefineSubroutine udsWinIdConvert(id)
IF !IsDefined(msvcrt)
    msvcrt = DllLoad("msvcrt")
    buff16 = BinaryAlloc(16)
    BinaryEodSet(buff16,16)
ENDIF
DllCallCdecl(msvcrt,long:"sprintf",lpbinary:buff16,lpstr:"#WIN$ID#%%08X",long:id)
Return BinaryPeekStr(buff16,0,16)
#EndSubroutine


This takes a Windows handle as input and returns a WinBatch id as output.  Yes, the parameter is misnamed.  Oh wellââ,¬Â¦

Note: This is setup as a DefineSubroutine instead of as a DefineFunction to protect a couple of local variables that are used by the function in future calls.
Title: Re: WinIdGet - returns consistent pattern?
Post by: Deana on April 06, 2014, 11:40:57 AM
The window ID is a specially formatted string that represents a 'pseudo-handle' of the window, that only WinBatch recognizes.

Windows IDs are recognized by all functions that also accept a partial window name.

Note: You can use cWinIdConvert to convert between a true Windows handle and a Window Id (pseudo-handle). If you pass in a Window ID, the function returns the corresponding Window handle.  This handle will be unique and could be used in your script.

However keep in mind once that window is dismissed that handle could be reused by Windows.
Title: Re: WinIdGet - returns consistent pattern?
Post by: stevengraff on April 06, 2014, 12:53:18 PM
I suppose I was more worried about whether

uid = winidget("")
uid = itemExtract( 3, uid, "#" )

would always produce legal file-name characters... looks like it will.
Title: Re: WinIdGet - returns consistent pattern?
Post by: td on April 07, 2014, 07:15:04 AM
Window handles and therefore WinBatch window ids are recycled more frequently than some apparently think.  So if your purpose is to create a unique log file name, you would be better served by simply using the current time, sequential numbers or a couple of lines of finite math. (using quadradic residues to generate a unique non sequential number) as part of the file name.
Title: Re: WinIdGet - returns consistent pattern?
Post by: stevengraff on April 07, 2014, 07:20:19 AM
Sounds good... thanks all.