Pitronic Опубликовано 20 ноября, 2022 Поделиться Опубликовано 20 ноября, 2022 Вопрос меня давно волновал, но забывал спросить. Когда то скачал, не помню для какой игры трейнер. Там была такая пользовательская фишка. Там где описания горячих клавиш. Была кнопка edit при активации которой пользователь мог изменить горячие клавиши которые там по умолчанию. Можно ли реализовать это в ce на форме udf1. Если кто знает подскажите пожалуйста пж по шагам. Ссылка на комментарий Поделиться на другие сайты Поделиться
LIRW Опубликовано 20 ноября, 2022 Поделиться Опубликовано 20 ноября, 2022 3 часа назад, Pitronic сказал: Можно ли реализовать это в ce на форме udf1 Так давал же.... Чпок! Ссылка на комментарий Поделиться на другие сайты Поделиться
Pitronic Опубликовано 20 ноября, 2022 Автор Поделиться Опубликовано 20 ноября, 2022 (изменено) 4 минуты назад, LIRW сказал: Можно ли реализовать это в ce на форме udf1 Я там не чего не понял. и втой теме по ходу делу форма не udf1 а CETrainer Изменено 20 ноября, 2022 пользователем Pitronic Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 22 ноября, 2022 Поделиться Опубликовано 22 ноября, 2022 Спойлер https://forum.cheatengine.org/viewtopic.php?p=5706638#5706638 Спойлер Разобраться будет непросто. Основной принцип надо уловить. 1) userDefinedKeys - Lua-таблица с hot-keys. Не более 5 комбинаций нажатий. В эту таблицу происходит запись и чтение. 2) (object1.ClassName=='tcheat') and (object2.ClassName=='TMemoryRecordHotkey') это типы недокументированные в celua.txt. Экземпляры этих типов генерируются на форме при создании hot-keys Спойлер 3) Сколько опций нагенерировали на форме, столько надо добавить потом. например addChangeHotkeyKeysFunctionality(CETrainer.CHEAT0,memrec0_hotkey0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT1,memrec1_hotkey0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT2,memrec2_hotkey0) 4) userPressedKey - обработчик нажатий в поле ввода текста, который будет работать с таблицей кодов hotkeys userDefinedKeys на 5 нажатий 5) clearHotkey() - обработчик клика на кнопку, очистит таблицу кодов hotkeys userDefinedKeys 6) -- создание формы changeHotkeyKeysForm "local function formCreate()". Принцип, который надо понять и уловить состоит в подмене хоткеев в tcheat и TMemoryRecordHotkey. Как именно подменяется можно увидеть по исходникам и по документации. К сожалению, документировано не все. Те, кто постоянно лазят на форуме CE, по исходником CE они знают и описание tcheat и TMemoryRecordHotkey. С моими комментариями: Спойлер -- обработчик нажатий до 5 hot-keys на поле для поля CEEdit1.OnKeyDown = userPressedKey (ниже задается) -- userDefinedKeys = {} таблица hot-keys local function userPressedKey(sender, key) if userDefinedKeys[5]==0 then for i=1,5 do if userDefinedKeys[i]==0 then userDefinedKeys[i]=key break else if userDefinedKeys[i]==key then break end end end end -- преобразование таблицы hot-keys в строку и запись в поле changeHotkeyKeysForm.CEEdit1.Text changeHotkeyKeysForm.CEEdit1.Text=convertKeyComboToString(userDefinedKeys) return 0 end -- Обработчик для очистки hot-key local function clearHotkey() userDefinedKeys={0,0,0,0,0} changeHotkeyKeysForm.CEEdit1.Text=convertKeyComboToString(userDefinedKeys) changeHotkeyKeysForm.CEEdit1.setFocus() end -- создание формы changeHotkeyKeysForm local function formCreate() changeHotkeyKeysForm=createForm(false) changeHotkeyKeysForm.Name = 'changeHotkeyKeysForm' changeHotkeyKeysForm.Caption = 'Hotkey Manually Set' changeHotkeyKeysForm.Width = 300 changeHotkeyKeysForm.Height = 120 changeHotkeyKeysForm.Position = poScreenCenter changeHotkeyKeysForm.OnClose = function () changeHotkeyKeysForm.CEEdit1.setFocus() return caHide end local CELabel1=createLabel(changeHotkeyKeysForm) CELabel1.Name = 'CELabel1' CELabel1.Left = 20 CELabel1.Top = 20 CELabel1.Caption = 'Set hotkey:' local CEEdit1=createEdit(changeHotkeyKeysForm) CEEdit1.Name = 'CEEdit1' CEEdit1.Text = '' CEEdit1.AnchorSideLeft.Control = CELabel1 CEEdit1.AnchorSideTop.Control = CELabel1 CEEdit1.AnchorSideTop.Side = asrBottom CEEdit1.Height = 25 CEEdit1.Width = 248 CEEdit1.BorderSpacing.Top = 4 local clearButton=createButton(changeHotkeyKeysForm) clearButton.Name = 'clearButton' clearButton.AnchorSideLeft.Control = CEEdit1 clearButton.AnchorSideTop.Control = CEEdit1 clearButton.AnchorSideTop.Side = asrBottom clearButton.Height = 30 clearButton.Width = 80 clearButton.BorderSpacing.Top = 8 clearButton.Caption = 'Clear' local applyButton=createButton(changeHotkeyKeysForm) applyButton.Name = 'applyButton' applyButton.AnchorSideLeft.Control = clearButton applyButton.AnchorSideLeft.Side = asrBottom applyButton.AnchorSideTop.Control = clearButton applyButton.Height = 30 applyButton.Width = 80 applyButton.BorderSpacing.Left = 10 applyButton.Caption = 'Apply' CEEdit1.OnKeyDown = userPressedKey -- обработчки нажатий -- https://lazarus-ccr.sourceforge.io/docs/lcl/controls/tmousebutton.html для записи хот-кей мышки. local mbtn={false,true,true,true} CEEdit1.OnMouseDown = function (s,k) if mbtn[k] then s.OnKeyDown(s,k+2) end end clearButton.OnClick = clearHotkey -- обработчик очистки hot-keys applyButton.ModalResult = mrYes -- apply button end -- Обработчик кнопки смены hot-key. Показывает форму смены hot-keys function changeHotkeyKeys(hotkey) -- если форма не создана, то создать if not changeHotkeyKeysFormCreated then changeHotkeyKeysFormCreated = true formCreate() end if hotkey==nil then return end -- таблица из пользовательский hot-keys. Максимум 5 userDefinedKeys={0,0,0,0,0} -- проверка на свопаданеие для ClassName=='TGenericHotkey' или на "TMemoryRecordHotkey" if hotkey.ClassName=='TGenericHotkey' then -- если TGenericHotkey, то запись клавиш -- TGenericHotkey, вроде, не документирована. Так что либо лезем в git либо запоминаем что есть .getKeys() у hotkey for i,v in ipairs({hotkey.getKeys()}) do userDefinedKeys[i]=v -- установка hot-key end -- показать таблицу с кодами hot-keys как строку changeHotkeyKeysForm.CEEdit1.Text=convertKeyComboToString(userDefinedKeys) -- запомнить что есть setKeys у hotkey типа TGenericHotkey. Передать пять нажатий if changeHotkeyKeysForm.showModal()==mrYes then hotkey.setKeys(userDefinedKeys[1],userDefinedKeys[2], userDefinedKeys[3],userDefinedKeys[4], userDefinedKeys[5]) end elseif hotkey.ClassName=='TMemoryRecordHotkey' then -- если же это TMemoryRecordHotkey for i,v in ipairs(hotkey.Keys) do userDefinedKeys[i]=v -- записать коды hot-key end -- показать строку changeHotkeyKeysForm.CEEdit1.Text=convertKeyComboToString(userDefinedKeys) -- если подвержедение закрытия формы через showModal()==mrYes, то назначить клавиши if changeHotkeyKeysForm.showModal()==mrYes then hotkey.Keys = userDefinedKeys end end end -- Функция для связи CETrainer.CHEAT0 и memrec0_hotkey0. Примеры ниже. -- object1 это тип условный тип tcheat, object2 это тип TMemoryRecordHotkey. Типы не документированы в celua.txt. Просто запомнить или лезть в git CE function addChangeHotkeyKeysFunctionality(object1, object2) if (type(object1)=='userdata') and (object1.ClassName=='tcheat') and (object2.ClassName=='TMemoryRecordHotkey') then local btn = createButton(object1.Owner) btn.Parent = object1.Parent btn.AnchorSideLeft.Control = object1 btn.AnchorSideTop.Control = object1 btn.Height = object1.Height btn.Width = 15 btn.BorderSpacing.Left = object1.Descriptionleft - 20 btn.Caption = 'E' -- создание кнопок вида "E" редактироавния hot-key btn.OnClick = function () changeHotkeyKeys(object2) object1.Hotkey = object2.HotkeyString end end end -- автоматическая, генерация как обычно. Оставить как есть для трех опций. --TRAINERGENERATORSTART-- --This is autogenerated code. Changing code in this block will --get erased and rewritten if you regenerate the trainer code --Uncomment the following line if this is a Cheat Table format trainer and you don't want CE to show (Tip, save as .CETRAINER alternatively) --hideAllCEWindows() RequiredCEVersion=6.6 if (getCEVersion==nil) or (getCEVersion()<RequiredCEVersion) then messageDialog('Please install Cheat Engine '..RequiredCEVersion, mtError, mbOK) closeCE() end addresslist=getAddressList() memrec0=addresslist.getMemoryRecordByID(0) memrec1=addresslist.getMemoryRecordByID(1) memrec2=addresslist.getMemoryRecordByID(2) memrec0_hotkey0=memrec0.getHotkeyByID(0) memrec1_hotkey0=memrec1.getHotkeyByID(0) memrec2_hotkey0=memrec2.getHotkeyByID(0) function onPostHotkey0(Hotkey) --Executed after the "toggle*" cheat got executed local memrec=Hotkey.Owner local isActive=memrec.Active --get the state after the hotkey got triggered CETrainer.CHEAT0.setActive(isActive) --gui update, nothing else if gPlaySoundOnAction then if isActive then playSound(gActivateSound) else playSound(gDeactivateSound) end end end memrec0_hotkey0.onPostHotkey=onPostHotkey0 function onPostHotkey1(Hotkey) --Executed after the "toggle*" cheat got executed local memrec=Hotkey.Owner local isActive=memrec.Active --get the state after the hotkey got triggered CETrainer.CHEAT1.setActive(isActive) --gui update, nothing else if gPlaySoundOnAction then if isActive then playSound(gActivateSound) else playSound(gDeactivateSound) end end end memrec1_hotkey0.onPostHotkey=onPostHotkey1 function onHotkey2(Hotkey) --Executed before the hotkey is handled CETrainer.CHEAT2.setActive(true, 1500) if gPlaySoundOnAction then playSound(gActivateSound) end end memrec2_hotkey0.onHotkey=onHotkey2 CETrainer.SEPERATOR.Visible=false getAutoAttachList().add("ddgd") gPlaySoundOnAction=false CETrainer.show() function AboutClick() showMessage(gAboutText) end gAboutText=[[This trainer was made by Cheat Engine www.cheatengine.org]] function CloseClick() --called by the close button onClick event, and when closing the form closeCE() return caFree --onClick doesn't care, but onClose would like a result end --TRAINERGENERATORSTOP-- -- А это уже дописывать. Сколько опций, столько и строк addChangeHotkeyKeysFunctionality(CETrainer.CHEAT0,memrec0_hotkey0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT1,memrec1_hotkey0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT2,memrec2_hotkey0) Вариант, рабочий. Главное не запутаться, когда будешь переделывать под свой вариант меняя опции или добавляя свои. Если что не понятно, то пиши. Я когда исходник открыл вообще ничего не понял. Когда начинаешь разбираться, потом картина выстраивается. Если бы я делал с нуля, то, наверно, делал бы без tcheat и TMemoryRecordHotkey, но остальное почти также с convertKeyComboToString Ссылка на комментарий Поделиться на другие сайты Поделиться
Pitronic Опубликовано 23 ноября, 2022 Автор Поделиться Опубликовано 23 ноября, 2022 22 часа назад, MasterGH сказал: Если бы я делал с нуля, то А как бы сделали вы? Хочу попробовать оба варианта этот и ваш и сравнить какой удобней. Если можно то тоже с коментами как здесь. Но не настаиваю просто если есть время и возможность. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 23 ноября, 2022 Поделиться Опубликовано 23 ноября, 2022 Я не особо любитель автономных трейнеров. Если бы я заморочился, то т.к. форма генерируемого трейнера продолжает работать с обычными MemoryRecord из таблицы CE, то можно в MemoryRecord подменять Hotkey. Я бы все удалил с формы. Создал бы сначала CECheckbox1, CEEdit1 и связал бы их с некоторым MemoryRecord по уникальному названию. В MemoryRecord подменял бы Hotkey через обработчик CEEdit1. По esc клавише стирать все, что в CEEdit1 Спойлер Потом бы для остальных записей по аналогии... На мой взгляд, это большие заморочки и сложнее чем если писать на WinAPI + язык программирования. Я бы предложил просто пользоваться *.CT-таблицей 🙂 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Pitronic Опубликовано 29 ноября, 2022 Автор Поделиться Опубликовано 29 ноября, 2022 (изменено) В 22.11.2022 в 20:47, MasterGH сказал: Вариант, рабочий. Не много не рентабельный скрипт. Необходимо два раза генерировать, чтобы потом в таблицу не достающие строки добавить. Методом тыка удаляя функции и проверяя работоспособность, переделал. Теперь после создании формы можно просто сохранить в exe, и нет необходимости второй раз генерировать из за того что первый раз генерировал чтоб в таблицу строки добавить. Вот ваш доработанный мною код. Спойлер -- обработчик нажатий до 5 hot-keys на поле для поля CEEdit1.OnKeyDown = userPressedKey (ниже задается) -- userDefinedKeys = {} таблица hot-keys local function userPressedKey(sender, key) if userDefinedKeys[5]==0 then for i=1,5 do if userDefinedKeys[i]==0 then userDefinedKeys[i]=key break else if userDefinedKeys[i]==key then break end end end end -- преобразование таблицы hot-keys в строку и запись в поле changeHotkeyKeysForm.CEEdit1.Text changeHotkeyKeysForm.CEEdit1.Text=convertKeyComboToString(userDefinedKeys) return 0 end -- Обработчик для очистки hot-key local function clearHotkey() userDefinedKeys={0,0,0,0,0} changeHotkeyKeysForm.CEEdit1.Text=convertKeyComboToString(userDefinedKeys) changeHotkeyKeysForm.CEEdit1.setFocus() end -- создание формы changeHotkeyKeysForm local function formCreate() changeHotkeyKeysForm=createForm(false) changeHotkeyKeysForm.Name = 'changeHotkeyKeysForm' changeHotkeyKeysForm.Caption = 'Редактор горячих клавишь' changeHotkeyKeysForm.Width = 300 changeHotkeyKeysForm.Height = 120 changeHotkeyKeysForm.Position = poScreenCenter changeHotkeyKeysForm.OnClose = function () changeHotkeyKeysForm.CEEdit1.setFocus() return caHide end local CELabel1=createLabel(changeHotkeyKeysForm) CELabel1.Name = 'CELabel1' CELabel1.Left = 20 CELabel1.Top = 20 CELabel1.Caption = 'Горячая клавиша:' local CEEdit1=createEdit(changeHotkeyKeysForm) CEEdit1.Name = 'CEEdit1' CEEdit1.Text = '' CEEdit1.AnchorSideLeft.Control = CELabel1 CEEdit1.AnchorSideTop.Control = CELabel1 CEEdit1.AnchorSideTop.Side = asrBottom CEEdit1.Height = 25 CEEdit1.Width = 248 CEEdit1.BorderSpacing.Top = 4 local clearButton=createButton(changeHotkeyKeysForm) clearButton.Name = 'clearButton' clearButton.AnchorSideLeft.Control = CEEdit1 clearButton.AnchorSideTop.Control = CEEdit1 clearButton.AnchorSideTop.Side = asrBottom clearButton.Height = 30 clearButton.Width = 80 clearButton.BorderSpacing.Top = 8 clearButton.Caption = 'Очистить' local applyButton=createButton(changeHotkeyKeysForm) applyButton.Name = 'applyButton' applyButton.AnchorSideLeft.Control = clearButton applyButton.AnchorSideLeft.Side = asrBottom applyButton.AnchorSideTop.Control = clearButton applyButton.Height = 30 applyButton.Width = 80 applyButton.BorderSpacing.Left = 10 applyButton.Caption = 'Применить' CEEdit1.OnKeyDown = userPressedKey -- обработчки нажатий -- https://lazarus-ccr.sourceforge.io/docs/lcl/controls/tmousebutton.html для записи хот-кей мышки. local mbtn={false,true,true,true} CEEdit1.OnMouseDown = function (s,k) if mbtn[k] then s.OnKeyDown(s,k+2) end end clearButton.OnClick = clearHotkey -- обработчик очистки hot-keys applyButton.ModalResult = mrYes -- apply button end -- Обработчик кнопки смены hot-key. Показывает форму смены hot-keys function changeHotkeyKeys(hotkey) -- если форма не создана, то создать if not changeHotkeyKeysFormCreated then changeHotkeyKeysFormCreated = true formCreate() end if hotkey==nil then return end -- таблица из пользовательский hot-keys. Максимум 5 userDefinedKeys={0,0,0,0,0} -- проверка на свопаданеие для ClassName=='TGenericHotkey' или на "TMemoryRecordHotkey" if hotkey.ClassName=='TGenericHotkey' then -- если TGenericHotkey, то запись клавиш -- TGenericHotkey, вроде, не документирована. Так что либо лезем в git либо запоминаем что есть .getKeys() у hotkey for i,v in ipairs({hotkey.getKeys()}) do userDefinedKeys[i]=v -- установка hot-key end -- показать таблицу с кодами hot-keys как строку changeHotkeyKeysForm.CEEdit1.Text=convertKeyComboToString(userDefinedKeys) -- запомнить что есть setKeys у hotkey типа TGenericHotkey. Передать пять нажатий if changeHotkeyKeysForm.showModal()==mrYes then hotkey.setKeys(userDefinedKeys[1],userDefinedKeys[2], userDefinedKeys[3],userDefinedKeys[4], userDefinedKeys[5]) end elseif hotkey.ClassName=='TMemoryRecordHotkey' then -- если же это TMemoryRecordHotkey for i,v in ipairs(hotkey.Keys) do userDefinedKeys[i]=v -- записать коды hot-key end -- показать строку changeHotkeyKeysForm.CEEdit1.Text=convertKeyComboToString(userDefinedKeys) -- если подвержедение закрытия формы через showModal()==mrYes, то назначить клавиши if changeHotkeyKeysForm.showModal()==mrYes then hotkey.Keys = userDefinedKeys end end end -- Функция для связи CETrainer.CHEAT0 и memrec0_hotkey0. Примеры ниже. -- object1 это тип условный тип tcheat, object2 это тип TMemoryRecordHotkey. Типы не документированы в celua.txt. Просто запомнить или лезть в git CE function addChangeHotkeyKeysFunctionality(object1, object2) if (type(object1)=='userdata') and (object1.ClassName=='tcheat') and (object2.ClassName=='TMemoryRecordHotkey') then local btn = createButton(object1.Owner) btn.Parent = object1.Parent btn.AnchorSideLeft.Control = object1 btn.AnchorSideTop.Control = object1 btn.Height = object1.Height btn.Width = 15 btn.BorderSpacing.Left = object1.Descriptionleft - 15 btn.Caption = 'E' -- создание кнопок вида "E" редактироавния hot-key btn.OnClick = function () changeHotkeyKeys(object2) object1.Hotkey = object2.HotkeyString end end end addresslist=getAddressList() memrec0=addresslist.getMemoryRecordByID(0) memrec1=addresslist.getMemoryRecordByID(1) memrec2=addresslist.getMemoryRecordByID(2) memrec3=addresslist.getMemoryRecordByID(3) memrec4=addresslist.getMemoryRecordByID(4) memrec5=addresslist.getMemoryRecordByID(5) memrec6=addresslist.getMemoryRecordByID(6) memrec7=addresslist.getMemoryRecordByID(7) memrec8=addresslist.getMemoryRecordByID(8) memrec9=addresslist.getMemoryRecordByID(9) memrec0_hotkey0=memrec0.getHotkeyByID(0) memrec1_hotkey0=memrec1.getHotkeyByID(0) memrec2_hotkey0=memrec2.getHotkeyByID(0) memrec3_hotkey0=memrec3.getHotkeyByID(0) memrec4_hotkey0=memrec4.getHotkeyByID(0) memrec5_hotkey0=memrec5.getHotkeyByID(0) memrec6_hotkey0=memrec6.getHotkeyByID(0) memrec7_hotkey0=memrec7.getHotkeyByID(0) memrec8_hotkey0=memrec8.getHotkeyByID(0) memrec9_hotkey0=memrec9.getHotkeyByID(0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT0,memrec0_hotkey0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT1,memrec1_hotkey0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT2,memrec2_hotkey0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT3,memrec3_hotkey0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT4,memrec4_hotkey0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT5,memrec5_hotkey0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT6,memrec6_hotkey0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT7,memrec7_hotkey0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT8,memrec8_hotkey0) addChangeHotkeyKeysFunctionality(CETrainer.CHEAT9,memrec9_hotkey0) gPlaySoundOnAction=false CETrainer.fixDPI() CETrainer.show() function CloseClick() closeCE() return caFree end А вот образец таблицы Тык Зацените по десяти бальной шкале. Изменено 29 ноября, 2022 пользователем Pitronic исправление грамм ошибок Ссылка на комментарий Поделиться на другие сайты Поделиться
Pitronic Опубликовано 29 ноября, 2022 Автор Поделиться Опубликовано 29 ноября, 2022 23 минуты назад, Pitronic сказал: Передать пять нажатий А почему именно пять? Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 4 декабря, 2022 Поделиться Опубликовано 4 декабря, 2022 Скорее всего, так решил Dark Byte и посчитал, что такое число нажатий достаточно. Число нажатий можно проверить в окне установки hotkeys при редактировании memory record через контекстное меню Ссылка на комментарий Поделиться на другие сайты Поделиться
Pitronic Опубликовано 4 декабря, 2022 Автор Поделиться Опубликовано 4 декабря, 2022 (изменено) 47 минут назад, MasterGH сказал: так решил Dark Byte Понял. А как моя редакция скрипта? Я просил оценить в этой теме не кто не откликнулся. Изменено 4 декабря, 2022 пользователем Pitronic Дополнение. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 4 декабря, 2022 Поделиться Опубликовано 4 декабря, 2022 12 минут назад, Pitronic сказал: Понял. А как моя редакция скрипта? Наверно, надо целиком таблицу .CT смотреть. Так ошибки. По скрипту и сравнению с прошлой версией, вроде, нормально. Ссылка на комментарий Поделиться на другие сайты Поделиться
Pitronic Опубликовано 4 декабря, 2022 Автор Поделиться Опубликовано 4 декабря, 2022 (изменено) 43 минуты назад, MasterGH сказал: Наверно, надо целиком таблицу .CT Так я же скинул там таблицу. Всё работает. На десять читов сделал. вот ссылка на топик где я скинул ссылку здесь под показать контент увидите ( А вот образец таблицы Тык Зацените по десяти бальной шкале. ) Изменено 4 декабря, 2022 пользователем Pitronic Ссылка на комментарий Поделиться на другие сайты Поделиться
Pitronic Опубликовано 4 декабря, 2022 Автор Поделиться Опубликовано 4 декабря, 2022 Да забыл сказать, я там в форме что то не так сделал. форма трейнера сзади таблицы получилась. Просто после запроса ( выполнить скрипт ) подтвердить и подвинуть в сторону таблицу. Можно тестировать. Увидите. Всё работает. Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения