1 (изменено: BlackCat, 2022-01-13 13:40:55)

Тема: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

Добрый день всем!
Написал скрипт, который работает в качестве конвертера hex данных реестра REG_EXPAND_SZ или REG_MULTI_SZ в текст и обратно.
Данные hex или text можно вводить как методом Copy-Paste, так и непосредственным набором с клавиатуры.
Конвертация данных происходит в Real Time в процессе набора или вставки данных.
Но возникла небольшая проблемка - если вводить текст, который начинается с двух первых цифр и запятой, то конвертация прекращается.
т.е., для примера:
38 попугаев - нормально конвертируется в hex
Результат конвертации:

33,00,38,00,20,00,3f,04,3e,04,3f,04,43,04,33,04,30,04,35,04,32,04,00,00

38, попугаев - проблема с конвертацией
Проблема скорее всего в этом шаблоне:

If RegExMatch(Source, "^\h*(\d\d,|\d\w,)+")

Но может и в другом шаблоне.
Я пока еще не совсем разобрался в составлении шаблонов RegEx.
Хотя, конечно, такое сочетание текста (две цифры и запятая) маловероятно встретить в реестре, но все же "а если вдруг" ...
Хотелось бы, чтобы все работало.
Есть ли у кого какие предложения и желание помочь?
Буду признателен за любую помощь.
Код скрипта конвертера:


#NoEnv
#NoTrayIcon
#SingleInstance force
SendMode Input
SetBatchLines -1

ProgName := "RegHex Converter"

Info =
(
1. Для конвертации в текст, вставить hex данные из *.reg файла.
2. Для конвертации в hex формата REG_EXPAND_SZ или REG_MULTI_SZ, вставить текст.`n
Примечания:
Для конвертации многострочного текста в формат REG_MULTI_SZ, данные для новой строки вводятся нажатием клавиши [Enter]
Конвертация происходит в реальном времени после вставки данных [Ctrl] + [V] или в процессе набора текста или hex данных.
)

GuiClr := "000000" ; цвет Gui
GuiW := 800 ; параметр для изменения (при изменении данного параметра изменяются все прочие параметры gui)
GuiH := GuiW/1.5
GuiTrans := 220 ; параметр для изменения - от 0 (невидимо) до 255 (без прозрачности)

FntStile := "Bold"
FntName := "Comic Sans MS" ; название шрифта

HeadSz := GuiW/46

FntClrHead := "00FFFF"
FntSzHead := HeadSz
TxtPosHead := "x0 y" GuiW/60 " Center"
TxtSzHead := "w" GuiW-(HeadSz*2) " h" HeadSz*2

FntClrClose := "FF0000"
FntSzClose := HeadSz
TxtPosClose := "x" GuiW-(HeadSz*2) " yp0 Center"
TxtSzClose := "w" HeadSz " h" HeadSz*2

FntClrAct := "FFFF00"
FntSzAct := GuiW/60
TxtPosAct := "x0 w" GuiW " Center"
TxtSzAct := ""

FntClrData := "000000"
FntSzData := 9 ; параметр для изменения
DataPos := "x" HeadSz
DataSz := "w" GuiW-(HeadSz*2) " h" GuiH/2.9

Gui -Caption +ToolWindow ;+AlwaysOnTop
Gui Color, % "c" GuiClr

Gui Font, % "c" FntClrHead " s" FntSzHead " " FntStile, % FntName
Gui Add, Text, % TxtPosHead " " TxtSzHead " gMoveGUI", % ProgName ; первая строка

Gui Font, % "c" FntClrClose " s" FntSzClose " " FntStile, % FntName
Gui Add, Text, % TxtPosClose " " TxtSzClose " vCloseProg gCloseProg", X

Gui Font, % "c" FntClrAct " s" FntSzAct " " FntStile, % FntName
Gui Add, Text, % TxtPosAct " " TxtSzAct " vReset gReset", Очистить все данные

Gui Font, % "c" FntClrData " s" FntSzData " " FntStile
Gui Add, Edit, % DataPos " " DataSz " vSource gConvert", % Info

Gui Font, % "c" FntClrAct " s" FntSzAct " " FntStile, % FntName
Gui, Add, Text, % TxtPosAct " " TxtSzAct " vCopy gCopy", Копировать данные в буфер

Gui Font, % "c" FntClrData " s" FntSzData " " FntStile
Gui Add, Edit, % DataPos " " DataSz " vResult"

Gui Show, % "w" GuiW " h" GuiH "Center", % ProgName
WinSet Region, % "w" GuiW " h" GuiH " R" GuiW/24 "-" GuiW/24 " 0-0", % ProgName
WinSet Transparent, % GuiTrans, % ProgName
Return

Convert:
	GuiControlGet, Source
	If RegExMatch(Source, "^\h*(\d\d,|\d\w,)+"){
		GetTxt()
		}
		Else {
			GetHex()
			}
Return

Reset:
	TxtClr("Reset",FntClrAct,FntSzAct)
	GuiControl,, Source
	GuiControl,, Result
Return

Copy:
	TxtClr("Copy",FntClrAct,FntSzAct)
	Gui Submit, NoHide
	Clipboard := Result
return

MoveGUI(){
	PostMessage, 0xA1, 0x2,,, A
	}
	
CloseProg:
	TxtClr("CloseProg",FntClrClose,FntSzClose)
	Loop 100 {
		TransFade := GuiTrans - A_Index
		WinSet Transparent, % TransFade, % ProgName
		Sleep 1
		}
	Gui Destroy
ExitApp

;〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
; Translate functions

GetTxt(){
	GuiControlGet, Source
	Source := RegExReplace(Source, ",00,00,00,00,00$", ",00") ; удалить заключительный блок ,00,00,00,00 из REG_MULTI_SZ, чтобы не замещался на `n
	Source := RegExReplace(Source, ",00,00,00$", ",00") ; удалить заключительный блок ,00,00,00 из REG_EXPAND_SZ за ненадобностью
	Source := RegExReplace(Source, ",00,00,00,", ",00,0a,00,") ; предыдущий ,00, + символ перевода новой строки 00,00, (встречается только между строк) заменить на реальный \n = 0a,00
	Source := RegExReplace(Source, "i)[^\da-f]") ; удалить запятые, пробелы и \
	Loop % StrLen(Source) /2 {
		Txt .= Chr("0x" SubStr(Source, A_index *4 -1, 2) SubStr(Source, A_index *4 -3, 2))
		}
GuiControl,, Result, % Txt
}

GetHex(){
	GuiControlGet, Source
	VarSetCapacity(Hex, Len*(A_IsUnicode ? 2:1))
	Len := StrPutVar(Source, V, "UTF-16")
	Pointer := &V
	Form := A_FormatInteger
	SetFormat IntegerFast, H
	Loop % Len*2 {
		Hex .= (SubStr(0x100 + NumGet(Pointer + A_Index-1, 0, "Uchar"), -1) ",")
		}
	SetFormat IntegerFast, % Form
	Hex := SubStr(Hex, 1, -1) ; удалить последнюю запятую
	Hex := RegExReplace(Hex, "i)0a", "00") ; заменить символ новой строки 0a в формат реестра 00
	Hex := RegExReplace(Hex, ".*?", "$L0") ; преобразовать в lowercase (объединение с нижним RegExReplace дает ошибку при множественной взаимной конвертации!)
	Hex := RegExReplace(Hex, ".{74},(?!$)", "$0\`r`n  ") ; разбить на короткие строки, добавить \ в конец строки и двойной Space вначале строки
GuiControl,, Result, % Hex
}

StrPutVar(Source, ByRef V, Encoding) {
	VarSetCapacity(V, StrPut(Source, Encoding) * ((Encoding="UTF-16"||Encoding="CP1200") ? 2 : 1))
Return StrPut(Source, &V, Encoding)
}

;〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
; Text color functions

TxtClr(Point,FntClrStd,FntSzStd){
	global
	FntClrEnt := "00FF01"
	FntSzEnt := FntSzStd-2.6
	SetFont("c" FntClrEnt " s" FntSzEnt, Point)
	Sleep 333
	SetFont("c" FntClrStd " s" FntSzStd, Point)
}

SetFont(Opt, Control){
	Gui Font, % Opt
	GuiControl Font, % Control
}

2

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

Для конвертации в hex и обратно не нужно использовать регулярки, есть winapi функции CryptBinaryToString и CryptStringToBinary, ищите примеры использования.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

teadrinker благодарю за ответ и подсказку!
Хотелось бы уточнить - эти функции конвертируют в формат реестра?
Нужно получать результат такого вида:

22,00,25,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,69,00,6c,\
  00,65,00,73,00,25,00,5c,00,4e,00,6f,00,74,00,65,00,70,00,61,00,64,00,2b,00,\
  2b,00,5c,00,6e,00,6f,00,74,00,65,00,70,00,61,00,64,00,2b,00,2b,00,2e,00,65,\
  00,78,00,65,00,22,00,20,00,22,00,25,00,31,00,22,00,00,00

4

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

Запятые, конечно, они не вставят, для этого можно регулярку использовать. Как вставить запятые через две цифры, разберётесь?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5 (изменено: BlackCat, 2022-01-13 18:51:18)

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

teadrinker постараюсь разобраться, ежели че - к вам приду за помощью
Благодарю!

6 (изменено: Alectric, 2022-01-13 17:28:35)

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

Дело было вечером, делать было нечего.

gui,1:font,s8,Tahoma
gui,1:add,edit,vintext w400 h100 gConvert,
gui,1:add,edit,vouttext w400 h100 gConvert2,
gui,show
return

Convert:
gui,1:submit,nohide
size:=STRToDATA(intext,tmp1,0)
HEXText:=DATAtoHEX(&tmp1,0,size)
GuiControl,,outtext,%HEXText%
return

Convert2:
gui,1:submit,nohide
size:=HEXstrToDATA(outtext,tmp1,0)
StrText:=DATAtoSTR(&tmp1,0,size)
GuiControl,,intext,%StrText%
return


STRToDATA(str,byref var,swap=0)
{
  size:=strlen(str)
  varsetcapacity(var,size+2)
  loop,parse,str
  {
    if !swap
      NumPut(asc(a_loopfield),var,a_index-1,"Uchar")
    else
      NumPut(asc(a_loopfield),var,size-a_index,"Uchar")
  }
  return size
}

DATAtoHEX(var,st,size,sw=0)
{
  loop,% size
  {
    hex.=format("{:02X},",numget(var+0,(sw?(size-a_index):(st+a_index-1)),"uchar"))
    if (!mod(a_index,23) and a_index!=size)
      hex.="\`n"
  }
  stringtrimright,hex,hex,1
  return hex
}







HEXstrToDATA(str,byref var,swap=0)
{
  stringreplace,str,str,%a_space%,,all
  stringreplace,str,str,`\,,all
  stringreplace,str,str,`n,,all
  stringreplace,str,str,`,,,all
  size:=ceil(strlen(str)/2)
  varsetcapacity(var,size+2)
  loop,% size
  {
    stringright,tmp2,str,2
    if !swap
      NumPut("0x"tmp2,var,size-a_index,"Uchar")
    else
      NumPut("0x"tmp2,var,a_index-1,"Uchar")
    StringTrimRight,str,str,2

 }
  return size
}

DATAtoSTR(var,st,size,sw=0)
{
  loop,% size
    str.=chr(numget(var+0,(sw?(size-a_index):(st+a_index-1)),"uchar"))
  return str
}
Win 7 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

7 (изменено: BlackCat, 2022-01-13 18:50:57)

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

Alectric а в обратку-то оно не переводит
В смысле, если конвертированный результат строки в hex опять вставить для перевода, выход опять в hex.
Мой код переводит туда-сюда, если до бесконечности вставлять и конвертировать результат.
Проблема только в том, что он распознает не как строку, а как hex, если строка начинается с двух цифр и запятой (38, попугаев - пример).

8

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

Поправил, попробуй.

Win 7 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

9 (изменено: BlackCat, 2022-01-13 18:50:33)

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

Alectric нифика оно не мурлычит.
К тому-же 4 окна неудобно.
Если бы как-то научить распознавать код текс/хекс.
В моем коде делает эта фигня:

Convert:
	GuiControlGet, Source
	If RegExMatch(Source, "^\h*(\d\d,|\d\w,)+"){
		GetTxt()
		}
		Else {
			GetHex()
			}

Но на двух цифрах с запятой дает сбой.
Либо шаблон нужно сделать крутой, либо что-то придумать другое - без RegEx

10

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

Еще раз поправил. HEX строку в нижний вставляй, в верхнем текст изменится. Только мой вариант с русским текстом не дружит.

Win 7 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

11 (изменено: BlackCat, 2022-01-13 18:50:15)

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

Alectric ну да, я тестил на кириллице.
Вообще это проблемка - кириллица часто встречается в реестре.

12 (изменено: Alectric, 2022-01-13 17:36:26)

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

Нужно делать переключатель ANSI - Unicode, наверно.

Справка пишет:

Gui, Add, Radio, vMyRadioGroup, Wait for all items to be in stock before shipping.

Win 7 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

13 (изменено: BlackCat, 2022-01-13 18:50:01)

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

Alectric возможно, но это лишние "переключалки" в gui.
Хотел сделать максимально простой интерфейс без лишних заморочек.
Возможно придется делать лишнюю фигню в gui, печалька
Или оставить все, как есть - код дает сбой только на одной фигне, которая может и не встретиться вовсе.

14

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

BlackCat, пожалуйста, не пишите каждое предложение с новой строки, у нас тут не вотсап. Ставьте точку в конце каждого предложения. Много точек ставить не нужно, это выглядит глупо. Исправьте пожалуйста свои посты.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

15 (изменено: Alectric, 2022-01-13 19:23:25)

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

С переключателем.

global encoding
gui,1:font,s8,Tahoma
Gui,1:Add,Radio,Checked vChoice w100 gsubm,utf-16
Gui,1:Add,Radio,xp y+10 w100 gsubm,utf-8
gui,1:add,text,,Вставь сюда текст:
gui,1:add,edit,vintext w400 h100 gConvert,
gui,1:add,text,,Вставь сюда HEX:
gui,1:add,edit,vouttext w400 h100 gConvert2,
gui,show
return

Convert:
gui,1:submit,nohide
size:=STRToDATA(intext,tmp1,encoding)
HEXText:=DATAtoHEX(&tmp1,0,size)
GuiControl,,outtext,%HEXText%
return

Convert2:
gui,1:submit,nohide
size:=HEXstrToDATA(outtext,tmp1,0)
StrText:=DATAtoSTR(&tmp1,encoding,size)
GuiControl,,intext,%StrText%
return

subm:
gui,1:submit,nohide
encoding:=Choice-1
gosub,Convert
return

STRToDATA(str,byref var,enc)
{
    size:=enc?strlen(str):strlen(str)*2
    varsetcapacity(var,size)
    StrPut(str,&var,enc?"utf-8":"utf-16")
    return size
}

DATAtoHEX(var,st,size,sw=0)
{
    loop,% size
    {
        hex.=format("{:02X},",numget(var+0,(sw?(size-a_index):(st+a_index-1)),"uchar"))
        if (!mod(a_index,23) and a_index!=size)
            hex.="\`n"
    }
    stringtrimright,hex,hex,1
    return hex
}

HEXstrToDATA(str,byref var,swap=0)
{
    stringreplace,str,str,%a_space%,,all
    stringreplace,str,str,`\,,all
    stringreplace,str,str,`n,,all
    if RegExMatch(str,"00")
      encoding:=0
    stringreplace,str,str,`,,,all
    size:=ceil(strlen(str)/2)
    varsetcapacity(var,size+2)
    loop,% size
    {
        stringright,tmp2,str,2
        if !swap
            NumPut("0x"tmp2,var,size-a_index,"Uchar")
        else
            NumPut("0x"tmp2,var,a_index-1,"Uchar")
        StringTrimRight,str,str,2

    }
    return size
}

DATAtoSTR(var,enc,size,sw=0)
{
  return StrGet(var,enc?size:size/2,enc?"utf-8":"utf-16")
}
Win 7 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

16

Re: AHK: RegHex Converter - ввод данных с двумя цифрами и запятой

Alectric, просьба, если видите, что было сделано замечание по оформлению, а исправления пока не сделаны, новые посты в теме создавать не нужно.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder