Ziggle() : A handy tool to lookup Win32 Constants
Posted: 30 Jan 2022, 07:46
Ziggle( hEdit, Rows, Cols, HideButtons? )
About the data file:
Parameters:
Usage/Call example:
Switches for search:
Thanks
The Function:
Requires data file Ziggle.txt (5.13 MiB) available in Ziggle1.zip (1.44 MiB)
Requires data file Ziggle.txt (6.22 MiB) available in Ziggle2.zip (1.79 MiB)
Requires data file Ziggle.txt (6.22 MiB) available in Ziggle3.zip (1.79 MiB)
Requires data file Ziggle.txt (6.59 MiB) available in Ziggle4.zip (1.87 MiB)
About the data file:
The bulk of the data was parsed out from header files of Zig Programming Language, available at GitHub
- Data is plain text in unix file format.
- The data starts immediately after the marker .data..
- Records are delimited with a solitary linefeed.
- Each record has 2 fields: Value followed by Constant, separated by a Tab character.
- Downloads
Parameters:
- hEdit
Optional. A handle to Edit control (Edit, RichEdit, Scintilla etc.)
By default Copy and Paste buttons will copy selected data (check-marked) to clipboard.
If this parameter set, then Paste would (additionally) message the control to paste the text available in clipboard. - Rows, Cols
The UI can be shown larger or smaller by using these.
- Rows is number of rows visible in ListView.
- Cols is number of characters in Switch indicator, the first text control in UI.
- HideButtons?
Hides the buttons. (One doesn't need them if they can remember the Accelerator keys).
Call Ziggle() without last 3 parameters to load UI in its default size/state.
The screenshots in this topic have been made with Ziggle(hEdit, 6, 60, True).
Usage/Call example:
Code: Select all
#Requires AutoHotkey v2.0-
#SingleInstance
HotIfWinActive("ahk_class Notepad") ; Pass your editor's classname
Hotkey( "F2", (*) => Ziggle( ControlGetFocus() ; hEdit
, 6 ; Rows
, 60 ; Cols
, True ; Hide buttons
)
)
HotIfWinActive()
- Run the code
- Press F2 when Notepad is active.
- Search for constants.
- Use Checkboxes in ListView to select them.
- Use Accelerator Alt+V or press [Enter] to paste/dismiss UI. When/if visible, one may also Click Paste button.
- Use Accelerator Alt+C to copy/dismiss UI. When/if visible, one may also Click Copy button.
ListView shortcuts (When ListView has focus).
- Ctrl+C will copy the current selected item to clipboard.
- Ctrl+V will copy/paste the current selected item to background Edit control.
Web-search current selected item: - F1 : MagnumDB
- F2 : Microsoft docs
- F3 : AutoHotkey
Auto mode
When in auto-mode, Ziggle will monitor clipboard activity and auto-replace or auto-insert constants into your editor.
When in auto-mode, Ziggle will monitor clipboard activity and auto-replace or auto-insert constants into your editor.
- Use accelerator Alt+A to enter Auto-mode. When/if visible, you may also Click Auto button.
- Minimize Ziggle prompt.
- Type a constant in your editor, select it (accurately) and copy it.
Ziggle will replace it with a found record.
- Now, minimize your editor too.
- Visit any MS docs page and start copying Constants from it (need not be very accurate, Trim() will take care).
Ziggle will auto-insert them into your editor, with a found record.
Switches for search:
The default search behavior:
- Search input will accept only Uppercase characters.
Click Caps button or press accelerator key Alt+S to toggle it.
- Search term is case-sensitive.
- Search term will be matched anywhere in a record.
- Search term can be prefixed with switches to alter the default behavior.
Watch the indicators to get a feel of how the results are being enumerated.
Matching
Use < switch to find Constants beginning with the search term,
or > switch to find Constants ending with the search term,
or both switches <> to find an exact match.
or > switch to find Constants ending with the search term,
or both switches <> to find an exact match.
Refine results
At times, results returned could be large.
Use | switch followd by additional search term to perform a search in search results.
For example <EM_ would match 198 results. <EM_|SEL would refine original results to only those that have SEL in it.
Use | switch followd by additional search term to perform a search in search results.
For example <EM_ would match 198 results. <EM_|SEL would refine original results to only those that have SEL in it.
Case sensitivity
Use / switch to perform a case-insensitive search. (.. without having to toggle caps).
A vast majority of constants are in uppercase.
Case-sensitive search can be as high as 5 times faster than a case-insensitive search.
These are the reasons why the input control defaults to uppercase and default search is case-sensitive.
Always use / switch when searching for GdiPlus enums.
A vast majority of constants are in uppercase.
Case-sensitive search can be as high as 5 times faster than a case-insensitive search.
These are the reasons why the input control defaults to uppercase and default search is case-sensitive.
Always use / switch when searching for GdiPlus enums.
Searching a value
Use ? switch to search for a Value instead of a Constant.
For example, Ziggle prompt is styled +AlwaysOnTop using E8 in options.
To find constant for the extended style E0x8, one could use the search term ?8 (or ?0x8).
But that would enumerate 3600 results. One may/should already know windows extended styles are prefixed with WS_EX_,
in which case the search term ?8|WS_EX_ would give us the answer.
Note that all indicators are lit up.
For example, Ziggle prompt is styled +AlwaysOnTop using E8 in options.
Code: Select all
MyGui := Gui("+DpiScale E8", MyTitle)
But that would enumerate 3600 results. One may/should already know windows extended styles are prefixed with WS_EX_,
in which case the search term ?8|WS_EX_ would give us the answer.
Note that all indicators are lit up.
Hot / Cold search
Ziggle prompt doesn't have a GO button.
By default, the searches are Hot.. meaning results will change instantly while typing*.
*Note : minimum search term length is 2 characters, excluding any switches.
To do a cold search, prefix and suffix the search term with a space.
This will work correctly except in a few specific cases like follows:
For example, if one is searching for a value and typing it like ? WINDOWS NT ACCESS PROVIDER,
the search would have been triggered 4 times by the time the ending space was entered.
A cold search works even for a single character, but note that I have imposed a limit of 10,000 rows for the ListView.
By default, the searches are Hot.. meaning results will change instantly while typing*.
*Note : minimum search term length is 2 characters, excluding any switches.
To do a cold search, prefix and suffix the search term with a space.
This will work correctly except in a few specific cases like follows:
For example, if one is searching for a value and typing it like ? WINDOWS NT ACCESS PROVIDER,
the search would have been triggered 4 times by the time the ending space was entered.
A cold search works even for a single character, but note that I have imposed a limit of 10,000 rows for the ListView.
Thanks
@jeeswg for suggesting/getting implemented an important change to InStr Occurrence parameter.
@just me / @swagfag for helping me: Virtual ListView 10000 rows, high CPU time
@TheArkive for all the enthusiasm and support shown/offered towards this project.
@neogna2 for useful suggestions.
@eugenesv for contribution to data.
@just me / @swagfag for helping me: Virtual ListView 10000 rows, high CPU time
@TheArkive for all the enthusiasm and support shown/offered towards this project.
@neogna2 for useful suggestions.
@eugenesv for contribution to data.
The Function:
Requires data file Ziggle.txt (6.59 MiB) available in Ziggle4.zip (1.87 MiB)
Code: Select all
Ziggle( P_Ctrl:=Unset, P_Rows:=16, P_Cols:=120, P_Hide:=0, * ) ; Ziggle() v0.31
{ ; By SKAN on D514/D52I
Static S_GuiWnd := "" ; @ autohotkey.com/r?t=99581
Local TickCount := A_TickCount
Local MyTitle := "Ziggle prompt : Win32 constants"
, DataFile := "ziggle.txt"
, LF := Chr(10) ; line feed
, Quote := Chr(34) ; double quote
, Hay := ""
P_Rows := Min(256, Max( 4, Format("{:d}", P_Rows)))
P_Cols := Min(256, Max(60, Format("{:d}", P_Cols)))
If WinExist(MyTitle "ahk_id" S_GuiWnd)
Return WinActivate()
Local Pos1
, Pos2
, Pos3
Try Hay := FileRead(DataFile, LF)
HayGetValue(Str1, Str2)
{
Pos1 := InStr(Hay, Str1, True)
Pos2 := Pos1 ? InStr(Hay, Str2, True, Pos1+1) : 0
Return SubStr(Hay, Pos2 ? Pos1 + StrLen(Str1) : 0, Pos2 - Pos1 - StrLen(Str1))
}
Local HaySize := StrLen(Hay)
, Debug := HayGetValue(LF "Debug=", LF)
, Count := HayGetValue(LF "Constants=", LF)
, nData := ( nData := InStr(Hay, LF ".data." LF, True) )
? nData + 7
: 0
If not (Count Or nData)
Return MsgBox("Datafile error", "Ziggle", "Iconx")
Local Hay2
StrSet(&Str, Chars:=0)
{
If Chars > -1
Return VarSetStrCapacity(&Str, Chars)
Else NumPut("short", 0, StrPtr(Str))
Return VarSetStrCapacity(&Str, -1)
}
StrSet(&Hay2, 512*1024) ; 1 MiB
Local MyGui
MyGui := Gui("+DpiScale E8", MyTitle)
S_GuiWnd := MyGui.Hwnd
MyGui.MarginX := 16
MyGui.MarginY := 12
Local Indi
, Ord1 := 0x25A1 ; unicodeplus.com/U+25A1 and unicodeplus.com/U+259D
, Ord2 := 0x25CB ; unicodeplus.com/U+25CB and unicodeplus.com/U+25CF
, FormatStr:= "{1:} / InSense {2:} < Match {3:} > Match {4:} ? Val {5:} | Refine"
MyGui.SetFont("s10", "Consolas")
Indi := MyGui.AddText("xm ym 0x200 Right", Format("{:" P_Cols "}", ""))
Indi.Text := Format(FormatStr,Chr(Ord1),Chr(Ord1),Chr(Ord1),Chr(Ord1),Chr(Ord1))
Local Edit1
, MaxX
, MaxW
, MaxH
, RM
MyGui.SetFont("s12")
Edit1 := MyGui.AddEdit("xm y+m wp +Uppercase Limit128")
Edit1.GetPos(&MaxX,,&MaxW, &MaxH)
RM := MaxW + MaxX
SendMessage(0xD3, 0x3, Format("0x{2:04X}{1:04X}", 16*(A_ScreenDPI/96), 4), Edit1.Hwnd)
Edit1.OnEvent("Change", OnQuery)
Local AutoState := 0
, CapsState := 1
, Auto
, Caps
, RowNumber
, RowCount
MyGui.SetFont("s12", "Calibri")
Auto := MyGui.AddText("xm+8 y+4 w48 h28 0x200", Chr(Ord2+0) " Auto")
Caps := MyGui.AddText("x+4 yp w48 hp 0x200 Right", Chr(Ord2+4) " Caps")
RowNumber := MyGui.AddText("x" RM-(48*1) " w48 yp hp 0x200 Right", 0)
RowCount := MyGui.AddText("x" RM-(48*2)-8 " w48 yp hp 0x200 Right", 0)
Count := MyGui.AddText("x" RM-(48*4) " w80 yp hp 0x200 Right", "( " Count " )")
Local MyLV
, ColW := MaxW
, Constant := ""
, Value := ""
, Checked := 0
, ItemState:= 0
MyGui.SetFont("s11", "Consolas")
MyLV := MyGui.AddListView(
"xm w" MaxW " y+8 -hdr -multi +grid +checked LV0x10000 count10000 r" P_Rows
, ["Constant"," Value"]
)
ColW := ( ColW -= (((SysGet(2)/A_ScreenDPI)*100)+8) ) / 100
MyLV.ModifyCol(1, ColW * 54)
MyLV.ModifyCol(2, ColW * 46)
MyLV.OnEvent("ItemSelect", MyLV_ItemSelect)
MyLV.OnEvent("ItemCheck", MyLV_ItemCheck)
MyLV.OnEvent("DoubleClick", MyLV_DoubleClick)
MyLV.OnNotify(-155, MyLV_KeyDown) ; LVN_KEYDOWN
Local Push1
, Push2
, Push3
, Push4
, Push5
MyGui.SetFont("s11", "Calibri")
AutoMode(*)
{
If not IsSet(P_Ctrl)
Return
If AutoState = 1
AutoState := 0
, Auto.Text := Chr(Ord2+0) " Auto"
, OnClipboardChange(OnClipChange, False)
Else AutoState := 1
, Auto.Text := Chr(Ord2+4) " Auto"
, OnClipboardChange(OnClipChange, True)
}
Push1 := MyGui.AddButton("xm y+12 w76 -Tabstop h" (P_Hide ? 0 : 28) , "&Auto")
Push1.OnEvent("Click", AutoMode)
EditCaps(*)
{
CapsState := not CapsState
Caps.Text := CapsState ? Chr(Ord2+4) " Caps" : Chr(Ord2+0) " Caps"
Edit1.Opt(CapsState ? "+UpperCase" : "-Uppercase")
}
Push2 := MyGui.AddButton("x+8 yp wp hp -Tabstop", "Cap&s")
Push2.OnEvent("Click", EditCaps)
Push3 := MyGui.AddButton("x" RM-(76*2)-8 " yp wp hp -Tabstop", "&Copy")
Push3.OnEvent("Click", (*) => Paste(False))
Push4 := MyGui.AddButton("x" RM-(76*1)-0 " yp wp hp -Tabstop +Default", "Paste")
Push4.OnEvent("Click", (*) => Paste( True))
Push5 := MyGui.AddButton("x+0 yp w0 h0 -Tabstop", "&V")
Push5.OnEvent("Click", (*) => Paste( True))
Local MySB
MyGui.SetFont("s10", "Calibri")
MySB := MyGui.AddStatusBar()
MySB.SetParts(MyGui.MarginX, RM-MaxX)
GuiClose(*)
{
OnClipboardChange(OnClipChange, False)
StrSet(&Hay, 0)
StrSet(&Hay2, 0)
Return MyGui.Destroy()
}
MyGui.OnEvent("Close", GuiClose)
MyGui.OnEvent("Escape", GuiClose)
Local TrimChrs := "`r`n`t,. /<>?;:[]{}\|!@#$%^&*()+-=~``" . "'" . '"'
, tHwnd := 0
, InFocus := 0
, Found := 0
, Str := ""
, All := ""
, ClipSaved := ""
Local CaseSense
, Sought
, MatchLeft
, MatchRight
, Refine
, Val
, I
, T
Local Query := []
, Selected := Map()
, PrvQuery := ""
, Switches := ""
, nResults := 0
, nRefined := 0
MyGui_Size(_, MinMax, *)
{
If MinMax = -1 ; when minimized, lose TOPMOST style and
MyGui.Opt("-AlwaysOnTop +ToolWindow") ; remove icon from alt-tab list
, WinMoveBottom(MyGui.Hwnd) ; and move to the bottom of z-order
, MyGui.Opt("-ToolWindow") ; and add icon as last item in alt-tab
Else MyGui.Opt("+AlwaysOnTop")
}
MyGui.OnEvent("Size", MyGui_Size)
Edit1.Focus()
MyGui.MarginY := P_Hide ? 0 : 12
MyGui.Show()
Tickcount := Format("{:.15g}", (A_TickCount-TickCount)/1000)
MySB_Tip(Text, TimeOut := 2000)
{
Try MySB.SetText(RTrim( A_Space Text, A_Space), 2)
If TimeOut
SetTimer((*) => MySB_Tip("", 0), 0 - Abs(Timeout))
}
MySB_Tip("Loading completed in " TickCount "s")
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; General routine(s) 1
FormattedValue(Value)
{
Local newValue
If InStr(Value,"[",, 2, -1) and InStr(Value,"]",, -1, 1)
Or InStr(Value,"(",, 2, -1) and InStr(Value,")",, -1, 1)
Value .= ""
Else
If IsFloat(Value)
newValue := Format("{1:.15g} {2:} {1:}", Value, ";")
, Value := StrLen(newValue) < StrLen(Value)
? newValue
: Value
Else
If IsInteger(Value)
newValue := Value
, Value := StrLen(Value) < 3
? Format("{1:} {2:} 0x{1:X}", Value, ";")
: Format("0x{1:X} {2:} {1:}", Value, ";")
, Value .= newValue<0
? Format(" (uint32: 0x{1:8X})", newValue & 0xffffffff)
: ""
Else
If not InStr(Value,Quote)
Value := Format("{2:}{1:}{2:}", Value, Quote)
Return Value
}
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Edit routine 1: OnQuery()
OnQuery(*)
{
Sought := False
, I := 0
, T := Edit1.Text
If not StrLen(T)
Return ( MyLV.Delete()
, RowCount.Value := 0
, RowNumber.Value := 0
, PrvQuery := ""
)
Loop Parse, T
If InStr('_-+[]{}();:,#0123456789abcdefghijklmnopqrstuvwxyz"', A_LoopField)
and I := A_Index
Break
Switches := SubStr( T, 1
, I=1 ? 0
: I>1 ? I-1
: StrLen(T)
)
CaseSense := 1
MatchLeft := 0
MatchRight := 0
Val := 0
Query := StrSplit( SubStr(T, StrLen(Switches)+1) . "|", "|", A_Space)
Refine := not not Query[2]
Switches := ( InStr(Switches,"/") ? "/" : "" )
. ( InStr(Switches,"<") ? "<" : "" )
. ( InStr(Switches,">") ? ">" : "" )
. ( InStr(Switches,"?") ? "?" : "" )
. ( InStr(Switches," ") ? " " : "" )
If not StrLen(Query[1])
Return
If InStr(Switches, "/", True)
CaseSense := False
If InStr(Switches, "?")
Query[1] := IsNumber(Query[1]) and IsInteger(Query[1])
? LF Format("{:d}", Query[1]) A_Tab
: IsNumber(Query[1]) and IsFloat(Query[1])
? LF Format("{:.15G}", Query[1]) A_Tab
: InStr(Query[1], A_Space) and not InStr(Query[1], Quote)
? LF Quote Query[1] Quote A_Tab
: LF Query[1] A_Tab
, CaseSense := 0
, MatchLeft := 1
, MatchRight := 1
, Val := 1
Else
{
If InStr(Switches, "<", True)
Query[1] := A_Tab Query[1]
, MatchLeft := 1
If InStr(Switches, ">", True)
Query[1] := Query[1] LF
, MatchRight := 1
}
Indi.Text := Format( FormatStr
, Chr(Ord1 - !CaseSense)
, Chr(Ord1 - MatchLeft)
, Chr(Ord1 - MatchRight)
, Chr(Ord1 - Val)
, Chr(Ord1 - Refine)
)
If InStr(Switches, A_Space, True) and
not InStr(T, A_Space, True, -1, 1)
Return
If StrLen(Query[1]) < 1
Return
If StrLen(Query[1]) = 1 and
not InStr(Switches, A_Space, True)
Return
Sought := True
SetTimer((*) => Search(), -1)
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; OnQuery() subroutines 3: Search() / MainSearch() / RefineSearch()
Search(*)
{
If ( Switches . Query[1] ) !== PrvQuery
PrvQuery := Switches . Query[1]
, MainSearch(Query[1])
If StrLen(Query[2])
RefineSearch(Query[2])
Sought := False
}
MainSearch(Q)
{
StrSet(&Hay2, -1)
Hay2 := LF
nResults := 0
Pos1 := 0
, Pos2 := nData
, Pos3 := 0
, Found := 1
If not Query[2]
MyLV.Opt("-Redraw")
, MyLV.Delete()
While Sought
and ( nResults := A_Index ) < 10001
and ( Found := InStr(Hay, Q, CaseSense, Pos2) )
{
If A_Index = P_Rows+1
MyLV.Modify(1, "Select Focus")
, MyLV.Opt( "+Redraw" )
, Sleep(-1)
, MyLV.Opt( "-Redraw" )
Pos1 := SubStr(Q,1,1) = LF
? Found
: InStr(Hay, LF, CaseSense, Found, -1)
, Pos2 := InStr(Hay, LF, CaseSense, Pos1, 2)
, Pos3 := InStr(Hay, A_Tab, CaseSense, Pos2, -1)
, Hay2 .= Substr(Hay, Pos1 + 1, Pos2 - Pos1 - 1) LF
If not Query[2]
MyLV.Add("", SubStr(Hay, Pos3 + 1, Pos2 - Pos3 - 1)
, SubStr(Hay, Pos1 + 1, Pos3 - Pos1 - 1))
}
If not Query[2]
MyLV.Modify(1, "Select Focus")
, MyLV.Opt("+Redraw")
, RowCount.Value := nResults -= 1
, RowNumber.Value := !! nResults
}
RefineSearch(Q)
{
nRefined := 0
Pos1 := 0
, Pos2 := 1
, Pos3 := 0
, Found := 1
MyLV.Opt("-Redraw")
MyLV.Delete()
While Sought
and ( nRefined := A_Index ) < 10001
and ( Found := InStr(Hay2, Q, False, Pos2) )
{
If A_Index = P_Rows+1
MyLV.Modify(1, "Select Focus")
, MyLV.Opt( "+Redraw" )
, Sleep( -1 )
, MyLV.Opt( "-Redraw" )
Pos1 := InStr(Hay2, LF, True, Found, -1)
, Pos2 := InStr(Hay2, LF, True, Pos1, 2)
, Pos3 := InStr(Hay2, A_Tab, True, Pos2, -1)
, MyLV.Add("", SubStr(Hay2, Pos3 + 1, Pos2 - Pos3 - 1)
, SubStr(Hay2, Pos1 + 1, Pos3 - Pos1 - 1))
}
MyLV.Modify(1, "Select Focus")
MyLV.Opt("+Redraw")
RowCount.Value := nRefined -= 1
RowNumber.Value := !! nRefined
}
}
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; ListView routines 4:
; MyLV_ItemSelect() / MyLV_ItemCheck() / MyLV_DoubleClick() / MyLV_KeyDown()
MyLV_ItemSelect(_, Item, Selected)
{
If not MyLV.GetNext()
MyLV.Modify(Item, "Select")
RowNumber.Value := MyLV.GetNext()
}
MyLV_ItemCheck(_, Item, Checked)
{
Constant := MyLV.GetText(Item, 1)
Value := MyLV.GetText(Item, 2)
If Checked = False
and Selected.Has(Constant)
Return Selected.Delete(Constant)
Selected[Constant] := FormattedValue(Value)
}
MyLV_DoubleClick(_, RowNumber)
{
If not RowNumber
Return
ItemState := SendMessage(0x102C, RowNumber - 1, 0xF000, MyLV.Hwnd)
Checked := (ItemState >> 12) - 1 ; 2 lines from docs
MyLV.Modify(RowNumber, Checked ? "-Check" : "+Check")
MyLV_ItemCheck(MyLV, RowNumber, Checked)
}
MyLV_KeyDown(_, lParam)
{
Local VKey := NumGet(lParam+(A_PtrSize*3),"short")
Local KeyName := GetKeyName(Format( "VK{:X}", VKey))
If not InStr("F1cF2vF3", KeyName)
Return
Constant := MyLV.GetText(RowNumber.Value, 1)
Value := MyLV.GetText(RowNumber.Value, 2)
If InStr("F1F2F3", KeyName)
Return KeyName="F1" ? Run("https://www.magnumdb.com/search?q=" Constant)
: KeyName="F2" ? Run("https://docs.microsoft.com/en-us/search/?category="
. "Documentation&terms=" Constant)
: Run("https://www.autohotkey.com/boards/search.php?terms"
. "=all&author=&sc=1&sf=all&sr=topics&sk=t&sd=d&st=0&"
. "ch=300&t=0&submit=Search&keywords=" Constant)
If not GetKeyState("Control", "P") and InStr("cv", KeyName, False)
Return
If AutoState
OnClipboardChange(OnClipChange, False)
ClipSaved := ClipboardAll()
A_Clipboard := Constant " := " FormattedValue(Value) LF
MySB_Tip("Copied to clipboard")
If KeyName = "v"
and IsSet(P_Ctrl)
Try SendMessage(0x302, 0, 0, P_Ctrl) ; WM_PASTE
, MySB_Tip("Pasted")
, A_Clipboard := ClipSaved
Catch
MySB_Tip("Error: Paste failed.")
Else StrSet(&ClipSaved, 0)
If AutoState
OnClipboardChange(OnClipChange, True)
}
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Clipboard routines 2: Paste() / OnClipChange()
Paste(PasteIt:=0)
{
If not Selected.Count
Return
All := ""
For Constant, Value in Selected
All .= Constant " := " Value LF
If AutoState
OnClipboardChange(OnClipChange, False)
ClipSaved := ClipboardAll()
A_Clipboard := All
If not PasteIt
Return (
GuiClose()
, StrSet(&ClipSaved, 0)
)
Try Return (
Sleep(20)
, SendMessage(0x302, 0, 0, P_Ctrl) ; WM_PASTE
, A_Clipboard := ClipSaved
, GuiClose()
)
MySB_Tip("Error: Paste failed.")
If AutoState
AutoMode()
}
OnClipChange(Type)
{
If WinActive(S_GuiWnd)
or Type != 1
or not StrLen(A_Clipboard)
Return
InFocus := ControlGetFocus("A") = P_Ctrl
Str := InFocus ? A_Clipboard : Trim( SubStr(A_Clipboard, 1, 100), TrimChrs)
If not Str
or StrLen(Str) > 100
or IsNumber(Str)
Return
Loop Parse, Str, TrimChrs
If A_Index > 1
Return
Str := A_Tab Str LF
If not Found := InStr(Hay, Str, False, nData)
Return SoundBeep(2400, 24)
Pos1 := InStr(Hay, LF, True, Found, -1)
Pos2 := InStr(Hay, LF, True, Pos1, 2)
Pos3 := InStr(Hay, A_Tab, True, Pos2, -1)
Constant := SubStr(Hay, Pos3 + 1, Pos2 - Pos3 - 1)
Value := SubStr(Hay, Pos1 + 1, Pos3 - Pos1 - 1)
Value := FormattedValue(Value)
OnClipboardChange(OnClipChange, False)
A_Clipboard := Constant " := " Value (InFocus ? "" : LF)
OnClipboardChange(OnClipChange, True)
Try Sleep(20)
, SendMessage(0x302, 0, 0, P_Ctrl) ; WM_PASTE
Catch
Return (
SoundPlay("*16")
, AutoMode()
, MySB_Tip("Error: Invalid control. Auto-mode exited")
, MyGui.Show("")
)
}
} ; ________________________________________________________________________________________________________