Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


run lua function async using Form button [Solved]

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
paul44
Expert Cheater
Reputation: 2

Joined: 20 Jul 2017
Posts: 194

PostPosted: Fri Nov 15, 2024 5:39 am    Post subject: run lua function async using Form button [Solved] Reply with quote

Via the addresslist, one can enable the 'execute asynchronous' option. This offers - at least - 3 important features:
1. CE will not "hang" during its running
2. info updated to a form (gui) will constantly be updated
3. a 'watch' icon visually shows its progress state

How can one configure/program this using lua ?

Basically: i have a form with a button, to run a particular script. If i run the script via the addresslist, everything is peachy (as per aforementioned). If i try to run this same script via the (form) button, no cigar... (ie it does execute, but CE shows "no activity", and trying to 'intervene' prompts "it being busy")

btw: if i disable the 'async' option in the addresslist, i "loose" that same featureset.
ps: createthread comes to mind, but not overly enthousiastic about using it (as no real experience with its use)
ps2: also checked celua.txt but nothing seems "appropriate"


Last edited by paul44 on Thu Nov 21, 2024 11:50 am; edited 3 times in total
Back to top
View user's profile Send private message
panraven
Grandmaster Cheater
Reputation: 61

Joined: 01 Oct 2008
Posts: 958

PostPosted: Fri Nov 15, 2024 10:23 am    Post subject: Reply with quote

Here an example to assure a memrec to be exec async, (copy and paste in the addresslist panel)

Code:

<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>0</ID>
      <Description>"test async exec"</Description>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript Async="1">{$lua}
-- aa command for testing
local cmd = 'log'
unregisterAutoAssemblerCommand(cmd)
registerAutoAssemblerCommand(cmd, function(msg, sc)
  print((sc and '[s]'or'[x]')..msg)
end)

 cmd = 'nap'
unregisterAutoAssemblerCommand(cmd)
registerAutoAssemblerCommand(cmd, function(ms, sc)
  if not sc then
    ms = tonumber(ms) or 1
    sleep(ms)
  end
end)
--
{$asm}

{$lua}
-- code to asure async exec
if syntaxcheck then return end

local mr = memrec
if not mr.Async then

  synchronize(createTimer, 100, function()
    mr.Async = true
    mr.Active = not mr.Active
  end)
  error're-activating' -- this will stop current exec

end
--

{$asm}

[ENABLE]
log(hello)

nap(3000)

log(world)

nap(3000)

log(the end)
 
 
[DISABLE]

</AssemblerScript>
    </CheatEntry>
  </CheatEntries>
</CheatTable>




lua code in an async exec mr that use UI should use synchronize (send the call to main thread, the above createTimer is an example )

_________________
- Retarded.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 150

Joined: 06 Jul 2014
Posts: 4657

PostPosted: Fri Nov 15, 2024 11:33 am    Post subject: Reply with quote

All {$lua} blocks are executed in a separate thread when memrec.Async is set to true. Use createThread if needed.

This also means you should never access anything related to the GUI from that {$lua} block of code. Only the main thread should access the GUI. This includes but is not limited to GUI elements (buttons, edits, menus), the address list / memory records, and timers. If you need to access any of these, use synchronize.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
paul44
Expert Cheater
Reputation: 2

Joined: 20 Jul 2017
Posts: 194

PostPosted: Fri Nov 15, 2024 12:53 pm    Post subject: strictly lua... Reply with quote

^^ @panraven: i now realise that my wording is incorrect here. I am actually talking about Lua only; iow no use/call of a script in the addresslist. And I should have stated 'function' instead of 'script' ! My bad...

Picture this: you have a form with 2 elements: 1 button and 1 label (or listbox, etc). when clicking that button, it will/must run a lua functon (~ not script) - using eg 'Onclick' event - which will (constantly) be updating that label... (assume the label is a counter)
=> what happens is that you will not see the label being updated ("counting") till it finishes (which basically will show you the endresult)...
==> and if you touch any CE window (incl form), it'll seem to "hang"... till the function finishes of course. Which is the 2nd reason why having the function/script running async !

And as #ParkourPenguin states: gui updates must be executed using 'synchronize()'; as how i have set it. But based on my observation, synchronize will only "behave" as such if/when the function (or script) is set in a async state (~ if i'm wording this correctly)

If you need a small example table/form, let me know.
Back to top
View user's profile Send private message
panraven
Grandmaster Cheater
Reputation: 61

Joined: 01 Oct 2008
Posts: 958

PostPosted: Fri Nov 15, 2024 3:23 pm    Post subject: Reply with quote

Usually event handler should be run short, as if it not exit the handling function, it may block other event to be handle.

If your handler may start a long processing, it is better do it in a timer (if it is repeating, or can be simulate as a state machine), or spawn an os thread.

Not sure if following can illustrate the point or match your problem, but hope it can be useful.

It use a module from my github which need internet access.

Code:

if not CEO then
  CEO = GetInternet().GetURL'https://raw.githubusercontent.com/wolfoops/XKCE/master/ceo.lua'
  CEO = CEO and #CEO > 200 and load(CEO)
  CEO = CEO and CEO()
end
local UI = CEO and CEO.ceo_upd
if not UI then error'CEO not load'end

-- test form
local frm = UI(createForm()){
  Caption ='CntTest', Name='CntTest', OnClose = function() return caFree end,
  Constraints = { minWidth = 300, minHeight = 200 }, BorderStyle= bsSizeable,
  Button{ Name ='btnTimer',  Caption='Timer',  Top = 0, AutoSize = true},
  Button{ Name ='btnLongSleep', Caption='Loop Sleep Long', Top = 30, AutoSize = true} ,
  Button{ Name ='btnShortSleep',  Caption='Loop Sleep Short',  Top = 60, AutoSize = true},
  Button{ Name ='btnStep',  Caption='Step and stop others ',  Top = 90, AutoSize = true},
  Label{  Name ='lbRun', Caption='IDLE', Top = 0, Left = 200, AutoSize = true},
  Label{  Name ='lbCnt', Caption='#Count', Top = 30, Left = 200, AutoSize = true},
  Label{  Name ='otherCnt', Caption='#other cnt', Top = 60, Left = 200, AutoSize = true},
}
frm.Show()

-- some UI helper

local function inc(o)
  return function(dir)
    dir = tonumber(dir) or 1
    local caption = o.Caption
    local cnt = tonumber(caption) or 0
    synchronize(o.SetCaption,(cnt + dir) % 100)
  end
end

local function runMsg(run)
  synchronize(frm.lbRun.SetCaption, run and tostring(run) or '-oops-')
end

local ocnt = frm.otherCnt
local incOther = inc(ocnt)

local cnt = frm.lbCnt
local incCounter = inc(cnt)

-- the constant running counter
local otmr = createTimer(ocnt)
otmr.Interval, otmr.OnTimer = 50, incOther
----

-- state of other button handlers
local stopLong, stopShort, bTimer

-- use to stop other hanlders
local function stopOthers()
  runLong, runShort = false, false
  if bTimer then bTimer = nil, synchronize(bTimer.Destroy); return true end
end

-- handlers

-- btnStep
local step = frm.btnStep
step.OnClick = function(me)
  runMsg'Step'
  stopOthers()
  incCounter(-1)
end

-- btnTimer
local timer = frm.btnTimer
timer.OnClick = function(me)
  if stopOthers()then return end
  runMsg'Timer'
  bTimer = createTimer(me)
  bTimer.Interval, bTimer.OnTimer = 1000, incCounter
end

-- btnLongSleep (large ms)
local long = frm.btnLongSleep
local maxLongIter = 10
long.OnClick = function(me)
  if runLong then return end
  stopOthers()
  runLong = true
  local iter = 0
  runMsg'long'
  createThread(function(thd)
    while runLong and iter < maxLongIter do
      iter = iter + 1
      incCounter()
      sleep(1000)
    end
    runLong = false
    runMsg'IDLE'
  end)
end

-- btnShortSleep (small ms)
local short = frm.btnShortSleep
local maxShortIter = 200
short.OnClick = function(me)
  if runShort then return end
  stopOthers()
  runShort = true
  local iter = 0
  runMsg'Short'
  createThread(function(thd)
    while runShort and iter < maxShortIter do
      iter = iter + 1
      if (iter % 5) == 0 then incCounter(-1)end
      sleep(50)
    end
    runShort = false
    runMsg'IDLE'
  end)
end

_________________
- Retarded.
Back to top
View user's profile Send private message
paul44
Expert Cheater
Reputation: 2

Joined: 20 Jul 2017
Posts: 194

PostPosted: Sat Nov 16, 2024 2:51 am    Post subject: createthread seems the proper solution... Reply with quote

^ @panraven: "Usually event handler should be run short, as if it not exit the handling function, it may block other event to be handle".
=> which is indeed my biggest concern here; and i might come back on this in due time...

that said, in the meantime - and I had not read your response here - i had found this: [ https://www.cheatengine.org/forum/viewtopic.php?t=611040&sid=a123ea47687796ba46e7a1a85a5d490c ]; and have used that in my call script. And it now works as expected !
=> he did not mention the 'terminate()' method, which must be added (see below)

BIG question: is there a way to see if (particular/initiated) threads are effectively terminated ? Perhaps use a technique used here for timers: [ https://www.cheatengine.org/forum/viewtopic.php?t=618933&sid=ea8d85619a9513450cc63fbe2f1a3443 ] ?!
(which would allow one to kill the thread, if needed)
=> Btw: i ran [ms process explorer] to see when/where the thread would be added/removed, but it did not show any "particular/related" update...?

PS: consider the topic as closed; will leave it open for a couple of days for possible feedback...


[code] createThread(function (threadObj)
-- Loop until the thread is terminated..
while (not threadObj.Terminated) do
-- Sleep to prevent excessive CPU usage..
Sleep(100)

asmScan(0)
... (any other fn that need to run here)
analyse_Offset()

threadObj.terminate()
end
end)
[/code]


Last edited by paul44 on Sun Nov 17, 2024 4:16 am; edited 1 time in total
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 468

Joined: 09 May 2003
Posts: 25709
Location: The netherlands

PostPosted: Sat Nov 16, 2024 3:22 am    Post subject: Reply with quote

normally created threads will free themselves on return/exit/error unless you add the code threadobject.freeOnTerminate(false)

if you want to see if a thread has finished and it doesn't free itself on terminate, then you can check threadobject.Finished

You will have to call threadobject.destroy() when done.
Note that calling threadobject.destroy() will set Terminated to true and then wait until Finished is set, so you can also do that if you only need to know when it's done and then discard it.

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
AylinCE
Grandmaster Cheater Supreme
Reputation: 35

Joined: 16 Feb 2017
Posts: 1483

PostPosted: Sat Nov 16, 2024 7:04 am    Post subject: Reply with quote

(Off-topic)

Code:
if not CEO then
  CEO = GetInternet().GetURL'https://raw.githubusercontent.com/wolfoops/XKCE/master/ceo.lua'
  CEO = CEO and #CEO > 200 and load(CEO)
  CEO = CEO and CEO()
end
local UI = CEO and CEO.ceo_upd
if not UI then error'CEO not load'end

-- test form
local frm = UI(createForm()){
  Caption ='CntTest', Name='CntTest', OnClose = function() return caFree end,
  Constraints = { minWidth = 300, minHeight = 200 }, BorderStyle= bsSizeable,
  Button{ Name ='btnTimer',  Caption='Timer',  Top = 0, AutoSize = true},
  Button{ Name ='btnLongSleep', Caption='Loop Sleep Long', Top = 30, AutoSize = true} ,
  Button{ Name ='btnShortSleep',  Caption='Loop Sleep Short',  Top = 60, AutoSize = true},
  Button{ Name ='btnStep',  Caption='Step and stop others ',  Top = 90, AutoSize = true},
  Label{  Name ='lbRun', Caption='IDLE', Top = 0, Left = 200, AutoSize = true},
  Label{  Name ='lbCnt', Caption='#Count', Top = 30, Left = 200, AutoSize = true},
  Label{  Name ='otherCnt', Caption='#other cnt', Top = 60, Left = 200, AutoSize = true},
}
frm.Show()


Am I the only one noticing these? Smile
@panraven is doing something and we are left unfamiliar with CE.
Code:
aa2 = "prt"

load("return registerLuaFunctionHighlight(aa2)")()

function prt(s) print(s) end

prt("hello lua")

-- After running the code, click on the prt text above and
-- create a prt example below. prt("my prt")


Thanks for the beautiful design examples @panraven.

_________________
Hi Hitler Different Trainer forms for you!
https://forum.cheatengine.org/viewtopic.php?t=619279
Enthusiastic people: Always one step ahead
Do not underestimate me Master: You were a beginner in the past
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
paul44
Expert Cheater
Reputation: 2

Joined: 20 Jul 2017
Posts: 194

PostPosted: Sun Nov 17, 2024 4:38 am    Post subject: feedback & update Reply with quote

^^ @Dark Byte: yep, i already noticed that. In fact, i tried to print the name of the thread, and got a nil error after the 'terminate' and outside the 'createthread'.
also came across this: [ https://www.cheatengine.org/forum/viewtopic.php?p=5743663&sid=b3cf17aae897feffd573f882ae3ce8d7 ]... Perfect example to get a pretty good idea on how to tackle gui updates.
=> still: I do get the 'thread' concept, but have to admit i hardly have "grip" on its implementation. In snippet mentioned above, my logic tells me that it will constantly (?) execute them functions till it encounters "a" terminate somehow. But: if it just/always executes the 3 fn - in that order - then why the loop ?
(I think i've tested this without the loop and then my 3 fn got executed instantly, rather then consecutively - or something of that order)
==> anyways: it is working fine now from within the form; so happy bunny...

^ @AylinCE: i actually tried out his example this morning, but ran into a 'Lua Panic' error. since this is not "directly" related to this topic, i've sent him a pm to tackle tihs offline as such...

Minor detail, but really not all that important: can the (animated gif ?) "clock_icon" - as shown in the addresslist - also be used on a form ?
(i'm assuming here it is/loaded_up_as part of CE)
Back to top
View user's profile Send private message
AylinCE
Grandmaster Cheater Supreme
Reputation: 35

Joined: 16 Feb 2017
Posts: 1483

PostPosted: Sun Nov 17, 2024 12:26 pm    Post subject: Re: feedback & update Reply with quote

paul44 wrote:
Minor detail, but really not all that important: can the (animated gif ?) "clock_icon" - as shown in the addresslist - also be used on a form ?
(i'm assuming here it is/loaded_up_as part of CE)


What if I said I've never seen it? It could be a feature I haven't used or come across.
(Maybe @Dark Byte has a comment on this.)

Here are some different ideas:

--( image result code: "Ekr1")
Code:
local tp3 = 10
local lf3 = 10

if mf2 then mf2.Destroy() mf2=nil end

mf2 = createForm()
mf2.Caption="test"

local spbtn = {}

for i=0, 40 do
spbtn["btn"..i] = createComponentClass('TSpeedButton', mf2)
spbtn["btn"..i].Parent = mf2
spbtn["btn"..i].Images = MainForm.mfImageList
spbtn["btn"..i].ImageIndex = i
spbtn["btn"..i].Height=25
spbtn["btn"..i].Width=25
spbtn["btn"..i].Left=lf3
spbtn["btn"..i].Top=tp3
spbtn["btn"..i].OnClick=function() print("Image Index: " .. i) end

lf3=tonumber(lf3) + 35
--print(i .. " - " .. lf3)
if lf3==360 then lf3=10 tp3=tonumber(tp3) + 35 end
end

spbtn.bckpnl1 = createPanel(mf2)
spbtn.bckpnl1.Height=35
spbtn.bckpnl1.Width=35
spbtn.bckpnl1.Left=10
spbtn.bckpnl1.Top=180

spbtn.btn7.Parent=spbtn.bckpnl1
spbtn.btn7.Left=5
spbtn.btn7.Top=5

if gftmr1 then gftmr1.Destroy() gftmr1=nil end

gftmr1=createTimer()
gftmr1.Interval=1000
gftmr1.Enabled=false

gftmr1.OnTimer=function()
spbtn.bckpnl1.Color = (spbtn.bckpnl1.Color + 100001)
end

mf2.OnClick = function() -- form click..
  if gftmr1.Enabled==false then
    gftmr1.Enabled=true
  else
    gftmr1.Enabled=false
  end
end


-- or gift: --( image result code: "Ekr2")
Code:
if fr3 then fr3.Destroy() fr3=nil end

fr3=createForm()
fr3.Caption="gif test"

img3=createImage(fr3)
img3.Height=100
img3.Width=100
img3.Left=30 img3.Top=50
img3.Stretch=true

pnl3=createPanel(fr3)
pnl3.Height=110
pnl3.Width=110
pnl3.Left=165 pnl3.Top=45

img4=createImage(pnl3)
img4.Height=100
img4.Width=100
img4.Left=5 img4.Top=2
img4.Stretch=true

if loadTimer then loadTimer.Destroy() loadTimer=nil end
loadTimer=createTimer() loadTimer.Interval=1000 / 6 loadTimer.Enabled=false

function createPictureFromURL(url)
 http = getInternet()
 file = http.getURL(url)
 http.destroy()
 pct = createPicture()
 stream = createStringStream(file)
 pct.loadFromStream(stream)
 return pct
end

local picTbl3 = {}
local lnk1 = [[https://i.hizliresim.com/]]

local linkTbl3 = {"ritk1xn.png","p7tdfjo.png",
"bmrvmy3.png","luxigeo.png",
"gku655w.png","2kznd0u.png",
"1pncm56.png","dld3qyg.png",
"alszbml.png","796ljmf.png",
"ssoxcaf.png","nssydd3.png"}

for i=1, 12 do -- my gif picture max 12..
  local pct1 = createPictureFromURL(lnk1..linkTbl3[i])
  table.insert(picTbl3, pct1)
end

img3.Picture = picTbl3[1]
img4.Picture = picTbl3[1]
local indx = 0
local img3start = 0
local img4start = 0

loadTimer.OnTimer=function()
  if img3start==1 then
    indx=tonumber(indx) + 1
    if indx==13 then indx=1 end
    img3.Picture = picTbl3[indx]
  end
  if img4start==1 then
    pnl3.Color = (pnl3.Color + 100001)
  end
  if img3start==0 and img4start==0 then
    loadTimer.Enabled=false
  end
end

img3.OnClick=function()
  if img3start==0 then
    img3start=1
    loadTimer.Enabled=true
  else
    img3start=0
    img3.Picture = picTbl3[1]
  end
end

img4.OnClick=function()
  if img4start==0 then
    img4start=1
    loadTimer.Enabled=true
  else
    img4start=0
  end
end



Ekr2.PNG
 Description:
 Filesize:  6.75 KB
 Viewed:  8539 Time(s)

Ekr2.PNG



Ekr1.PNG
 Description:
 Filesize:  14.89 KB
 Viewed:  8539 Time(s)

Ekr1.PNG



_________________
Hi Hitler Different Trainer forms for you!
https://forum.cheatengine.org/viewtopic.php?t=619279
Enthusiastic people: Always one step ahead
Do not underestimate me Master: You were a beginner in the past


Last edited by AylinCE on Mon Nov 18, 2024 1:38 pm; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Dark Byte
Site Admin
Reputation: 468

Joined: 09 May 2003
Posts: 25709
Location: The netherlands

PostPosted: Sun Nov 17, 2024 2:54 pm    Post subject: Reply with quote

the clock is just a canvas draw. A circle, and two lines drawn from the center to a x and y calculated using cos and sin
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
AylinCE
Grandmaster Cheater Supreme
Reputation: 35

Joined: 16 Feb 2017
Posts: 1483

PostPosted: Mon Nov 18, 2024 10:38 am    Post subject: Reply with quote

It's a bit of an old idea.
If it's edited, it'll make for a shorter and better code.
I think it'll give you an idea to start with.

Code:
function ClockMaker(f, height1, width1, leftX, topY)

if item then item.destroy() item = nil end
item = createImage(f)
item.Height=height1
item.Width=width1
item.Left=leftX
item.Top=topY
item.Stretch = true
local x0=tonumber(item.width / 2)
local y0=tonumber(item.height / 2)
local x10=tonumber(item.width / 2)
local y10=tonumber(item.height / 2)
local x20=tonumber(item.width / 2)
local y20=tonumber(item.height / 2)
local xx=tonumber(item.width / 2)

local r = y0 - 20
local x = x0
local x1 = x10
local x2 = x20
local xx1=item.Width/6
------------------------------------

if ix3 then ix3.destroy() ix3 = nil end
ix3 = createLabel(f)
ix3.Font.Size = item.Width / 12
ix3.Font.Style = "fsBold"
ix3.Font.Color = "0x00FF00"
ix3.AutoSize = false
ix3.Alignment= "taCenter"
ix3.Height = item.Height / 8
ix3.Width = item.Width / 2
ix3.Left = item.Left + (item.Width / 2) - (ix3.Width / 2)
ix3.Top = item.Top + item.Height / 4

local s = tonumber(os.date('%S'))
local m2 = tonumber(os.date('%M')) * 60
local h2 = tonumber(os.date('%I')) * 3600
--print(h2.." - "..m2.." - "..s)

local m = tonumber(os.date('%M')) local h = tonumber(os.date('%I'))
-------------------------------------
function test(timer)
local x,y = item.screenToClient(x,y)

local bm=item.picture.Bitmap
bm.Width=item.Width
bm.Height=item.Height
local Canvas = bm.Canvas

  Canvas.clear()
bm.Canvas.Brush.Color="0x2000a0";
bm.Canvas.roundRect(0, 0, item.Height, item.Width, item.Height, item.Width);

 r = math.random(x0)
 y = y0 - r
  if r < xx then r=xx end
 s = s + 1
 x = x0 + math.floor(r * math.sin(s * math.pi/30))
 y = y0 - math.floor(r * math.cos(s * math.pi/30))

 r = math.random(x10)
  if r then r=xx - 15 end
local x1,y1 = item.screenToClient(x1,y1)
 y1 = y10 - r
 m2 = m2 + 1
 x1 = x10 + math.floor(r * math.sin(m2 * math.pi/1800))
 y1 = y10 - math.floor(r * math.cos(m2 * math.pi/1800))
  if r then r=xx - 40 end
local x2,y2 = item.screenToClient(x2,y2)
 y2 = y20 - r
 h2 = h2 + 1
 x2 = x20 + math.floor(r * math.sin(h2 * math.pi/21000))
 y2 = y20 - math.floor(r * math.cos(h2 * math.pi/21000))
  Canvas.pen.Color = "0xFFFFFF"
  Canvas.pen.Width = 2
  Canvas.line(x, y, xx, xx) --s
  Canvas.pen.Color = "0xFFFF00"
  Canvas.pen.Width = 4
  Canvas.line(x1, y1, xx, xx) --d
  Canvas.pen.Color = "0x00ffff"
  Canvas.pen.Width = 6
  Canvas.line(x2, y2 + 10, xx, xx) --h
  Canvas.pen.Color = "0xFF9000"
  Canvas.pen.Width = 3
  Canvas.line(xx1*6, xx1*3, xx1*5, xx1*3) --15 >> 3
  Canvas.line(xx1*3, xx1*6, xx1*3, xx1*5) --30 >> 6
  Canvas.line(0, xx1*3, xx1, xx1*3) --45 >> 9
  Canvas.line(xx1*3, xx1, xx1*3, 0) --60 >> 0-12

bm.TransparentColor=clBlack
item.Transparent=true
if s >= 60 then s=0  m=m + 1 end
if m >= 60 then m=0 h=h + 1 end
if h >= 13 then h=1 end
------------------------------------
  ix3.caption=(h..":"..m..":"..s)
ix3.bringToFront()
end

if t then t.destroy(); t=nil end
t=createTimer()
t.Interval = 1000
t.onTimer = test
end

--use of
--ClockMaker(f, height1, width1, leftX, topY)
--form = you Trainer name
ClockMaker(UDF1, 100, 100, 75, 50)



clkvct.png
 Description:
 Filesize:  4.39 KB
 Viewed:  8426 Time(s)

clkvct.png



_________________
Hi Hitler Different Trainer forms for you!
https://forum.cheatengine.org/viewtopic.php?t=619279
Enthusiastic people: Always one step ahead
Do not underestimate me Master: You were a beginner in the past
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
paul44
Expert Cheater
Reputation: 2

Joined: 20 Jul 2017
Posts: 194

PostPosted: Mon Nov 18, 2024 12:16 pm    Post subject: "thread" animation Reply with quote

^^ @AylinCE: "What if I said I've never seen it?"

see here [ https://ibb.co/jzzmz1k ]
=> i use/set this in particular when "seeding" lots of info (such as inventory) to the listbox. and: it is not just important to the user - who now visually sees it is still "in progress" - but also to me on development/testing end !

As for your examples/suggestions: I have quite a few things to do this week, but surely have a look by next weekend latest. If i'm "inspired", i will definitely get back to you... (via pm ~ if active @FRF, do pm me from there)

@Dark Byte: thx for that "mystery". one can probably find that code on github then.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites