WBStudio.RegLocate
;==========================================================================================================================================
; WinBatch Studio Tool
; RegLocate
;----------------------------------------------------------------------------------------------------------------------
; This WBStudio tool "RegLocate" examines the selected text line, which in fact should contain a valid registry path
; and tries to locate the specified registry key in the Windows registry by invoking the Regedit application.
;
; The RegLocate tool can handle three different input formats, for example:
;
;    "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\"
;
;    "HKCU\Software\Microsoft\Windows\CurrentVersion\"
;
;    RegQueryValue (@REGCURRENT, "Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\Favorites")
;
;----------------------------------------------------------------------------------------------------------------------
; Note:
;    This WB Studio Tool is shipped for using Hotkey [Alt]+[F] to invoke the "Favorites" menu from Regedit main menu.
;    There is a "SendkeysTo" statement which may need to be adapted to a language dependent version of Regedit.
;
;    User must have read and write access to the registry key:
;    "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\Favorites"
;
;    The built in cleaning routine behaves as best guess, so sometimes the user has to clean the input string
;    manually by using the edit dialog. Or even better, the user does the text selection already in the right way.
;
;    Regedit.exe will be invoked even with a bad registry path, but remains in the registry root "MyComputer".
;
;    In order to work as intended the Regedit application does not have any dialog child window openend!!!
;------------------------------------------------------------------------------------------------------------------------------------------
; Example for integration into wsp-user.mnu:
;
;   _WBStudio.RegLocate \ {F7} ;
;       Call ("W:\WBT\WBSTUDIO\WBStudio.RegLocate.wbt", 0)
;----------------------------------------------------------------------------------------------------------------------
; 20120427: Version 1.02 : Added detection of HKey abbreviations HKCR, HKCU, HKLM.
; 20100211: Version 1.01 : Dialog "last chance to edit" will be skipped when user has entered data manually by first dialog.
;                        : Small changes in program flow.
; 20100210: Version 1.00 : Initial version.
;
; (c)Detlev Dalitz.20100210.20120427.
;==========================================================================================================================================

;------------------------------------------------------------------------------------------------------------------------------------------
#DefineSubRoutine udsDialog (strTitle)
; Give user the chance to edit the string.
MyDialogFormat = `WWWDLGED,6.2`
MyDialogCaption = `WinBatch Studio|RegLocate - ` : strTitle
MyDialogX = 002
MyDialogY = 057
MyDialogWidth = 508
MyDialogHeight = 040
MyDialogNumControls = 003
MyDialogProcedure = `DEFAULT`
MyDialogFont = `DEFAULT`
MyDialogTextColor = `DEFAULT`
MyDialogBackground = `DEFAULT,DEFAULT`
MyDialogConfig = 0
MyDialog001 = `205,021,036,012,PUSHBUTTON,"PushButton_OK",DEFAULT,"OK",1,2,32,"Microsoft Sans Serif|6656|40|34","0|0|0",DEFAULT`
MyDialog002 = `263,021,036,012,PUSHBUTTON,"PushButton_Cancel",DEFAULT,"Cancel",0,3,DEFAULT,"Microsoft Sans Serif|6656|40|34","0|0|0",DEFAULT`
MyDialog003 = `001,001,502,012,EDITBOX,"EditBox_1",strRegPath,DEFAULT,DEFAULT,1,4096,"Microsoft Sans Serif|6656|40|34","0|0|0",DEFAULT`
ButtonPushed = Dialog ("MyDialog")
Return strRegPath
#EndSubRoutine
;------------------------------------------------------------------------------------------------------------------------------------------


strScriptName = "WBStudio.RegLocate"
strMsgTitle = "WinBatch script terminated."
strMsgText = "This WinBatch script " : '"' : strScriptName : '"' : @LF : " is designed only to work from user menu in WinBatch Studio."
Terminate (RtStatus () != 10, strMsgTitle, strMsgText)

strMsgRunning = "Running... " : strScriptName
strMsgReady = "Ready. " : strScriptName

wStatusMsg (strMsgRunning)

intLineNo = wGetLineNo ()
intColNo = wGetColNo ()
; If !wGetSelstate ()
;    wSelectAll ()
; EndIf

If wGetSelstate ()
   ; Get selection information.
   strSelInfo = wSelInfo ()
   intSelStartLine = ItemExtract (1, strSelInfo, @TAB)
   ; intSelStartCol   = ItemExtract (2, strSelInfo, @TAB)
   ; intSelStopLine   = ItemExtract (3, strSelInfo, @TAB)
   ; intSelStopCol    = ItemExtract (4, strSelInfo, @TAB)

   wCopy ()
   strLines = ClipGet ()
   blnIsSelection = @TRUE
Else
   strLines = udsDialog ("Enter registry path manually or paste from Clipboard.") ; Give user the chance to enter a regpath string manually.
   blnIsSelection = @FALSE
EndIf

If strLines == "" Then Goto CANCEL ; If nothing to do, then direct way out.


; Cleaning the incoming text.
strRegPath = ""
strLines = StrTrim (StrClean (strLines, """'`()" : @CRLF : @TAB, "", @TRUE, 1))
strLines = StrReplace (strLines, "\\", "\")
Switch @TRUE
Case @TRUE
   intPosWild = StrIndexWild (strLines, "HKCR\", 1)
   If !intPosWild Then intPosWild = StrIndexWild (strLines, "HKCU\", 1)
   If !intPosWild Then intPosWild = StrIndexWild (strLines, "HKLM\", 1)
   If intPosWild
      strLines = StrSub (strLines, intPosWild, -1)
      strWild = StrSubWild (strLines, "HK??\", 1)
      strReg = StrTrim (ItemRemove (-1, strWild, "\"))
      intPosLoc = ItemLocate (strReg, "HKCR,HKCU,HKLM", ",")
      strHKey = ItemExtract (intPosLoc, "HKEY_CLASSES_ROOT,HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE", ",")
      strSubKey = StrTrim (StrSub (strLines, StrLen (strWild) + 1, -1))
      strRegPath = strHKey : "\" : strSubKey
      Break
   EndIf
   intPosWild = StrIndexWild (strLines, "HKEY_*\", 1)
   If intPosWild
      strLines = StrSub (strLines, intPosWild, -1)
      strWild = StrSubWild (strLines, "HKEY_*\", 1)
      strHKey = StrTrim (ItemRemove (-1, strWild, "\"))
      strSubKey = StrTrim (StrSub (strLines, StrLen (strWild) + 1, -1))
      strRegPath = strHKey : "\" : strSubKey
      Break
   EndIf
   intPosWild = StrIndexWild (strLines, "@REG*,", 1)
   If intPosWild
      strLines = StrSub (strLines, intPosWild, -1)
      strWild = StrSubWild (strLines, "@REG*,", 1)
      strReg = StrTrim (ItemRemove (-1, strWild, ","))
      intPosLoc = ItemLocate (strReg, "@REGCLASSES,@REGCURRENT,@REGMACHINE,@REGUSERS", ",")
      strHKey = ItemExtract (intPosLoc, "HKEY_CLASSES_ROOT,HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_USERS", ",")
      strSubKey = StrTrim (StrSub (strLines, StrLen (strWild) + 1, -1))
      strRegPath = strHKey : "\" : strSubKey
      Break
   EndIf
EndSwitch

; Cleaning. Remove possible backslash and spaces.
strRegPath = StrSub (strRegPath, 1, StrLen (strRegPath) - (StrSub (strRegPath, StrLen (strRegPath), 1) == "\"))
strRegPath = StrTrim (strRegPath)

If strRegPath == "" Then Goto CANCEL ; If nothing to do, then direct way out.


; Give user the chance to edit the string.
If blnIsSelection Then udsDialog ("Last chance to edit the registry path.")


; Cleaning. Remove possible backslash and spaces.
strRegPath = StrTrim (strRegPath)
strRegPath = StrSub (strRegPath, 1, StrLen (strRegPath) - (StrSub (strRegPath, StrLen (strRegPath), 1) == "\"))
strRegPath = StrTrim (strRegPath)

If strRegPath == "" Then Goto CANCEL ; If nothing to do, then direct way out.


; Write Regedit favorite entry into registry and define our temporary special hotkey.
hdlRK = RegOpenKey (@REGCURRENT, "Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\Favorites")
intResult = RegSetValue (hdlRK, "[&!]", strRegPath)
RegCloseKey (hdlRK)


; Run Regedit ... regardless if running already.
strProcId = RunShell ("regedit.exe", "", "", @ZOOMED, @GETPROCID)
; strProcId is useless when Regedit is running during multiple calls of the WB script, because WinItemProcId fails.
; Possible WinItemProcId bug reported 20100210.


; Detect running instance of Regedit window class, get the window handle and convert it to WinBatch WinId for sure.
strWinId = WinIdGet (FindWindow ("RegEdit_RegEdit"))


; Invoke the "Favorite" menu entry by pressing hotkey [Alt] + [F],
; then invoke our previously defined Favorite entry with "!".
If WinWaitReady (strWinId, 5) Then SendKeysTo (strWinId, "!f{!}")

; Note:
; The "SendkeysTo" parameter is probably dependent on the Regedit language version.
; The german version of Regedit accepts the hotkey [Alt] + [F] to open the menu "Favorites".
; When using other versions of Regedit the menu hotkey character probably needs to be adapted.


; Remove our favorite entry from registry.
hdlRK = RegOpenKey (@REGCURRENT, "Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\Favorites")
intResult = RegDelValue (hdlRK, "[&!]")
RegCloseKey (hdlRK)


:CANCEL
wClearSel ()
wGotoLine (intLineNo)
;wGotoLine (intSelStartLine)
wGotoCol (intColNo)
wStatusMsg (strMsgReady)
Exit

;##########################################################################################################################################
;
; @REGCURRENT ; HKEY_CURRENT_USER   ; HKCU ; Shortcut to the current user’s sub-section.
; @REGMACHINE ; HKEY_LOCAL_MACHINE  ; HKLM ; Root of the machine section of the Registration Database.
; @REGCLASSES ; HKEY_CLASSES_ROOT   ; HKCR ; Shortcut to the classes sub-section.
; @REGUSERS   ; HKEY_USERS          ; ---- ; Root of the user section of the Registration Database.
; ----------- ; HKEY_CURRENT_CONFIG ; ---- ;
;
;##########################################################################################################################################
; Testcases following ...
;
; strLines = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit"          ; Test.
; strLines = '(@REGCURRENT, "Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\Favorites")' ; Test.
; HKEY_CURRENT_USER\Software\Wilson WindowWare\WinBatch Studio\Settings\File mapping
; HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer
; HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer

;##########################################################################################################################################