Skysnake

.a3x Demo

25 posts in this topic

#1 ·  Posted (edited)

Several questions around the forum get asked repeatedly:

  1. How to avoid false-positive Anti-Virus detection? Answered by AutoIt god himself
  2. How to make AutoIt software safe from hacking?
  3. How to prevent AutoIt software being de-compiled?
  4. How to prevent exposure of native AutoIt code?

The general answers all go in the direction of (a) can't be done or (b) make it an .a3x script.

The Wiki contains a single entry under "compiler directives" and the Help File  contains mainly compiler info, with this note

Quote

Note: Scripts can be compiled with .a3x extension. They should be run with AutoIt.exe filename.a3x. The .a3x contains the script itself with all referred #include plus the FileInstall files. This format allows you to distribute smaller files as they don't include the AutoIt3.exe in each compiled script. You still need to have it accessible on the target machine but just AutoIt3.exe.

 

 

Also see this thread.

 

So I thought I would make a little demo to actually show how it works.

Here are the 2 scripts.  The a3x_demo.zip file contains these 2, plus the compiled .a3x file and the .EXE

 

The body

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile_type=a3x
#AutoIt3Wrapper_Outfile=a3x_demo.a3x
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#cs ----------------------------------------------------------------------------

    AutoIt Version: 3.3.14.2
    Author:         Skysnake

    Script Function:
    Demonstates working of a3x

    Instructions

    Code as normal
    Set Compiler option to .a3x as per Help File
    Compile
    Note output is (a) .a3x file,
    (b) now compile wrapper to make .exe file

    The compiled .a3x is included inside the .exe.

    To demonstrate, copy .exe to any new location and run. :)



#ce ----------------------------------------------------------------------------


; Script Start
#include <MsgBoxConstants.au3>

MsgBox($MB_SYSTEMMODAL, "a3x demo", "This message box is called from an a3x pre-compiled script " & @CRLF & "will timeout after 10 seconds or select the OK button.", 10)

; code ends

 

The wrapper

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile=a3x_wrapper.exe
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#cs ----------------------------------------------------------------------------

    AutoIt Version: 3.3.14.2
    Author:         Skysnake

    Script Function:
    Wrapper for .a3x demo

    the INCLUDE line below forces the .a3x to be included in the new .EXE

    other option is to use FileIsntall and then run the a3x_demo.a3x as an
    external file

    NOTE: required in order are the following steps
    1. body .au3 script
    2. compile body .au3 as .a3x file, include in wrapper
    3. wrapper .au3 script, to become the .exe -> compile as .EXE


#ce ----------------------------------------------------------------------------

; Script Start -

#include "a3x_demo.a3x"

; code ends

DOWNLOAD: The ax3_demo.zip file

 

EDIT:

2016.07.08 Fixed typos

Edited by Skysnake
added a link
2 people like this

Skysnake

Why is the snake in the sky?

Share this post


Link to post
Share on other sites



#3 ·  Posted (edited)

Dear @argumentum I am not sure how to interpret your response.  

This little demo was so supposed to show exactly how an .au3 file becomes an .a3x file and gets included in an .EXE.

AFAIK this is the only complete example in the Forum.  Thank you for reading. :)

 

Edited by Skysnake
Typo
1 person likes this

Skysnake

Why is the snake in the sky?

Share this post


Link to post
Share on other sites

I've tryed it because I has a program made in Autoit wich is use by a lot of people and I get a lot "False Positive".

It takes with every update about 3 weeks to report it to al virusscan company, because a lot of them reply very slow on these reports.

What I've discovered is that a lot of scanners stil mark it as virus when I use a3x file packed in a exe file but it are less then usally.

But I think it's a matter of time before viruscan company marks this way as virus as well.

 

Thanks for showing how to do this.

1 person likes this

Share this post


Link to post
Share on other sites

@nend thank you kindly


Skysnake

Why is the snake in the sky?

Share this post


Link to post
Share on other sites

@Skysnake,

it is understood that what this topic is all about is a demonstration of how to make a3x file distributable.

however, as for the reasons for doing so, i side with @argumentum here. in respect to the reasons you mention - it works, but does not do much. here's how:

On 7/7/2016 at 1:27 PM, Skysnake said:

How to avoid false-positive Anti-Virus detection?

working with your demo, i compiled it to exe directly (commented-out the wrapper directives). then i uploaded the directly-compiled exe to VirusTotal, as well as your pre-compiled wrapper using a3x.

links:     directly compiled     compiled using a3x

results:

directly compiled:

Antivirus Result Update
Antiy-AVL Trojan/Generic.ASVCS3S.1E5 20160719
McAfee-GW-Edition BehavesLike.Win32.Downloader.ch 20160719
Qihoo-360 QVM10.1.Malware.Gen 20160719

compiled using a3x:

Antivirus Result Update
Antiy-AVL Trojan/Generic.ASVCS3S.1E5 20160719
McAfee-GW-Edition BehavesLike.Win32.Downloader.ch 20160719

so there is some improvement. more interestingly, in addition to current observation (above), i think it should prove interesting to follow those links and re-scan from time to time.

 

as for the other 3 reasons you gave -

1) is it just me, or these are all rephrasing the same concept? :huh2:

2) the wrapped a3x and directly-compiled exe are both equally unprotected.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Dear @orbs, I could not find a complete example, so I made one and demonstrated it.

As to all your other comments, I did not intend, nor suggest that I could solve these.  The point was to show how it works.  The reasons why these problems remain fall beyond the scope of this demo.  I will admit that these appear valid, but are inherently part of the package we use, and beyond the scope of this example.

What is mentioned in some posts is to (a) install AutoIt, and then (b) run the .a3x as a stand-alone file using the AutoIt interpreter.  In this way the .a3x file escapes detection.  This is suggested to be the preferred option. Perhaps you want to run your virus scan like this?

Thank you. :)

 

Edited by Skysnake
typo

Skysnake

Why is the snake in the sky?

Share this post


Link to post
Share on other sites

I was thinking about all of this.

Somewhere @Melba23 uses the term "the .a3x file is tokenised" and I was wondering how far that tokenised file is form being binary?  If we can get the tokenised file converted to binary, would that solve the problems mentioned above?  

 


Skysnake

Why is the snake in the sky?

Share this post


Link to post
Share on other sites

This is good as far as it goes, but I'm wondering if you can give an example of running an A3x script with another compiled script?

Run(@ScriptDir & "BasicRunProgram.exe" ,"FileToruna3x.a3x")

I don't want to insert the a3x file, but run different a3x files in different places with the same compiled script... Is that possible? It sounds like it from the help file but I can't find, after quite a bit of searching, an example.

Thanks for reading.

Share this post


Link to post
Share on other sites

#10 ·  Posted

Graeme,

Look in the Help file under <Using AutoIt - Running Scripts - AutoIt specific command Line Switches - Run a script using another compiled script>. You run the .a3x files just as you would an standard .au3 file - the "Important Notes" section at the end of the page even suggests that this is the preferred method (and also explains why), as well as what you need to do to the master executable to ensure that it is permitted to run external scripts.

M23

 


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#11 ·  Posted

Dear Melba,

Thanks for your comments but sadly I had already seen that help file and not been able to make anything work. As well I was surprised that you said, just as you would a standard .au3 file. I've never run a standard au3 file other than by compiling it and running the exe file or from within the editor. This is why I was hoping for an example.

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Graeme,

Here are 3 files:

Example.exe is this script compiled to exe:

#pragma compile(AutoItExecuteAllowed, True)

Run("Example.exe /AutoIt3ExecuteScript Script.au3")

Run ("Example.exe /AutoIt3ExecuteScript Script.a3x")

Script.a3x is this script compiled to a3x:

#include <MsgBoxConstants.au3>

MsgBox($MB_SYSTEMMODAL, "Example", "Compiled a3x script")

Script.au3 is this script left as text:

; Note no include file n the au3 script as it will not necessarily be available

MsgBox(4096, "Example", "au3 script") ; So we need magic numbers instead

Run Example.exe and you will see the 2 MsgBoxes appear. Note that the .a3x file automatically includes the required MsgBoxConstants file when compiled - if you try running the same script as an .au3 file you are likely to get an error.

M23

Edited by Melba23
Added more detail
1 person likes this

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#13 ·  Posted

Thanks so much!!

Graeme

Share this post


Link to post
Share on other sites

#14 ·  Posted

Graeme,

My pleasure as always.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#15 ·  Posted

So now I'm using a3x files to get around the AV problem... I'm doing this by compiling my au3 files as a3x files and running them with

Run("C:\Program Files (x86)\QA\AutoIT3.exe" Example.a3x)

This works fine. The only problem I have is that whereas before I could use

if processexists("example.exe") do stuff

now I have several instances of autoit3.exe in the process lists and I can't find out how to distinguish between them... Is there a way?

Blessings

Share this post


Link to post
Share on other sites

#16 ·  Posted

Sure, I see 2 options:

  1. Use the _Singleton function with a unique name for each script
  2. Use the hidden window of each AutoIt3 session and set it to a unique name, which you then can test with WinExist()

Jos


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#17 ·  Posted

Thanks Jos!

Blessings

Share this post


Link to post
Share on other sites

#18 ·  Posted

Sorry, I think I'm a bit simple.

I tried to use the Singleton idea. I looked at the help and couldn't see how to set the string to identify the occurrence. I tried the name of the script and the name of the script without the extension but neither worked.

Blessings

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

12 hours ago, Graeme said:

Sorry, I think I'm a bit simple.

#include <Array.au3>
Global $sTitle = "let's call this a title, identifier, whatnot"
AutoItWinSetTitle($sTitle & Chr(1) & @AutoItPID)
Local $b, $n, $aMyScripts = WinList("[TITLE:" & $sTitle & ";CLASS:AutoIt v3;]")
ReDim $aMyScripts[UBound($aMyScripts)][3]
$aMyScripts[0][1] = "$hWindow"
$aMyScripts[0][2] = "@AutoItPID"
For $n = 1 To $aMyScripts[0][0]
    $b = StringSplit($aMyScripts[$n][0], Chr(1))
    $aMyScripts[$n][0] = $b[1]
    $aMyScripts[$n][2] = $b[2]
Next
_ArrayDisplay($aMyScripts, "this way you can ProcessClose(@AutoItPID) or WinKill($hWindow)")

; also
If WinExists($sTitle) Then Exit 123

That's it   =)

Edited by argumentum
more ideas :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Similar Content

    • Simpel
      By Simpel
      Hi.
      When I click 'open this script' in AutoIt Help the example isn't opening. I tried this (FixHelpFileExamples.au3):
      https://www.autoitscript.com/forum/topic/68828-opening-an-example-inside-autoitchm-in-scite/?do=findComment&comment=506522
      All is set. But 'open this script' not working. I tried that (batchfile):
      https://www.autoitscript.com/forum/topic/188272-resolved-random-failure-of-help-to-open-examples/
      This isn't working too.
      What I wonder if my mouse is over 'Copy to clipboard' my cursor is changing to a hand, showing there is a link. If I do the same over 'Open this Script' then mouse is showing the hand for very short time and then getting back to show the arrow. So if I move slowly the cursor over this link it's 'blinking' hand and arrow. What could this be?
      Regards, Conrad
    • Skysnake
      By Skysnake
      Hi
      I need help.
      I have re-installed AutoIt, but the problem persists.
      My script uses an #include <tourney_mymain.a3x> which Scite fails to read.  To be clear, as long as it is in .au3 format, it works.  The moment I build it as .a3x, it fails.
      ;#include <tourney_mymain.a3x> #include <tourney_mymain.au3> _MyMainFunc() The file tourney_mymain.au3 exists in the same folder, and the header looks like this
      #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Outfile_type=a3x #AutoIt3Wrapper_Outfile=C:\AutoIt\tourney\tourney_mymain.a3x #AutoIt3Wrapper_Run_AU3Check=n #AutoIt3Wrapper_Run_Tidy=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** The error looks like this:
      >"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "C:\AutoIt\tourney\tourney.au3" /UserParams +>16:13:57 Starting AutoIt3Wrapper v.16.306.1237.0 SciTE v.3.6.2.0 Keyboard:00000409 OS:WIN_10/ CPU:X64 OS:X64 Environment(Language:0409) CodePage:0 utf8.auto.check:4 # detect ascii high characters and if none found set default encoding to UTF8 and do not add BOM +> SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE UserDir => C:\Users\user\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper SCITE_USERHOME => C:\Users\user\AppData\Local\AutoIt v3\SciTE >Running Tidy (16.306.1237.0) from:C:\Program Files (x86)\AutoIt3\SciTE\tidy +>16:13:57 Tidy ended.rc:0 >Running AU3Check (3.3.14.2) from:C:\Program Files (x86)\AutoIt3 input:C:\AutoIt\tourney\tourney.au3 "C:\AutoIt\tourney\tourney.au3"(55,13) : error: _MyMainFunc(): undefined function. _MyMainFunc() ~~~~~~~~~~~~^ C:\AutoIt\tourney\tourney.au3 - 1 error(s), 0 warning(s) !>16:13:57 AU3Check ended. Press F4 to jump to next error.rc:2 +>16:13:57 AutoIt3Wrapper Finished. >Exit code: 2 Time: 1.028 When I toggle back to the .au3 file and compile/run, it works.
      >"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "C:\AutoIt\tourney\tourney.au3" /UserParams +>16:28:05 Starting AutoIt3Wrapper v.16.306.1237.0 SciTE v.3.6.2.0 Keyboard:00000409 OS:WIN_10/ CPU:X64 OS:X64 Environment(Language:0409) CodePage:0 utf8.auto.check:4 # detect ascii high characters and if none found set default encoding to UTF8 and do not add BOM +> SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE UserDir => C:\Users\user\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper SCITE_USERHOME => C:\Users\user\AppData\Local\AutoIt v3\SciTE >Running Tidy (16.306.1237.0) from:C:\Program Files (x86)\AutoIt3\SciTE\tidy +>16:28:06 Tidy ended.rc:0 >Running AU3Check (3.3.14.2) from:C:\Program Files (x86)\AutoIt3 input:C:\AutoIt\tourney\tourney.au3 +>16:28:06 AU3Check ended.rc:0 >Running:(3.3.14.2):C:\Program Files (x86)\AutoIt3\autoit3.exe "C:\AutoIt\tourney\tourney.au3" --> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop I was here! +>16:28:06 AutoIt3.exe ended.rc:0 +>16:28:06 AutoIt3Wrapper Finished. >Exit code: 0 Time: 1.066 Building the .a3x file, returns this:
      >"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /NoStatus /prod /in "C:\AutoIt\tourney\tourney_mymain.au3" +>16:29:01 Starting AutoIt3Wrapper v.16.306.1237.0 SciTE v.3.6.2.0 Keyboard:00000409 OS:WIN_10/ CPU:X64 OS:X64 Environment(Language:0409) CodePage:0 utf8.auto.check:4 # detect ascii high characters and if none found set default encoding to UTF8 and do not add BOM +> SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE UserDir => C:\Users\user\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper SCITE_USERHOME => C:\Users\user\AppData\Local\AutoIt v3\SciTE >Running Tidy (16.306.1237.0) from:C:\Program Files (x86)\AutoIt3\SciTE\tidy +>16:29:01 Tidy ended.rc:0 >Running:(3.3.14.2):C:\Program Files (x86)\AutoIt3\aut2exe\aut2exe.exe /in "C:\AutoIt\tourney\tourney_mymain.au3" /out "C:\Users\user\AppData\Local\AutoIt v3\Aut2exe\~AUDA33.tmp.a3x" /nopack /comp 2 +>16:29:02 Aut2exe.exe ended.C:\Users\user\AppData\Local\AutoIt v3\Aut2exe\~AUDA33.tmp.a3x. rc:0 +>16:29:02 Created program:C:\AutoIt\tourney\tourney_mymain.a3x +>16:29:02 AutoIt3Wrapper Finished. >Exit code: 0 Time: 1.718 And the header of the  contents of the .a3x file looks like this:
      £HK¾˜lJ©™LS †ÖH}AU3!EA06M¨ÿs$§<öz�ñg¬Á“çkCÊR¦­ á»:!¥)ãìç�˜.@½ášÞ€F±�k;!Ô±Öu:È=ÆÐ3÷�¯Ë�¢”���ˆþd•aç¶M�ø ,p~©=�ã™Õˆ ¬C�9˜�8öþ8_Yr©0h�d It looks like this in pure AutoIt:
      Func _MainFunc() ConsoleWrite("I was here!" & @CRLF) Local $sMainstatus = 'The database is empty' $Main = GUICreate("Roster", 640, 480) ; --- Top level menu Global $idHelpmenu = GUICtrlCreateMenu(" Help ") I have a similar AutoIT installation running on Windows 7, no problem.  The machine giving problems is Win 10.
      Any ideas would be appreciated.  This is a new pet project of mine and this is just the start, so I am willing to zip ALL of it and send it along if anyone wants to see inside.
      Thanks.
      Skysnake
    • spudw2k
      By spudw2k
      Here's a fun tool I put together.  It's a Plasma sandbox.  More features to come.

      This page was a useful resource for learning about this kind of Plasma implementation.
      Warning! Not Epileptic Friendly (probably)! Use at own Risk!
      I tried to curve the "default/initial" Plasma patterns so they aren't too erratic.  That doesn't mean you can't alter the Plasmas to be more erratic.  If you are sensitive to flashing colors and lights, use due caution.  
      #Region - Includes and Globals #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <ComboConstants.au3> #include <GuiComboBox.au3> #include <SliderConstants.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <GDIPlus.au3> #include <Misc.au3> ;#include <Array.au3> Opt("GUIOnEventMode", 1) Local $hDLL = DllOpen("user32.dll") Global Const $iWinMinWidth = @DesktopWidth * .25 Global Const $iWinMinHeight = @DesktopHeight * .25 Global $bIsPlaying = True, $bIsDrawing = False Global $hTimerFPS Global $iRows = 18, $iCols = 18 Global $iDisplayPlasma = 0, $iSelectPlasma = 0 Global $aPlasmaShapes[4] = ["($iX)", "($iY)", "($iX + $iY)", "Sqrt(($iX * $iX) + ($iY * $iY))"] Global $aPlasmas[4][7] = [[0, Random(6, 14, 1), 0, 0, 1, 0, 0], [1, Random(6, 14, 1), 0, 0, 0, 0, 0], [2, Random(8, 16,1 ), 0, 0, 1, 0, 0], [3, Random(8, 16, 1), 0, 0, Random(0,1,1), 0, 0]] ;Sine Wave | Spread | Position | Rotation | Spread Motion | Position Motion | Rotation Motion Global $aPallete[256] Global $aPalleteSettings[3][3] = [[0, 128, 128], [-1.75, 128, 128], [1.75, 128, 128]] ;Position | Spread | Value Global $aPalleteDefaults = $aPalleteSettings Global $iPalleteShift = 0, $bPalleteShift = True, $iPalletShiftDirection = -5 #EndRegion - Includes and Globals #Region - Main GUI Global $aGUI[1] = ["id|hWnd"] Global Enum $hGUI = 1, $idMnuFile, $idMnuFileExit, $idMnuFilePlay, $idMnuOptions, $idMnuOptionsPallete, $idMnuOptionsPalleteShift, $idMnuOptionsEditor, $idMnuOptionsZoom, $idMnuOptionsZoomIn, $idMnuOptionsZoomOut, $iGUILast ReDim $aGUI[$iGUILast] Global Const $sVersion = "0.1" Global Const $sTitle = "Plasma_kIt - Version " & $sVersion $aGUI[$hGUI] = GUICreate($sTitle, $iWinMinWidth, $iWinMinHeight, -1, -1, BitOR($WS_SIZEBOX, $WS_MAXIMIZEBOX, $WS_MINIMIZEBOX)) GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit") $aGUI[$idMnuFile] = GUICtrlCreateMenu("&File") $aGUI[$idMnuFilePlay] = GUICtrlCreateMenuItem("&Pause", $aGUI[$idMnuFile]) GUICtrlSetOnEvent(-1, "_PlayToggle") $aGUI[$idMnuFileExit] = GUICtrlCreateMenuItem("E&xit", $aGUI[$idMnuFile]) GUICtrlSetOnEvent(-1, "_Exit") $aGUI[$idMnuOptions] = GUICtrlCreateMenu("&Options") $aGUI[$idMnuOptionsPallete] = GUICtrlCreateMenuItem("Pallete Mixer", $aGUI[$idMnuOptions]) GUICtrlSetOnEvent(-1, "_GUIPallete_Show") $aGUI[$idMnuOptionsPalleteShift] = GUICtrlCreateMenuItem("Pallete Shift", $aGUI[$idMnuOptions]) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlSetOnEvent(-1, "_GUIPallete_ShiftToggle") $aGUI[$idMnuOptionsEditor] = GUICtrlCreateMenuItem("Plasma Editor", $aGUI[$idMnuOptions]) GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_Show") $aGUI[$idMnuOptionsZoom] = GUICtrlCreateMenu("Zoom", $aGUI[$idMnuOptions]) $aGUI[$idMnuOptionsZoomIn] = GUICtrlCreateMenuItem("Zoom In" & @TAB & "+", $aGUI[$idMnuOptionsZoom]) GUICtrlSetOnEvent(-1, "_Zoom") $aGUI[$idMnuOptionsZoomOut] = GUICtrlCreateMenuItem("Zoom Out" & @TAB & "-", $aGUI[$idMnuOptionsZoom]) GUICtrlSetOnEvent(-1, "_Zoom") _GDIPlus_Startup() ;Start GDI+ UDF Global Const $hDC = _WinAPI_GetDC($aGUI[$hGUI]) Global Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, @DesktopWidth, @DesktopHeight) Global Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC) Global Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap) $hBackbuffer = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer) ;_GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;Sets the graphics object rendering quality (antialiasing) $hBrush = _GDIPlus_BrushCreateSolid(0x00000000) ;Brush for Coloring/Painting LED Pixels Local $aAccelKeys[5][2] = [["{+}", $aGUI[$idMnuOptionsZoomIn]], ["{NUMPADADD}", $aGUI[$idMnuOptionsZoomIn]], ["{-}", $aGUI[$idMnuOptionsZoomOut]], ["{NUMPADSUB}", $aGUI[$idMnuOptionsZoomOut]], ["{pause}", $aGUI[$idMnuFilePlay]]] GUISetAccelerators($aAccelKeys) #EndRegion - Main GUI #Region - Pallete Mixer GUI Global $aGUIPallete[1] = ["id|hWnd"] Global Enum $hGUIPallete = 1, $idSliderRPosition, $idSliderRValue, $idSliderRSpread, $idSliderGPosition, $idSliderGValue, _ $idSliderGSpread, $idSliderBPosition, $idSliderBValue, $idSliderBSpread, $idBtnResetPallete, $iGUIPalleteLast ReDim $aGUIPallete[$iGUIPalleteLast] $aGUIPallete[$hGUIPallete] = GUICreate("Pallete Mixer", 338, 260, -1, -1) GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIPallete_Hide") $aGUIPallete[$idSliderRPosition] = GUICtrlCreateSlider(8, 132, 97, 33, $TBS_ENABLESELRANGE) GUICtrlSetLimit(-1, 20, -20) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderRValue] = GUICtrlCreateSlider(48, 56, 33, 73, BitOR($TBS_VERT, $TBS_ENABLESELRANGE)) GUICtrlSetLimit(-1, 128, 0) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderRSpread] = GUICtrlCreateSlider(8, 168, 97, 33, $TBS_ENABLESELRANGE) GUICtrlSetLimit(-1, 24, 2) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderGPosition] = GUICtrlCreateSlider(120, 132, 97, 33, $TBS_ENABLESELRANGE) GUICtrlSetLimit(-1, 20, -20) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderGValue] = GUICtrlCreateSlider(160, 56, 33, 73, BitOR($TBS_VERT, $TBS_ENABLESELRANGE)) GUICtrlSetLimit(-1, 128, 0) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderGSpread] = GUICtrlCreateSlider(120, 168, 97, 33, $TBS_ENABLESELRANGE) GUICtrlSetLimit(-1, 24, 2) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderBPosition] = GUICtrlCreateSlider(232, 132, 97, 33, $TBS_ENABLESELRANGE) GUICtrlSetLimit(-1, 20, -20) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") GUICtrlSetData(-1, 9) $aGUIPallete[$idSliderBValue] = GUICtrlCreateSlider(272, 56, 33, 73, BitOR($TBS_VERT, $TBS_ENABLESELRANGE)) GUICtrlSetLimit(-1, 128, 0) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderBSpread] = GUICtrlCreateSlider(232, 168, 97, 33, $TBS_ENABLESELRANGE) GUICtrlSetLimit(-1, 24, 2) GUICtrlSetData(-1, 11) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") GUICtrlCreateLabel("RED", 46, 200, 30, 20) GUICtrlCreateLabel("GREEN", 150, 200, 38, 20) GUICtrlCreateLabel("BLUE", 268, 200, 30, 20) $aGUIPallete[$idBtnResetPallete] = GUICtrlCreateButton("Reset", 136, 236, 67, 17) GUICtrlSetOnEvent(-1, "_GUIPallete_Reset") GUISetAccelerators($aAccelKeys) Global Const $hDCPallete = _WinAPI_GetDC($aGUIPallete[$hGUIPallete]) Global Const $hHBitmapPallete = _WinAPI_CreateCompatibleBitmap($hDCPallete, 320, 40) Global Const $hDC_backbufferPallete = _WinAPI_CreateCompatibleDC($hDCPallete) Global Const $DC_objPallete = _WinAPI_SelectObject($hDC_backbufferPallete, $hHBitmapPallete) Global Const $hBackbufferPallete = _GDIPlus_GraphicsCreateFromHDC($hDC_backbufferPallete) Global $hBrushPallete = _GDIPlus_BrushCreateSolid(0xFF000000) ;~ _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;Sets the graphics object rendering quality (antialiasing) _GUIPallete_Update() _GUIPallete_Reset() #EndRegion - Pallete Mixer GUI #Region - Plasma Editor GUI Global $aGUIPlasmaEditor[1] = ["id|hWnd"] Global Enum $hGUIPlasmaEditor = 1, $idCmbPlasmaSelector, $idCmbPlasmaDisplay, $idBtnPlasmaAdd, $idBtnPlasmaDel, $idCmbPlasmaShape, $idSliderPlasmaSpread, $idCmbPlasmaSpread, $idSliderPlasmaRotation, $idCmbPlasmaRotation, $idSliderPlasmaPosition, $idCmbPlasmaPosition, $iGUIPlasmaEditorLast ReDim $aGUIPlasmaEditor[$iGUIPlasmaEditorLast] $aGUIPlasmaEditor[$hGUIPlasmaEditor] = GUICreate("Plasma Editor", 419, 323, -1, -1) GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIPlasmaEditor_Hide") GUICtrlCreateLabel("Display", 16, 8, 95, 17) GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif") $aGUIPlasmaEditor[$idCmbPlasmaDisplay] = GUICtrlCreateCombo("", 16, 24, 121, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "All Combined|Selected Plasma", "All Combined") GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaDisplay") GUICtrlCreateLabel("Selected Plasma", 24, 96, 120, 17) GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif") $aGUIPlasmaEditor[$idBtnPlasmaAdd] = GUICtrlCreateButton("Add Plasma", 160, 16, 113, 33) GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaAddRem") GUICtrlSetState(-1, $GUI_DISABLE) $aGUIPlasmaEditor[$idBtnPlasmaDel] = GUICtrlCreateButton("Remove Plasma", 296, 16, 113, 33) GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaAddRem") GUICtrlSetState(-1, $GUI_DISABLE) GUICtrlCreateGroup("Plasma Controls", 8, 64, 401, 249) GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif") $aGUIPlasmaEditor[$idCmbPlasmaSelector] = GUICtrlCreateCombo("", 24, 112, 121, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "Plasma #1|Plasma #2|Plasma #3|Plasma #4", "Plasma #1") GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSelect") GUICtrlCreateLabel("Shape", 174, 96, 35, 17) $aGUIPlasmaEditor[$idCmbPlasmaShape] = GUICtrlCreateCombo("", 174, 112, 113, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "Horizontal|Vertical|Diagonal|Circular", "Horizontal") GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSetShape") GUICtrlCreateLabel("Spread", 24, 145, 38, 17) $aGUIPlasmaEditor[$idSliderPlasmaSpread] = GUICtrlCreateSlider(16, 160, 257, 25, $TBS_FIXEDLENGTH) GUICtrlSetLimit(-1, 255, 5) $aGUIPlasmaEditor[$idCmbPlasmaSpread] = GUICtrlCreateCombo("", 280, 160, 113, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "Static|Oscillate", "Static") GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSetSpread") GUICtrlCreateLabel("Rotation", 24, 201, 44, 17) GUICtrlSetState(-1, $GUI_DISABLE) $aGUIPlasmaEditor[$idSliderPlasmaRotation] = GUICtrlCreateSlider(16, 216, 257, 25, $TBS_FIXEDLENGTH) GUICtrlSetState(-1, $GUI_DISABLE) $aGUIPlasmaEditor[$idCmbPlasmaRotation] = GUICtrlCreateCombo("", 280, 216, 113, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "Static|Oscillate", "Static") GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSetRotation") GUICtrlSetState(-1, $GUI_DISABLE) GUICtrlCreateLabel("Position", 24, 257, 41, 17) GUICtrlSetState(-1, $GUI_DISABLE) $aGUIPlasmaEditor[$idSliderPlasmaPosition] = GUICtrlCreateSlider(16, 272, 257, 25, $TBS_FIXEDLENGTH) GUICtrlSetLimit(-1, 127, -127) GUICtrlSetState(-1, $GUI_DISABLE) $aGUIPlasmaEditor[$idCmbPlasmaPosition] = GUICtrlCreateCombo("", 280, 272, 113, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "Static|Oscillate", "Static") GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSetPosition") GUICtrlSetState(-1, $GUI_DISABLE) GUICtrlCreateGroup("", -99, -99, 1, 1) _GUIPlasmaEditor_PlasmaSettingsLoad($iSelectPlasma) ;_GUIPlasmaEditor_PlasmaControlsLock() GUISetAccelerators($aAccelKeys) #EndRegion - Plasma Editor GUI #Region - Initialization and Main Loop GUIRegisterMsg($WM_GETMINMAXINFO, "_WM_GETMINMAXINFO") GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") GUISetState(@SW_SHOW, $aGUI[$hGUI]) While 1 If $bIsPlaying And Not $bIsDrawing Then _DrawScreen(_RenderPlasma()) Sleep(10) WEnd #EndRegion - Initialization and Main Loop #Region - Main GUI Functions Func _DrawScreen($aPixels) ;If Function called while Drawing Return 0 If $bIsDrawing Then Return 0 ;Set Drawing Status Indictaor $bIsDrawing = True ;Create Timer for Drawing Performance/Duration Local $hTimer = TimerInit() ;Erase Bitmap Graphic _GDIPlus_GraphicsClear($hBackbuffer, 0xFFFFFFFF) ;Capture Client Window Size $aWinClientSize = WinGetClientSize($aGUI[$hGUI]) ;Setup Variables Local $iPixelIndex = 0 Local $iCol = $iCols Local $iRow = $iRows Local $iWidth = $aWinClientSize[0] / $iCol Local $iHeight = $aWinClientSize[1] / $iRow ;Draw Pixel Grid (Top-Left to Bottom Right) For $iY = 0 To $iRow - 1 For $iX = 0 To $iCol - 1 Local $dARGB = $aPixels[$iPixelIndex] ;Set Brush Color _GDIPlus_BrushSetSolidColor($hBrush, $dARGB) ;Draw "Pixel" _GDIPlus_GraphicsFillRect($hBackbuffer, $iX * $iWidth, $iY * $iHeight, $iWidth, $iHeight, $hBrush) ;Increment Pixel Counter $iPixelIndex += 1 If $iPixelIndex = UBound($aPixels) Then $iPixelIndex = 0 Next Next ;Draw Bitmap to Screen _WinAPI_BitBlt($hDC, 0, 0, $aWinClientSize[0], $aWinClientSize[1], $hDC_backbuffer, 0, 0, $SRCCOPY) ;blit drawn bitmap to GUI ;FPS Counter $hTimer = TimerDiff($hTimer) ;~ ConsoleWrite("Whole Process time: " & Round($hTimer / 1000, 3) & @CRLF) If $bIsPlaying Then If TimerDiff($hTimerFPS) >= 998 Then Local $iFPS = Round(1000 / $hTimer, 2) WinSetTitle($aGUI[$hGUI], "", $sTitle & " (" & $iFPS & " FPS)") $hTimerFPS = TimerInit() EndIf Else ;Show FPS in Window Title WinSetTitle($aGUI[$hGUI], "", $sTitle) EndIf $bIsDrawing = False EndFunc ;==>_DrawScreen Func _Exit() ; Clean up resources _GUIPallete_Exit() GUIDelete($aGUIPallete[$hGUIPallete]) GUIDelete($aGUIPlasmaEditor[$hGUIPlasmaEditor]) GUIDelete($aGUI[$hGUI]) _GDIPlus_BrushDispose($hBrush) _GDIPlus_GraphicsDispose($hBackbuffer) _WinAPI_SelectObject($hDC, $DC_obj) _WinAPI_DeleteObject($hHBitmap) _WinAPI_ReleaseDC($hGUI, $hDC) _GDIPlus_Shutdown() DllClose($hDLL) Exit EndFunc ;==>_Exit Func _PlayToggle() ;Toggle Play State If Not $bIsPlaying Then ;Start Playing $bIsPlaying = True $hTimerFPS = TimerInit() GUICtrlSetData($aGUI[$idMnuFilePlay], "&Pause") Else ;Stop Playing $bIsPlaying = False GUICtrlSetData($aGUI[$idMnuFilePlay], "&Play") EndIf EndFunc ;==>_PlayToggle Func _RenderPlasma() ;Setup Variables Local $aWorkPallete = $aPallete Local $iRow = $iRows Local $iCol = $iCols Local $iGridSize = $iRow * $iCol Local $aPixels[$iGridSize] Local $iIndex = 0 Local $iPlasma = 0 Local $iPlasmas Local $iDisplayPlasmaNumber = $iDisplayPlasma Local $iSine, $iSpread, $iPosition ;Loop Through Pixel Grid and Calculate Plasma(s) For $iY = 0 To $iRow - 1 For $iX = 0 To $iCol - 1 $iPlasmas = 0 If Not $iDisplayPlasmaNumber Then For $iZ = 0 To UBound($aPlasmas) - 1 $iSine = $aPlasmas[$iZ][0] ;Spread Motions If $aPlasmas[$iZ][4] Then $aPlasmas[$iZ][4] += ($aPlasmas[$iZ][1] * 0.00001125) $iSpread = -7*Sin($aPlasmas[$iZ][4])+9 Else $iSpread = $aPlasmas[$iZ][1] EndIf $iPosition = $aPlasmas[$iZ][2] $iPlasma = Execute("128.0 + (128.0 * Sin(" & $aPlasmaShapes[$iSine] & " / " & $iSpread & "))") $iPlasmas += $iPlasma Next Else $iSine = $aPlasmas[$iDisplayPlasmaNumber - 1][0] ;Spread Motions If $aPlasmas[$iDisplayPlasmaNumber - 1][4] Then $aPlasmas[$iDisplayPlasmaNumber - 1][4] += ($aPlasmas[$iDisplayPlasmaNumber - 1][1] * 0.005) $iSpread = Sin($aPlasmas[$iDisplayPlasmaNumber - 1][4])/2 Else $iSpread = $aPlasmas[$iDisplayPlasmaNumber - 1][1] EndIf $iPosition = $aPlasmas[$iDisplayPlasmaNumber - 1][2] ;$iPlasmas = Execute("128.0 + (128.0 * Sin(" & $aPlasmaShapes[$aPlasmas[$iDisplayPlasmaNumber - 1][0]] & " / " & $aPlasmas[$iDisplayPlasmaNumber - 1][1] & ") - " & $aPlasmas[$iDisplayPlasmaNumber - 1][2] & ")") $iPlasmas = Execute("128.0 + (128.0 * Sin(" & $aPlasmaShapes[$iSine] & " / " & $iSpread & "))") EndIf $iPlasma = Int($iPlasmas) ;Account for Pallete Shift $iPlasma += $iPalleteShift ;Wrap Pixel Pallete Color If $iPlasma >= 256 Then Do $iPlasma -= 256 Until $iPlasma < 256 EndIf If $iPlasma <= -1 Then Do $iPlasma += 256 Until $iPlasma > -1 EndIf ;Set Pixel Color value from Pallete $aPixels[$iIndex] = $aWorkPallete[$iPlasma] ;Increment Pixel Index Counter $iIndex += 1 If $iIndex = $iGridSize Then $iIndex = 0 Next Next ;Pallete Shift Logic If $bPalleteShift Then $iPalleteShift += $iPalletShiftDirection If $iPalleteShift >= 256 Then $iPalleteShift = 0 If $iPalleteShift <= -1 Then $iPalleteShift = 255 EndIf Return $aPixels EndFunc ;==>_RenderPlasma Func _WM_GETMINMAXINFO($hwnd, $Msg, $wParam, $lParam) ;Only Control Size of Main GUI If $hwnd <> $aGUI[$hGUI] Then Return Default $tagMaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam) DllStructSetData($tagMaxinfo, 7, $iWinMinWidth) ; min X DllStructSetData($tagMaxinfo, 8, $iWinMinHeight) ; min Y Return 0 EndFunc ;==>_WM_GETMINMAXINFO Func _WM_NOTIFY($hwnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") ;Local $tInfo If Not _IsPressed("01", $hDLL) Then Return Default Switch $iIDFrom Case $aGUIPallete[$idSliderRPosition] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(0, -1, GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderRValue] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(0, GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderRSpread] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(0, -1, "", GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderGPosition] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(1, -1, GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderGValue] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(1, GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderGSpread] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(1, -1, "", GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderBPosition] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(2, -1, GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderBValue] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(2, GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderBSpread] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(2, -1, "", GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPlasmaEditor[$idSliderPlasmaSpread] Switch $iCode Case $NM_CUSTOMDRAW $aPlasmas[$iSelectPlasma][1] = 0.2 * GUICtrlRead($iIDFrom) EndSwitch Return 0 Case $aGUIPlasmaEditor[$idSliderPlasmaRotation] Switch $iCode Case $NM_CUSTOMDRAW EndSwitch Return 0 Case $aGUIPlasmaEditor[$idSliderPlasmaPosition] Switch $iCode Case $NM_CUSTOMDRAW $aPlasmas[$iSelectPlasma - 1][2] = GUICtrlRead($iIDFrom) EndSwitch Return 0 EndSwitch Return 0 EndFunc ;==>_WM_NOTIFY Func _Zoom() Local $bPlaying = $bIsPlaying If $bPlaying Then $bIsPlaying = False Local $iCtrlID = @GUI_CtrlId Switch $iCtrlID Case $aGUI[$idMnuOptionsZoomOut] $iCols += 4 $iRows += 4 If $iCols >= 4 * 20 Then $iCols = 4 * 20 If $iRows >= 4 * 20 Then $iRows = 4 * 20 Case $aGUI[$idMnuOptionsZoomIn] $iCols -= 2 $iRows -= 2 If $iCols <= 4 Then $iCols = 4 If $iRows <= 4 Then $iRows = 4 EndSwitch If $bPlaying Then $bIsPlaying = $bPlaying EndFunc ;==>_Zoom #EndRegion - Main GUI Functions #Region - Pallete Mixer GUI Functions Func _GUIPallete_ColorSet($iColor, $iValue = -1, $iPosition = "", $iSpread = "") If $iValue >= 0 Then $aPalleteSettings[$iColor][2] = (128.0 - $iValue) If $iPosition Then $aPalleteSettings[$iColor][0] = (0.25 * $iPosition) If $iSpread Then $aPalleteSettings[$iColor][1] = ($iSpread ^ 2) Return _GUIPallete_Update() EndFunc ;==>_GUIPallete_ColorSet Func _GUIPallete_Draw() ;Draw Color Pallete in Palette Mixer GUI _GDIPlus_GraphicsClear($hBackbufferPallete, 0xFF000000) Local $iX = 0 For $iColor = 1 To 256 Local $dARGB = $aPallete[$iColor - 1] ;Set Brush Color _GDIPlus_BrushSetSolidColor($hBrushPallete, $dARGB) ;Draw Color Bar to Bitmap _GDIPlus_GraphicsFillRect($hBackbufferPallete, $iX, 0, 320 / 256, 40, $hBrushPallete) $iX += (320 / 256) Next ;Write Bitmap to Screen Return _WinAPI_BitBlt($hDCPallete, 8, 8, 320, 40, $hDC_backbufferPallete, 0, 0, $SRCCOPY) ;blit drawn bitmap to GUI EndFunc ;==>_GUIPallete_Draw Func _GUIPallete_Exit() ; Clean up resources GUIDelete() _GDIPlus_BrushDispose($hBrushPallete) _GDIPlus_GraphicsDispose($hBackbufferPallete) _WinAPI_SelectObject($hDCPallete, $DC_objPallete) _WinAPI_DeleteObject($hHBitmapPallete) _WinAPI_ReleaseDC($aGUIPallete[$hGUIPallete], $hDCPallete) Return 1 EndFunc ;==>_GUIPallete_Exit Func _GUIPallete_Hide() Return GUISetState(@SW_HIDE, $aGUIPallete[$hGUIPallete]) EndFunc ;==>_GUIPallete_Hide Func _GUIPallete_Reset() $aPalleteSettings = $aPalleteDefaults GUICtrlSetData($aGUIPallete[$idSliderRPosition], $aPalleteSettings[0][0] / 0.25) GUICtrlSetData($aGUIPallete[$idSliderRValue], 128 - $aPalleteSettings[0][2]) GUICtrlSetData($aGUIPallete[$idSliderRSpread], Sqrt($aPalleteSettings[0][1])) GUICtrlSetData($aGUIPallete[$idSliderGPosition], $aPalleteSettings[1][0] / 0.25) GUICtrlSetData($aGUIPallete[$idSliderGValue], 128 - $aPalleteSettings[1][2]) GUICtrlSetData($aGUIPallete[$idSliderGSpread], Sqrt($aPalleteSettings[1][1])) GUICtrlSetData($aGUIPallete[$idSliderBPosition], $aPalleteSettings[2][0] / 0.25) GUICtrlSetData($aGUIPallete[$idSliderBValue], 128 - $aPalleteSettings[2][2]) GUICtrlSetData($aGUIPallete[$idSliderBSpread], Sqrt($aPalleteSettings[2][1])) Return _GUIPallete_Update() EndFunc ;==>_GUIPallete_Reset Func _GUIPallete_ShiftToggle() ;Toggle Pallete Shift Local $iCtrlState = GUICtrlRead(@GUI_CtrlId) If BitAND($iCtrlState, $GUI_CHECKED) Then ;Disable PalleteShift $bPalleteShift = False GUICtrlSetState(@GUI_CtrlId, $GUI_UNCHECKED) Else ;Enable PalleteShift $bPalleteShift = True GUICtrlSetState(@GUI_CtrlId, $GUI_CHECKED) EndIf EndFunc ;==>_GUIPallete_ShiftToggle Func _GUIPallete_Show() GUISetState(@SW_SHOW, $aGUIPallete[$hGUIPallete]) _GUIPallete_Draw() EndFunc ;==>_GUIPallete_Show Func _GUIPallete_Update() ;Re-Calculate Work Color Pallete For $iStep = 0 To 255 Local $iR = Int($aPalleteSettings[0][2] + ($aPalleteSettings[0][2] * Sin((3.1415 * $iStep / $aPalleteSettings[0][1]) - $aPalleteSettings[0][0]))) Local $iG = Int($aPalleteSettings[1][2] + ($aPalleteSettings[1][2] * Sin((3.1415 * $iStep / $aPalleteSettings[1][1]) - $aPalleteSettings[1][0]))) Local $iB = Int($aPalleteSettings[2][2] + ($aPalleteSettings[2][2] * Sin((3.1415 * $iStep / $aPalleteSettings[2][1]) - $aPalleteSettings[2][0]))) $aPallete[$iStep] = "0xFF" & Hex($iR, 2) & Hex($iG, 2) & Hex($iB, 2) Next Return _GUIPallete_Draw() EndFunc ;==>_GUIPallete_Update #EndRegion - Pallete Mixer GUI Functions #Region - Plasma Editor GUI Functions Func _GUIPlasmaEditor_Hide() GUISetState(@SW_HIDE, $aGUIPlasmaEditor[$hGUIPlasmaEditor]) EndFunc ;==>_GUIPlasmaEditor_Hide Func _GUIPlasmaEditor_PlasmaAddRem() EndFunc ;==>_GUIPlasmaEditor_PlasmaAddRem Func _GUIPlasmaEditor_PlasmaDisplay() Local $sSelection = GUICtrlRead($aGUIPlasmaEditor[$idCmbPlasmaDisplay]) If $sSelection = "All Combined" Then $iDisplayPlasma = 0 Else $iDisplayPlasma = _GUICtrlComboBox_GetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSelector])+1 EndIf Return $iDisplayPlasma EndFunc ;==>_GUIPlasmaEditor_PlasmaDisplay Func _GUIPlasmaEditor_PlasmaSelect() Local $sSelection = GUICtrlRead($aGUIPlasmaEditor[$idCmbPlasmaSelector]) $iSelectPlasma = _GUICtrlComboBox_GetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSelector]) _GUIPlasmaEditor_PlasmaDisplay() Return _GUIPlasmaEditor_PlasmaSettingsLoad($iSelectPlasma) EndFunc ;==>_GUIPlasmaEditor_PlasmaSelect Func _GUIPlasmaEditor_PlasmaSetPosition() EndFunc ;==>_GUIPlasmaEditor_PlasmaSetPosition Func _GUIPlasmaEditor_PlasmaSetRotation() EndFunc ;==>_GUIPlasmaEditor_PlasmaSetRotation Func _GUIPlasmaEditor_PlasmaSetShape() $aPlasmas[$iSelectPlasma][0] = _GUICtrlComboBox_GetCurSel($aGUIPlasmaEditor[$idCmbPlasmaShape]) EndFunc ;==>_GUIPlasmaEditor_PlasmaSetShape Func _GUIPlasmaEditor_PlasmaSetSpread() $aPlasmas[$iSelectPlasma][4] = _GUICtrlComboBox_GetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSpread]) EndFunc ;==>_GUIPlasmaEditor_PlasmaSetSpread Func _GUIPlasmaEditor_PlasmaSettingsLoad(ByRef $iPlasma) GUICtrlSetData($aGUIPlasmaEditor[$idSliderPlasmaSpread],$aPlasmas[$iPlasma][1]/0.2) _GUICtrlComboBox_SetCurSel($aGUIPlasmaEditor[$idCmbPlasmaShape],$aPlasmas[$iPlasma][0]) If $aPlasmas[$iPlasma][4] Then _GUICtrlComboBox_SetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSpread],1) Else _GUICtrlComboBox_SetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSpread],0) EndIf Return 1 EndFunc ;==>_GUIPlasmaEditor_PlasmaSettingsLoad Func _GUIPlasmaEditor_Show() GUISetState(@SW_SHOW, $aGUIPlasmaEditor[$hGUIPlasmaEditor]) EndFunc ;==>_GUIPlasmaEditor_Show #EndRegion - Plasma Editor GUI Functions #Region - Obsolete ;~ Func _GUIPallete_SettingsChange() ;~ Local $iCtrlID = @GUI_CtrlId ;~ Switch $iCtrlID ;~ Case $aGUIPallete[$idSliderRPosition] ;~ Return _GUIPallete_ColorSet(0, -1, GUICtrlRead($iCtrlID)) ;~ Case $aGUIPallete[$idSliderRValue] ;~ Return _GUIPallete_ColorSet(0, GUICtrlRead($iCtrlID)) ;~ Case $aGUIPallete[$idSliderRSpread] ;~ Return _GUIPallete_ColorSet(0, -1, "", GUICtrlRead($iCtrlID)) ;~ Case $aGUIPallete[$idSliderGPosition] ;~ Return _GUIPallete_ColorSet(1, -1, GUICtrlRead($iCtrlID)) ;~ Case $aGUIPallete[$idSliderGValue] ;~ Return _GUIPallete_ColorSet(1, GUICtrlRead($iCtrlID)) ;~ Case $aGUIPallete[$idSliderGSpread] ;~ Return _GUIPallete_ColorSet(1, -1, "", GUICtrlRead($iCtrlID)) ;~ Case $aGUIPallete[$idSliderBPosition] ;~ Return _GUIPallete_ColorSet(2, -1, GUICtrlRead($iCtrlID)) ;~ Case $aGUIPallete[$idSliderBValue] ;~ Return _GUIPallete_ColorSet(2, GUICtrlRead($iCtrlID)) ;~ Case $aGUIPallete[$idSliderBSpread] ;~ Return _GUIPallete_ColorSet(2, -1, "", GUICtrlRead($iCtrlID)) ;~ EndSwitch ;~ Return 0 ;~ EndFunc ;==>_GUIPallete_SettingsChange ;~ Func _GUIPlasmaEditor_PlasmaControlsLock() ;~ Return _GUIPlasmaEditor_PlasmaControlsSetState($GUI_DISABLE) ;~ EndFunc ;==>_GUIPlasmaEditor_PlasmaControlsLock ;~ Func _GUIPlasmaEditor_PlasmaControlsUnLock() ;~ Return _GUIPlasmaEditor_PlasmaControlsSetState($GUI_ENABLE) ;~ EndFunc ;==>_GUIPlasmaEditor_PlasmaControlsUnLock ;~ Func _GUIPlasmaEditor_PlasmaControlsSetState($iState) ;~ If ($iState <> $GUI_ENABLE) And ($iState <> $GUI_DISABLE) Then Return SetError(1, 0, 0) ;~ GUICtrlSetState($aGUIPlasmaEditor[$idBtnPlasmaDel], $iState) ;~ GUICtrlSetState($aGUIPlasmaEditor[$idCmbPlasmaShape], $iState) ;~ GUICtrlSetState($aGUIPlasmaEditor[$idCmbPlasmaSpread], $iState) ;~ GUICtrlSetState($aGUIPlasmaEditor[$idCmbPlasmaRotation], $iState) ;~ GUICtrlSetState($aGUIPlasmaEditor[$idCmbPlasmaPosition], $iState) ;~ GUICtrlSetState($aGUIPlasmaEditor[$idSliderPlasmaSpread], $iState) ;~ GUICtrlSetState($aGUIPlasmaEditor[$idSliderPlasmaRotation], $iState) ;~ GUICtrlSetState($aGUIPlasmaEditor[$idSliderPlasmaPosition], $iState) ;~ Return 1 ;~ EndFunc ;==>_GUIPlasmaEditor_PlasmaControlsSetState #EndRegion - Obsolete edit: Minor bug fix
    • JohnOne
      By JohnOne
      There has been many questions about using tesseract of late.
      Here is a very basic example which works for me, along with the exact version of standalone tesseract executable and English language data used
      I found it some time ago at a time I thought I needed it, I do not recall from where.
      $ImageToReadPath = @ScriptDir & "\image.bmp" $ResultTextPath = @ScriptDir & "\Result" $OutPutPath = $ResultTextPath & ".txt" $TesseractExePath = @ScriptDir & "\Tesseract.exe" ShellExecuteWait($TesseractExePath, '"' & $ImageToReadPath & '" "' & $ResultTextPath & '"', "", "", @SW_HIDE) If @error Then Exit MsgBox(0, "Error", @error) EndIf MsgBox(0, "Result", FileRead($OutPutPath)) FileDelete($OutPutPath) Some Answers:
      The files contained in the download, only support English language.
      From the only documentation I got with this version...
      Original Binaries and Source can be found here: http://code.google.com/p/tesseract-ocr/ I do not know where to get other languages support.
      I do not know if there is a later standalone version.
      I do not know why it does not read your image accurately.
      It does not have a virus in it.
      You can search the forums or internet to learn how to create / cut / copy / paste, or otherwise manipulate your own images.
      TesseractExample.zip