Repository: FreeP4lestine/Lost-Crypto-Finder-Helper Branch: main Commit: 23e109c71713 Files: 48 Total size: 296.9 KB Directory structure: gitextract_bty5ohzv/ ├── .gitignore ├── GUIDefine.ahk ├── GUIDefine_Functions.ahk ├── GUIDefine_Hotkeys.ahk ├── GUIDefine_Labels.ahk ├── GUIDetails.ahk ├── GUIDetails_Functions.ahk ├── GUIDetails_Labels.ahk ├── GUIKridi.ahk ├── GUIKridiM.ahk ├── GUIKridiM_Functions.ahk ├── GUIKridiM_Hotkeys.ahk ├── GUIKridiM_Labels.ahk ├── GUIKridi_Functions.ahk ├── GUIKridi_Hotkeys.ahk ├── GUIKridi_Labels.ahk ├── GUIReview.ahk ├── GUIReview_Functions.ahk ├── GUIReview_Hotkeys.ahk ├── GUIReview_Labels.ahk ├── GUISell.ahk ├── GUISell_Functions.ahk ├── GUISell_Hotkeys.ahk ├── GUISell_Labels.ahk ├── GUISubmit.ahk ├── GUISubmit_Functions.ahk ├── GUISubmit_Hotkeys.ahk ├── GUISubmit_Labels.ahk ├── GUIUpdate.ahk ├── GUIUser.ahk ├── GUIUser_Functions.ahk ├── GUIUser_Hotkeys.ahk ├── GUIUser_Labels.ahk ├── GenerateRelease.ahk ├── Import.ahk ├── Install.ahk ├── Lib/ │ ├── Classes/ │ │ ├── Class_CtlColors.ahk │ │ ├── Class_GDIplus.ahk │ │ ├── Class_ImageButton.ahk │ │ └── Class_RichEdit.ahk │ └── Language.ahk ├── README.md ├── StartUp.ahk ├── Template.css ├── Template.html ├── Template.js ├── Uninstall.ahk └── Version.txt ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ __Compiler/ __Release/ CKr/ Curr/ Dump/ HighChart/ Hist/ Kr/ Sets/ Unvalid/ Valid/ *.ico ================================================ FILE: GUIDefine.ahk ================================================ #Requires AutoHotkey v1.1 #SingleInstance, Force SetBatchLines, -1 SetWorkingDir, % A_ScriptDir #Include, Lib\Classes\Class_CtlColors.ahk #Include, Lib\Classes\Class_ImageButton.ahk #Include, Lib\Classes\Class_GDIplus.ahk #Include, Lib\Language.ahk FolderSet() If !Level := LogIn(AdminName := A_Args[1], AdminPass := A_Args[2]) { FileRead, Reciever, Sets\Login.Hwnd FileOpen("Sets\Login.Request", "w").Write("Run|" A_ScriptFullPath).Close() SendMessage, 0x1000,,,, ahk_id %Reciever% Sleep, 1000 MsgBox, 16, % _112, % _114 ExitApp } Gui, +HwndMain +Resize Gui, Add, Pic, % "x0 y0", Img\BG.png Gui, Margin, 10, 10 Gui, Color, 0x7D7D3A Gui, Font, s14 Bold, Calibri qw := ((A_ScreenWidth - 255) // 5) Gui, Add, Text, % "xm+220 y30 vDbcT w" qw " h32 Center BackgroundTrans", % _56 ":" Gui, Add, Text, % "xp+" qw " yp wp hp Center BackgroundTrans", % _57 ":" Gui, Add, Text, % "xp+" qw " yp wp hp Center BackgroundTrans", % _58 ":" Gui, Add, Text, % "xp+" qw " yp wp hp Center BackgroundTrans", % _59 ":" Gui, Add, Text, % "xp+" qw " yp wp hp Center BackgroundTrans", % _176 ":" Gui, Font, s15 Gui, Add, Edit, % "xp-" qw * 4 " yp+32 wp Center Border vDbc -E0x200 cBlue" Gui, Add, Edit, % "xp+" qw " yp wp Center Border vDnm -E0x200" Gui, Add, Edit, % "xp+" qw " yp wp Center Border vDbp -E0x200 Number cRed" Gui, Add, Edit, % "xp+" qw " yp wp Center Border vDsp -E0x200 Number cGreen" Gui, Add, Edit, % "xp+" qw " yp wp Center Border vDst -E0x200" Gui, Font, s15 Gui, Add, ListView, % "xm+220 yp+75 w" qw * 5 " h" A_ScreenHeight - 280 " Grid vLV2 HwndHCtrl gEdit BackgroundE6E6E6", % _63 "|" _38 "|" _40 "|" _39 "|" _118 LV_ModifyCol(1, qw) LV_ModifyCol(2, qw) LV_ModifyCol(3, qw) LV_ModifyCol(4, qw) LV_ModifyCol(5, qw) Gui, Font, s17 Gui, Add, Edit, % "xp+" qw*3 " yp+" A_ScreenHeight - 275 " w" qw*2 " Center vStockSum -E0x200 HwndHCtrl Border" CtlColors.Attach(HCtrl, "EAEAB5") ButtonTheme := [[3, 0x80FF80, 0x5ABB5A, 0x000000, 2,, 0x008000, 1] , [3, 0x44DB44, 0x2F982F, 0x000000, 2,, 0x008000, 1] , [3, 0x1AB81A, 0x107410, 0x000000, 2,, 0x008000, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0x999999, 1]] ButtonTheme2 := [[3, 0x00E7E7, 0x02A0A0, 0x000000, 2,, 0x007E80, 1] , [3, 0x02CBCB, 0x028080, 0x000000, 2,, 0x007E80, 1] , [3, 0x03A4A4, 0x036767, 0x000000, 2,, 0x007E80, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0x999999, 1]] ButtonTheme3 := [[3, 0xFFC488, 0xBF9264, 0x000000, 2,, 0x804000, 1] , [3, 0xE0AB75, 0x96724E, 0x000000, 2,, 0x804000, 1] , [3, 0xC29465, 0x826344, 0x000000, 2,, 0x804000, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0x999999, 1]] ButtonTheme4 := [[3, 0xFF6F6F, 0xBC5454, 0x000000, 2,, 0xFF0000, 1] , [3, 0xDC6262, 0x9C4545, 0x000000, 2,, 0xFF0000, 1] , [3, 0xBF5454, 0x8A3C3C, 0x000000, 2,, 0xFF0000, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0xFF0000, 1]] Gui, Add, Text, xm+5 ym w190 Center BackgroundTrans, % _200 Gui, Font, s14 Gui, Add, Text, wp BackgroundTrans, % _208 ":" Gui, Add, DDL, vViewMode wp AltSubmit gLoadProducts, % _209 "||" _210 Gui, Add, ListBox, % "0x100 wp r10 vGroup gDisplayGroup HwndHCtrl", % _74 CtlColors.Attach(HCtrl, "D8D8AD") Gui, Font, s13 Gui, Add, Button, % "wp h30 gAddGroup HwndHCtrl", % _183 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "w190 h30 gDelGroup HwndHCtrl", % _195 ImageButton.Create(HCtrl, ButtonTheme4*) Gui, Add, Button, % "xm+220 y100 wp h30 gEnter HwndHCtrl", % _36 " ↓" ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "xp+" qw*4 + (qw - 190) " yp w190 hp gEdit HwndHCtrl", % "↑ " _131 ImageButton.Create(HCtrl, ButtonTheme2*) Gui, Font, Italic Gui, Add, Button, % "xm+220 y" A_ScreenHeight - 130 " w100 h30 gFillForms HwndHCtrl", % _193 ImageButton.Create(HCtrl, ButtonTheme3*) Gui, Add, Button, % "xp+110 yp wp hp gResetAll HwndHCtrl", % _142 ImageButton.Create(HCtrl, ButtonTheme3*) Gui, Add, Button, % "xp+110 yp wp hp gDelete HwndHCtrl", % _130 ImageButton.Create(HCtrl, ButtonTheme3*) Gui, Add, Button, % "xp+110 yp wp hp gEsc HwndHCtrl", % _169 ImageButton.Create(HCtrl, ButtonTheme3*) Gui, Font Gui, Font, s12 Bold, Calibri Levels := ["Admin", "User"] Gui, Add, StatusBar SB_SetParts(10, 200, 200) SB_SetText(_206 ": " AdminName, 2) SB_SetText(_207 ": " Levels[Level], 3) Gui, Show, Maximize, Definition GUI ThemeAdd() LoadGroups() GuiControl, Choose, Group, |1 Return #Include, GUIDefine_Labels.ahk #Include, GUIDefine_Functions.ahk #Include, GUIDefine_Hotkeys.ahk ================================================ FILE: GUIDefine_Functions.ahk ================================================ LoadGroups() { Global _74 GuiControl,, Group, | GuiControl,, Group, % _74 Loop, Files, Sets\Def\*, D GuiControl,, Group, % A_LoopFileName GuiControl, Choose, Group, |1 } LogIn(Username, Password) { If (FileExist("Sets\Acc.chu")) { Account := {} FileRead, RawAccount, Sets\Acc.chu TextAccount := b64Decode(RawAccount) For Each, User in StrSplit(TextAccount, ",") { LOG := StrSplit(User, "|") Account[LOG[1]] := [LOG[2], LOG[3]] } If (Account[Username][1] = Password) { If (Account[Username][2] = "Admin") Return, 1 Else If (Account[Username][2] = "User") Return, 2 } } Return, 0 } b64Encode(string) { VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1 if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", 0, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) VarSetCapacity(buf, size << 1, 0) if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", &buf, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) return StrGet(&buf) } b64Decode(string) { if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", 0, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) VarSetCapacity(buf, size, 0) if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", &buf, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) return StrGet(&buf, size, "UTF-8") } LoadProducts() { LV_Delete(), Files := "", Loc := {} GuiControl,, StockSum Loop, Files, % "Sets\Def\*.def", R { Bc := StrReplace(A_LoopFileName, ".def") Files .= Files != "" ? "`n" Bc : Bc Loc["" Bc ""] := A_LoopFileFullPath } Sort, Files, N StockSum := 0 GuiControlGet, ViewMode,, ViewMode Loop, Parse, Files, `n { If (ViewMode = 2) && !FileExist("Sets\Def\" A_LoopField ".def") { Continue } FileRead, Content, % Loc["" A_LoopField ""] Content := StrSplit(Content, ";"), Content[4] != "" ? StockSum += Content[4] * Content[3] : 0 LV_Add(, A_LoopField, Content[1], Content[2], Content[3], "[" (Content[4] != "" ? Content[4] : 0) "]") GuiControl,, StockSum, % StockSum " " ConvertMillimsToDT(StockSum) } Return, StockSum } ConvertMillimsToDT(Value, Sign := "") { If (Value + 1 = "") Return ValueArr := StrSplit(Value / 1000, ".") Return, "[" ValueArr[1] (ValueArr[2] ? "." RTrim(ValueArr[2], 0) : "") " DT]" } FolderSet() { Array := [ "Curr" , "Sets" , "Sets\Def" , "Valid" , "Dump" , "Kr" , "CKr" , "Unvalid" , "Hist" ] For Every, Folder in Array { If !FolderExist(Folder) { FileCreateDir, % Folder } } } FolderExist(Folder) { Return InStr(FileExist(Folder), "D") } ThemeAdd() { Loop, 5 { Gui, Add, Text, % "y0 x" 208 + A_Index * 2 " w1 h" A_ScreenHeight " HwndHCtrl" CtlColors.Attach(HCtrl, "7D7D64") } } Add() { Global StockSum, _177, _178 GuiControlGet, Dbc,, Dbc ExistedDef := "" Loop, Files, % "Sets\Def\" Dbc ".def", R { ExistedDef := A_LoopFileFullPath } If (ExistedDef != "") { FileRead, Content, % ExistedDef MsgBox, 48, % _177, % _178 "`n`n" Dbc " = " StrSplit(Content, ";")[1] Return, 0 } GuiControlGet, Group,, Group WD := (Group = "ALL") ? "Sets\Def\" : "Sets\Def\" Group "\" GuiControlGet, Dnm,, Dnm GuiControlGet, Dbp,, Dbp GuiControlGet, Dsp,, Dsp GuiControlGet, Dst,, Dst LV_Insert(1,, Dbc, Dnm, Dbp, Dsp, "[" Dst "]") FileOpen(WD Dbc ".def", "w").Write(Dnm ";" Dbp ";" Dsp ";" Dst).Close() GuiControl,, Dbc GuiControl,, Dnm GuiControl,, Dbp GuiControl,, Dsp GuiControl,, Dst StockSum += Dsp * Dst GuiControl,, StockSum, % StockSum " " ConvertMillimsToDT(StockSum) GuiControl, Focus, Dbc FileOpen("Sets\Message.Request", "w").Write("Update_Definitions").Close() FileRead, Reciever, Sets\GUISell.Hwnd SendMessage, 0x1000,,,, ahk_id %Reciever% Return, 1 } Modify() { Global Row, _177, _178, StockSum GuiControlGet, Dbc,, Dbc LV_GetText(Bc, Row, 1) ExistedDef := "" Loop, Files, % "Sets\Def\" Dbc ".def", R { ExistedDef := A_LoopFileFullPath } If (Bc != Dbc) && (ExistedDef != "") { FileRead, Content, % ExistedDef MsgBox, 48, % _177, % _178 "`n`n" Dbc " = " StrSplit(Content, ";")[1] Return, 0 } ExistedDef := "" Loop, Files, % "Sets\Def\" Bc ".def", R { ExistedDef := A_LoopFileFullPath } If (ExistedDef != "") { SplitPath, % ExistedDef,, WD WD .= "\" } Else { GuiControlGet, Group,, Group WD := (Group = "ALL") ? "Sets\Def\" : "Sets\Def\" Group "\" } GuiControlGet, Dnm,, Dnm GuiControlGet, Dbp,, Dbp GuiControlGet, Dsp,, Dsp GuiControlGet, Dst,, Dst FileDelete, % WD Bc ".def" FileOpen(WD Dbc ".def", "w").Write(Dnm ";" Dbp ";" Dsp ";" Dst).Close() LV_GetText(St, Row, 5) LV_GetText(Sp, Row, 4) StockSum -= Trim(St, "[]") * Sp StockSum += Dsp * Dst LV_Modify(Row,, Dbc, Dnm, Dbp, Dsp, "[" Dst "]") GuiControl,, Dbc GuiControl,, Dnm GuiControl,, Dbp GuiControl,, Dsp GuiControl,, Dst GuiControl,, StockSum, % StockSum " " ConvertMillimsToDT(StockSum) GuiControl, Focus, Dbc FileOpen("Sets\Message.Request", "w").Write("Update_Definitions").Close() FileRead, Reciever, Sets\GUISell.Hwnd SendMessage, 0x1000,,,, ahk_id %Reciever% Return, 1 } VerifyInputs() { Global _181, _182, _177, _178 GuiControlGet, Dbc,, Dbc If (Dbc = "") { GuiControl, Focus, Dbc ShakeControl("Dbc") Return, 0 } GuiControlGet, Dnm,, Dnm If (Dnm = "") { GuiControl, Focus, Dnm ShakeControl("Dnm") Return, 0 } If InStr(Dnm, ";") { GuiControl, Focus, Dnm ShakeControl("Dnm") Return, 0 } GuiControlGet, Dbp,, Dbp If (Dbp = "") { GuiControl, Focus, Dbp ShakeControl("Dbp") Return, 0 } GuiControlGet, Dsp,, Dsp If (Dsp = "") { GuiControl, Focus, Dsp ShakeControl("Dsp") Return, 0 } GuiControlGet, Dst,, Dst If (Dst = "") { GuiControl, Focus, Dst ShakeControl("Dst") Return, 0 } Return, 1 } ShakeControl(Ctrl) { GuiControlGet, Pos, Pos, % Ctrl Loop, 5 { GuiControl, Move, % Ctrl, % "x" PosX -= 4 Sleep, 50 GuiControl, Move, % Ctrl, % "x" PosX += 4 Sleep, 50 } } ================================================ FILE: GUIDefine_Hotkeys.ahk ================================================ #If WinActive("ahk_id " Main) Enter:: If !VerifyInputs() Return If (!EditModOn) { Add() Return } If Modify() { EditModOn := 0 } Return Delete:: If (Row := LV_GetNext()) { LV_GetText(Bc, Row, 1) LV_GetText(St, Row, 5) LV_GetText(Sp, Row, 4) LV_Delete(Row) ExistedDef := "" Loop, Files, % "Sets\Def\" Bc ".def", R { ExistedDef := A_LoopFileFullPath } If (ExistedDef != "") FileDelete, % ExistedDef GuiControlGet, StockSum StockSum -= Trim(St, "[]") * Sp GuiControl,, StockSum, % StockSum " " ConvertMillimsToDT(StockSum) EditModOn := 0 } Return Esc:: GuiControl,, Dbc GuiControl,, Dnm GuiControl,, Dbp GuiControl,, Dsp GuiControl,, Dst EditModOn := 0 GuiControl, Focus, Dbc LoadProducts() Return ^!LButton:: MouseClick GoSub, FillForms Return ^F:: GuiControlGet, Group,, Group GuiControlGet, Dbc,, Dbc GuiControlGet, Dnm,, Dnm GuiControlGet, Dbp,, Dbp GuiControlGet, Dsp,, Dsp GuiControlGet, Dst,, Dst If (Group = "ALL") { If (Dbc != "") || (Dnm != "") || (Dst != "") || (Dbp != "") || (Dsp != "") { LV_Delete() Loop, Files, Sets\Def\*.def, R { FileRead, Content, % A_LoopFileFullPath Content := StrSplit(Content, ";") If InStr(StrReplace(A_LoopFileName, ".def"), Dbc) && InStr(Content[1], Dnm) && InStr(Content[2], Dbp) && InStr(Content[3], Dsp) && InStr(Content[4], Dst) { LV_Add(, StrReplace(A_LoopFileName, ".def"), Content[1], Content[2], Content[3], "[" (Content[4] != "" ? Content[4] : 0) "]") } } } } Else { If (Dbc != "") || (Dnm != "") || (Dst != "") || (Dbp != "") || (Dsp != "") { LV_Delete() Loop, Files, Sets\Def\%Group%\*.def { FileRead, Content, % A_LoopFileFullPath Content := StrSplit(Content, ";") If InStr(StrReplace(A_LoopFileName, ".def"), Dbc) && InStr(Content[1], Dnm) && InStr(Content[2], Dbp) && InStr(Content[3], Dsp) && InStr(Content[4], Dst) { LV_Add(, StrReplace(A_LoopFileName, ".def"), Content[1], Content[2], Content[3], "[" (Content[4] != "" ? Content[4] : 0) "]") } } } } Return #If ================================================ FILE: GUIDefine_Labels.ahk ================================================ DelGroup: GuiControlGet, Group,, Group If (Group != "ALL") { Msgbox, 36,% _187, % _194 " " Group " ?" IfMsgBox, Yes { Msgbox, 36,% _187, % _174 IfMsgBox, Yes { FileRemoveDir, % "Sets\Def\" Group, 1 LoadGroups() } } } Return FillForms: If (Row := LV_GetNext()) { LV_GetText(Dbc, Row, 1) LV_GetText(Dnm, Row, 2) LV_GetText(Dbp, Row, 3) LV_GetText(Dsp, Row, 4) LV_GetText(Dst, Row, 5) GuiControl,, Dbc, % Dbc GuiControl,, Dnm, % Dnm GuiControl,, Dbp, % Dbp GuiControl,, Dsp, % Dsp GuiControl,, Dst, % Trim(Dst, "[]") } Return AddGroup: InputBox, Groupname, % _184, % _185,, 300, 130 If !InStr(FileExist("Sets\Def\" Groupname), "D") && (Groupname != "ALL") { FileCreateDir, % "Sets\Def\" Groupname If (!ErrorLevel) { GuiControl,, Group, % Groupname } } Groupname := Groupname = "ALL" ? "" : Groupname "\" Row := 0 While (Row := LV_GetNext(Row)) { LV_GetText(Bc, Row, 1) Loop, Files, % "Sets\Def\" Bc ".def", R Src := A_LoopFileFullPath FileMove, % Src, % "Sets\Def\" Groupname Bc ".def" } GuiControl, ChooseString, Group, % "|" (Groupname = "" ? "ALL" : SubStr(Groupname, 1, -1)) Return ResetAll: GuiControlGet, Group,, Group If (Group = "ALL") { Loop, Files, Sets\Def\*.def, R { FileRead, Content, % A_LoopFileFullPath Content := StrSplit(Content, ";") FileOpen(A_LoopFileFullPath, "w").Write(Content[1] ";" Content[2] ";" Content[3] ";0").Close() } StockSum := LoadProducts() } Else { Loop, Files, Sets\Def\%Group%\*.def { FileRead, Content, % A_LoopFileFullPath Content := StrSplit(Content, ";") FileOpen(A_LoopFileFullPath, "w").Write(Content[1] ";" Content[2] ";" Content[3] ";0").Close() } GoSub, DisplayGroup } Return DisplayGroup: GuiControlGet, Group,, Group GuiControl,, StockSum If (GROUP != "ALL") { LV_Delete(), Files := "" Loop, Files, % "Sets\Def\" Group "\*.def" { Bc := StrReplace(A_LoopFileName, ".def") Files .= Files != "" ? "`n" Bc : Bc } Sort, Files, N StockSum := 0 Loop, Parse, Files, `n { FileRead, Content, % "Sets\Def\" Group "\" A_LoopField ".def" Content := StrSplit(Content, ";"), Content[4] != "" ? StockSum += Content[4] * Content[3] : 0 LV_Add(, A_LoopField, Content[1], Content[2], Content[3], "[" (Content[4] != "" ? Content[4] : 0) "]") GuiControl,, StockSum, % StockSum " " ConvertMillimsToDT(StockSum) } } Else { StockSum := LoadProducts() } Return Edit: If (Row := LV_GetNext()) { LV_GetText(Dbc, Row, 1) LV_GetText(Dnm, Row, 2) LV_GetText(Dbp, Row, 3) LV_GetText(Dsp, Row, 4) LV_GetText(Dst, Row, 5) GuiControl,, Dbc, % Dbc GuiControl,, Dnm, % Dnm GuiControl,, Dbp, % Dbp GuiControl,, Dsp, % Dsp GuiControl,, Dst, % Trim(Dst, "[]") EditModOn := 1 } Return GuiClose: IniDelete, Sets\PID.ini, PID, GUIDefine ExitApp ================================================ FILE: GUIDetails.ahk ================================================ #Requires AutoHotkey v1.1 #SingleInstance, Force SetBatchLines, -1 SetWorkingDir, % A_ScriptDir #Include, Lib\Classes\Class_CtlColors.ahk #Include, Lib\Classes\Class_ImageButton.ahk #Include, Lib\Classes\Class_GDIplus.ahk #Include, Lib\Language.ahk FolderSet() Gui, Color, 0xD8D8AD Gui, -MinimizeBox Gui, Font, s15 Bold, Calibri Gui, Margin, 5, 5 Gui, Add, ListBox, w200 h250 0x100 vReInLB gDisplayDetails AltSubmit Gui, Add, Edit, xp+210 yp w500 h200 ReadOnly vDInfo -E0x200 Border -VScroll Gui, Add, Edit, xp yp+212 ReadOnly w500 vOverAll -E0x200 Border cGreen Center h38 Gui, Font, s12 Underline Gui, Add, CheckBox, xm+600 yp+45 vShowMore gShowMore, % _170 Gui, Font, Norm Gui, Font, s15 Bold Gui, Add, Text, xm yp+30, % _123 ":" Gui, Add, Edit, xp yp+30 w300 vRemise ReadOnly -E0x200 Border cGreen Gui, Add, Text, xp yp+35, % _124 ":" Gui, Add, Edit, xp yp+30 w710 vClient -E0x200 Border ReadOnly cBlue Gui, Add, Text, xp yp+35 wp, % _125 ":" Gui, Add, Edit, xp yp+30 wp vSellDesc cBlue r10 -E0x200 Border ReadOnly -VScroll Gui, Show, h290 If (A_Args[1]) { FileRead, Content, %1% Content := StrSplit(Content, "> ") Sells := StrSplit(Content[2], "|") Array := {}, OverAll := 0 For Each, One in Sells { Section := StrSplit(One, ";") Array[A_Index] := [Section[1] ; Barcode , Section[2] ; Name , Section[3] ; SellStr , Section[4] ; Sells , Section[5] ; BuyStr , Section[6] ; Buys , Section[7]] ; Profit GuiControl,, ReInLB, % Array[A_Index][2] OverAll += Section[7] } GuiControl,, OverAll, % OverAll " " ConvertMillimsToDT(OverAll) If (Content[4]) { AddInfo := StrSplit(Content[4], ";") If (AddInfo[1]) GuiControl,, Remise, % AddInfo[1] " %" If (AddInfo[2]) GuiControl,, Client, % AddInfo[2] If (AddInfo[3]) GuiControl,, SellDesc, % AddInfo[3] } GuiControl, Choose, ReInLB, |1 } Return #Include, GUIDetails_Labels.ahk #Include, GUIDetails_Functions.ahk ================================================ FILE: GUIDetails_Functions.ahk ================================================ ConvertMillimsToDT(Value, Sign := "") { If (Value = "..." || !Value) Return ValueArr := StrSplit(Value / 1000, ".") Return, "(" (Sign ? " " Sign " " : "") ValueArr[1] (ValueArr[2] ? "." RTrim(ValueArr[2], 0) : "") " DT)" } FolderSet() { Array := [ "Curr" , "Sets" , "Sets\Def" , "Valid" , "Dump" , "Kr" , "CKr" , "Unvalid" , "Hist" ] For Every, Folder in Array { If !FolderExist(Folder) { FileCreateDir, % Folder } } } FolderExist(Folder) { Return InStr(FileExist(Folder), "D") } ================================================ FILE: GUIDetails_Labels.ahk ================================================ GuiClose: ExitApp DisplayDetails: GuiControlGet, ReInLB,, ReInLB If (ReInLB) { GuiControl,, DInfo, % _27 ": " Array[ReInLB][1] . "`n" _38 ": " Array[ReInLB][2] . "`n" _39 ": " Array[ReInLB][3] " = " Array[ReInLB][4] . "`n" _40 ": " Array[ReInLB][5] " = " Array[ReInLB][6] . "`n" _41 ": " Array[ReInLB][7] } Return ShowMore: GuiControlGet, ShowMore,, ShowMore If (ShowMore) { Gui, Show, h705 Center GuiControl,, ShowMore, % _171 } Else { Gui, Show, h290 Center GuiControl,, ShowMore, % _170 } Return ================================================ FILE: GUIKridi.ahk ================================================ #SingleInstance, Force SetBatchLines, -1 SetWorkingDir, % A_ScriptDir #Include, Lib\Classes\Class_CtlColors.ahk #Include, Lib\Classes\Class_ImageButton.ahk #Include, Lib\Classes\Class_GDIplus.ahk #Include, Lib\Language.ahk FolderSet() Gui, -MinimizeBox Gui, Color, 0xD8D8AD Gui, Margin, 10, 10 Gui, Font, s15 Bold, Calibri Gui, Add, Edit, w200 vKName -E0x200 Border gCheckKExist Gui, Font, s13 Gui, Add, Button, xm+210 ym w100 h33 HwndHCtrl gEnter, % _36 ImageButton.Create(HCtrl,[[0, 0x2ECB52, , 0x000000, 0, , 0x28A745, 2] , [0, 0x31E059, , 0x000000, 0, , 0x28A745, 2] , [0, 0x37F462, , 0x000000, 0, , 0x28A745, 2] , [0, 0xD8D8AD, , 0xB2B2B2, 0, , 0xB2B2B2, 2]]* ) Gui, Font, s15 Gui, Add, ListBox, w200 xm ym+40 vKLB h450 gDisplayThisKridi -Multi Gui, Add, ListView, xm+210 ym+40 w760 h435 Grid cBlue HwndHCtrl -Hdr, Col1|Col2|Col3|Col4|Col5 LV_ModifyCol(1, 0) LV_ModifyCol(2, 190) LV_ModifyCol(3, 190 " Center") LV_ModifyCol(4, 190 " Center") LV_ModifyCol(5, 190 " Center") Gui, Add, Edit, xm+550 ym w200 h33 -E0x200 Border ReadOnly vTotal Center Gui, Add, Edit, xm+768 ym w200 h33 -E0x200 Border ReadOnly vThisTotal Center cRed HwndE CtlColors.Attach(E, "FFFFFF", "000000") Gui, Show LoadKridiUsers() Return #Include, GUIKridi_Functions.ahk #Include, GUIKridi_Labels.ahk #Include, GUIKridi_Hotkeys.ahk ================================================ FILE: GUIKridiM.ahk ================================================ #SingleInstance, Force SetBatchLines, -1 SetWorkingDir, % A_ScriptDir #Include, Lib\Classes\Class_CtlColors.ahk #Include, Lib\Classes\Class_ImageButton.ahk #Include, Lib\Classes\Class_GDIplus.ahk #Include, Lib\Language.ahk FolderSet() If !Level := LogIn(AdminName := A_Args[1], AdminPass := A_Args[2]) { FileRead, Reciever, Sets\Login.Hwnd FileOpen("Sets\Login.Request", "w").Write("Run|" A_ScriptFullPath).Close() SendMessage, 0x1000,,,, ahk_id %Reciever% Sleep, 1000 MsgBox, 16, % _112, % _114 ExitApp } Gui, +HwndMain +Resize Gui, Add, Pic, % "x0 y0", Img\BG.png Gui, Margin, 10, 10 Gui, Color, 0x7D7D3A Gui, Font, s14 Bold, Calibri ButtonTheme := [[3, 0x80FF80, 0x5ABB5A, 0x000000, 2,, 0x008000, 1] , [3, 0x44DB44, 0x2F982F, 0x000000, 2,, 0x008000, 1] , [3, 0x1AB81A, 0x107410, 0x000000, 2,, 0x008000, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0x999999, 1]] ButtonTheme2 := [[3, 0xFF6F6F, 0xBC5454, 0x000000, 2,, 0xFF0000, 1] , [3, 0xDC6262, 0x9C4545, 0x000000, 2,, 0xFF0000, 1] , [3, 0xBF5454, 0x8A3C3C, 0x000000, 2,, 0xFF0000, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0xFF0000, 1]] ButtonTheme3 := [[3, 0xFFC080, 0xBE8F60, 0x000000, 2,, 0xFF8000, 1] , [3, 0xE0AA72, 0xA47C53, 0x000000, 2,, 0xFF8000, 1] , [3, 0xC89664, 0x906D48, 0x000000, 2,, 0xFF8000, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0xFF8000, 1]] ButtonTheme4 := [[3, 0x96C864, 0x739A4C, 0x000000, 2,, 0x80FF00, 1] , [3, 0x8CBB5D, 0x658643, 0x000000, 2,, 0x80FF00, 1] , [3, 0x79A051, 0x56733A, 0x000000, 2,, 0x80FF00, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0x80FF00, 1]] Gui, Add, Button, % "xm+5 ym+20 gAdd HwndHCtrl w190 h60", % _198 ImageButton.Create(HCtrl, ButtonTheme* ) Gui, Font, s16 Gui, Add, Edit, % "xm+5 ym+90 wp r2 vAllKridi -E0x200 Border Center ReadOnly HwndHCtrl -VScroll" CtlColors.Attach(HCtrl, "EAEAB5") Gui, Font, s14 qw := ((A_ScreenWidth - 255) // 3) Gui, Add, ListBox, % "wp h" A_ScreenHeight - 340 " vKLB HwndHCtrl Multi gShowKridiInfo 0x100" CtlColors.Attach(HCtrl, "EAEAB5") Gui, Font, s16 Gui, Add, Button, % "gDelete HwndHCtrl wp h60", % _191 ImageButton.Create(HCtrl, ButtonTheme2* ) Gui, Font, s14 Gui, Add, ListView, % "xm+421 ym+20 w" qw * 3 - 391 " h" A_ScreenHeight - 200 " vLV", % "|" _38 "|" _68 "|" _39 LV_ModifyCol(1, "0 Center") LV_ModifyCol(2, qw - 130) LV_ModifyCol(3, qw - 130) LV_ModifyCol(4, qw - 130) Gui, Font, s16 Gui, Add, Edit, % "xp-201 yp w190 r2 vThisKridi -E0x200 Border Center ReadOnly HwndHCtrl -VScroll" CtlColors.Attach(HCtrl, "FFC080") Gui, Font, s14 Gui, Add, ListBox, % "wp h" A_ScreenHeight - 425 " vKDate gSelectFromLv AltSubmit HwndHCtrl Multi 0x100" CtlColors.Attach(HCtrl, "FFC080") Gui, Font, s16 Gui, Add, Edit, % "wp r2 vSubThisKridi -E0x200 Border Center ReadOnly HwndHCtrl -VScroll" CtlColors.Attach(HCtrl, "FFC080") Gui, Add, Edit, % "wp vKridi -E0x200 Border Center HwndHCtrl -VScroll Number" CtlColors.Attach(HCtrl, "FFFFFF") Gui, Add, Button, % "wp h30 HwndHCtrl gKridiOut", % _29 ImageButton.Create(HCtrl, ButtonTheme3*) Gui, Add, Edit, % "xm+" qw * 3 - 391 + 12 + 421 " ym+20 wp r2 vPay -E0x200 Border Center ReadOnly HwndHCtrl -VScroll" CtlColors.Attach(HCtrl, "96C864") Gui, Font, s14 Gui, Add, ListBox, % "wp h" A_ScreenHeight - 425 " vPDate HwndHCtrl AltSubmit gShowPayVal 0x100" CtlColors.Attach(HCtrl, "96C864") Gui, Font, s16 Gui, Add, Edit, % "wp r2 vThisPay -E0x200 Border Center ReadOnly HwndHCtrl -VScroll" CtlColors.Attach(HCtrl, "96C864") Gui, Add, Edit, % "wp vPayBack -E0x200 Border Center HwndHCtrl -VScroll Number" CtlColors.Attach(HCtrl, "FFFFFF") Gui, Add, Button, % "wp h30 HwndHCtrl gPayOut", % _186 ImageButton.Create(HCtrl, ButtonTheme4*) Gui, Font, s20 Gui, Add, Edit, % "vBalance xm+421 y" A_ScreenHeight - 160 " w" qw * 3 - 391 " -E0x200 Border Center HwndHCtrl ReadOnly" CtlColors.Attach(HCtrl, "D8D8AD", "FF0000") Gui, Font, s12 Levels := ["Admin", "User"] Gui, Add, StatusBar SB_SetParts(10, 200, 200) SB_SetText(_206 ": " AdminName, 2) SB_SetText(_207 ": " Levels[Level], 3) Gui, Show, Maximize, Review GUI ThemeAdd() LoadKridis() Return #Include, GUIKridiM_Hotkeys.ahk #Include, GUIKridiM_Functions.ahk #Include, GUIKridiM_Labels.ahk ================================================ FILE: GUIKridiM_Functions.ahk ================================================ FolderSet() { Array := [ "Curr" , "Sets" , "Sets\Def" , "Valid" , "Dump" , "Kr" , "CKr" , "Unvalid" , "Hist" ] For Every, Folder in Array { If !FolderExist(Folder) { FileCreateDir, % Folder } } } FolderExist(Folder) { Return InStr(FileExist(Folder), "D") } LogIn(Username, Password) { If (FileExist("Sets\Acc.chu")) { Account := {} FileRead, RawAccount, Sets\Acc.chu TextAccount := b64Decode(RawAccount) For Each, User in StrSplit(TextAccount, ",") { LOG := StrSplit(User, "|") Account[LOG[1]] := [LOG[2], LOG[3]] } If (Account[Username][1] = Password) { If (Account[Username][2] = "Admin") Return, 1 Else If (Account[Username][2] = "User") Return, 2 } } Return, 0 } b64Encode(string) { VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1 if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", 0, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) VarSetCapacity(buf, size << 1, 0) if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", &buf, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) return StrGet(&buf) } b64Decode(string) { if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", 0, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) VarSetCapacity(buf, size, 0) if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", &buf, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) return StrGet(&buf, size, "UTF-8") } ThemeAdd() { Loop, 5 { Gui, Add, Text, % "y0 x" 208 + A_Index * 2 " w1 h" A_ScreenHeight " HwndHCtrl" CtlColors.Attach(HCtrl, "7D7D64") } } ConvertMillimsToDT(Value, Sign := "") { If (Value = "..." || !Value) Return ValueArr := StrSplit(Value / 1000, ".") Return, "[" (Sign ? Sign " " : "") ValueArr[1] (ValueArr[2] ? "." RTrim(ValueArr[2], 0) : "") " DT]" } LoadKridis(ChooseName := "") { GuiControl,, KLB, | GuiControl,, SelectFromLv, | LV_Delete() GuiControl,, SubThisKridi GuiControl,, ThisKridi GuiControl,, AllKridi GuiControl,, ThisPay GuiControl,, PayBack GuiControl,, Pay GuiControl,, PDate GuiControl,, Balance AK := 0 Loop, Files, Kr\*, D { Name := A_LoopFileName Loop, Files, % "Kr\" Name "\*.sell" { FileRead, Content, % A_LoopFileFullPath AK += StrSplit(StrSplit(Content, "> ")[3], ";")[1] } GuiControl,, KLB, % Name GuiControl,, AllKridi, % AK "`n" ConvertMillimsToDT(AK) } If (ChooseName = "") GuiControl, Choose, KLB, |1 Else { GuiControl, ChooseString, KLB, |%ChooseName% } } KridiDates(KLB) { LV_Delete() GuiControl,, KDate, | DateRow := {}, ItemSum := {}, I := 0, TK := 0 Loop, Files, % "Kr\" KLB "\*.sell" { FileRead, Content, % A_LoopFileFullPath Content := StrSplit(Content, "> ") Date := StrSplit(Content[1], "|")[2] DateRow[++I] := [] ItemSum[I] := StrSplit(Content[3], ";")[1] TK += ItemSum[I] GuiControl,, ThisKridi, % TK "`n" ConvertMillimsToDT(TK) GuiControl,, KDate, % Date Sells := StrSplit(Trim(Content[2], "|"), "|") For Every, Sell in Sells { SubSell := StrSplit(Sell, ";") Row := LV_Add(, SubSell[1], SubSell[2], SubSell[3], SubSell[4]) DateRow[I].Push(Row) } } GuiControl,, SubThisKridi Return, [DateRow, ItemSum, TK] } PayDates(KLB) { P := 0, PayVal := {} GuiControl,, PDate, | GuiControl,, Pay GuiControl,, ThisPay Loop, Files, % "Kr\" KLB "\*.pay" { FileRead, Content, % A_LoopFileFullPath P += Content PayVal[A_Index] := Content GuiControl,, Pay, % P "`n" ConvertMillimsToDT(P) FormatTime, oTime, % StrReplace(A_LoopFileName, ".pay"), yyyy/MM/dd HH:mm:ss GuiControl,, PDate, % oTime } Return, [PayVal, P] } ================================================ FILE: GUIKridiM_Hotkeys.ahk ================================================ #If WinActive("ahk_id " Main) Delete:: GuiControlGet, KLB,, KLB If (KLB) { MsgBox, 36, % _187, % KLB " " _190 IfMsgBox, Yes { MsgBox, 36, % _187, % _189 IfMsgBox, Yes { FileMoveDir, % "Kr\" KLB, % "CKr\", 1 LoadKridis() } } } Return #If ================================================ FILE: GUIKridiM_Labels.ahk ================================================ ShowKridiInfo: GuiControlGet, KLB,, KLB If (KLB) { DateRow := KridiDates(KLB) PayVal := PayDates(KLB) Ba := DateRow[3] - PayVal[2] GuiControl,, Balance, % KLB ": " Ba " " ConvertMillimsToDT(Ba) } Return PayOut: GuiControlGet, PayBack,, PayBack If (PayBack) { GuiControlGet, KLB,, KLB MsgBox, 36, % _187, % KLB " " _188 " " PayBack " " ConvertMillimsToDT(PayBack) IfMsgBox, Yes { MsgBox, 36, % _187, % _189 IfMsgBox, Yes { FileAppend, % PayBack, % "Kr\" KLB "\" A_Now ".pay" GuiControl,, PayBack PayVal := PayDates(KLB) Ba := DateRow[3] - PayVal[2] GuiControl,, Balance, % KLB ": " Ba " " ConvertMillimsToDT(Ba) } } } Return KridiOut: GuiControlGet, Kridi,, Kridi If (Kridi > 0) { GuiControlGet, KLB,, KLB MsgBox, 36, % _187, % KLB " " _197 " " Kridi " " ConvertMillimsToDT(PayBack) IfMsgBox, Yes { MsgBox, 36, % _187, % _189 IfMsgBox, Yes { FormatTime, OutTime, % Now := A_Now, yyyy/MM/dd HH:mm:ss FileAppend, % AdminName "|" OutTime "> > " Kridi ";" Kridi ";0", % "Kr\" KLB "\" A_Now ".sell" GuiControl,, Kridi DateRow := KridiDates(KLB) Ba := DateRow[3] - PayVal[2] GuiControl,, Balance, % KLB ": " Ba " " ConvertMillimsToDT(Ba) } } } Return SelectFromLV: GuiControlGet, KDate,, KDate If (!KDate) Return Loop, % LV_GetCount() { LV_Modify(A_Index, "-Select") } If (!InStr(KDate, "|")) { For Each, Row in DateRow[1][KDate] { LV_Modify(Row, "Select") } GuiControl, Focus, LV } Else { For Each, Date in StrSplit(KDate, "|") { For Each, Row in DateRow[1][Date] { LV_Modify(Row, "Select") } GuiControl, Focus, LV } } GuiControl,, SubThisKridi, % DateRow[2][KDate] "`n" ConvertMillimsToDT(DateRow[2][KDate]) Return ShowPayVal: GuiControlGet, PDate,, PDate If (PDate) { GuiControl,, ThisPay, % PayVal[1][PDate] "`n" ConvertMillimsToDT(PayVal[1][PDate]) } Return Add: InputBox, PersonName, Name?, Person Name?,, 300, 130 Validity := ErrorLevel If (Validity = 0) { If (PersonName != "") && (PersonName ~= "\b\w+\b") && !InStr(FileExist("Kr\" PersonName), "D") { FileCreateDir, % "Kr\" PersonName LoadKridis(PersonName) } Else { MsgBox, 16, % _13, % _199 } } Return KUpdateVal: Return GUIClose: IniDelete, Sets\PID.ini, PID, GUIKridiM ExitApp ================================================ FILE: GUIKridi_Functions.ahk ================================================ LoadKridiUsers() { GuiControl, , KLB, | Loop, Files, % "Kr\*", D GuiControl,, KLB, % A_LoopFileName TotalValue := 0 Obj := FileOpen("Dump\tmp.sell", "r") While !Obj.AtEOF() { Line := Obj.ReadLine() Col := StrSplit(Line, ",") LV_Add(, Col[1], Col[2], Col[3], Col[4], Col[5]) TotalValue += Col[5] } Obj.Close() GuiControl,, Total, % "+" TotalValue " " ConvertMillimsToDT(TotalValue, "+") } SetExplorerTheme(HCTL) { If (DllCall("GetVersion", "UChar") > 5) { VarSetCapacity(ClassName, 1024, 0) If DllCall("GetClassName", "Ptr", HCTL, "Str", ClassName, "Int", 512, "Int") { Return !DllCall("UxTheme.dll\SetWindowTheme", "Ptr", HCTL, "WStr", "Explorer", "Ptr", 0) } } Return False } ConvertMillimsToDT(Value, Sign := "") { If (Value = "..." || !Value) Return ValueArr := StrSplit(Value / 1000, ".") Return, "(" (Sign ? " " Sign " " : "") ValueArr[1] (ValueArr[2] ? "." RTrim(ValueArr[2], 0) : "") " DT)" } FolderSet() { Array := [ "Curr" , "Sets" , "Sets\Def" , "Valid" , "Dump" , "Kr" , "CKr" , "Unvalid" , "Hist" ] For Every, Folder in Array { If !FolderExist(Folder) { FileCreateDir, % Folder } } } FolderExist(Folder) { Return InStr(FileExist(Folder), "D") } ================================================ FILE: GUIKridi_Hotkeys.ahk ================================================ #If WinActive("ahk_id " Kridi) Enter:: GuiControlGet, KName,, KName If (KName = "") GuiControlGet, KName,, KLB If (KName != "") { FileOpen("Dump\Kridi.sell", "w").Write(KName).Close() ;FileDelete, % "Dump\Kridi.sell" ExitApp } Return #If ================================================ FILE: GUIKridi_Labels.ahk ================================================ GuiClose: FileDelete, % "Dump\Kridi.sell" ExitApp CheckKExist: GuiControlGet, KName,, KName GuiControl, Choose, KLB, 0 GuiControl, ChooseString, KLB, % "|" KName Return DisplayThisKridi: MaxValue := 0 GuiControlGet, KLB,, KLB Loop, Files, % "Kr\" KLB "\*.sell" { FileRead, Content, % A_LoopFileFullPath Content := StrSplit(Content, "> ")[3] MaxValue += StrSplit(Content, ";")[1] } GuiControl,, ThisTotal, % MaxValue " " ConvertMillimsToDT(MaxValue) Return ================================================ FILE: GUIReview.ahk ================================================ #SingleInstance, Force SetBatchLines, -1 #NoEnv SetWorkingDir, % A_ScriptDir #Include, Lib\Classes\Class_CtlColors.ahk #Include, Lib\Classes\Class_ImageButton.ahk #Include, Lib\Classes\Class_GDIplus.ahk #Include, Lib\Language.ahk FolderSet() If !Level := LogIn(AdminName := A_Args[1], AdminPass := A_Args[2]) { FileRead, Reciever, Sets\Login.Hwnd FileOpen("Sets\Login.Request", "w").Write("Run|" A_ScriptFullPath).Close() SendMessage, 0x1000,,,, ahk_id %Reciever% Sleep, 1000 MsgBox, 16, % _112, % _114 ExitApp } Gui, +HwndMain +Resize Gui, Add, Pic, % "x0 y0", Img\BG.png Gui, Margin, 10, 10 Gui, Color, 0x7D7D3A Gui, Font, s14 Bold Italic, Calibri ButtonTheme := [[3, 0x80FF80, 0x5ABB5A, 0x000000, 2,, 0x008000, 1] , [3, 0x44DB44, 0x2F982F, 0x000000, 2,, 0x008000, 1] , [3, 0x1AB81A, 0x107410, 0x000000, 2,, 0x008000, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0x999999, 1]] Gui, Font, Norm Gui, Font, s15 Bold qw := ((A_ScreenWidth - 255) / 4) Gui, Add, Text, % "xm+5 ym w190 vProfByProductText BackgroundTrans", % _202 ":" Gui, Add, DDL, xp yp+30 wp vProfByProduct gShowTheInfo AltSubmit, % _203 "||" _204 Gui, Add, Text, wp vShowTheInfo BackgroundTrans, % _156 ":" Gui, Add, DDL, xp yp+30 wp vProfByName gShowTheInfo Gui, Add, DateTime, w190 vBegin Center h30, yyyy/MM/dd Gui, Add, DateTime, wp vEnd Center hp, yyyy/MM/dd Gui, Font, Norm Gui, Font, s13 Bold italic Gui, Add, Button, wp gCheckTheListBox HwndHCtrl h30, % "↓ " _172 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, ListBox, % "0x100 wp h" A_ScreenHeight - 410 " vDates HwndHCtrl gShowTheInfo Multi" CtlColors.Attach(HCtrl, "D8D8AD", "404000") Gui, Font, s12 Gui, Add, Edit, % "xm+220 ym+10 w" qw*2 " vOverview -E0x200 HwndHCtrl" CtlColors.Attach(HCtrl, "000000", "FFFF00") Gui, Font, Norm Gui, Font, s15 Bold Gui, Add, Progress, % "xm+" A_ScreenWidth - 240 " yp cC3C378 vPB w200 hp", 0 Gui, Add, ListView, % "xm+220 yp+40 w" qw*4 " h" A_ScreenHeight - 200 " Grid HwndHLV -Multi BackgroundE6E6E6 gShowDetails", % _70 "|" _72 "|" _39 "|" _40 "|" _41 "|Notused" Global HLV LV_ModifyCol(1, 0) LV_ModifyCol(2, qw) LV_ModifyCol(3, qw) LV_ModifyCol(4, qw) LV_ModifyCol(5, qw) Gui, Add, Edit, % "xp+" qw + 4 " yp+" A_ScreenHeight - 190 " -E0x200 ReadOnly vSPr w" qw - 4 " Border HwndHCtrl Center" CtlColors.Attach(HCtrl, "EAEAB5", "000000") Gui, Add, Edit, % "xp+" qw " yp -E0x200 ReadOnly vCPr wp Border HwndHCtrl Center" CtlColors.Attach(HCtrl, "EAEAB5", "FF0000") Gui, Add, Edit, % "xp+" qw " yp -E0x200 ReadOnly vOAProfit wp Border HwndHCtrl Center" CtlColors.Attach(HCtrl, "EAEAB5", "008000") Gui, Add, Button, % "xm+220 yp w" qw " hp vSinceBegin HwndHCtrl gCalculateAll", % _85 " ↑" ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, xm+5 yp w190 gChart vChart HwndHCtrl hp, % "→ " _173 " ←" ImageButton.Create(HCtrl, ButtonTheme*) Gui, Font, s12 Levels := ["Admin", "User"] View := ["Normal", "More Details"] Gui, Add, StatusBar SB_SetParts(10, 200, 200) SB_SetText(_206 ": " AdminName, 2) SB_SetText(_207 ": " Levels[Level], 3) Gui, Show, Maximize, Review GUI ThemeAdd() Global LVContent, Header := 1 LoadAllSells() AnalyzeUsers() AnalyzeDates() GuiControl, Choose, Dates, |1 Return #Include, GUIReview_Hotkeys.ahk #Include, GUIReview_Functions.ahk #Include, GUIReview_Labels.ahk ================================================ FILE: GUIReview_Functions.ahk ================================================ FolderSet() { Array := [ "Curr" , "Sets" , "Sets\Def" , "Valid" , "Dump" , "Kr" , "CKr" , "Unvalid" , "Hist" ] For Every, Folder in Array { If !FolderExist(Folder) { FileCreateDir, % Folder } } } FolderExist(Folder) { Return InStr(FileExist(Folder), "D") } LogIn(Username, Password) { If (FileExist("Sets\Acc.chu")) { Account := {} FileRead, RawAccount, Sets\Acc.chu TextAccount := b64Decode(RawAccount) For Each, User in StrSplit(TextAccount, ",") { LOG := StrSplit(User, "|") Account[LOG[1]] := [LOG[2], LOG[3]] } If (Account[Username][1] = Password) { If (Account[Username][2] = "Admin") Return, 1 Else If (Account[Username][2] = "User") Return, 2 } } Return, 0 } b64Encode(string) { VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1 if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", 0, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) VarSetCapacity(buf, size << 1, 0) if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", &buf, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) return StrGet(&buf) } b64Decode(string) { if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", 0, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) VarSetCapacity(buf, size, 0) if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", &buf, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) return StrGet(&buf, size, "UTF-8") } SetExplorerTheme(HCTL) { If (DllCall("GetVersion", "UChar") > 5) { VarSetCapacity(ClassName, 1024, 0) If DllCall("GetClassName", "Ptr", HCTL, "Str", ClassName, "Int", 512, "Int") { Return !DllCall("UxTheme.dll\SetWindowTheme", "Ptr", HCTL, "WStr", "Explorer", "Ptr", 0) } } Return False } ThemeAdd() { Loop, 5 { Gui, Add, Text, % "y0 x" 208 + A_Index * 2 " w1 h" A_ScreenHeight " HwndHCtrl" CtlColors.Attach(HCtrl, "7D7D64") } } AddToList(File) { FileRead, Content, % File SplitPath, % File, OutFileName Date := SubStr(OutFileName, 1, 8) DataAll := StrSplit(Content, "> ") DateUser := StrSplit(DataAll[1], "|") If (DateUser.Length() = 2) && !LVContent["Users"].HasKey("" DateUser[1] "") { LVContent["Users"]["" DateUser[1] ""] := "" } Data := StrSplit(DataAll[3], ";") If (Data[1] Data[2] Data[3] ~= "\b\d+\b") { Names := "", Items := {} For Each, Prod in StrSplit(Trim(DataAll[2], "|"), "|") { Info := StrSplit(Prod, ";") If !Items.HasKey("" Info[1] "") { Items["" Info[1] ""] := [Info[2], 0, 0, 0, 0] } Items["" Info[1] ""][2] += StrSplit(Info[3], "x")[2] Items["" Info[1] ""][3] += Info[4] Items["" Info[1] ""][4] += Info[6] Items["" Info[1] ""][5] += Info[7] Names .= Names ? " | " Info[2] : Info[2] } C1 := [Date, File] C2 := DateUser C3 := "+ " Data[1] " " ConvertMillimsToDT(Data[1], "+") C4 := "- " Data[2] " " ConvertMillimsToDT(Data[2], "+") C5 := "+ " Data[3] " " ConvertMillimsToDT(Data[3], "+") C6 := Names C7 := Items C8 := Data LVContent["Lines"].Push([C1, C2, C3, C4, C5, C6, C7, C8]) If !LVContent["Dates"].HasKey("" Date "") { LVContent["Dates"]["" Date ""] := "" } } GuiControl,, PB, +1 } GetFilesCount() { FilesNum := 0 Loop, Files, Valid\*.sell, R FilesNum += 1 Loop, Files, Curr\*.sell, R FilesNum += 1 Return, FilesNum } LoadAllSells() { LVContent := { "Lines" : [] , "Users" : {} , "Dates" : {} } GuiControl,, SPr GuiControl,, CPr GuiControl,, OAProfit GuiControl, , PB, 0 Range := GetFilesCount() GuiControl, +Range0-%Range%, PB Loop, Files, Valid\*.sell, R AddToList(A_LoopFileFullPath) Loop, Files, Curr\*.sell, R AddToList(A_LoopFileFullPath) } ConvertMillimsToDT(Value, Sign := "") { If (Value = "..." || !Value) Return ValueArr := StrSplit(Value / 1000, ".") Return, "[" (Sign ? Sign " " : "") ValueArr[1] (ValueArr[2] ? "." RTrim(ValueArr[2], 0) : "") " DT]" } UpdateSumValues(DataSum) { GuiControl,, SPr, % "+ " DataSum[1] " " ConvertMillimsToDT(DataSum[1], "+") GuiControl,, CPr, % "- " DataSum[2] " " ConvertMillimsToDT(DataSum[2], "-") GuiControl,, OAProfit, % "+ " DataSum[3] " " ConvertMillimsToDT(DataSum[3], "+") } AnalyzeUsers() { Global _74 GuiControl,, ProfByName, | GuiControl,, ProfByName, % _74 For User in LVContent["Users"] { GuiControl,, ProfByName, % User } GuiControl, Choose, ProfByName, 1 } AnalyzeDates() { GuiControl,, Dates, | For Date in LVContent["Dates"] { FormatTime, ThisDay, % Date, yyyy/MM/dd GuiControl,, Dates, % "-- " ThisDay " --" } } UpdateHeaders() { Global LV_Delete() If (ProfByProduct = 1) && (Header = 2) { For Each, Title in [[_70, 0], [_72, qw], [_39, qw], [_40, qw], [_41, qw]] LV_ModifyCol(Each, Title[2], Title[1]) Header := 1 } If (ProfByProduct = 2) && (Header = 1) { For Each, Title in [[_63, sqw := qw*4 / 6], [_38, sqw], [_68, sqw, " Integer Left"], [_39, sqw, " Integer Left"], [_40, sqw, " Integer Left"], [_41, sqw, " Integer Left"]] LV_ModifyCol(Each, Title[2] Title[3], Title[1]) Header := 2 } } ================================================ FILE: GUIReview_Hotkeys.ahk ================================================ #If WinActive("ahk_id " Main) Enter:: GuiControlGet, Begin,, Begin GuiControlGet, End,, End GuiControl, Choose, Dates, 0 While (End >= Begin) { FormatTime, FBegin, % Begin, yyyy/MM/dd GuiControl, ChooseString, Dates, % "|-- " FBegin " --" Begin += 1, Days } Return ================================================ FILE: GUIReview_Labels.ahk ================================================ ShowDetails: GuiControlGet, ProfByProduct,, ProfByProduct If (!(Row := LV_GetNext()) || ProfByProduct = 2) Return LV_GetText(FileName, LV_GetNext(), 1) Run, % "GUIDetails." (A_IsCompiled ? "exe" : "ahk") " " FileName Return CalculateAll: For Date in LVContent["Dates"] { GuiControl, Choose, Dates, % A_Index } ShowTheInfo: GuiControlGet, ProfByProduct,, ProfByProduct GuiControlGet, ProfByName,, ProfByName GuiControlGet, Dates,, Dates GuiControl,, Overview, % View[ProfByProduct] " | " ProfByName " | " Dates ProfByName := (ProfByName = _74) ? "" : ProfByName UpdateHeaders() DataSum := [0, 0, 0] If (ProfByProduct = 1) { For Each, Line in LVContent["Lines"] { FormatTime, ThisDay, % Line[1][1], '--' yyyy/MM/dd '--' UName := (Line[2].Length() = 2) ? Line[2][1] : "" If InStr(Dates, ThisDay) && InStr(UName, ProfByName) { LV_Add(, Line[1][2], Line[2][1] (Line[2][2] ? " | " Line[2][2] : ""), Line[3], Line[4], Line[5], Line[6]) DataSum[1] += Line[8][1] DataSum[2] += Line[8][2] DataSum[3] += Line[8][3] UpdateSumValues(DataSum) } } } If (ProfByProduct = 2) { Info := {} For Each, Line in LVContent["Lines"] { FormatTime, ThisDay, % Line[1][1], '--' yyyy/MM/dd '--' UName := (Line[2].Length() = 2) ? Line[2][1] : "" If InStr(Dates, ThisDay) && InStr(UName, ProfByName) { For Barcode, Detail in Line[7] { If !Info.HasKey("" Barcode "") { Info["" Barcode ""] := [ LV_Add(, Barcode, Detail[1], Detail[2], Detail[3], Detail[4], Detail[5]) , Detail[1] , Detail[2] , Detail[3] , Detail[4] , Detail[5] ] } Else { Info["" Barcode ""][3] += Detail[2] Info["" Barcode ""][4] += Detail[3] Info["" Barcode ""][5] += Detail[4] Info["" Barcode ""][6] += Detail[5] LV_Modify( Info["" Barcode ""][1] ,, , , Info["" Barcode ""][3] , Info["" Barcode ""][4] , Info["" Barcode ""][5] , Info["" Barcode ""][6] ) } } DataSum[1] += Line[8][1] DataSum[2] += Line[8][2] DataSum[3] += Line[8][3] UpdateSumValues(DataSum) } } } Return CheckTheListBox: GuiControlGet, Begin,, Begin GuiControlGet, End,, End GuiControl, Choose, Dates, |0 While (End >= Begin) { FormatTime, FBegin, % Begin, yyyy/MM/dd GuiControl, ChooseString, Dates, % "|-- " FBegin " --" Begin += 1, Days } Return Chart: GuiControl, Disabled, Chart GuiControlGet, ProfByProduct,, ProfByProduct If (ProfByProduct = 1) { If (RowCount := LV_GetCount()) { Dummy := {} Loop, % RowCount { LV_GetText(F, A_Index, 1) LV_GetText(S, A_Index, 3) LV_GetText(B, A_Index, 4) LV_GetText(P, A_Index, 5) SplitPath, % F,,,, O RegExMatch(S, "\d+", S) RegExMatch(B, "\d+", B) RegExMatch(P, "\d+", P) If !Dummy.HasKey("" (O := SubStr(O, 1, 8)) "") { Dummy["" O ""] := [0, 0, 0] } Dummy["" O ""][1] += S Dummy["" O ""][2] += B Dummy["" O ""][3] += P } Dates := "" Sells := "" Costs := "" Profits := "" For Each, Date in Dummy { FormatTime, D, % Each, yyyy/MM/dd Dates .= Dates != "" ? ",'" D "'" : "'" D "'" Sells .= Sells != "" ? "," Date[1] : Date[1] Costs .= Costs != "" ? "," Date[2] : Date[2] Profits .= Profits != "" ? "," Date[3] : Date[3] } Dates := "[" Dates "]" Sells := "[" Sells "]" Costs := "[" Costs "]" Profits := "[" Profits "]" FileCopy, HighChart\template\Chart.html, Template.html, 1 FileCopy, HighChart\template\Chart.css, Template.css, 1 FileCopy, HighChart\template\Chart.js, Template.js, 1 FileRead, JS, Template.js JS := StrReplace(JS, "'[CASH_HELPER_DATES_HOLDER]'", Dates) JS := StrReplace(JS, "'[CASH_HELPER_SELLS_HOLDER]'", Sells) JS := StrReplace(JS, "'[CASH_HELPER_BUYS_HOLDER]'", Costs) JS := StrReplace(JS, "'[CASH_HELPER_PROFITS_HOLDER]'", Profits) FileOpen("Template.js" , "w").Write(JS).Close() Run, Template.html } } GuiControl, Enabled, Chart Return GuiClose: IniDelete, Sets\PID.ini, PID, GUIReview ExitApp ================================================ FILE: GUISell.ahk ================================================ #Requires AutoHotkey v1.1 #SingleInstance, Force SetBatchLines, -1 #NoEnv SetWorkingDir, % A_ScriptDir #Include, Lib\Classes\Class_CtlColors.ahk #Include, Lib\Classes\Class_ImageButton.ahk #Include, Lib\Classes\Class_GDIplus.ahk #Include, Lib\Language.ahk FolderSet() Global UserPic If !Level := LogIn(AdminName := A_Args[1], AdminPass := A_Args[2]) { FileRead, Reciever, Sets\Login.Hwnd FileOpen("Sets\Login.Request", "w").Write("Run|" A_ScriptFullPath).Close() SendMessage, 0x1000,,,, ahk_id %Reciever% Sleep, 1000 MsgBox, 16, % _112, % _114 ExitApp } Gui, +HwndMain +Resize Gui, Add, Pic, % "x0 y0", Img\BG.png Gui, Add, Pic, % "x" A_ScreenWidth - 120 " ym w80 h80", % UserPic ? UserPic : "Img\UserLogo.png" Gui, Margin, 10, 10 Gui, Color, 0x7D7D3A Gui, Font, s14 Bold Italic, Calibri Gui, Add, Text, xm+5 ym w190 BackgroundTrans, % _205 ":" Gui, Add, ListBox, 0x100 w190 r10 vSearch gWriteToBc AltSubmit HwndHCtrl CtlColors.Attach(HCtrl, "D8D8AD", "404000") Gui, Font, s18 norm Bold Gui, Add, Edit, % "xp y" A_ScreenHeight - 450 " w190 vItemsSold r2 -E0x200 ReadOnly Center -VScroll Hidden HwndHCtrl", 0 CtlColors.Attach(HCtrl, "EAEAB5", "FF0000") Gui, Add, Edit, % "xp yp+70 w190 vSoldP -E0x200 r2 ReadOnly Center -VScroll cGreen Hidden HwndHCtrl", 0 CtlColors.Attach(HCtrl, "EAEAB5", "008000") Gui, Add, Edit, % "xp yp+70 w190 vCostP -E0x200 r2 ReadOnly Center -VScroll cRed Hidden HwndHCtrl", 0 CtlColors.Attach(HCtrl, "EAEAB5", "FF0000") Gui, Add, Edit, % "xp yp+70 w190 vProfitP -E0x200 r2 ReadOnly Center -VScroll cGreen Hidden HwndHCtrl", 0 CtlColors.Attach(HCtrl, "EAEAB5", "008000") ButtonTheme := [[3, 0x80FF80, 0x5ABB5A, 0x000000, 2,, 0x008000, 1] , [3, 0x44DB44, 0x2F982F, 0x000000, 2,, 0x008000, 1] , [3, 0x1AB81A, 0x107410, 0x000000, 2,, 0x008000, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0x999999, 1]] Gui, Font, s25 pw := (A_ScreenWidth - 235) / 3 Gui, Add, Edit, % "x225 ym+85 w" pw " h45 vGivenMoney -E0x200 gCalc Center Border Hidden" CtlColors.Attach(HCtrl, "EAEAB5", "FF0000") Gui, Add, Edit, % "xp+" pw " yp wp h45 vAllSum -E0x200 ReadOnly Center Border cGreen Hidden HwndHCtrl" CtlColors.Attach(HCtrl, "EAEAB5", "000000") Gui, Add, Edit, % "xp+" pw " yp wp h45 vChange -E0x200 ReadOnly Center Border cRed Hidden HwndHCtrl" CtlColors.Attach(HCtrl, "EAEAB5", "FF0000") Gui, Font, s25 Gui, Add, Edit, % "x225 y30 w" pw " -VScroll vBc Center -E0x200 gAnalyzeAvail Border HwndHCtrl " SetEditCueBanner(HCtrl, _201) Gui, Add, Button, % "xp+" pw + 5 " yp vAddEnter gEnter w80 hp HwndHCtrl Disabled", % "→" ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Edit, % "xp-" (pw + 5) " yp+85 w" pw " vNm h45 -E0x200 ReadOnly Center HwndHCtrl Border" CtlColors.Attach(HCtrl, "C5C585") Gui, Add, Edit, % "xp+" pw " yp wp h45 vQn Center -E0x200 ReadOnly HwndHCtrl Border cRed" CtlColors.Attach(HCtrl, "C5C585") Gui, Add, Edit, % "xp+" pw " wp h45 -E0x200 ReadOnly Center HwndHCtrl Border vSum" CtlColors.Attach(HCtrl, "C5C585") Gui, Add, Button, % "vAddUp xp-" pw/2 + 50 " yp+70 gUp HwndHCtrl w50 h30 Disabled", % "+" ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "vAddDown xp+50 yp gDown HwndHCtrl wp hp Disabled", % "-" ImageButton.Create(HCtrl, ButtonTheme*) Gui, Font, s16 Gui, Add, Text, % "x225 yp w" pw - 31 " h30 vTransc HwndTHCtrl Center gViewLastTrans Hidden" CtlColors.Attach(THCtrl, "B2B2B2") Gui, Add, Pic, % "x" 225 + pw - 31 " yp w30 h30 vTranscOK gViewLastTrans Hidden", Img\Idle.png Gui, Font, s18 Gui, Add, ListView, % "HwndHCtrl x225 yp+37 w" pw*3 " h" A_ScreenHeight - 380 " vListView Grid ", % _63 "|" _61 "|" _38 "|" _68 "|" _69 LV_ModifyCol(1, "0 Center") LV_ModifyCol(2, Level = 1? pw / 2 : 0) LV_ModifyCol(3, (Level = 1? pw / 2 : pw) " Center") LV_ModifyCol(4, pw " Center") LV_ModifyCol(5, pw " Center") ;Gui, Font, s15 Gui, Add, Edit, % "xp+" pw*2 " yp-50 w" pw " vThisListSum -E0x200 ReadOnly HwndHCtrl Center" CtlColors.Attach(HCtrl, "D8D8AD", "FF0000") Gui, Font, s12 Gui, Add, Button, % "vAddSell x225 y" A_ScreenHeight - 150 " gSpace w100 hp HwndHCtrl Disabled", % _115 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "vAddDelete xp+100 yp gDelete HwndHCtrl wp hp Disabled", % _130 ImageButton.Create(HCtrl, ButtonTheme* ) Gui, Add, Button, % "vAddSubmit xp+100 yp gEnter w100 hp HwndHCtrl Disabled", % _168 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "vSubKridi xp+100 yp gSubKridi HwndHCtrl wp hp Disabled", % _29 ImageButton.Create(HCtrl, ButtonTheme* ) Gui, Add, Button, % "vCancel xp+100 yp gEsc HwndHCtrl wp hp Disabled", % _169 ImageButton.Create(HCtrl, ButtonTheme* ) Gui, Font, s15 ;Gui, Add, Pic, % "x" A_ScreenWidth - 70 " yp", Img\User.png ;Gui, Add, Edit, % "xp-200 yp w200 vUser hp -E0x200 ReadOnly HwndHCtrl Border -VScroll", % _206 ": " AdminName ; . "`n" _207 ": " Levels[Level] ;CtlColors.Attach(HCtrl, "C5C585") Gui, Add, Button, % "xm+15 y" A_ScreenHeight - 160 " w30 h25 vSession1 HwndHCtrl gSession1 ", 1 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "xp+35 yp wp hp vSession2 HwndHCtrl gSession2 ", 2 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "xp+35 yp wp hp vSession3 HwndHCtrl gSession3 ", 3 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "xp+35 yp wp hp vSession4 HwndHCtrl gSession4 ", 4 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "xp+35 yp wp hp vSession5 HwndHCtrl gSession5 ", 5 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "xm+15 yp+35 wp hp vSession6 HwndHCtrl gSession6 ", 6 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "xp+35 yp wp hp vSession7 HwndHCtrl gSession7 ", 7 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "xp+35 yp wp hp vSession8 HwndHCtrl gSession8 ", 8 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "xp+35 yp wp hp vSession9 HwndHCtrl gSession9 ", 9 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Add, Button, % "xp+35 yp wp hp vSession10 HwndHCtrl gSession10 ", 10 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Font, s12 Levels := ["Admin", "User"] Gui, Add, StatusBar SB_SetParts(10, 200, 200) SB_SetText(_206 ": " AdminName, 2) SB_SetText(_207 ": " Levels[Level], 3) Gui, Show, Maximize, Sell GUI OnMessage(0x1000, "Message") FileOpen("Sets\GUISell.Hwnd", "w").Write(Main).Close() ThemeAdd() GuiControl, Disabled, Session1 Selling := 0 ProdDefs := LoadDefinitions() Session := 1 If FileExist("Dump\" Session ".session") { RestoreSession() CalculateSum() } CheckLatestSells() CurrentProfit := CalculateCurrent() Return #Include, GUISell_Hotkeys.ahk #Include, GUISell_Functions.ahk #Include, GUISell_Labels.ahk ================================================ FILE: GUISell_Functions.ahk ================================================ ConvertMillimsToDT(Value, Sign := "") { If (Value = "..." || !Value) Return ValueArr := StrSplit(Value / 1000, ".") Return, "[" (Sign ? Sign " " : "") ValueArr[1] (ValueArr[2] ? "." RTrim(ValueArr[2], 0) : "") " DT]" } RestoreSession() { Global Session If LV_GetCount() { LV_Delete() GuiControl, Disabled, AddUp GuiControl, Disabled, AddDown GuiControl, Disabled, AddSell GuiControl, Disabled, AddDelete } If FileExist("Dump\" Session ".session") { Obj := FileOpen("Dump\" Session ".session", "r") While !Obj.AtEOF() { Line := Trim(Obj.ReadLine(), "`n") Col := StrSplit(Line, ",") LV_Add(, Col[1], Col[2], Col[3], Col[4], Col[5]) } Obj.Close() If LV_GetCount() { GuiControl, Enabled, AddUp GuiControl, Enabled, AddDown GuiControl, Enabled, AddSell GuiControl, Enabled, AddDelete } } GuiControl, Focus, Bc } WriteSession() { Global Session Obj := FileOpen("Dump\" Session ".session", "w") Loop, % LV_GetCount() { LV_GetText(Col1, A_Index, 1) LV_GetText(Col2, A_Index, 2) LV_GetText(Col3, A_Index, 3) LV_GetText(Col4, A_Index, 4) LV_GetText(Col5, A_Index, 5) Obj.WriteLine(Col1 "," Col2 "," Col3 "," Col4 "," Col5) } Obj.Close() } SetExplorerTheme(HCTL) { If (DllCall("GetVersion", "UChar") > 5) { VarSetCapacity(ClassName, 1024, 0) If DllCall("GetClassName", "Ptr", HCTL, "Str", ClassName, "Int", 512, "Int") { Return !DllCall("UxTheme.dll\SetWindowTheme", "Ptr", HCTL, "WStr", "Explorer", "Ptr", 0) } } Return False } LoadDefinitions() { Definitions := {} Loop, Files, Sets\Def\*.Def, R { FileRead, Content, % A_LoopFileFullPath Content := StrSplit(Content, ";") Definitions["" StrReplace(A_LoopFileName, ".def") ""] := { "Name" : Content[1] , "BuyPrice" : Content[2] , "SellPrice" : Content[3] , "Quantity" : Content[4] } } Return, Definitions } CalculateSum() { Global AdditionalInfo CharSum := 0 Loop, % LV_GetCount() { LV_GetText(ThisCharSum, A_Index, 5) CharSum += ThisCharSum } If (CharSum) { GuiControlGet, Remise, , Remise CharSumRemise := CharSum If (Remise) && (AdditionalInfo) { CharSumRemise -= Round(Remise / 100 * CharSum) } GuiControl, , ThisListSum, % CharSumRemise " " ConvertMillimsToDT(CharSumRemise) GuiControl, , AllSum, % CharSumRemise } Else { GuiControl, , ThisListSum } } CartView() { Global Selling Selling := 0 GuiControl, , AllSum GuiControl, , Change GuiControl, , GivenMoney GuiControl, Hide, GivenMoney GuiControl, Hide, AllSum GuiControl, Hide, Change GuiControl, Show, Bc GuiControl, Show, AddEnter GuiControl, Show, Nm GuiControl, Show, Qn GuiControl, Show, Sum LV_Delete() GuiControl, Focus, Bc } SellView() { Global Selling Selling := 1 GuiControl, Hide, Bc GuiControl, Hide, AddEnter GuiControl, Hide, Nm GuiControl, Hide, Qn GuiControl, Hide, Sum GuiControl, Show, GivenMoney GuiControl, Show, AllSum GuiControl, Show, Change GuiControl, Focus, GivenMoney } TrancsView(Tranc, View) { Global _126, THCtrl, CountToHide := 1 If (View) { GuiControl, Show, Transc GuiControl, Show, TranscOK If (Tranc) { FormatTime, Now, % A_Now, yyyy/MM/dd 'at' HH:mm:ss CtlColors.Change(THCtrl, "008000", "FFFFFF") GuiControl, , Transc, % Now GuiControl, , TranscOK, Img\OK.png SetTimer, TranscHide, 1000 } Else { CtlColors.Change(THCtrl, "CCCCCC") GuiControl, , Transc GuiControl, , TranscOK, Img\Idle.png } } Else { GuiControl, Hide, Transc GuiControl, Hide, TranscOK } } CheckLatestSells() { Global ProdDefs, SearchList := [] GuiControl,, Search, | If FileExist("Dump\Last.sell") { Loop, Read, Dump\Last.sell { If (ProdDefs["" Trim(A_LoopReadLine, "`n") ""] != "") { GuiControl,, Search, % " -- " ProdDefs["" Trim(A_LoopReadLine, "`n") ""]["Name"] " -- " SearchList.Push("" A_LoopReadLine "") } } } } CalculateCurrent() { Global _37 S := B := P := I := 0 Loop, Files, Curr\*.sell { FileRead, Content, % A_LoopFileFullPath Content := StrSplit(StrSplit(Content, "> ")[2], "|") For Each, One in Content { F := StrSplit(One, ";") I += StrSplit(F[3], "x")[2] S += F[4] B += F[6] P += F[7] } } GuiControl,, ItemsSold, % I " " _37 GuiControl,, SoldP, % S "`n" ConvertMillimsToDT(S) GuiControl,, CostP, % B "`n" ConvertMillimsToDT(B) GuiControl,, ProfitP, % P "`n" ConvertMillimsToDT(P) Return, [I, S, B, P] } LogIn(Username, Password) { If (FileExist("Sets\Acc.chu")) { Account := {} FileRead, RawAccount, Sets\Acc.chu TextAccount := b64Decode(RawAccount) For Each, User in StrSplit(TextAccount, ",") { LOG := StrSplit(User, "|") Account[LOG[1]] := [LOG[2], LOG[3], LOG[4]] } If (Account[Username][1] = Password) { If (Account[Username][3]) { UserPic := Account[Username][3] } If (Account[Username][2] = "Admin") Return, 1 Else If (Account[Username][2] = "User") Return, 2 } } Return, 0 } b64Encode(string) { VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1 if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", 0, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) VarSetCapacity(buf, size << 1, 0) if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", &buf, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) return StrGet(&buf) } b64Decode(string) { if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", 0, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) VarSetCapacity(buf, size, 0) if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", &buf, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) return StrGet(&buf, size, "UTF-8") } GUISellHistory(Text) { FormatTime, OutTime, % A_Now, yyyy/MM/dd HH:mm:ss Obj := FileOpen("Hist\SellHistory.Hist", "a") Obj.WriteLine(OutTime " ==> " Text) Obj.Close() } FolderSet() { Array := [ "Curr" , "Sets" , "Sets\Def" , "Valid" , "Dump" , "Kr" , "CKr" , "Unvalid" , "Hist" ] For Every, Folder in Array { If !FolderExist(Folder) { FileCreateDir, % Folder } } } FolderExist(Folder) { Return InStr(FileExist(Folder), "D") } ThemeAdd() { Loop, 5 { Gui, Add, Text, % "y0 x" 208 + A_Index * 2 " w1 h" A_ScreenHeight " HwndHCtrl" CtlColors.Attach(HCtrl, "7D7D64") } } Message() { Global ProdDefs FileRead, Message, Sets\Message.Request If (Message = "Update_Definitions") { ProdDefs := LoadDefinitions() } } SetEditCueBanner(HWND, Cue) { Static EM_SETCUEBANNER := (0x1500 + 1) Return DllCall("User32.dll\SendMessageW", "Ptr", HWND, "Uint", EM_SETCUEBANNER, "Ptr", True, "WStr", Cue) } InsertLineAtStart(File, Text) { rText := FileOpen("Dump\Last.sell", "r").Read(5000) FileOpen("Dump\Last.sell", "w").Write(Text "`n" rText).Close() } ================================================ FILE: GUISell_Hotkeys.ahk ================================================ #If WinActive("ahk_id " Main) Enter:: GuiControlGet, Bc, , Bc GuiControl, Disabled, Bc If (!Selling) { Barcode := Bc If (ProdDefs["" Barcode ""]["Name"] != "") && (ProdDefs["" Barcode ""]["SellPrice"] != "") && (ProdDefs["" Barcode ""]["Quantity"] != "") { Nm := ProdDefs["" Barcode ""]["Name"] SellPrice := ProdDefs["" Barcode ""]["SellPrice"] ThisCurrQuantity := ProdDefs["" Barcode ""]["Quantity"] ? ProdDefs["" Barcode ""]["Quantity"] : 0 QuantitySumArg := SellPrice "x1" JobDone := 0 Loop, % LV_GetCount() { LV_GetText(ThisBc, Row := A_Index, 1) If (ThisBc = Barcode) { LV_GetText(AddedCurrQuantity, Row, 2), AddedCurrQuantity := StrSplit(AddedCurrQuantity, " >> ") LV_GetText(AddedQuantitySumArg, Row, 4), AddedQuantitySumArg := StrSplit(AddedQuantitySumArg, "x"), QuantitySumArg := AddedQuantitySumArg[1] "x" AddedQuantitySumArg[2] + 1 LV_GetText(PreviousSum, Row, 5) SellPrice := ProdDefs["" Barcode ""]["SellPrice"] LV_Modify(Row,,, AddedCurrQuantity[1] " >> " AddedCurrQuantity[2] - 1,, QuantitySumArg, PreviousSum + SellPrice) JobDone := 1 Break } } If (!JobDone) { LV_Add("", Barcode, ThisCurrQuantity " >> " ThisCurrQuantity - 1, Nm, QuantitySumArg, SellPrice) } CalculateSum() WriteSession() GuiControl, Enabled, AddUp GuiControl, Enabled, AddDown GuiControl, Enabled, AddSell GuiControl, Enabled, AddDelete } } Else { FormatTime, OutTime, % (Now := A_Now), yyyy/MM/dd HH:mm:ss SellOBJ := FileOpen(LastestSO := "Curr\" Now ".sell", "w") SellOBJ.Write(AdminName "|" OutTime) I := Sum := Cost := 0 Loop, % LV_GetCount() { LV_GetText(Bc, A_Index, 1) LV_GetText(Qn, A_Index, 4) Qn := StrSplit(Qn, "x")[2] If (!Qn) || (!Bc) { MsgBox, 16, % _13, % _160 "`nRow: " A_Index Continue } ProdDefs["" Bc ""]["Quantity"] -= Qn FileRead, Content, % "Sets\Def\" Bc ".def" Content := StrSplit(Content, ";") DefObj := FileOpen("Sets\Def\" Bc ".def", "w") DefObj.Write(Content[1] ";" Content[2] ";" Content[3] ";" Content[4] - Qn) DefObj.Close() Name := ProdDefs["" Bc ""]["Name"] SellStr := ProdDefs["" Bc ""]["SellPrice"] "x" Qn Sell := ProdDefs["" Bc ""]["SellPrice"] * Qn Sum += Sell BuyStr := ProdDefs["" Bc ""]["BuyPrice"] "x" Qn Buy := ProdDefs["" Bc ""]["BuyPrice"] * Qn Cost += Buy SellOBJ.Write(((A_Index > 1) ? "|" : "> ") Bc ";" Name ";" SellStr ";" Sell ";" BuyStr ";" Buy ";" Sell - Buy) I += Qn InsertLineAtStart("Dump\Last.sell", Bc) } SellOBJ.Write("> " Sum ";" Cost ";" Sum - Cost) SellOBJ.Close() If FileExist("Dump\Kridi.sell") { FileRead, Content, Dump\Kridi.sell If !InStr(FileExist("Kr\" Content), "D") { FileCreateDir, % "Kr\" Content } FileMove, % LastestSO, % "Kr\" Content FileDelete, % "Dump\Kridi.sell" LastestSO := StrReplace(LastestSO, "Curr\", "Kr\" Content "\") } Selling := 0 GuiControl, Disabled, AddEnter GuiControl, Disabled, AddUp GuiControl, Disabled, AddDown GuiControl, Disabled, AddSell GuiControl, Disabled, AddSubmit If (Level = 1) GuiControl, Disabled, SubKridi GuiControl, Disabled, AddDelete GuiControl, Disabled, Cancel GuiControl,, AllSum GuiControl,, Change GuiControl,, GivenMoney GuiControl, Hide, GivenMoney GuiControl, Hide, AllSum GuiControl, Hide, Change GuiControl, Show, Bc GuiControl, Show, AddEnter GuiControl, Show, Nm GuiControl, Show, Qn GuiControl, Show, Sum LV_Delete() WriteSession() CalculateSum() TrancsView(1, 1) CheckLatestSells() CurrentProfit[1] += I CurrentProfit[2] += Sum CurrentProfit[3] += Cost CurrentProfit[4] += Sum - Cost GuiControl,, ItemsSold, % (CurrentProfit[1]) " " _37 GuiControl,, SoldP, % (CurrentProfit[2]) "`n" ConvertMillimsToDT(CurrentProfit[2]) GuiControl,, CostP, % (CurrentProfit[3]) "`n" ConvertMillimsToDT(CurrentProfit[3]) GuiControl,, ProfitP, % (CurrentProfit[4]) "`n" ConvertMillimsToDT(CurrentProfit[4]) } GuiControl, Enabled, Bc GuiControl, , Bc GuiControl, Focus, Bc Sleep, 125 Return Space:: GuiControlGet, FocusedControl, FocusV If (FocusedControl ~= "Client|SellDesc") { SendInput, {Space} } Else { If LV_GetCount() { SellView() AllSum := 0 Loop, % LV_GetCount() { LV_GetText(ThisAllSum, A_Index, 5) AllSum += ThisAllSum } GuiControl, , AllSum, % AllSum GuiControl, Disabled, AddUp GuiControl, Disabled, AddDown GuiControl, Disabled, AddDelete GuiControl, Disabled, AddSell If (Level = 1) GuiControl, Enabled, SubKridi GuiControl, Enabled, AddSubmit GuiControl, Enabled, Cancel GuiControl, Focus, GivenMoney CalculateSum() Selling := 1 } Else { GuiControl, Focus, Bc } } Sleep, 125 Return Left:: If !(--Session) { Session += 10 } Loop, 10 { If (A_Index = Session) { GuiControl, Disabled, Session%A_Index% } Else { GuiControl, Enabled, Session%A_Index% } } RestoreSession() CalculateSum() Sleep, 125 Return Right:: If (++Session = 11) { Session -= 10 } Loop, 10 { If (A_Index = Session) { GuiControl, Disabled, Session%A_Index% } Else { GuiControl, Enabled, Session%A_Index% } } RestoreSession() CalculateSum() Sleep, 125 Return Up:: If (Row := LV_GetNext()) { LV_GetText(ThisQn, Row, 4) LV_GetText(ThisBc, Row, 1) VQ := StrSplit(ThisQn, "x") LV_Modify(Row,,, ProdDefs["" ThisBc ""]["Quantity"] " >> " ProdDefs["" ThisBc ""]["Quantity"] - (VQ[2] + 1),, VQ[1] "x" VQ[2] + 1, VQ[1] * (VQ[2] + 1)) } Else If (Row := LV_GetCount()) { LV_GetText(ThisQn, Row, 4) LV_GetText(ThisBc, Row, 1) VQ := StrSplit(ThisQn, "x") LV_Modify(Row,,, ProdDefs["" ThisBc ""]["Quantity"] " >> " ProdDefs["" ThisBc ""]["Quantity"] - (VQ[2] + 1),, VQ[1] "x" VQ[2] + 1, VQ[1] * (VQ[2] + 1)) } CalculateSum() WriteSession() Sleep, 125 Return Down:: GuiControlGet, Focused, FocusV If (Row := LV_GetNext()) { LV_GetText(ThisQn, Row, 4) LV_GetText(ThisBc, Row, 1) VQ := StrSplit(ThisQn, "x") If (VQ[2] > 1) { LV_Modify(Row,,, ProdDefs["" ThisBc ""]["Quantity"] " >> " ProdDefs["" ThisBc ""]["Quantity"] - (VQ[2] - 1),, VQ[1] "x" VQ[2] - 1, VQ[1] * (VQ[2] - 1)) } } Else If (Row := LV_GetCount()) { LV_GetText(ThisQn, Row, 4) LV_GetText(ThisBc, Row, 1) VQ := StrSplit(ThisQn, "x") If (VQ[2] > 1) { LV_Modify(Row,,, ProdDefs["" ThisBc ""]["Quantity"] " >> " ProdDefs["" ThisBc ""]["Quantity"] - (VQ[2] - 1),, VQ[1] "x" VQ[2] - 1, VQ[1] * (VQ[2] - 1)) } } CalculateSum() WriteSession() Sleep, 125 Return Delete:: If (LV_GetCount()) { If (Row := LV_GetNext()) { LV_Delete(Row) CalculateSum() } Else { LV_Delete(1) CalculateSum() } If (!LV_GetCount()) { GuiControl, Disabled, AddEnter GuiControl, Disabled, AddUp GuiControl, Disabled, AddDown GuiControl, Disabled, AddSell GuiControl, Disabled, AddSubmit GuiControl, Disabled, SubKridi GuiControl, Disabled, AddDelete GuiControl, Disabled, Cancel LV_Delete() GuiControl, Focus, Bc } } WriteSession() Sleep, 125 Return Esc:: If (Selling) { Selling := 0 GuiControl, Disabled, AddEnter GuiControl, Disabled, AddUp GuiControl, Disabled, AddDown GuiControl, Disabled, AddSell GuiControl, Disabled, AddSubmit GuiControl, Disabled, SubKridi GuiControl, Disabled, AddDelete GuiControl, Disabled, Cancel GuiControl,, AllSum GuiControl,, Change GuiControl,, GivenMoney GuiControl, Hide, GivenMoney GuiControl, Hide, AllSum GuiControl, Hide, Change GuiControl,, Bc GuiControl, Show, Bc GuiControl, Show, AddEnter GuiControl, Show, Nm GuiControl, Show, Qn GuiControl, Show, Sum ;LV_Delete() GuiControl, Focus, Bc WriteSession() CalculateSum() } CheckLatestSells() Sleep, 125 Return ^F:: GuiControlGet, Bc,, Bc GuiControl,, Search, | SearchList := [] For Every, Product in ProdDefs { If InStr(Product["Name"], Bc) { SearchList.Push("" Every "") GuiControl, , Search, % Product["Name"] } } Sleep, 125 Return Tab:: If (Level = 1) { GuiControlGet, Visi, Visible, ItemsSold Action := (Visi) ? "Hide" : "Show" GuiControl, % Action, ItemsSold GuiControl, % Action, SoldP GuiControl, % Action, CostP GuiControl, % Action, ProfitP } Else { SendInput, {Tab} } Sleep, 125 Return #If ================================================ FILE: GUISell_Labels.ahk ================================================ GuiClose: IniDelete, Sets\PID.ini, PID, GUISell ExitApp LaunchKeyboard: Run, osk.exe Return SubKridi: Obj := FileOpen("Dump\tmp.sell", "w") Loop, % LV_GetCount() { LV_GetText(C1, A_Index, 1) LV_GetText(C2, A_Index, 2) LV_GetText(C3, A_Index, 3) LV_GetText(C4, A_Index, 4) LV_GetText(C5, A_Index, 5) Obj.Write(C1 "," C2 "," C3 "," C4 "," C5 "`n") } Obj.Close() RunWait, % "GUIKridi" (A_IsCompiled ? ".exe" : ".ahk") GoSub, Enter Return Calc: GuiControlGet, GivenMoney,, GivenMoney GuiControlGet, AllSum,, AllSum GuiControl, , Change Change := GivenMoney - AllSum If GivenMoney is Digit { GuiControl, , Change, % (Change >= 0) ? Change : 0 } Return AnalyzeAvail: GuiControlGet, Bc,, Bc If (Bc != "") { If (ProdDefs.HasKey("" Bc "")) { GuiControl, , Nm, % ProdDefs["" Bc ""]["Name"] GuiControl, , Qn, % ProdDefs["" Bc ""]["Quantity"] GuiControl, , Sum, % ProdDefs["" Bc ""]["SellPrice"] GuiControl, Enabled, AddEnter } Else { GuiControl, , Nm GuiControl, , Sum GuiControl, , Qn GuiControl, Disabled, AddEnter } } Else { GuiControl, , Nm GuiControl, , Sum GuiControl, , Qn GuiControl, Disabled, AddEnter } Return Remise: GuiControlGet, Remise, , Remise If (Remise > 100) GuiControl, , Remise, % Remise := "" CalculateSum() Return Client: SellDesc: CalculateSum() Return Return AdditionalInfo: If (AdditionalInfo := !AdditionalInfo) { GuiControl, Enabled, Remise GuiControl, Enabled, Client GuiControl, Enabled, SellDesc GuiControl, ,AdditionalInfoPic, % "Img\MIE.png" } Else { GuiControl, Disabled, Remise GuiControl, Disabled, Client GuiControl, Disabled, SellDesc GuiControl, ,AdditionalInfoPic, % "Img\MID.png" } CalculateSum() Return ViewLastTrans: If (LastestSO) { Run, % "GUIDetails" (A_IsCompiled ? ".exe" : ".ahk") " " LastestSO } Return Session1: Session := 1 Loop, 10 { If (A_Index = 1) { GuiControl, Disabled, Session%A_Index% } Else { GuiControl, Enabled, Session%A_Index% } } RestoreSession() CalculateSum() Return Session2: Session := 2 Loop, 10 { If (A_Index = 2) { GuiControl, Disabled, Session%A_Index% } Else { GuiControl, Enabled, Session%A_Index% } } RestoreSession() CalculateSum() Return Session3: Session := 3 Loop, 10 { If (A_Index = 3) { GuiControl, Disabled, Session%A_Index% } Else { GuiControl, Enabled, Session%A_Index% } } RestoreSession() CalculateSum() Return Session4: Session := 4 Loop, 10 { If (A_Index = 4) { GuiControl, Disabled, Session%A_Index% } Else { GuiControl, Enabled, Session%A_Index% } } RestoreSession() CalculateSum() Return Session5: Session := 5 Loop, 10 { If (A_Index = 5) { GuiControl, Disabled, Session%A_Index% } Else { GuiControl, Enabled, Session%A_Index% } } RestoreSession() CalculateSum() Return Session6: Session := 6 Loop, 10 { If (A_Index = 6) { GuiControl, Disabled, Session%A_Index% } Else { GuiControl, Enabled, Session%A_Index% } } RestoreSession() CalculateSum() Return Session7: Session := 7 Loop, 10 { If (A_Index = 7) { GuiControl, Disabled, Session%A_Index% } Else { GuiControl, Enabled, Session%A_Index% } } RestoreSession() CalculateSum() Return Session8: Session := 8 Loop, 10 { If (A_Index = 8) { GuiControl, Disabled, Session%A_Index% } Else { GuiControl, Enabled, Session%A_Index% } } RestoreSession() CalculateSum() Return Session9: Session := 9 Loop, 10 { If (A_Index = 9) { GuiControl, Disabled, Session%A_Index% } Else { GuiControl, Enabled, Session%A_Index% } } RestoreSession() CalculateSum() Return Session10: Session := 10 Loop, 10 { If (A_Index = 10) { GuiControl, Disabled, Session%A_Index% } Else { GuiControl, Enabled, Session%A_Index% } } RestoreSession() CalculateSum() Return WriteToBc: GuiControlGet, Search,, Search If (Search) { GuiControl,, Bc, % SearchList[Search] } Return TranscHide: If (++CountToHide = 30) { SetTimer, TranscHide, Off CountToHide := 0 GuiControl, Hide, Transc GuiControl, Hide, TranscOK } Return ================================================ FILE: GUISubmit.ahk ================================================ #Requires AutoHotkey v1.1 #SingleInstance, Force SetBatchLines, -1 SetWorkingDir, % A_ScriptDir #Include, Lib\Classes\Class_CtlColors.ahk #Include, Lib\Classes\Class_ImageButton.ahk #Include, Lib\Classes\Class_GDIplus.ahk #Include, Lib\Language.ahk FolderSet() If !Level := LogIn(AdminName := A_Args[1], AdminPass := A_Args[2]) { FileRead, Reciever, Sets\Login.Hwnd FileOpen("Sets\Login.Request", "w").Write("Run|" A_ScriptFullPath).Close() SendMessage, 0x1000,,,, ahk_id %Reciever% Sleep, 1000 MsgBox, 16, % _112, % _114 ExitApp } Gui, +HwndMain +Resize Gui, Add, Pic, % "x0 y0", Img\BG.png Gui, Margin, 10, 10 Gui, Color, 0x7D7D3A Gui, Font, s14 Bold, Calibri Gui, Add, Text, % "xm+5 ym w190 vProfByProductText BackgroundTrans", % _202 ":" Gui, Add, DDL, xp yp+30 wp vProfByProduct gShowTheInfo AltSubmit, % _203 "||" _204 Gui, Add, Text, % "wp vProfByNameText BackgroundTrans", % _156 ":" Gui, Add, DDL, xp yp+30 wp vProfByName gShowTheInfo Gui, Add, Text, % "wp vDatesText BackgroundTrans", % _72 ":" Gui, Font, Italic Gui, Add, ListBox, % "0x100 wp h" A_ScreenHeight - 330 " vDates HwndHCtrl gShowTheInfo Multi" CtlColors.Attach(HCtrl, "D8D8AD", "404000") Gui, Font, Norm Gui, Font, s15 Bold qw := ((A_ScreenWidth - 255) / 2) ButtonTheme := [[3, 0x80FF80, 0x5ABB5A, 0x000000, 2,, 0x008000, 1] , [3, 0x44DB44, 0x2F982F, 0x000000, 2,, 0x008000, 1] , [3, 0x1AB81A, 0x107410, 0x000000, 2,, 0x008000, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0x999999, 1]] Gui, Add, Button, % "x" A_ScreenWidth - 327 " ym+40 vEnsBtn w300 h40 HwndHCtrl gValid", % _9 ImageButton.Create(HCtrl, ButtonTheme*) Gui, Font, s12 Italic Gui, Add, Edit, % "xm+220 yp+10 w" qw " vOverview -E0x200 HwndHCtrl" CtlColors.Attach(HCtrl, "000000", "FFFF00") Gui, Font, Norm Gui, Font, s15 Bold Gui, Add, ListView, % "w" (qw * 2) " h" A_ScreenHeight - 240 " vLV Grid gShowDetails HwndHCtrl BackgroundE6E6E6 -Multi", % _70 "|" _71 "|" _39 "|" _40 "|" _41 "|" _79 LV_ModifyCol(1, "0") LV_ModifyCol(2, qw) LV_ModifyCol(3, 0) LV_ModifyCol(4, 0) LV_ModifyCol(5, 0) LV_ModifyCol(6, qw) Gui, Font, s20 Gui, Add, Edit, % "xm+220 y" A_ScreenHeight - 132 " w" (qw * 2) / 3 " vSold Center -E0x200 ReadOnly cGreen Border HwndHCtrl" CtlColors.Attach(HCtrl, "EAEAB5", "404000") Gui, Font, s15 Gui, Add, Button, xm+5 yp w190 gChart vChart HwndHCtrl h40, % "→ " _173 " ←" ImageButton.Create(HCtrl, ButtonTheme*) Gui, Font, s20 Gui, Add, Edit, % "xp+" (qw * 2)/3 + 215 " yp w" (qw * 2) / 3 " h40 vBought -E0x200 ReadOnly Center cRed Border HwndHCtrl" CtlColors.Attach(HCtrl, "EAEAB5", "FF0000") Gui, Add, Edit, % "xp+" (qw * 2)/3 " yp wp hp vProfitEq -E0x200 ReadOnly Center cGreen Border HwndHCtrl" CtlColors.Attach(HCtrl, "EAEAB5", "008000") ThemeAdd() Gui, Font, s12 Levels := ["Admin", "User"] View := ["Normal", "More Details"] Gui, Add, StatusBar SB_SetParts(10, 200, 200) SB_SetText(_206 ": " AdminName, 2) SB_SetText(_207 ": " Levels[Level], 3) Gui, Show, Maximize, Submit GUI Global LVContent, Header := 1 LoadAllSells() AnalyzeUsers() AnalyzeDates() GuiControl, Choose, Dates, |1 Return #Include, GUISubmit_Hotkeys.ahk #Include, GUISubmit_Functions.ahk #Include, GUISubmit_Labels.ahk ================================================ FILE: GUISubmit_Functions.ahk ================================================ ThemeAdd() { Loop, 5 { Gui, Add, Text, % "y0 x" 208 + A_Index * 2 " w1 h" A_ScreenHeight " HwndHCtrl" CtlColors.Attach(HCtrl, "7D7D64") } } LogIn(Username, Password) { If (FileExist("Sets\Acc.chu")) { Account := {} FileRead, RawAccount, Sets\Acc.chu TextAccount := b64Decode(RawAccount) For Each, User in StrSplit(TextAccount, ",") { LOG := StrSplit(User, "|") Account[LOG[1]] := [LOG[2], LOG[3]] } If (Account[Username][1] = Password) { If (Account[Username][2] = "Admin") Return, 1 Else If (Account[Username][2] = "User") Return, 2 } } Return, 0 } b64Encode(string) { VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1 if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", 0, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) VarSetCapacity(buf, size << 1, 0) if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", &buf, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) return StrGet(&buf) } b64Decode(string) { if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", 0, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) VarSetCapacity(buf, size, 0) if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", &buf, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) return StrGet(&buf, size, "UTF-8") } ConvertMillimsToDT(Value, Sign := "") { If (Value = "..." || !Value) Return ValueArr := StrSplit(Value / 1000, ".") Return, "[" (Sign ? Sign " " : "") ValueArr[1] (ValueArr[2] ? "." RTrim(ValueArr[2], 0) : "") " DT]" } AddToList(File, DataSum) { FileRead, Content, % File SplitPath, % File, OutFileName Date := SubStr(OutFileName, 1, 8) DataAll := StrSplit(Content, "> ") DateUser := StrSplit(DataAll[1], "|") If (DateUser.Length() = 2) && !LVContent["Users"].HasKey("" DateUser[1] "") { LVContent["Users"]["" DateUser[1] ""] := "" } Data := StrSplit(DataAll[3], ";") If (Data[1] Data[2] Data[3] ~= "\b\d+\b") { Names := "", Items := {} For Each, Prod in StrSplit(Trim(DataAll[2], "|"), "|") { Info := StrSplit(Prod, ";") If !Items.HasKey("" Info[1] "") { Items["" Info[1] ""] := [Info[2], 0, 0, 0, 0] } Items["" Info[1] ""][2] += StrSplit(Info[3], "x")[2] Items["" Info[1] ""][3] += Info[4] Items["" Info[1] ""][4] += Info[6] Items["" Info[1] ""][5] += Info[7] Names .= Names ? " | " Info[2] : Info[2] } C1 := ["" Date "", File] C2 := DateUser C3 := "+ " Data[1] " " ConvertMillimsToDT(Data[1], "+") C4 := "- " Data[2] " " ConvertMillimsToDT(Data[2], "+") C5 := "+ " Data[3] " " ConvertMillimsToDT(Data[3], "+") C6 := Names C7 := Items C8 := Data LVContent["Lines"].Push([C1, C2, C3, C4, C5, C6, C7, C8]) If !LVContent["Dates"].HasKey("" Date "") { LVContent["Dates"]["" Date ""] := "" } } } LoadAllSells() { DataSum := [0, 0, 0] LVContent := { "Lines" : [] , "Users" : {} , "Dates" : {} } GuiControl,, Sold GuiControl,, Bought GuiControl,, ProfitEq Loop, Files, Curr\*.sell, R DataSum := AddToList(A_LoopFileFullPath, DataSum) } AnalyzeUsers() { Global _74 GuiControl,, ProfByName, | GuiControl,, ProfByName, % _74 For User in LVContent["Users"] { GuiControl,, ProfByName, % User } GuiControl, Choose, ProfByName, 1 } AnalyzeDates() { GuiControl,, Dates, | For Date in LVContent["Dates"] { FormatTime, ThisDay, % Date, yyyy/MM/dd GuiControl,, Dates, % "-- " ThisDay " --" } } UpdateHeaders() { Global LV_Delete() If (ProfByProduct = 1) && (Header = 2) { For Each, Title in [[_70, 0], [_71, qw], [_39, 0], [_40, 0], [_41, 0], [_79, qw]] LV_ModifyCol(Each, Title[2], Title[1]) Header := 1 } If (ProfByProduct = 2) && (Header = 1) { For Each, Title in [[_63, sqw := qw / 3], [_38, sqw], [_68, sqw, " Integer Left"], [_39, sqw, " Integer Left"], [_40, sqw, " Integer Left"], [_41, sqw, " Integer Left"]] LV_ModifyCol(Each, Title[2] Title[3], Title[1]) Header := 2 } } UpdateSumValues(DataSum) { GuiControl,, Sold, % "+ " DataSum[1] " " ConvertMillimsToDT(DataSum[1], "+") GuiControl,, Bought, % "- " DataSum[2] " " ConvertMillimsToDT(DataSum[2], "-") GuiControl,, ProfitEq, % "+ " DataSum[3] " " ConvertMillimsToDT(DataSum[3], "+") } FolderSet() { Array := [ "Curr" , "Sets" , "Sets\Def" , "Valid" , "Dump" , "Kr" , "CKr" , "Unvalid" , "Hist" ] For Every, Folder in Array { If !FolderExist(Folder) { FileCreateDir, % Folder } } } FolderExist(Folder) { Return InStr(FileExist(Folder), "D") } ================================================ FILE: GUISubmit_Hotkeys.ahk ================================================ ================================================ FILE: GUISubmit_Labels.ahk ================================================ Valid: MsgBox, 33, % _174, % _175 IfMsgBox, OK { FileCreateDir, % "Valid\" (Now := A_Now) Loop, % LV_GetCount() { LV_GetText(File, A_Index, 1) FileMove, % File, % "Valid\" Now } LoadAllSells() AnalyzeUsers() AnalyzeDates() } Return Chart: GuiControl, Disabled, Chart GuiControlGet, ProfByProduct,, ProfByProduct If (ProfByProduct = 1){ If (RowCount := LV_GetCount()) { Dummy := {} Loop, % RowCount { LV_GetText(F, A_Index, 1) LV_GetText(S, A_Index, 3) LV_GetText(B, A_Index, 4) LV_GetText(P, A_Index, 5) SplitPath, % F,,,, O RegExMatch(S, "\d+", S) RegExMatch(B, "\d+", B) RegExMatch(P, "\d+", P) If !Dummy.HasKey("" (O := SubStr(O, 1, 8)) "") { Dummy["" O ""] := [0, 0, 0] } Dummy["" O ""][1] += S Dummy["" O ""][2] += B Dummy["" O ""][3] += P } Dates := "" Sells := "" Costs := "" Profits := "" For Each, Date in Dummy { FormatTime, D, % Each, yyyy/MM/dd Dates .= Dates != "" ? ",'" D "'" : "'" D "'" Sells .= Sells != "" ? "," Date[1] : Date[1] Costs .= Costs != "" ? "," Date[2] : Date[2] Profits .= Profits != "" ? "," Date[3] : Date[3] } Dates := "[" Dates "]" Sells := "[" Sells "]" Costs := "[" Costs "]" Profits := "[" Profits "]" FileCopy, HighChart\template\Chart.html, Template.html, 1 FileCopy, HighChart\template\Chart.css, Template.css, 1 FileCopy, HighChart\template\Chart.js, Template.js, 1 FileRead, JS, Template.js JS := StrReplace(JS, "'[CASH_HELPER_DATES_HOLDER]'", Dates) JS := StrReplace(JS, "'[CASH_HELPER_SELLS_HOLDER]'", Sells) JS := StrReplace(JS, "'[CASH_HELPER_BUYS_HOLDER]'", Costs) JS := StrReplace(JS, "'[CASH_HELPER_PROFITS_HOLDER]'", Profits) FileOpen("Template.js" , "w").Write(JS).Close() Run, Template.html } } GuiControl, Enabled, Chart Return ShowDetails: GuiControlGet, ProfByProduct,, ProfByProduct If !(Row := LV_GetNext()) || ProfByProduct = 2 Return LV_GetText(FileName, Row, 1) Run, % "GUIDetails." (A_IsCompiled ? "exe" : "ahk") " " FileName Return ShowTheInfo: GuiControlGet, ProfByProduct,, ProfByProduct GuiControlGet, ProfByName,, ProfByName GuiControlGet, Dates,, Dates GuiControl,, Overview, % View[ProfByProduct] " | " ProfByName " | " Dates ProfByName := (ProfByName = _74) ? "" : ProfByName UpdateHeaders() DataSum := [0, 0, 0] Info := {} If (ProfByProduct = 1) { For Each, Line in LVContent["Lines"] { FormatTime, ThisDay, % SubStr(Line[1][1], 1, 8), '--' yyyy/MM/dd '--' UName := (Line[2].Length() = 2) ? Line[2][1] : "" If InStr(Dates, ThisDay) && InStr(UName, ProfByName) { LV_Add(, Line[1][2], Line[2][1] (Line[2][2] ? " | " Line[2][2] : ""), Line[3], Line[4], Line[5], Line[6]) DataSum[1] += Line[8][1] DataSum[2] += Line[8][2] DataSum[3] += Line[8][3] UpdateSumValues(DataSum) } } } If (ProfByProduct = 2) { For Each, Line in LVContent["Lines"] { FormatTime, ThisDay, % SubStr(Line[1][1], 1, 8), '--' yyyy/MM/dd '--' UName := (Line[2].Length() = 2) ? Line[2][1] : "" If InStr(Dates, ThisDay) && InStr(UName, ProfByName) { For Barcode, Detail in Line[7] { If !Info.HasKey("" Barcode "") { Info["" Barcode ""] := [LV_Add(, Barcode, Detail[1], Detail[2], Detail[3], Detail[4], Detail[5]) , Detail[1] , Detail[2] , Detail[3] , Detail[4] , Detail[5]] } Else { Info["" Barcode ""][3] += Detail[2] Info["" Barcode ""][4] += Detail[3] Info["" Barcode ""][5] += Detail[4] Info["" Barcode ""][6] += Detail[5] LV_Modify(Info["" Barcode ""][1],,,, Info["" Barcode ""][3], Info["" Barcode ""][4], Info["" Barcode ""][5], Info["" Barcode ""][6]) } } DataSum[1] += Line[8][1] DataSum[2] += Line[8][2] DataSum[3] += Line[8][3] UpdateSumValues(DataSum) } } } Return GuiClose: IniDelete, Sets\PID.ini, PID, GUISubmit ExitApp ================================================ FILE: GUIUpdate.ahk ================================================ #Requires AutoHotkey v1.1 #SingleInstance, Force SetBatchLines, -1 #NoEnv SetWorkingDir, % A_ScriptDir Gui, Font, Bold s12, Consolas Gui, +HwndMain -Border +Resize FileRead, Version, LVersion.txt Gui, Add, Text, w300 Center, % "Cash Helper v" Version Gui, Add, Text, w300 Center vDownloadInfo cRed Gui, Add, Progress, xp yp+50 wp h15 +0x00000008 HwndPB -Smooth DllCall("User32.dll\SendMessage", "Ptr", PB, "Int", 0x00000400 + 10, "Ptr", 1, "Ptr", 50) SetTimer, CheckSize, 1000 Gui, Show Return CheckSize: FileGetSize, Size, % A_Temp "\Install.exe", B GuiControl,, DownloadInfo, % "↓ " Round(Size/1000000, 2) " mb..." Return GuiClose: ExitApp ================================================ FILE: GUIUser.ahk ================================================ #Requires AutoHotkey v1.1 #SingleInstance, Force SetBatchLines, -1 SetWorkingDir, % A_ScriptDir #Include, Lib\Classes\Class_CtlColors.ahk #Include, Lib\Classes\Class_ImageButton.ahk #Include, Lib\Classes\Class_GDIplus.ahk #Include, Lib\Language.ahk FolderSet() If !Level := LogIn(AdminName := A_Args[1], AdminPass := A_Args[2]) { FileRead, Reciever, Sets\Login.Hwnd FileOpen("Sets\Login.Request", "w").Write("Run|" A_ScriptFullPath).Close() SendMessage, 0x1000,,,, ahk_id %Reciever% Sleep, 1000 MsgBox, 16, % _112, % _114 ExitApp } Gui, +HwndMain +Resize Gui, Add, Pic, % "x0 y0", Img\BG.png Gui, Margin, 10, 10 Gui, Color, 0x7D7D3A Gui, Font, s12 Bold, Calibri ButtonTheme := [[3, 0x80FF80, 0x5ABB5A, 0x000000, 2,, 0x008000, 1] , [3, 0x44DB44, 0x2F982F, 0x000000, 2,, 0x008000, 1] , [3, 0x1AB81A, 0x107410, 0x000000, 2,, 0x008000, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0x999999, 1]] ButtonTheme2 := [[3, 0xFF6F6F, 0xBC5454, 0x000000, 2,, 0xFF0000, 1] , [3, 0xDC6262, 0x9C4545, 0x000000, 2,, 0xFF0000, 1] , [3, 0xBF5454, 0x8A3C3C, 0x000000, 2,, 0xFF0000, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0xFF0000, 1]] qw := (A_ScreenWidth - 20) / 3 Gui, Add, GroupBox, % "BackgroundTrans xm+5 ym w" qw " h" A_ScreenHeight - 100, % _156 Gui, Add, Button, % "HwndHCtrl xp+" qw - 320 " yp+30 w150 gAddUser h30", % _89 " [++]" ImageButton.Create(HCtrl, ButtonTheme* ) Gui, Add, Button, % "HwndHCtrl xp+160 yp wp gDelUser h30", % _91 " [--]" ImageButton.Create(HCtrl, ButtonTheme2* ) Gui, Add, ListView, % "AltSubmit xm+15 ym+65 w" qw - 20 " h" A_ScreenHeight - 180 " gShowInfo c804000", % _38 "|" _88 "|" _207 LV_ModifyCol(1, (qw-20) / 3) LV_ModifyCol(2, (qw-20) / 3) LV_ModifyCol(3, (qw-20) / 3) Gui, Add, GroupBox, % "BackgroundTrans xm+" qw + 10 " ym w" qw " h" A_ScreenHeight - 100, % _211 Gui, Add, Text, xp+10 yp+30 BackgroundTrans, % _214 ": " Gui, Add, Pic, % "xp+" ((qw - 220) / 2) " yp+30 w200 h200 vUserPic Border BackgroundTrans gChooseAPic", Img\UserLogo.png Gui, Add, Text, % "xp-" ((qw - 220) / 2) " yp+220 BackgroundTrans" , % _87 ": " Gui, Add, Edit, % "vUN w" qw - 20 " -E0x200 Border cGreen" Gui, Add, Text, BackgroundTrans , % _88 ": " Gui, Add, Edit, % "w" qw - 20 " vPW -E0x200 Border cRed" Gui, Add, Text, BackgroundTrans , % _207 ": " Gui, Add, DDL, % "w" qw - 20 " vLVL -E0x200 Border", %_212%|%_213% Gui, Add, Button, % "HwndHCtrl xp yp+50 wp gSaveChanges h30", % _62 ImageButton.Create(HCtrl, ButtonTheme* ) Gui, Add, GroupBox, % "BackgroundTrans xm+" (qw + 8) * 2 " ym w" qw - 15 " h" A_ScreenHeight - 100, % _215 Gui, Add, CheckBox, % "BackgroundTrans Center xp+10 yp+30 wp-20", % _216 Gui, Add, CheckBox, % "BackgroundTrans Center wp", % _222 Gui, Add, CheckBox, % "BackgroundTrans Center wp", % _223 Gui, Add, CheckBox, % "BackgroundTrans Center wp", % _217 Gui, Add, CheckBox, % "BackgroundTrans Center wp", % _218 Gui, Add, CheckBox, % "BackgroundTrans Center wp", % _219 Gui, Add, CheckBox, % "BackgroundTrans Center wp", % _220 Gui, Add, CheckBox, % "BackgroundTrans Center wp", % _221 Global UserList LoadAccounts() Gui, Font, s12 Levels := ["Admin", "User"] Gui, Add, StatusBar SB_SetParts(10, 200, 200) SB_SetText(_206 ": " AdminName, 2) SB_SetText(_207 ": " Levels[Level], 3) Gui, Show, Maximize, GUI User Return #Include, GUIUser_Functions.ahk #Include, GUIUser_Hotkeys.ahk #Include, GUIUser_Labels.ahk ================================================ FILE: GUIUser_Functions.ahk ================================================ FolderSet() { Array := [ "Curr" , "Sets" , "Sets\Def" , "Valid" , "Dump" , "Kr" , "CKr" , "Unvalid" , "Hist" ] For Every, Folder in Array { If !FolderExist(Folder) { FileCreateDir, % Folder } } } FolderExist(Folder) { Return InStr(FileExist(Folder), "D") } LogIn(Username, Password) { If (FileExist("Sets\Acc.chu")) { Account := {} FileRead, RawAccount, Sets\Acc.chu TextAccount := b64Decode(RawAccount) For Each, User in StrSplit(TextAccount, ",") { LOG := StrSplit(User, "|") Account[LOG[1]] := [LOG[2], LOG[3]] } If (Account[Username][1] = Password) { If (Account[Username][2] = "Admin") Return, 1 Else If (Account[Username][2] = "User") Return, 2 } } Return, 0 } UpdateAccounts() { Data := "" For User, Info in UserList { Data .= Data != "" ? "," User "|" Info[1] "|" Info[2] (Info[3] != "" ? "|" Info[3] : "") : User "|" Info[1] "|" Info[2] (Info[3] != "" ? "|" Info[3] : "") } If (Data != "") FileOpen("Sets\Acc.chu", "w").Write(b64Encode(Data)).Close() Else { FileDelete, Sets\Acc.chu FileDelete, Sets\RAcc.chu FileRead, Reciever, Sets\Login.Hwnd FileOpen("Sets\Login.Request", "w").Write("Reload").Close() SendMessage, 0x1000,,,, ahk_id %Reciever% ExitApp } } LoadAccounts() { UserList := {} LV_Delete() If FileExist("Sets\Acc.chu") { FileRead, RawAccount, Sets\Acc.chu Account := b64Decode(RawAccount) For Every, Acc in StrSplit(Account, ",") { Info := StrSplit(Acc, "|") UserList[Info[1]] := [Info[2], Info[3], Info[4]] LV_Add(, Info[1], Info[2], Info[3]) } } } NoAdminsLeft(Nm) { tmp := UserList tmp.Delete(Nm) For User, Info in tmp { If (Info[2] = "ADMIN") { Return, 0 } } Return, 1 } b64Encode(string) { VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1 if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", 0, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) VarSetCapacity(buf, size << 1, 0) if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", &buf, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) return StrGet(&buf) } b64Decode(string) { if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", 0, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) VarSetCapacity(buf, size, 0) if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", &buf, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) return StrGet(&buf, size, "UTF-8") } ================================================ FILE: GUIUser_Hotkeys.ahk ================================================ #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. ; #Warn ; Enable warnings to assist with detecting common errors. SendMode Input ; Recommended for new scripts due to its superior speed and reliability. SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. ================================================ FILE: GUIUser_Labels.ahk ================================================ ShowInfo: If (R := LV_GetNext()) { LV_GetText(Nm, R, 1) LV_GetText(Pw, R, 2) LV_GetText(Lv, R, 3) GuiControl,, UN, % Nm GuiControl,, PW, % Pw GuiControl, ChooseString, LVL, % Lv If (UserList[Nm][3]) { GuiControl,, UserPic, % UserList[Nm][3] } Else { GuiControl,, UserPic, Img\UserLogo.png } } Return DelUser: If (R := LV_GetNext()) { LV_GetText(Nm, R, 1) If NoAdminsLeft(Nm) { MsgBox, 33, % _174, % _224 IfMsgBox, Cancel Return } MsgBox, 33, % _174, % _91 " '" Nm "'" IfMsgBox, OK { UserList.Delete(Nm) UpdateAccounts() LoadAccounts() } } Return AddUser: InputBox, UN, % _87, % _87,, 300, 130 InputBox, PW, % _88, % _88,, 300, 130 LVL := "USER" If (UN != "") && (PW != "") && !UserList.HasKey(UN) { UserList[UN] := [PW, LVL] UpdateAccounts() LoadAccounts() } Else { Msgbox, 16, % _13, % _225 } Return SaveChanges: GuiControlGet, UN,, UN GuiControlGet, PW,, PW GuiControlGet, LVL,, LVL If (R := LV_GetNext()) && (UN != "" && UN = Nm) && (PW != "") { UserList[Nm][1] := PW UserList[Nm][2] := LVL UpdateAccounts() LoadAccounts() } Else { Msgbox, 16, % _13, % _225 } Return ChooseAPic: if !(R := LV_GetNext()) { Return } LV_GetText(Nm, R, 1) FileSelectFile, UserPic iF (UserPic != "") { GuiControl,, UserPic, % UserPic SplitPath, % UserPic,,, OutExt FileCopy, % UserPic, % "Img\Users\" Nm "." OutExt, 1 UserList[Nm][3] := "Img\Users\" Nm "." OutExt } Else { GuiControl,, UserPic, Img\UserLogo.png FileDelete, % UserList[Nm][3] UserList[Nm].RemoveAt(3) } Return GuiClose: IniDelete, Sets\PID.ini, PID, GUIUser ExitApp ================================================ FILE: GenerateRelease.ahk ================================================ #Requires AutoHotkey v1.1 #NoEnv SendMode Input SetWorkingDir %A_ScriptDir% SetBatchLines, -1 #Persistent #SingleInstance, Force 7zipExitCode:= { 0 : "No error" , 1 : "Warning (Non fatal error(s)). For example, one or more files were locked by some other application, so they were not compressed." , 2 : "Fatal error" , 7 : "Command line error" , 8 : "Not enough memory for operation" , 255 : "User stopped the process"} Gui, Add, ListBox, w100 r10 vCompileAHK, % "StartUp" . "|Import" . "|GUIUser" . "|GUISubmit" . "|GUISell" . "|GUIReview" . "|GUIKridiM" . "|GUIKridi" . "|GUIDetails" . "|GUIDefine" . "|GUIUpdate" . "|Uninstall" Gui, Add, ListBox, xp+110 wp hp vCopyRES, % "Img" . "|Lib" Gui, Add, ListBox, xp+110 wp hp vCompressF, % "HighChart" . "|CH-Install" Gui, Add, Button, xm wp gCompileSel, Compile Gui, Add, Button, xp yp+25 wp gCompileAll, Compile All Gui, Add, Button, xp+110 yp-25 wp gCopySel, Copy Gui, Add, Button, xp yp+25 wp gCopyAll, Copy All Gui, Add, Button, xp+110 yp-25 wp gCompressSel, Compress Gui, Add, Button, xp yp+25 wp gCompressAll, Compress All Gui, Add, Edit, xm w320 vLog -VScroll -HScroll ReadOnly FileRead, Version, Version.txt Gui, Add, Edit, Center cRed vVersion w100, % Version Gui, Add, Button, wp, Prepare All Gui, Show,, Create a release Return CompileSel: GuiControlGet, CompileAHK If (CompileAHK) { For Each, Script in StrSplit(CompileAHK, "|") { CompileScript(Script) } } Return CompileAll: CompileScript("StartUp") CompileScript("Import") CompileScript("GUIUser") CompileScript("GUISubmit") CompileScript("GUISell") CompileScript("GUIReview") CompileScript("GUIKridiM") CompileScript("GUIKridi") CompileScript("GUIDetails") CompileScript("GUIDefine") CompileScript("GUIUpdate") CompileScript("Uninstall") Return CopySel: GuiControlGet, CopyRES If (CopyRES) PrepareResource(CopyRES) Return CopyAll: PrepareResource("Img") PrepareResource("Lib") Return CompressSel: GuiControlGet, CompressF Switch CompressF { Case "HighChart": GuiControl,, Log, Compressing into HighChart... FileDelete, __Release\HighChart.zip RunWait, %ComSpec% /c __Compiler\7za.exe a -aoa __Release\HighChart.zip HighChart\ If (ErrorLevel) { Msgbox, 16, Error, % "Error Code: " ErrorLevel "`n" 7zipExitCode[ErrorLevel] } ELse { GuiControl,, Log, Compressing into HighChart.zip... - OK! } Return Case "CH-Install": GuiControl,, Log, Compressing into CH-Install.zip... FileDelete, __Release\CH-Install.zip FileDelete, __Release\Install.exe GuiControlGet, Version FileOpen("Version.txt", "w").Write(Version).Close() FileCopy, Version.txt, __Release\Version.txt, 1 RunWait, %ComSpec% /c cd __Release && ..\__Compiler\7za.exe a -aoa CH-Install.zip * If (E := ErrorLevel) { Msgbox, 16, Error, % "Error Code: " E "`n" 7zipExitCode[E] } ELse { GuiControl,, Log, Compressing into CH-Install.zip... - OK! } Return } Return CompressAll: GuiControl,, Log, Compressing into HighChart... FileDelete, __Release\HighChart.zip RunWait, %ComSpec% /c __Compiler\7za.exe a -aoa __Release\HighChart.zip HighChart\ If (ErrorLevel) { Msgbox, 16, Error, % "Error Code: " ErrorLevel "`n" 7zipExitCode[ErrorLevel] } ELse { GuiControl,, Log, Compressing into HighChart.zip... - OK! } GuiControl,, Log, Compressing into CH-Install.zip... FileDelete, __Release\CH-Install.zip FileDelete, __Release\Install.exe GuiControlGet, Version FileOpen("Version.txt", "w").Write(Version).Close() FileCopy, Version.txt, __Release\Version.txt, 1 RunWait, %ComSpec% /c cd __Release && ..\__Compiler\7za.exe a -aoa CH-Install.zip * If (ErrorLevel) { Msgbox, 16, Error, % "Error Code: " ErrorLevel "`n" 7zipExitCode[ErrorLevel] } ELse { GuiControl,, Log, Compressing into CH-Install.zip... - OK! } Return ButtonPrepareAll: GoSub, CompileAll GoSub, CopyAll GoSub, CompressAll CompileScript("Install") GuiControl,, Log, %A_ScriptDir%\__Release\Install.exe Return GuiClose: ExitApp CompileScript(AHKName, MoveTo := "") { GuiControlGet, Log RunWait, % """__Compiler\Ahk2Exe.exe""" . " /in """ AHKName ".ahk""" . " /out """ AHKName ".exe""" . " /icon " (FileExist(AHKName ".ico") ? AHKName ".ico" : "Default.ico") . " /base ""__Compiler\Unicode 32-bit.bin""" If (!ErrorLevel) { GuiControl,, Log, % "Compiling " AHKName " - OK!" If (!MoveTo) FileMove, %AHKName%.exe, __Release\%AHKName%.exe, 1 Else FileMove, %AHKName%.exe, __Release\%AHKName%.exe, 1 } Else Msgbox, 16, Error, % "Compiling " AHKName ".ahk... - ERROR!" } PrepareResource(Element) { GuiControl,, Log, % "Copying " Element "..." Sleep, 250 If !InStr(FileExist(Element), "D") { FileCopy, % Element, % "__Release\" Element, 1 } Else { FileCopyDir, % Element, % "__Release\" Element, 1 } If (!ErrorLevel) GuiControl,, Log, % "Copying " Element ".. - OK!" Else Msgbox, 16, Error, % "Copying " Element "... - ERROR!" } ================================================ FILE: Import.ahk ================================================ #Requires AutoHotkey v1.1 #SingleInstance, Force SetBatchLines, -1 SetWorkingDir, % A_ScriptDir Gui, Font, Bold s10, Consolas Gui, Add, Button, w300 gImportAccounts, 1 - Import Accounts Gui, Add, Button, wp gImportRAccounts Disabled, 2 - Import Remembered Account Gui, Add, Button, wp gImportPD, 3 - Import Product Definitions Gui, Add, Button, wp gImportKridi, 4 - Import Kridis Gui, Add, Button, wp gImportKridiKO, 5 - Import Kridis From Kridi Organizer Gui, Add, Button, wp gImportSells, 6 - Import Sells Gui, Show,, Load Custom Setting Return GuiClose: ExitApp ;--------------------------- ImportKridiKO: FileSelectFolder, Folder If (Folder) { InputBox, Responsable, Responsable, Responsable User Name,, 300, 120 If (Responsable != "") { Loop, Files, % Folder "\*.txt" { FileRead, CurrentAmount, % A_LoopFileFullPath If (CurrentAmount = "") Continue SplitPath, % A_LoopFileFullPath,,,, Name Name := Trim(Name, " ") If !InStr(FileExist("Kr\" Name), "D") { FileCreateDir, % "Kr\" Name } If (CurrentAmount != "") { Result := Eval(CurrentAmount) Amount := StrJoin(Result, "`n") FormatTime, OutTime, % Now := A_Now, yyyy/MM/dd HH:mm:ss FileOpen("Kr\" Name "\" Now ".sell", "w").Write(Responsable "|" OutTime "> > " Amount ";" Amount ";0").Close() } } } Msgbox, % "OK" Run, Kr } Return ImportRAccounts: FileSelectFile, File,,, Select Remembered Account File If (File) { Out .= StrReplace(DB_Read(File), ";", "|") Msgbox % "Data to be encoded:`n" Out FileOpen("Sets\RAcc.chu", "w").Write(b64Encode(Out)).Close() } Return ImportAccounts: FileSelectFile, File,,, Select Accounts File If (File) { Out := "" A := StrSplit(DB_Read(File), ";") A.RemoveAt(1) Out .= A[1] "|" A[2] "|Admin" Loop, 2 A.RemoveAt(1) For Each, Element in A { UP := StrSplit(Element, "/") Out .= "," UP[1] "|" UP[2] "|User" } Msgbox % "Data to be encoded:`n" Out If !InStr(FileExist("Sets"), "D") { FileCreateDir, Sets } FileOpen("Sets\Acc.chu", "w").Write(b64Encode(Out)).Close() Msgbox % "OK" Run, Sets } Return ImportSells: FileSelectFolder, Folder If (Folder) { SplitPath, % Folder,,,, oFolder FileCopyDir, % Folder, % oFolder, 1 Run, % oFolder Msgbox % "Copied:`n-> " Folder "`n-> " oFolder Loop, Files, %oFolder%\*.db, R { RD := DB_Read(A_LoopFileFullPath) If (RD) { SplitPath, % A_LoopFileFullPath,, OutDir,, OutNameNoExt FileOpen(OutDir "\" OutNameNoExt ".sell", "w").Write(RD).Close() } } Loop, Files, %oFolder%\*.db, R FileDelete, % A_LoopFileFullPath Msgbox % "OK" } Return ImportKridi: FileSelectFolder, Folder If (Folder) { Folders := [] Loop, Files, %Folder%\*, D Folders.Push(A_LoopFileFullPath) If !InStr(FileExist("Kr"), "D") { FileCreateDir, % "Kr" } For Every, Dir in Folders { SplitPath, % Dir, OutFileName, OutDir Msgbox % "Moving:`n-> " Dir "`n-> Kr\" DecodeAlpha(OutFileName) FileCopyDir, % Dir, % "Kr\" DecodeAlpha(OutFileName) } Msgbox % "OK" Run, Kr } Return ImportPD: FileSelectFile, File If (File) { SplitPath, % File,, OutDir If !InStr(FileExist("Sets\Def"), "D") { FileCreateDir, % "Sets\Def" } Msgbox % "Data to be encoded:`n" Out := DB_Read(File) For each, one in StrSplit(DB_Read(File), "|") { _one := StrSplit(one, ";") If (_one[1] && _one[2] && _one[3] && _one[4]) { FileOpen("Sets\Def\" _one[1] ".def", "w").Write(_one[2] ";" _one[3] ";" _one[4] ";" (_one[5] ? _one[5] : 0)).Close() } } Msgbox % "OK" Run, Sets\Def } Return b64Encode(string) { VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1 if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", 0, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) VarSetCapacity(buf, size << 1, 0) if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", &buf, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) return StrGet(&buf) } DB_Read(FileName, FastMode := 0) { DBObj := FileOpen(FileName, "r") If !(FastMode) { Hedr := "" Loop, 14 { Hedr .= Chr(DBObj.ReadChar()) } If (Hedr != "CH-26259084-DB") Return, 0 Info := "" DBObj.Pos := 1024 Loop { Info .= (ThisChar := Chr(DBObj.ReadChar())) } Until (ThisChar = "") } Else { DBObj.RawRead(Data, Len := DBObj.Length()) Pos := 1023, Info := "" While (Byte := NumGet(Data, Pos += 1, "Char")) { Info .= Chr(Byte) } DBObj.Close() } Return, Decode(Info) } Decode(string) { if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", 0, "uint*", size, "ptr", 0, "ptr", 0)) Return VarSetCapacity(buf, size, 0) if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", &buf, "uint*", size, "ptr", 0, "ptr", 0)) Return return, StrGet(&buf, size, "UTF-8") } DecodeAlpha(Str) { DecStr := "" Loop, Parse, Str { If (A_LoopField ~= "[B-Zb-z]") || (A_LoopField ~= "[1-9]") DecStr .= Chr(Asc(A_LoopField) - 1) Else If (A_LoopField = "A") DecStr .= Chr(Asc(A_LoopField) + 25) Else If (A_LoopField = "0") DecStr .= "9" Else DecStr .= A_LoopField } Return, DecStr } Encode(string) { VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1 if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", 0, "uint*", size)) Return VarSetCapacity(buf, size << 1, 0) if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", &buf, "uint*", size)) Return return, StrGet(&buf) } EncodeAlpha(Str) { EncStr := "" Loop, Parse, Str { If (A_LoopField ~= "[A-Ya-y]") || (A_LoopField ~= "[0-8]") EncStr .= Chr(Asc(A_LoopField) + 1) Else If (A_LoopField = "Z") EncStr .= Chr(Asc(A_LoopField) - 25) Else If (A_LoopField = "9") EncStr .= "0" Else EncStr .= A_LoopField } Return, EncStr } ;======================================================================================= ; ; Function: Eval ; Description: Evaluate Expressions in Strings. ; Return value: An array (object) with the result of each expression. ; ; Author: Pulover [Rodolfo U. Batista] ; Credits: ExprEval() by Uberi ; ;======================================================================================= ; ; Parameters: ; ; $x: The input string to be evaluated. You can enter multiple expressions ; separated by commas (inside the string). ; _CustomVars: An optional Associative Array object containing variables names ; as keys and values to replace them. ; For example, setting it to {A_Index: A_Index} inside a loop will replace ; occurrences of A_Index with the correct value for the iteration. ; _Init: Used internally for the recursive calls. If TRUE it resets the static ; object _Objects, which holds objects references to be restored. ; ;======================================================================================= Eval($x, _CustomVars := "", _Init := true) { Static _Objects, $Quote := Chr(2) _Elements := {} If (_Init) _Objects := {} ; Strip off comments $x := RegExReplace($x, "U)/\*.*\*/"), $x := RegExReplace($x, "U)\s;.*(\v|$)") ; Replace brackets, braces, parenthesis and literal strings While (RegExMatch($x, "sU)"".*""", _String)) _Elements["&_String" A_Index "_&"] := _String , $x := RegExReplace($x, "sU)"".*""", "&_String" A_Index "_&",, 1) While (RegExMatch($x, "\[([^\[\]]++|(?R))*\]", _Bracket)) _Elements["&_Bracket" A_Index "_&"] := _Bracket , $x := RegExReplace($x, "\[([^\[\]]++|(?R))*\]", "&_Bracket" A_Index "_&",, 1) While (RegExMatch($x, "\{[^\{\}]++\}", _Brace)) _Elements["&_Brace" A_Index "_&"] := _Brace , $x := RegExReplace($x, "\{[^\{\}]++\}", "&_Brace" A_Index "_&",, 1) While (RegExMatch($x, "\(([^()]++|(?R))*\)", _Parent)) _Elements["&_Parent" A_Index "_&"] := _Parent , $x := RegExReplace($x, "\(([^()]++|(?R))*\)", "&_Parent" A_Index "_&",, 1) ; Split multiple expressions $z := StrSplit($x, ",", " `t") For $i, $v in $z { ; Check for Ternary expression and evaluate If (RegExMatch($z[$i], "([^\?:=]+?)\?([^\?:]+?):(.*)", _Match)) { Loop, 3 { $o := A_Index, _Match%$o% := Trim(_Match%$o%) , _Match%$o% := RestoreElements(_Match%$o%, _Elements) } EvalResult := Eval(_Match1, _CustomVars, false) , $y := EvalResult[1] If ($y) { EvalResult := Eval(_Match2, _CustomVars, false) , $y := StrJoin(EvalResult,, true, false) , ObjName := RegExReplace(_Match2, "\W", "_") If (IsObject($y)) _Objects[ObjName] := $y $z[$i] := StrReplace($z[$i], _Match, IsObject($y) ? """<~#" ObjName "#~>""" : $y) } Else { EvalResult := Eval(_Match3, _CustomVars, false) , $y := StrJoin(EvalResult,, true, false) , ObjName := RegExReplace(_Match3, "\W", "_") If (IsObject($y)) _Objects[ObjName] := $y $z[$i] := StrReplace($z[$i], _Match, IsObject($y) ? """<~#" ObjName "#~>""" : $y) } } _Pos := 1 ; Check for Object calls While (RegExMatch($z[$i], "([\w%]+)(\.|&_Bracket|&_Parent\d+_&)[\w\.&%]+(.*)", _Match, _Pos)) { AssignParse(_Match, VarName, Oper, VarValue) If (Oper != "") { VarValue := RestoreElements(VarValue, _Elements) , EvalResult := Eval(VarValue, _CustomVars, false) , VarValue := StrJoin(EvalResult) If (!IsObject(VarValue)) VarValue := RegExReplace(VarValue, """{2,2}", """") } Else _Match := StrReplace(_Match, _Match3), VarName := _Match VarName := RestoreElements(VarName, _Elements) If _Match1 is Number { _Pos += StrLen(_Match1) continue } $y := ParseObjects(VarName, _CustomVars, Oper, VarValue) , ObjName := RegExReplace(_Match, "\W", "_") If (IsObject($y)) _Objects[ObjName] := $y Else If $y is not Number { $y := """" StrReplace($y, """", $Quote) """" , HidString := "&_String" (ObjCount(_Elements) + 1) "_&" , _Elements[HidString] := $y , $y := HidString } $z[$i] := StrReplace($z[$i], _Match, IsObject($y) ? """<~#" ObjName "#~>""" : $y,, 1) } ; Assign Arrays While (RegExMatch($z[$i], "&_Bracket\d+_&", $pd)) { $z[$i] := StrReplace($z[$i], $pd, _Elements[$pd],, 1) , RegExMatch($z[$i], "\[(.*)\]", _Match) , _Match1 := RestoreElements(_Match1, _Elements) , $y := Eval(_Match1, _CustomVars, false) , ObjName := RegExReplace(_Match, "\W", "_") , _Objects[ObjName] := $y , $z[$i] := StrReplace($z[$i], _Match, """<~#" ObjName "#~>""") } ; Assign Associative Arrays While (RegExMatch($z[$i], "&_Brace\d+_&", $pd)) { $y := {}, o_Elements := {} , $o := _Elements[$pd] , $o := RestoreElements($o, _Elements) , $o := SubStr($o, 2, -1) While (RegExMatch($o, "sU)"".*""", _String%A_Index%)) o_Elements["&_String" A_Index "_&"] := _String%A_Index% , $o := RegExReplace($o, "sU)"".*""", "&_String" A_Index "_&", "", 1) While (RegExMatch($o, "\[([^\[\]]++|(?R))*\]", _Bracket)) o_Elements["&_Bracket" A_Index "_&"] := _Bracket , $o := RegExReplace($o, "\[([^\[\]]++|(?R))*\]", "&_Bracket" A_Index "_&",, 1) While (RegExMatch($o, "\{[^\{\}]++\}", _Brace)) o_Elements["&_Brace" A_Index "_&"] := _Brace , $o := RegExReplace($o, "\{[^\{\}]++\}", "&_Brace" A_Index "_&",, 1) While (RegExMatch($o, "\(([^()]++|(?R))*\)", _Parent)) o_Elements["&_Parent" A_Index "_&"] := _Parent , $o := RegExReplace($o, "\(([^()]++|(?R))*\)", "&_Parent" A_Index "_&",, 1) Loop, Parse, $o, `,, %A_Space%%A_Tab% { $o := StrSplit(A_LoopField, ":", " `t") , $o.1 := RestoreElements($o.1, o_Elements) , $o.2 := RestoreElements($o.2, o_Elements) , EvalResult := Eval($o.2, _CustomVars, false) , $o.1 := Trim($o.1, """") , $y[$o.1] := EvalResult[1] } ObjName := RegExReplace(_Match, "\W", "_") , _Objects[ObjName] := $y , $z[$i] := StrReplace($z[$i], $pd, """<~#" ObjName "#~>""") } ; Restore and evaluate any remaining parenthesis While (RegExMatch($z[$i], "&_Parent\d+_&", $pd)) { _oMatch := StrSplit(_Elements[$pd], ",", " `t()") , _Match := RegExReplace(_Elements[$pd], "\((.*)\)", "$1") , _Match := RestoreElements(_Match, _Elements) , EvalResult := Eval(_Match, _CustomVars, false) , RepString := "(" For _i, _v in EvalResult { ObjName := RegExReplace($pd . _i, "\W", "_") If (IsObject(_v)) _Objects[ObjName] := _v Else If _v is not Number { If (_oMatch[_i] != "") { _v := """" StrReplace(_v, """", $Quote) """" , HidString := "&_String" (ObjCount(_Elements) + 1) "_&" , _Elements[HidString] := _v , _v := HidString } } RepString .= (IsObject(_v) ? """<~#" ObjName "#~>""" : _v) ", " } RepString := RTrim(RepString, ", ") ")" , $z[$i] := StrReplace($z[$i], $pd, RepString,, 1) } ; Check whether the whole string is an object $y := $z[$i] Try { If (_CustomVars.HasKey($y)) { If (IsObject(_CustomVars[$y])) { ObjName := RegExReplace($y, "\W", "_") , _Objects[ObjName] := _CustomVars[$y].Clone() , $z[$i] := """<~#" ObjName "#~>""" } } Else If (IsObject(%$y%)) { ObjName := RegExReplace($y, "\W", "_") , _Objects[ObjName] := %$y%.Clone() , $z[$i] := """<~#" ObjName "#~>""" } } ; Check for {} object assignment If (RegExMatch($z[$i], "\{\s*\}", _Match)) { $y := Object() , ObjName := "_emptyObj" , _Objects[ObjName] := $y , $z[$i] := StrReplace($z[$i], _Match, """<~#" ObjName "#~>""") } ; Check for Functions While (RegExMatch($z[$i], "s)([\w%]+)\((.*?)\)", _Match)) { _Match1 := (RegExMatch(_Match1, "^%(\S+)%$", $pd)) ? %$pd1% : _Match1 , _Match2 := RestoreElements(_Match2, _Elements) , _Params := Eval(_Match2, _CustomVars) , $y := %_Match1%(_Params*) , ObjName := RegExReplace(_Match, "\W", "_") If (IsObject($y)) _Objects[ObjName] := $y Else If $y is not Number { $y := """" StrReplace($y, """", $Quote) """" , HidString := "&_String" (ObjCount(_Elements) + 1) "_&" , _Elements[HidString] := $y , $y := HidString } $z[$i] := StrReplace($z[$i], _Match, IsObject($y) ? """<~#" ObjName "#~>""" : $y,, 1) } ; Dereference variables in percent signs While (RegExMatch($z[$i], "U)%(\S+)%", _Match)) EvalResult := Eval(_Match1, _CustomVars, false) , $z[$i] := StrReplace($z[$i], _Match, EvalResult[1]) ; ExprEval() cannot parse Unicode strings, so the "real" strings are "hidden" from ExprCompile() and restored later $z[$i] := RestoreElements($z[$i], _Elements) , __Elements := {}, _Pos := 1 While (RegExMatch($z[$i], "sU)""(.*)""", _String, _Pos)) { If (RegExMatch($z[$i], "sU)^""({.*})""$", _Brace)) __Elements["&_String" A_Index "_&"] := _Brace1 , $z[$i] := RegExReplace($z[$i], "sU)^""{.*}""$", "&_String" A_Index "_&",, 1) Else If (RegExMatch($z[$i], "sU)^""([.*])""$", _Bracket)) __Elements["&_String" A_Index "_&"] := _Bracket1 , $z[$i] := RegExReplace($z[$i], "sU)^""[.*]""$", "&_String" A_Index "_&",, 1) Else If (!RegExMatch(_String1, "^<~#.*#~>$")) __Elements["&_String" A_Index "_&"] := _String1 , $z[$i] := RegExReplace($z[$i], "sU)"".*""", "&_String" A_Index "_&",, 1) _Pos++ } $z[$i] := RegExReplace($z[$i], "&_String\d+_&", """$0""") ; Add concatenate operator after strings where necessary While (RegExMatch($z[$i], "(""&_String\d+_&""\s+)([^\d\.,\s:\+-=*/&|^><\?])")) $z[$i] := RegExReplace($z[$i], "(""&_String\d+_&""\s+)([^\d\.,\s:\+-=*/&|^><\?])", "$1. $2") ; Remove remaining parenthesis to allow math operations While (RegExMatch($z[$i], "\(([^()]++|(?R))*\)")) $z[$i] := RegExReplace($z[$i], "\(([^()]++|(?R))*\)", "$1") ; Evaluate right hand of assignments AssignParse($z[$i], _InVar, _OnOper, _OutValue) If ((!InStr(_OutValue, "&_String")) && (!RegExMatch(_OutValue, "^""<~#.*#~>""$")) && (_InVar && _OnOper && _OutValue)) $z[$i] := _InVar . _OnOper . Eval(_OutValue, _CustomVars, false)[1] ; Evaluate parsed expression with ExprEval() ExprInit() , CompiledExpression := ExprCompile($z[$i]) , $Result := ExprEval(CompiledExpression, _CustomVars, _Objects, __Elements) , $Result := StrSplit($Result, Chr(1)) ; Restore object references For _i, _v in $Result { If (RegExMatch(_v, "^<~#(.*)#~>$", $pd)) $Result[_i] := _Objects[$pd1] } $z[$i] := StrJoin($Result,, false, _Init, _Init) } ; If returning to the original call, remove missing expressions from the array If (_Init) { $x := StrSplit($x, ",", " `t") For _i, _v in $x { If (_v = "") $z.Delete(_i) } } return $z } ParseObjects(v_String, _CustomVars := "", o_Oper := "", o_Value := "") { Static _needle := "([\w%]+\.?|\(([^()]++|(?R))*\)\.?|\[([^\[\]]++|(?R))*\]\.?)" l_Matches := [], _Pos := 1 While (_Pos := RegExMatch(v_String, _needle, l_Found, _Pos)) l_Matches.Push(RegExMatch(RTrim(l_Found, "."), "^%(\S+)%$", $pd) ? %$pd1% : RTrim(l_Found, ".")) , _Pos += StrLen(l_Found) v_Obj := l_Matches[1] If (_CustomVars.HasKey(v_Obj)) _ArrayObject := _CustomVars[v_Obj] Else Try _ArrayObject := %v_Obj% For $i, $v in l_Matches { If (RegExMatch($v, "^\((.*)\)$")) continue If (RegExMatch($v, "^\[(.*)\]$", l_Found)) _Key := Eval(l_Found1, _CustomVars, false) Else _Key := [$v] $n := l_Matches[$i + 1] If (RegExMatch($n, "^\((.*)\)$", l_Found)) { _Key := _Key[1] , _Params := Eval(l_Found1, _CustomVars, false) Try { If ($i = 1) _ArrayObject := %_Key%(_Params*) Else _ArrayObject := _ArrayObject[_Key](_Params*) } Catch e { If (InStr(e.Message, "0x800A03EC")) { ; Workaround for strange bug in some Excel methods For _i, _v in _Params _Params[_i] := " " _v If ($i = 1) _ArrayObject := %_Key%(_Params*) Else _ArrayObject := _ArrayObject[_Key](_Params*) } Else Throw e } } Else If (($i = l_Matches.Length()) && (o_Value != "")) { Try { If (o_Oper = ":=") _ArrayObject := _ArrayObject[_Key*] := o_Value ? o_Value : false Else If (o_Oper = "+=") _ArrayObject := _ArrayObject[_Key*] += o_Value ? o_Value : false Else If (o_Oper = "-=") _ArrayObject := _ArrayObject[_Key*] -= o_Value ? o_Value : false Else If (o_Oper = "*=") _ArrayObject := _ArrayObject[_Key*] *= o_Value ? o_Value : false Else If (o_Oper = "/=") _ArrayObject := _ArrayObject[_Key*] /= o_Value ? o_Value : false Else If (o_Oper = "//=") _ArrayObject := _ArrayObject[_Key*] //= o_Value ? o_Value : false Else If (o_Oper = ".=") _ArrayObject := _ArrayObject[_Key*] .= o_Value ? o_Value : false Else If (o_Oper = "|=") _ArrayObject := _ArrayObject[_Key*] |= o_Value ? o_Value : false Else If (o_Oper = "&=") _ArrayObject := _ArrayObject[_Key*] &= o_Value ? o_Value : false Else If (o_Oper = "^=") _ArrayObject := _ArrayObject[_Key*] ^= o_Value ? o_Value : false Else If (o_Oper = ">>=") _ArrayObject := _ArrayObject[_Key*] >>= o_Value ? o_Value : false Else If (o_Oper = "<<=") _ArrayObject := _ArrayObject[_Key*] <<= o_Value ? o_Value : false } } Else If ($i > 1) _ArrayObject := _ArrayObject[_Key*] } return _ArrayObject } RestoreElements(_String, _Elements) { While (RegExMatch(_String, "&_\w+_&", $pd)) _String := StrReplace(_String, $pd, _Elements[$pd]) return _String } AssignParse(String, ByRef VarName, ByRef Oper, ByRef VarValue) { RegExMatch(String, "(.*?)(:=|\+=|-=|\*=|/=|//=|\.=|\|=|&=|\^=|>>=|<<=)(?=([^""]*""[^""]*"")*[^""]*$)(.*)", Out) , VarName := Trim(Out1), Oper := Out2, VarValue := Trim(Out4) } StrJoin(InputArray, JChr := "", Quote := false, Init := true, Unquote := false) { static $Quote := Chr(2) For i, v in InputArray { If (IsObject(v)) return v If v is not Number { If (!Init) v := RegExReplace(v, """{1,2}", """""") If (Quote) v := """" v """" If (Unquote) While (RegExMatch(v, """{2}")) v := RegExReplace(v, """{2}", """") v := StrReplace(v, $Quote, """") } JoinedStr .= v . JChr } If (JChr != "") JoinedStr := SubStr(JoinedStr, 1, -(StrLen(JChr))) return JoinedStr } ObjCount(Obj) { return NumGet(&Obj + 4 * A_PtrSize) } ;################################################## ; Author: Uberi ; Modified by: Pulover ; http://autohotkey.com/board/topic/64167-expreval-evaluate-expressions/ ;################################################## ExprInit() { global Exprot:="`n:= 0 R 2`n+= 0 R 2`n-= 0 R 2`n*= 0 R 2`n/= 0 R 2`n//= 0 R 2`n.= 0 R 2`n|= 0 R 2`n&= 0 R 2`n^= 0 R 2`n>>= 0 R 2`n<<= 0 R 2`n|| 3 L 2`n&& 4 L 2`n\! 5 R 1`n= 6 L 2`n== 6 L 2`n<> 6 L 2`n!= 6 L 2`n> 7 L 2`n< 7 L 2`n>= 7 L 2`n<= 7 L 2`n\. 8 L 2`n& 9 L 2`n^ 9 L 2`n| 9 L 2`n<< 10 L 2`n>> 10 L 2`n+ 11 L 2`n- 11 L 2`n* 12 L 2`n/ 12 L 2`n// 12 L 2`n\- 13 R 1`n! 13 R 1`n~ 13 R 1`n\& 13 R 1`n\* 13 R 1`n** 14 R 2`n\++ 15 R 1`n\-- 15 R 1`n++ 15 L 1`n-- 15 L 1`n. 16 L 2`n`% 17 R 1`n",Exprol:=SubStr(RegExReplace(Exprot,"iS) \d+ [LR] \d+\n","`n"),2,-1) Sort,Exprol,FExprols } ExprCompile(e) { e:=Exprt(e) Loop,Parse,e,% Chr(1) { lf:=A_LoopField,tt:=SubStr(lf,1,1),to:=SubStr(lf,2) If tt=f Exprp1(s,lf) Else If lf=, { While,s<>""&&Exprp3(s)<>"(" Exprp1(ou,Exprp2(s)) } Else If tt=o { While,SubStr(so:=Exprp3(s),1,1)="o" { ta:=Expras(to),tp:=Exprpr(to),sop:=Exprpr(SubStr(so,2)) If ((ta="L"&&tp>sop)||(ta="R"&&tp>=sop)) Break Exprp1(ou,Exprp2(s)) } Exprp1(s,lf) } Else If lf=( Exprp1(s,"(") Else If lf=) { While,Exprp3(s)<>"(" { If s= Return Exprp1(ou,Exprp2(s)) } Exprp2(s) If (SubStr(Exprp3(s),1,1)="f") Exprp1(ou,Exprp2(s)) } Else Exprp1(ou,lf) } While,s<>"" { t1:=Exprp2(s) If t1 In (,) Return Exprp1(ou,t1) } Return,ou } ExprEval(e,lp,eo,el) { c1:=Chr(1) Loop,Parse,e,%c1% { lf:=A_LoopField,tt:=SubStr(lf,1,1),t:=SubStr(lf,2) While (RegExMatch(lf,"&_String\d+_&",rm)) lf:=StrReplace(lf,rm,el[rm]) If tt In l,v lf:=Exprp1(s,lf) Else{ If tt=f t1:=InStr(t," "),a:=SubStr(t,1,t1-1),t:=SubStr(t,t1+1) Else a:=Exprac(t) Exprp1(s,Exprap(t,s,a,lp,eo)) } } Loop,Parse,s,%c1% { lf:=A_LoopField If (SubStr(lf,1,1)="v") t1:=SubStr(lf,2),r.=(lp.HasKey(t1) ? lp[t1] : %t1%) . c1 Else r.=SubStr(lf,2) . c1 } Return,SubStr(r,1,-1) } Exprap(o,ByRef s,ac,lp,eo) { local i,t1,a1,a2,a3,a4,a5,a6,a1v,a2v,a3v,a4v,a5v,a6v,a7v,a8v,a9v Loop,%ac% i:=ac-(A_Index-1),t1:=Exprp2(s),a%i%:=SubStr(t1,2),(SubStr(t1,1,1)="v")?(a%i%v:=1) Loop, 10 { If (RegExMatch(a%A_Index%,"^<~#(.*)#~>$",rm)) a%A_Index%:=eo[rm1],a%A_Index%v:=0 Else If (lp.HasKey(a%A_Index%)) a%A_Index%:=lp[a%A_Index%],a%A_Index%v:=0 } If o=++ Return,"l" . %a1%++ If o=-- Return,"l" . %a1%-- If o=\++ Return,"l" . ++%a1% If o=\-- Return,"l" . --%a1% If o=`% Return,"v" . %a1% If o=! Return,"l" . !(a1v ? %a1%:a1) If o=\! Return,"l" . (a1v ? %a1%:a1) If o=~ Return,"l" . ~(a1v ? %a1%:a1) If o=** Return,"l" . ((a1v ? %a1%:a1)**(a2v ? %a2%:a2)) If o=* Return,"l" . ((a1v ? %a1%:a1)*(a2v ? %a2%:a2)) If o=\* Return,"l" . *(a1v ? %a1%:a1) If o=/ Return,"l" . ((a1v ? %a1%:a1)/(a2v ? %a2%:a2)) If o=// Return,"l" . ((a1v ? %a1%:a1)//(a2v ? %a2%:a2)) If o=+ Return,"l" . ((a1v ? %a1%:a1)+(a2v ? %a2%:a2)) If o=- Return,"l" . ((a1v ? %a1%:a1)-(a2v ? %a2%:a2)) If o=\- Return,"l" . -(a1v ? %a1%:a1) If o=<< Return,"l" . ((a1v ? %a1%:a1)<<(a2v ? %a2%:a2)) If o=>> Return,"l" . ((a1v ? %a1%:a1)>>(a2v ? %a2%:a2)) If o=& Return,"l" . ((a1v ? %a1%:a1)&(a2v ? %a2%:a2)) If o=\& Return,"l" . &(a1v ? %a1%:a1) If o=^ Return,"l" . ((a1v ? %a1%:a1)^(a2v ? %a2%:a2)) If o=| Return,"l" . ((a1v ? %a1%:a1)|(a2v ? %a2%:a2)) If o=\. Return,"l" . ((a1v ? %a1%:a1) . (a2v ? %a2%:a2)) If o=. Return,"v" . a1 If o=< Return,"l" . ((a1v ? %a1%:a1)<(a2v ? %a2%:a2)) If o=> Return,"l" . ((a1v ? %a1%:a1)>(a2v ? %a2%:a2)) If o== Return,"l" . ((a1v ? %a1%:a1)=(a2v ? %a2%:a2)) If o=== Return,"l" . ((a1v ? %a1%:a1)==(a2v ? %a2%:a2)) If o=<> Return,"l" . ((a1v ? %a1%:a1)<>(a2v ? %a2%:a2)) If o=!= Return,"l" . ((a1v ? %a1%:a1)!=(a2v ? %a2%:a2)) If o=>= Return,"l" . ((a1v ? %a1%:a1)>=(a2v ? %a2%:a2)) If o=<= Return,"l" . ((a1v ? %a1%:a1)<=(a2v ? %a2%:a2)) If o=&& Return,"l" . ((a1v ? %a1%:a1)&&(a2v ? %a2%:a2)) If o=|| Return,"l" . ((a1v ? %a1%:a1)||(a2v ? %a2%:a2)) If o=:= { %a1%:=(a2v ? %a2%:a2) Return,"v" . a1 } If o=+= { %a1%+=(a2v ? %a2%:a2) Return,"v" . a1 } If o=-= { %a1%-=(a2v ? %a2%:a2) Return,"v" . a1 } If o=*= { %a1%*=(a2v ? %a2%:a2) Return,"v" . a1 } If o=/= { %a1%/=(a2v ? %a2%:a2) Return,"v" . a1 } If o=//= { %a1%//=(a2v ? %a2%:a2) Return,"v" . a1 } If o=.= { %a1%.=(a2v ? %a2%:a2) Return,"v" . a1 } If o=|= { %a1%|=(a2v ? %a2%:a2) Return,"v" . a1 } If o=&= { %a1%&=(a2v ? %a2%:a2) Return,"v" . a1 } If o=^= { %a1%^=(a2v ? %a2%:a2) Return,"v" . a1 } If o=>>= { %a1%>>=(a2v ? %a2%:a2) Return,"v" . a1 } If o=<<= { %a1%<<=(a2v ? %a2%:a2) Return,"v" . a1 } If ac=0 Return,"l" . %o%() If ac=1 Return,"l" . %o%(a1v ? %a1%:a1) If ac=2 Return,"l" . %o%((a1v ? %a1%:a1),(a2v ? %a2%:a2)) If ac=3 Return,"l" . %o%((a1v ? %a1%:a1),(a2v ? %a2%:a2),(a3v ? %a3%:a3)) If ac=4 Return,"l" . %o%((a1v ? %a1%:a1),(a2v ? %a2%:a2),(a3v ? %a3%:a3),(a4v ? %a4%:a4)) If ac=5 Return,"l" . %o%((a1v ? %a1%:a1),(a2v ? %a2%:a2),(a3v ? %a3%:a3),(a4v ? %a4%:a4),(a5v ? %a5%:a5)) If ac=6 Return,"l" . %o%((a1v ? %a1%:a1),(a2v ? %a2%:a2),(a3v ? %a3%:a3),(a4v ? %a4%:a4),(a5v ? %a5%:a5),(a6v ? %a6%:a6)) If ac=7 Return,"l" . %o%((a1v ? %a1%:a1),(a2v ? %a2%:a2),(a3v ? %a3%:a3),(a4v ? %a4%:a4),(a5v ? %a5%:a5),(a6v ? %a6%:a6),(a7v ? %a7%:a7)) If ac=8 Return,"l" . %o%((a1v ? %a1%:a1),(a2v ? %a2%:a2),(a3v ? %a3%:a3),(a4v ? %a4%:a4),(a5v ? %a5%:a5),(a6v ? %a6%:a6),(a7v ? %a7%:a7),(a8v ? %a8%:a8)) If ac=9 Return,"l" . %o%((a1v ? %a1%:a1),(a2v ? %a2%:a2),(a3v ? %a3%:a3),(a4v ? %a4%:a4),(a5v ? %a5%:a5),(a6v ? %a6%:a6),(a7v ? %a7%:a7),(a8v ? %a8%:a8),(a9v ? %a9%:a9)) If ac=10 Return,"l" . %o%((a1v ? %a1%:a1),(a2v ? %a2%:a2),(a3v ? %a3%:a3),(a4v ? %a4%:a4),(a5v ? %a5%:a5),(a6v ? %a6%:a6),(a7v ? %a7%:a7),(a8v ? %a8%:a8),(a9v ? %a9%:a9),(a10v ? %a10%:a10)) } Exprt(e) { global Exprol c1:=Chr(1),f:=1,f1:=1 While,(f:=RegExMatch(e,"S)""(?:[^""]|"""")*""",m,f)) { t1:=SubStr(m,2,-1) , t1:=StrReplace(t1,"""""","""") , t1:=StrReplace(t1,"'","'27") , t1:=StrReplace(t1,"````",c1) , t1:=StrReplace(t1,"``n","`n") , t1:=StrReplace(t1,"``r","`r") , t1:=StrReplace(t1,"``b","`b") , t1:=StrReplace(t1,"``t","`t") , t1:=StrReplace(t1,"``v","`v") , t1:=StrReplace(t1,"``a","`a") , t1:=StrReplace(t1,"``f","`f") , t1:=StrReplace(t1,c1,"``") SetFormat,IntegerFast,Hex While,RegExMatch(t1,"iS)[^\w']",c) t1:=StrReplace(t1,c,"'" . SubStr("0" . SubStr(Asc(c),3),-1)) SetFormat,IntegerFast,D e1.=SubStr(e,f1,f-f1) . c1 . "l" . t1 . c1,f+=StrLen(m),f1:=f } e1.=SubStr(e,f1),e:=InStr(e1,"""")? "":e1,e1:="",e:=RegExReplace(e,"S)/\*.*?\*/|[ \t]`;.*?(?=\r|\n|$)") , e:=StrReplace(e,"`t"," ") , e:=RegExReplace(e,"S)([\w#@\$] +|\) *)(?=" . Chr(1) . "*[\w#@\$\(])","$1 . ") , e:=StrReplace(e," . ","\.") , e:=StrReplace(e," ") , f:=1,f1:=1 While,(f:=RegExMatch(e,"iS)(^|[^\w#@\$\.'])(0x[0-9a-fA-F]+|\d+(?:\.\d+)?|\.\d+)(?=[^\d\.]|$)",m,f)) { If ((m1="\") && (RegExMatch(m2,"\.\d+"))) m1:="",m2:=SubStr(m2,2) m2+=0 m2:=StrReplace(m2,".","'2E",,1) e1.=SubStr(e,f1,f-f1) . m1 . c1 . "n" . m2 . c1,f+=StrLen(m),f1:=f } e:=e1 . SubStr(e,f1),e1:="" ; ,e:=RegExReplace(e,"S)(^|\(|[^" . c1 . "-])-" . c1 . "n","$1" . c1 . "n'2D") , e:=StrReplace(e,c1 "n",c1 "l") , e:=RegExReplace(e,"\\\.(\d+)\.(\d+)",c1 . "l$1'2E$2" . c1) , e:=RegExReplace(RegExReplace(e,"S)(%[\w#@\$]{1,253})%","$1"),"S)(?:^|[^\w#@\$'" . c1 . "])\K[\w#@\$]{1,253}(?=[^\(\w#@\$]|$)",c1 . "v$0" . c1),f:=1,f1:=1 While,(f:=RegExMatch(e,"S)(^|[^\w#@\$'])([\w#@\$]{1,253})(?=\()",m,f)) { t1:=f+StrLen(m) If (SubStr(e,t1+1,1)=")") ac=0 Else { If !Exprmlb(e,t1,fa) Return fa:=StrReplace(fa,"`,","`,",c) ac:=c+1 } e1.=SubStr(e,f1,f-f1) . m1 . c1 . "f" . ac . "'20" . m2 . c1,f+=StrLen(m),f1:=f } e:=e1 . SubStr(e,f1),e1:="" , e:=StrReplace(e,"\." c1 "vNot" c1 "\.","!") , e:=StrReplace(e,"\." c1 "vAnd" c1 "\.","&&") , e:=StrReplace(e,"\." c1 "vOr" c1 "\.","||") , e:=StrReplace(e,c1 "vNot" c1 "\.","!") , e:=StrReplace(e,c1 "vAnd" c1 "\.","&&") , e:=StrReplace(e,c1 "vOr" c1 "\.","||") , e:=StrReplace(e,"\." c1 "vNot" c1 . c1,"!") , e:=StrReplace(e,"\." c1 "vAnd" c1 . c1,"&&") , e:=StrReplace(e,"\." c1 "vOr" c1 . c1,"||") , e:=StrReplace(e,c1 "vNot" c1 . c1,"!") , e:=StrReplace(e,c1 "vAnd" c1 . c1,"&&") , e:=StrReplace(e,c1 "vOr" c1 . c1,"||") , e:=RegExReplace(e,"S)(^|[^" . c1 . "\)-])-" . c1 . "(?=[lvf])","$1\-" . c1) , e:=RegExReplace(e,"S)(^|[^" . c1 . "\)&])&" . c1 . "(?=[lvf])","$1\&" . c1) , e:=RegExReplace(e,"S)(^|[^" . c1 . "\)\*])\*" . c1 . "(?=[lvf])","$1\*" . c1) , e:=RegExReplace(e,"S)(^|[^" . c1 . "\)])(\+\+|--)" . c1 . "(?=[lvf])","$1\$2" . c1) , t1:=RegExReplace(Exprol,"S)[\\\.\*\?\+\[\{\|\(\)\^\$]","\$0") , t1:=StrReplace(t1,"`n","|") , e:=RegExReplace(e,"S)" . t1,c1 . "o$0" . c1) , e:=StrReplace(e,"`,",c1 "`," c1) , e:=StrReplace(e,"(",c1 "(" c1) , e:=StrReplace(e,")",c1 ")" c1) , e:=StrReplace(e,c1 . c1,c1) If RegExMatch(e,"S)" . c1 . "[^lvfo\(\),\n]") Return e:=SubStr(e,2,-1),f:=0 While,(f:=InStr(e,"'",False,f + 1)) { If ((t1:=SubStr(e,f+1,2))<>27) e:=StrReplace(e,"'" t1,Chr("0x" . t1)) } e:=StrReplace(e,"'27","'") Return,e } Exprols(o1,o2) { Return,StrLen(o2)-StrLen(o1) } Exprpr(o) { global Exprot t:=InStr(Exprot,"`n" . o . " ")+StrLen(o)+2 Return,SubStr(Exprot,t,InStr(Exprot," ",0,t)-t) } Expras(o) { global Exprot Return,SubStr(Exprot,InStr(Exprot," ",0,InStr(Exprot,"`n" . o . " ")+StrLen(o)+2)+1,1) } Exprac(o) { global Exprot Return,SubStr(Exprot,InStr(Exprot,"`n",0,InStr(Exprot,"`n" . o . " ")+1)-1,1) } Exprmlb(ByRef s,p,ByRef o="",b="(",e=")") { t:=SubStr(s,p),bc:=0,VarSetCapacity(o,StrLen(t)) If (SubStr(t,1,1)<>b) Return,0 Loop,Parse,t { lf:=A_LoopField If lf=%b% bc++ Else If lf=%e% { bc-- If bc=0 Return,p } Else If bc=1 o.=lf p++ } Return,0 } Exprp1(ByRef dl,d) { dl.=((dl="")? "":Chr(1)) . d } Exprp2(ByRef dl) { t:=InStr(dl,Chr(1),0,0),t ?(t1:=SubStr(dl,t+1),dl:=SubStr(dl,1,t-1)):(t1:=dl,dl:="") Return,t1 } Exprp3(ByRef dl) { Return,SubStr(dl,InStr(dl,Chr(1),0,0)+1) } ================================================ FILE: Install.ahk ================================================ #Requires AutoHotkey v1.1 #SingleInstance, Force SetBatchLines, -1 SetWorkingDir, % A_ScriptDir FileInstall, __Release\CH-Install.zip, CH-Install.zip, 1 FileInstall, Install.png, Install.png, 1 Gui, -MinimizeBox Gui, Font, s20 Bold, Calibri Gui, Color, White Gui, Add, Text, Center BackgroundTrans w400, Cash Helper Gui, Add, Pic, xm yp-10 w64 h64 BackgroundTrans, Install.png Gui, Font, Norm Gui, Font, s10 Bold Gui, Add, Edit, ReadOnly w290 vLoc, %A_ProgramFiles%\Cash Helper IS := InstallState() Gui, Font, s8 Gui, Add, Button, xp+300 yp w100 vCG, Change Gui, Font, s10 Gui, Add, Checkbox, xp-300 yp+30 Checked gInstallWay vIAU, Install for all users Gui, Add, Checkbox, yp+20 vPort, Portable Gui, Add, Button, w100 vIB gButtonInstall, % IS[1] Gui, Add, Progress, w400 vPB -Smooth h15 Hidden Gui, Font, s8 Gui, Add, Text, xp yp+17 wp Center vPercent BackgroundTrans FileInstall, __Release\Version.txt, Version.txt, 1 FileRead, Version, Version.txt Gui, Show,, Install Setup %Version% GuiControl, Focus, IB Return InstallWay: GuiControlGet, IAU If (IAU) { GuiControl,, Loc, %A_ProgramFiles%\Cash Helper } Else { GuiControl,, Loc, %A_AppData%\Cash Helper } IS := InstallState() Return GuiClose: ExitApp ButtonInstall: If !FileExist("CH-Install.zip") { MsgBox, 16, Error, Install package not found. Return } GuiControl, Disabled, IB GuiControl, Disabled, IAU GuiControl, Disabled, Port GuiControl, Disabled, Loc GuiControl, Disabled, CG GuiControl,, IB, % IS[2] GuiControlGet, Loc GuiControl, Show, PB GuiControl,, PB, + 20 GuiControl,, Percent, 20 `% FileCopyDir, CH-Install.zip, % Loc, 1 FileDelete, CH-Install.zip GuiControl,, PB, + 30 GuiControl,, Percent, 50 `% FileCopyDir, % Loc "\HighChart.zip", % Loc "\", 1 FileDelete, % Loc "\HighChart.zip" GuiControl,, PB, + 40 GuiControl,, Percent, 90 `% FileCopy, Version.txt, % Loc, 1 FileDelete, Version.txt GuiControl,, PB, + 10 GuiControl,, Percent, 100 `% GuiControlGet, Port If (!Port) { RegPath := "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Cash Helper" RegWrite, REG_SZ, %RegPath%, DisplayName, Cash Helper RegWrite, REG_SZ, %RegPath%, DisplayVersion, %Version% RegWrite, REG_SZ, %RegPath%, DisplayIcon, %Loc%\StartUp.exe RegWrite, REG_SZ, %RegPath%, InstallLocation, %Loc%\ RegWrite, REG_SZ, %RegPath%, UninstallString, %Loc%\Uninstall.exe RegWrite, REG_DWORD, %RegPath%, NoModify, 1 RegWrite, REG_DWORD, %RegPath%, NoRepair, 1 RegWrite, REG_SZ, %RegPath%, Publisher, Chandoul Mohamed GuiControl,, Log, Creating a shortcut... FileCreateShortcut, %Loc%\StartUp.exe, %A_Desktop%\Cash Helper.lnk } GuiControl,, IB, COMPLETE! MsgBox, 4, Launch, Run Cash Helper now? IfMsgBox, Yes { Run, % Loc "\StartUp.exe" } ExitApp ButtonChange: If (Dir := SelectFolderEx(StartingFolder := "", Prompt := "Select Program Location",, OkBtnLabel := "OK!")) { GuiControl,, Loc, % Dir "\Cash Helper" InstallState() } Return SelectFolderEx(StartingFolder := "", Prompt := "", OwnerHwnd := 0, OkBtnLabel := "") { Static OsVersion := DllCall("GetVersion", "UChar") , IID_IShellItem := 0 , InitIID := VarSetCapacity(IID_IShellItem, 16, 0) & DllCall("Ole32.dll\IIDFromString", "WStr", "{43826d1e-e718-42ee-bc55-a1e261c37bfe}", "Ptr", &IID_IShellItem) , Show := A_PtrSize * 3 , SetOptions := A_PtrSize * 9 , SetFolder := A_PtrSize * 12 , SetTitle := A_PtrSize * 17 , SetOkButtonLabel := A_PtrSize * 18 , GetResult := A_PtrSize * 20 SelectedFolder := "" If (OsVersion < 6) { FileSelectFolder, SelectedFolder, *%StartingFolder%, 3, %Prompt% Return SelectedFolder } OwnerHwnd := DllCall("IsWindow", "Ptr", OwnerHwnd, "UInt") ? OwnerHwnd : 0 If !(FileDialog := ComObjCreate("{DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7}", "{42f85136-db7e-439c-85f1-e4075d135fc8}")) Return "" VTBL := NumGet(FileDialog + 0, "UPtr") DllCall(NumGet(VTBL + SetOptions, "UPtr"), "Ptr", FileDialog, "UInt", 0x00002028, "UInt") If (StartingFolder <> "") If !DllCall("Shell32.dll\SHCreateItemFromParsingName", "WStr", StartingFolder, "Ptr", 0, "Ptr", &IID_IShellItem, "PtrP", FolderItem) DllCall(NumGet(VTBL + SetFolder, "UPtr"), "Ptr", FileDialog, "Ptr", FolderItem, "UInt") If (Prompt <> "") DllCall(NumGet(VTBL + SetTitle, "UPtr"), "Ptr", FileDialog, "WStr", Prompt, "UInt") If (OkBtnLabel <> "") DllCall(NumGet(VTBL + SetOkButtonLabel, "UPtr"), "Ptr", FileDialog, "WStr", OkBtnLabel, "UInt") If !DllCall(NumGet(VTBL + Show, "UPtr"), "Ptr", FileDialog, "Ptr", OwnerHwnd, "UInt") { If !DllCall(NumGet(VTBL + GetResult, "UPtr"), "Ptr", FileDialog, "PtrP", ShellItem, "UInt") { GetDisplayName := NumGet(NumGet(ShellItem + 0, "UPtr"), A_PtrSize * 5, "UPtr") If !DllCall(GetDisplayName, "Ptr", ShellItem, "UInt", 0x80028000, "PtrP", StrPtr) SelectedFolder := StrGet(StrPtr, "UTF-16"), DllCall("Ole32.dll\CoTaskMemFree", "Ptr", StrPtr) ObjRelease(ShellItem) } } If (FolderItem) ObjRelease(FolderItem) ObjRelease(FileDialog) Return SelectedFolder } InstallState() { RegRead, IC, HKLM, SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Cash Helper, InstallLocation GuiControlGet, Loc IS := (IC = Loc "\") ? ["Update", "Updating..."] : ["Install", "Installing..."] GuiControl,, IB, % IS[1] Return, IS } ================================================ FILE: Lib/Classes/Class_CtlColors.ahk ================================================ ; ====================================================================================================================== ; AHK 1.1+ ; ====================================================================================================================== ; Function: Auxiliary object to color controls on WM_CTLCOLOR... notifications. ; Supported controls are: Checkbox, ComboBox, DropDownList, Edit, ListBox, Radio, Text. ; Checkboxes and Radios accept only background colors due to design. ; Namespace: CtlColors ; Tested with: 1.1.25.02 ; Tested on: Win 10 (x64) ; Change log: 1.0.04.00/2017-10-30/just me - added transparent background (BkColor = "Trans"). ; 1.0.03.00/2015-07-06/just me - fixed Change() to run properly for ComboBoxes. ; 1.0.02.00/2014-06-07/just me - fixed __New() to run properly with compiled scripts. ; 1.0.01.00/2014-02-15/just me - changed class initialization. ; 1.0.00.00/2014-02-14/just me - initial release. ; ====================================================================================================================== ; This software is provided 'as-is', without any express or implied warranty. ; In no event will the authors be held liable for any damages arising from the use of this software. ; ====================================================================================================================== Class CtlColors { ; =================================================================================================================== ; Class variables ; =================================================================================================================== ; Registered Controls Static Attached := {} ; OnMessage Handlers Static HandledMessages := {Edit: 0, ListBox: 0, Static: 0} ; Message Handler Function Static MessageHandler := "CtlColors_OnMessage" ; Windows Messages Static WM_CTLCOLOR := {Edit: 0x0133, ListBox: 0x134, Static: 0x0138} ; HTML Colors (BGR) Static HTML := {AQUA: 0xFFFF00, BLACK: 0x000000, BLUE: 0xFF0000, FUCHSIA: 0xFF00FF, GRAY: 0x808080, GREEN: 0x008000 , LIME: 0x00FF00, MAROON: 0x000080, NAVY: 0x800000, OLIVE: 0x008080, PURPLE: 0x800080, RED: 0x0000FF , SILVER: 0xC0C0C0, TEAL: 0x808000, WHITE: 0xFFFFFF, YELLOW: 0x00FFFF} ; Transparent Brush Static NullBrush := DllCall("GetStockObject", "Int", 5, "UPtr") ; System Colors Static SYSCOLORS := {Edit: "", ListBox: "", Static: ""} ; Error message in case of errors Static ErrorMsg := "" ; Class initialization Static InitClass := CtlColors.ClassInit() ; =================================================================================================================== ; Constructor / Destructor ; =================================================================================================================== __New() { ; You must not instantiate this class! If (This.InitClass == "!DONE!") { ; external call after class initialization This["!Access_Denied!"] := True Return False } } ; ---------------------------------------------------------------------------------------------------------------- __Delete() { If This["!Access_Denied!"] Return This.Free() ; free GDI resources } ; =================================================================================================================== ; ClassInit Internal creation of a new instance to ensure that __Delete() will be called. ; =================================================================================================================== ClassInit() { CtlColors := New CtlColors Return "!DONE!" } ; =================================================================================================================== ; CheckBkColor Internal check for parameter BkColor. ; =================================================================================================================== CheckBkColor(ByRef BkColor, Class) { This.ErrorMsg := "" If (BkColor != "") && !This.HTML.HasKey(BkColor) && !RegExMatch(BkColor, "^[[:xdigit:]]{6}$") { This.ErrorMsg := "Invalid parameter BkColor: " . BkColor Return False } BkColor := BkColor = "" ? This.SYSCOLORS[Class] : This.HTML.HasKey(BkColor) ? This.HTML[BkColor] : "0x" . SubStr(BkColor, 5, 2) . SubStr(BkColor, 3, 2) . SubStr(BkColor, 1, 2) Return True } ; =================================================================================================================== ; CheckTxColor Internal check for parameter TxColor. ; =================================================================================================================== CheckTxColor(ByRef TxColor) { This.ErrorMsg := "" If (TxColor != "") && !This.HTML.HasKey(TxColor) && !RegExMatch(TxColor, "i)^[[:xdigit:]]{6}$") { This.ErrorMsg := "Invalid parameter TextColor: " . TxColor Return False } TxColor := TxColor = "" ? "" : This.HTML.HasKey(TxColor) ? This.HTML[TxColor] : "0x" . SubStr(TxColor, 5, 2) . SubStr(TxColor, 3, 2) . SubStr(TxColor, 1, 2) Return True } ; =================================================================================================================== ; Attach Registers a control for coloring. ; Parameters: HWND - HWND of the GUI control ; BkColor - HTML color name, 6-digit hexadecimal RGB value, or "" for default color ; ----------- Optional ; TxColor - HTML color name, 6-digit hexadecimal RGB value, or "" for default color ; Return values: On success - True ; On failure - False, CtlColors.ErrorMsg contains additional informations ; =================================================================================================================== Attach(HWND, BkColor, TxColor := "") { ; Names of supported classes Static ClassNames := {Button: "", ComboBox: "", Edit: "", ListBox: "", Static: ""} ; Button styles Static BS_CHECKBOX := 0x2, BS_RADIOBUTTON := 0x8 ; Editstyles Static ES_READONLY := 0x800 ; Default class background colors Static COLOR_3DFACE := 15, COLOR_WINDOW := 5 ; Initialize default background colors on first call ------------------------------------------------------------- If (This.SYSCOLORS.Edit = "") { This.SYSCOLORS.Static := DllCall("User32.dll\GetSysColor", "Int", COLOR_3DFACE, "UInt") This.SYSCOLORS.Edit := DllCall("User32.dll\GetSysColor", "Int", COLOR_WINDOW, "UInt") This.SYSCOLORS.ListBox := This.SYSCOLORS.Edit } This.ErrorMsg := "" ; Check colors --------------------------------------------------------------------------------------------------- If (BkColor = "") && (TxColor = "") { This.ErrorMsg := "Both parameters BkColor and TxColor are empty!" Return False } ; Check HWND ----------------------------------------------------------------------------------------------------- If !(CtrlHwnd := HWND + 0) || !DllCall("User32.dll\IsWindow", "UPtr", HWND, "UInt") { This.ErrorMsg := "Invalid parameter HWND: " . HWND Return False } If This.Attached.HasKey(HWND) { This.ErrorMsg := "Control " . HWND . " is already registered!" Return False } Hwnds := [CtrlHwnd] ; Check control's class ------------------------------------------------------------------------------------------ Classes := "" WinGetClass, CtrlClass, ahk_id %CtrlHwnd% This.ErrorMsg := "Unsupported control class: " . CtrlClass If !ClassNames.HasKey(CtrlClass) Return False ControlGet, CtrlStyle, Style, , , ahk_id %CtrlHwnd% If (CtrlClass = "Edit") Classes := ["Edit", "Static"] Else If (CtrlClass = "Button") { IF (CtrlStyle & BS_RADIOBUTTON) || (CtrlStyle & BS_CHECKBOX) Classes := ["Static"] Else Return False } Else If (CtrlClass = "ComboBox") { VarSetCapacity(CBBI, 40 + (A_PtrSize * 3), 0) NumPut(40 + (A_PtrSize * 3), CBBI, 0, "UInt") DllCall("User32.dll\GetComboBoxInfo", "Ptr", CtrlHwnd, "Ptr", &CBBI) Hwnds.Insert(NumGet(CBBI, 40 + (A_PtrSize * 2, "UPtr")) + 0) Hwnds.Insert(Numget(CBBI, 40 + A_PtrSize, "UPtr") + 0) Classes := ["Edit", "Static", "ListBox"] } If !IsObject(Classes) Classes := [CtrlClass] ; Check background color ----------------------------------------------------------------------------------------- If (BkColor <> "Trans") If !This.CheckBkColor(BkColor, Classes[1]) Return False ; Check text color ----------------------------------------------------------------------------------------------- If !This.CheckTxColor(TxColor) Return False ; Activate message handling on the first call for a class -------------------------------------------------------- For I, V In Classes { If (This.HandledMessages[V] = 0) OnMessage(This.WM_CTLCOLOR[V], This.MessageHandler) This.HandledMessages[V] += 1 } ; Store values for HWND ------------------------------------------------------------------------------------------ If (BkColor = "Trans") Brush := This.NullBrush Else Brush := DllCall("Gdi32.dll\CreateSolidBrush", "UInt", BkColor, "UPtr") For I, V In Hwnds This.Attached[V] := {Brush: Brush, TxColor: TxColor, BkColor: BkColor, Classes: Classes, Hwnds: Hwnds} ; Redraw control ------------------------------------------------------------------------------------------------- DllCall("User32.dll\InvalidateRect", "Ptr", HWND, "Ptr", 0, "Int", 1) This.ErrorMsg := "" Return True } ; =================================================================================================================== ; Change Change control colors. ; Parameters: HWND - HWND of the GUI control ; BkColor - HTML color name, 6-digit hexadecimal RGB value, or "" for default color ; ----------- Optional ; TxColor - HTML color name, 6-digit hexadecimal RGB value, or "" for default color ; Return values: On success - True ; On failure - False, CtlColors.ErrorMsg contains additional informations ; Remarks: If the control isn't registered yet, Add() is called instead internally. ; =================================================================================================================== Change(HWND, BkColor, TxColor := "") { ; Check HWND ----------------------------------------------------------------------------------------------------- This.ErrorMsg := "" HWND += 0 If !This.Attached.HasKey(HWND) Return This.Attach(HWND, BkColor, TxColor) CTL := This.Attached[HWND] ; Check BkColor -------------------------------------------------------------------------------------------------- If (BkColor <> "Trans") If !This.CheckBkColor(BkColor, CTL.Classes[1]) Return False ; Check TxColor ------------------------------------------------------------------------------------------------ If !This.CheckTxColor(TxColor) Return False ; Store Colors --------------------------------------------------------------------------------------------------- If (BkColor <> CTL.BkColor) { If (CTL.Brush) { If (Ctl.Brush <> This.NullBrush) DllCall("Gdi32.dll\DeleteObject", "Prt", CTL.Brush) This.Attached[HWND].Brush := 0 } If (BkColor = "Trans") Brush := This.NullBrush Else Brush := DllCall("Gdi32.dll\CreateSolidBrush", "UInt", BkColor, "UPtr") For I, V In CTL.Hwnds { This.Attached[V].Brush := Brush This.Attached[V].BkColor := BkColor } } For I, V In Ctl.Hwnds This.Attached[V].TxColor := TxColor This.ErrorMsg := "" DllCall("User32.dll\InvalidateRect", "Ptr", HWND, "Ptr", 0, "Int", 1) Return True } ; =================================================================================================================== ; Detach Stop control coloring. ; Parameters: HWND - HWND of the GUI control ; Return values: On success - True ; On failure - False, CtlColors.ErrorMsg contains additional informations ; =================================================================================================================== Detach(HWND) { This.ErrorMsg := "" HWND += 0 If This.Attached.HasKey(HWND) { CTL := This.Attached[HWND].Clone() If (CTL.Brush) && (CTL.Brush <> This.NullBrush) DllCall("Gdi32.dll\DeleteObject", "Prt", CTL.Brush) For I, V In CTL.Classes { If This.HandledMessages[V] > 0 { This.HandledMessages[V] -= 1 If This.HandledMessages[V] = 0 OnMessage(This.WM_CTLCOLOR[V], "") } } For I, V In CTL.Hwnds This.Attached.Remove(V, "") DllCall("User32.dll\InvalidateRect", "Ptr", HWND, "Ptr", 0, "Int", 1) CTL := "" Return True } This.ErrorMsg := "Control " . HWND . " is not registered!" Return False } ; =================================================================================================================== ; Free Stop coloring for all controls and free resources. ; Return values: Always True. ; =================================================================================================================== Free() { For K, V In This.Attached If (V.Brush) && (V.Brush <> This.NullBrush) DllCall("Gdi32.dll\DeleteObject", "Ptr", V.Brush) For K, V In This.HandledMessages If (V > 0) { OnMessage(This.WM_CTLCOLOR[K], "") This.HandledMessages[K] := 0 } This.Attached := {} Return True } ; =================================================================================================================== ; IsAttached Check if the control is registered for coloring. ; Parameters: HWND - HWND of the GUI control ; Return values: On success - True ; On failure - False ; =================================================================================================================== IsAttached(HWND) { Return This.Attached.HasKey(HWND) } } ; ====================================================================================================================== ; CtlColors_OnMessage ; This function handles CTLCOLOR messages. There's no reason to call it manually! ; ====================================================================================================================== CtlColors_OnMessage(HDC, HWND) { Critical If CtlColors.IsAttached(HWND) { CTL := CtlColors.Attached[HWND] If (CTL.TxColor != "") DllCall("Gdi32.dll\SetTextColor", "Ptr", HDC, "UInt", CTL.TxColor) If (CTL.BkColor = "Trans") DllCall("Gdi32.dll\SetBkMode", "Ptr", HDC, "UInt", 1) ; TRANSPARENT = 1 Else DllCall("Gdi32.dll\SetBkColor", "Ptr", HDC, "UInt", CTL.BkColor) Return CTL.Brush } } ================================================ FILE: Lib/Classes/Class_GDIplus.ahk ================================================ class GDIplus { __New() { if !DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr") DllCall("LoadLibrary", "Str", "gdiplus") VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1) DllCall("gdiplus\GdiplusStartup", "UPtrP", pToken, "Ptr", &si, "Ptr", 0) this.token := pToken } __Delete() { DllCall("gdiplus\GdiplusShutdown", "Ptr", this.token) if hModule := DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr") DllCall("FreeLibrary", "Ptr", hModule) } CreateBitmapFromStream(pStream) { DllCall("gdiplus\GdipCreateBitmapFromStream", "Ptr", pStream, "PtrP", pBitmap) Return pBitmap } CreateHBITMAPFromBitmap(pBitmap, background := 0xffffffff) { DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hbm, "UInt", background) return hbm } DisposeImage(pBitmap) { return DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap) } } ================================================ FILE: Lib/Classes/Class_ImageButton.ahk ================================================ ; ====================================================================================================================== ; Namespace: ImageButton ; Function: Create images and assign them to pushbuttons. ; Tested with: AHK 1.1.33.02 (A32/U32/U64) ; Tested on: Win 10 (x64) ; Change history: 1.5.00.00/2020-12-16/just me - increased script performance, added support for icons (HICON) ; 1.4.00.00/2014-06-07/just me - fixed bug for button caption = "0", "000", etc. ; 1.3.00.00/2014-02-28/just me - added support for ARGB colors ; 1.2.00.00/2014-02-23/just me - added borders ; 1.1.00.00/2013-12-26/just me - added rounded and bicolored buttons ; 1.0.00.00/2013-12-21/just me - initial release ; How to use: ; 1. Create a push button (e.g. "Gui, Add, Button, vMyButton hwndHwndButton, Caption") using the 'Hwnd' option ; to get its HWND. ; 2. Call ImageButton.Create() passing two parameters: ; HWND - Button's HWND. ; Options* - variadic array containing up to 6 option arrays (see below). ; --------------------------------------------------------------------------------------------------------------- ; The index of each option object determines the corresponding button state on which the bitmap will be shown. ; MSDN defines 6 states (http://msdn.microsoft.com/en-us/windows/bb775975): ; PBS_NORMAL = 1 ; PBS_HOT = 2 ; PBS_PRESSED = 3 ; PBS_DISABLED = 4 ; PBS_DEFAULTED = 5 ; PBS_STYLUSHOT = 6 <- used only on tablet computers (that's false for Windows Vista and 7, see below) ; If you don't want the button to be 'animated' on themed GUIs, just pass one option object with index 1. ; On Windows Vista and 7 themed bottons are 'animated' using the images of states 5 and 6 after clicked. ; --------------------------------------------------------------------------------------------------------------- ; Each option array may contain the following values: ; Index Value ; 1 Mode mandatory: ; 0 - unicolored or bitmap ; 1 - vertical bicolored ; 2 - horizontal bicolored ; 3 - vertical gradient ; 4 - horizontal gradient ; 5 - vertical gradient using StartColor at both borders and TargetColor at the center ; 6 - horizontal gradient using StartColor at both borders and TargetColor at the center ; 7 - 'raised' style ; 2 StartColor mandatory for Option[1], higher indices will inherit the value of Option[1], if omitted: ; - ARGB integer value (0xAARRGGBB) or HTML color name ("Red"). ; - Path of an image file or HBITMAP handle for mode 0. ; 3 TargetColor mandatory for Option[1] if Mode > 0. Higher indcices will inherit the color of Option[1], ; if omitted: ; - ARGB integer value (0xAARRGGBB) or HTML color name ("Red"). ; - String "HICON" if StartColor contains a HICON handle. ; 4 TextColor optional, if omitted, the default text color will be used for Option[1], higher indices ; will inherit the color of Option[1]: ; - ARGB integer value (0xAARRGGBB) or HTML color name ("Red"). ; Default: 0xFF000000 (black) ; 5 Rounded optional: ; - Radius of the rounded corners in pixel; the letters 'H' and 'W' may be specified ; also to use the half of the button's height or width respectively. ; Default: 0 - not rounded ; 6 GuiColor optional, needed for rounded buttons if you've changed the GUI background color: ; - RGB integer value (0xRRGGBB) or HTML color name ("Red"). ; Default: AHK default GUI background color ; 7 BorderColor optional, ignored for modes 0 (bitmap) and 7, color of the border: ; - RGB integer value (0xRRGGBB) or HTML color name ("Red"). ; 8 BorderWidth optional, ignored for modes 0 (bitmap) and 7, width of the border in pixels: ; - Default: 1 ; --------------------------------------------------------------------------------------------------------------- ; If the the button has a caption it will be drawn above the bitmap. ; Credits: THX tic for GDIP.AHK : http://www.autohotkey.com/forum/post-198949.html ; THX tkoi for ILBUTTON.AHK : http://www.autohotkey.com/forum/topic40468.html ; ====================================================================================================================== ; This software is provided 'as-is', without any express or implied warranty. ; In no event will the authors be held liable for any damages arising from the use of this software. ; ====================================================================================================================== ; ====================================================================================================================== ; CLASS ImageButton() ; ====================================================================================================================== Class ImageButton { ; =================================================================================================================== ; PUBLIC PROPERTIES ================================================================================================= ; =================================================================================================================== Static DefGuiColor := "" ; default GUI color (read/write) Static DefTxtColor := "Black" ; default caption color (read/write) Static LastError := "" ; will contain the last error message, if any (readonly) ; =================================================================================================================== ; PRIVATE PROPERTIES ================================================================================================ ; =================================================================================================================== Static BitMaps := [] Static GDIPDll := 0 Static GDIPToken := 0 Static MaxOptions := 8 ; HTML colors Static HTML := {BLACK: 0x000000, GRAY: 0x808080, SILVER: 0xC0C0C0, WHITE: 0xFFFFFF, MAROON: 0x800000 , PURPLE: 0x800080, FUCHSIA: 0xFF00FF, RED: 0xFF0000, GREEN: 0x008000, OLIVE: 0x808000 , YELLOW: 0xFFFF00, LIME: 0x00FF00, NAVY: 0x000080, TEAL: 0x008080, AQUA: 0x00FFFF, BLUE: 0x0000FF} ; Initialize Static ClassInit := ImageButton.InitClass() ; =================================================================================================================== ; PRIVATE METHODS =================================================================================================== ; =================================================================================================================== __New(P*) { Return False } ; =================================================================================================================== InitClass() { ; ---------------------------------------------------------------------------------------------------------------- ; Get AHK's default GUI background color GuiColor := DllCall("User32.dll\GetSysColor", "Int", 15, "UInt") ; COLOR_3DFACE is used by AHK as default This.DefGuiColor := ((GuiColor >> 16) & 0xFF) | (GuiColor & 0x00FF00) | ((GuiColor & 0xFF) << 16) Return True } ; =================================================================================================================== BitmapOrIcon(O2, O3) { ; OBJ_BITMAP = 7 Return (This.IsInt(O2) && (O3 = "HICON")) || (DllCall("GetObjectType", "Ptr", O2, "UInt") = 7) || FileExist(O2) } ; =================================================================================================================== FreeBitmaps() { For I, HBITMAP In This.BitMaps DllCall("Gdi32.dll\DeleteObject", "Ptr", HBITMAP) This.BitMaps := [] } ; =================================================================================================================== GetARGB(RGB) { ARGB := This.HTML.HasKey(RGB) ? This.HTML[RGB] : RGB Return (ARGB & 0xFF000000) = 0 ? 0xFF000000 | ARGB : ARGB } ; =================================================================================================================== IsInt(Val) { If Val Is Integer Return True Return False } ; =================================================================================================================== PathAddRectangle(Path, X, Y, W, H) { Return DllCall("Gdiplus.dll\GdipAddPathRectangle", "Ptr", Path, "Float", X, "Float", Y, "Float", W, "Float", H) } ; =================================================================================================================== PathAddRoundedRect(Path, X1, Y1, X2, Y2, R) { D := (R * 2), X2 -= D, Y2 -= D DllCall("Gdiplus.dll\GdipAddPathArc" , "Ptr", Path, "Float", X1, "Float", Y1, "Float", D, "Float", D, "Float", 180, "Float", 90) DllCall("Gdiplus.dll\GdipAddPathArc" , "Ptr", Path, "Float", X2, "Float", Y1, "Float", D, "Float", D, "Float", 270, "Float", 90) DllCall("Gdiplus.dll\GdipAddPathArc" , "Ptr", Path, "Float", X2, "Float", Y2, "Float", D, "Float", D, "Float", 0, "Float", 90) DllCall("Gdiplus.dll\GdipAddPathArc" , "Ptr", Path, "Float", X1, "Float", Y2, "Float", D, "Float", D, "Float", 90, "Float", 90) Return DllCall("Gdiplus.dll\GdipClosePathFigure", "Ptr", Path) } ; =================================================================================================================== SetRect(ByRef Rect, X1, Y1, X2, Y2) { VarSetCapacity(Rect, 16, 0) NumPut(X1, Rect, 0, "Int"), NumPut(Y1, Rect, 4, "Int") NumPut(X2, Rect, 8, "Int"), NumPut(Y2, Rect, 12, "Int") Return True } ; =================================================================================================================== SetRectF(ByRef Rect, X, Y, W, H) { VarSetCapacity(Rect, 16, 0) NumPut(X, Rect, 0, "Float"), NumPut(Y, Rect, 4, "Float") NumPut(W, Rect, 8, "Float"), NumPut(H, Rect, 12, "Float") Return True } ; =================================================================================================================== SetError(Msg) { If (This.Bitmap) DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", This.Bitmap) If (This.Graphics) DllCall("Gdiplus.dll\GdipDeleteGraphics", "Ptr", This.Graphics) If (This.Font) DllCall("Gdiplus.dll\GdipDeleteFont", "Ptr", This.Font) This.Delete("Bitmap") This.Delete("Graphics") This.Delete("Font") This.FreeBitmaps() ; This.GdiplusShutdown() This.LastError := Msg Return False } ; =================================================================================================================== ; PUBLIC METHODS ==================================================================================================== ; =================================================================================================================== Create(HWND, Options*) { ; Windows constants Static BCM_GETIMAGELIST := 0x1603, BCM_SETIMAGELIST := 0x1602 , BS_CHECKBOX := 0x02, BS_RADIOBUTTON := 0x04, BS_GROUPBOX := 0x07, BS_AUTORADIOBUTTON := 0x09 , BS_LEFT := 0x0100, BS_RIGHT := 0x0200, BS_CENTER := 0x0300, BS_TOP := 0x0400, BS_BOTTOM := 0x0800 , BS_VCENTER := 0x0C00, BS_BITMAP := 0x0080 , BUTTON_IMAGELIST_ALIGN_LEFT := 0, BUTTON_IMAGELIST_ALIGN_RIGHT := 1, BUTTON_IMAGELIST_ALIGN_CENTER := 4 , ILC_COLOR32 := 0x20 , OBJ_BITMAP := 7 , RCBUTTONS := BS_CHECKBOX | BS_RADIOBUTTON | BS_AUTORADIOBUTTON , SA_LEFT := 0x00, SA_CENTER := 0x01, SA_RIGHT := 0x02 , WM_GETFONT := 0x31 ; ---------------------------------------------------------------------------------------------------------------- This.LastError := "" HBITMAP := HFORMAT := PBITMAP := PBRUSH := PFONT := PPATH := 0 ; ---------------------------------------------------------------------------------------------------------------- ; Check HWND If !DllCall("User32.dll\IsWindow", "Ptr", HWND) Return This.SetError("Invalid parameter HWND!") ; ---------------------------------------------------------------------------------------------------------------- ; Check Options If !(IsObject(Options)) || (Options.MinIndex() <> 1) || (Options.MaxIndex() > This.MaxOptions) Return This.SetError("Invalid parameter Options!") ; ---------------------------------------------------------------------------------------------------------------- ; Get and check control's class and styles WinGetClass, BtnClass, ahk_id %HWND% ControlGet, BtnStyle, Style, , , ahk_id %HWND% If (BtnClass != "Button") || ((BtnStyle & 0xF ^ BS_GROUPBOX) = 0) || ((BtnStyle & RCBUTTONS) > 1) Return This.SetError("The control must be a pushbutton!") ; ---------------------------------------------------------------------------------------------------------------- ; Get the button's font HFONT := DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", WM_GETFONT, "Ptr", 0, "Ptr", 0, "Ptr") DC := DllCall("User32.dll\GetDC", "Ptr", HWND, "Ptr") DllCall("Gdi32.dll\SelectObject", "Ptr", DC, "Ptr", HFONT) DllCall("Gdiplus.dll\GdipCreateFontFromDC", "Ptr", DC, "PtrP", PFONT) DllCall("User32.dll\ReleaseDC", "Ptr", HWND, "Ptr", DC) If !(This.Font := PFONT) Return This.SetError("Couldn't get button's font!") ; ---------------------------------------------------------------------------------------------------------------- ; Get the button's rectangle VarSetCapacity(RECT, 16, 0) If !DllCall("User32.dll\GetWindowRect", "Ptr", HWND, "Ptr", &RECT) Return This.SetError("Couldn't get button's rectangle!") BtnW := NumGet(RECT, 8, "Int") - NumGet(RECT, 0, "Int") BtnH := NumGet(RECT, 12, "Int") - NumGet(RECT, 4, "Int") ; ---------------------------------------------------------------------------------------------------------------- ; Get the button's caption ControlGetText, BtnCaption, , ahk_id %HWND% If (ErrorLevel) Return This.SetError("Couldn't get button's caption!") ; ---------------------------------------------------------------------------------------------------------------- ; Create a GDI+ bitmap DllCall("Gdiplus.dll\GdipCreateBitmapFromScan0", "Int", BtnW, "Int", BtnH, "Int", 0 , "UInt", 0x26200A, "Ptr", 0, "PtrP", PBITMAP) If !(This.Bitmap := PBITMAP) Return This.SetError("Couldn't create the GDI+ bitmap!") ; Get the pointer to its graphics PGRAPHICS := 0 DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "Ptr", PBITMAP, "PtrP", PGRAPHICS) If !(This.Graphics := PGRAPHICS) Return This.SetError("Couldn't get the the GDI+ bitmap's graphics!") ; Quality settings DllCall("Gdiplus.dll\GdipSetSmoothingMode", "Ptr", PGRAPHICS, "UInt", 4) DllCall("Gdiplus.dll\GdipSetInterpolationMode", "Ptr", PGRAPHICS, "Int", 7) DllCall("Gdiplus.dll\GdipSetCompositingQuality", "Ptr", PGRAPHICS, "UInt", 4) DllCall("Gdiplus.dll\GdipSetRenderingOrigin", "Ptr", PGRAPHICS, "Int", 0, "Int", 0) DllCall("Gdiplus.dll\GdipSetPixelOffsetMode", "Ptr", PGRAPHICS, "UInt", 4) ; ---------------------------------------------------------------------------------------------------------------- ; Create the bitmap(s) This.BitMaps := [] For Idx, Opt In Options { If !IsObject(Opt) Continue BkgColor1 := BkgColor2 := TxtColor := Mode := Rounded := GuiColor := Image := "" ; Replace omitted options with the values of Options.1 Loop, % This.MaxOptions { If (Opt[A_Index] = "") Opt[A_Index] := Options[1, A_Index] } ; ------------------------------------------------------------------------------------------------------------- ; Check option values ; Mode Mode := SubStr(Opt[1], 1 ,1) If !InStr("0123456789", Mode) Return This.SetError("Invalid value for Mode in Options[" . Idx . "]!") ; StartColor & TargetColor If (Mode = 0) && This.BitmapOrIcon(Opt[2], Opt[3]) Image := Opt[2] Else { If !This.IsInt(Opt[2]) && !This.HTML.HasKey(Opt[2]) Return This.SetError("Invalid value for StartColor in Options[" . Idx . "]!") BkgColor1 := This.GetARGB(Opt[2]) If (Opt[3] = "") Opt[3] := Opt[2] If !This.IsInt(Opt[3]) && !This.HTML.HasKey(Opt[3]) Return This.SetError("Invalid value for TargetColor in Options[" . Idx . "]!") BkgColor2 := This.GetARGB(Opt[3]) } ; TextColor If (Opt[4] = "") Opt[4] := This.DefTxtColor If !This.IsInt(Opt[4]) && !This.HTML.HasKey(Opt[4]) Return This.SetError("Invalid value for TxtColor in Options[" . Idx . "]!") TxtColor := This.GetARGB(Opt[4]) ; Rounded Rounded := Opt[5] If (Rounded = "H") Rounded := BtnH * 0.5 If (Rounded = "W") Rounded := BtnW * 0.5 If ((Rounded + 0) = "") Rounded := 0 ; GuiColor If (Opt[6] = "") Opt[6] := This.DefGuiColor If !This.IsInt(Opt[6]) && !This.HTML.HasKey(Opt[6]) Return This.SetError("Invalid value for GuiColor in Options[" . Idx . "]!") GuiColor := This.GetARGB(Opt[6]) ; BorderColor BorderColor := "" If (Opt[7] <> "") { If !This.IsInt(Opt[7]) && !This.HTML.HasKey(Opt[7]) Return This.SetError("Invalid value for BorderColor in Options[" . Idx . "]!") BorderColor := 0xFF000000 | This.GetARGB(Opt[7]) ; BorderColor must be always opaque } ; BorderWidth BorderWidth := Opt[8] ? Opt[8] : 1 ; ------------------------------------------------------------------------------------------------------------- ; Clear the background DllCall("Gdiplus.dll\GdipGraphicsClear", "Ptr", PGRAPHICS, "UInt", GuiColor) ; Create the image If (Image = "") { ; Create a BitMap based on the specified colors PathX := PathY := 0, PathW := BtnW, PathH := BtnH ; Create a GraphicsPath DllCall("Gdiplus.dll\GdipCreatePath", "UInt", 0, "PtrP", PPATH) If (Rounded < 1) ; the path is a rectangular rectangle This.PathAddRectangle(PPATH, PathX, PathY, PathW, PathH) Else ; the path is a rounded rectangle This.PathAddRoundedRect(PPATH, PathX, PathY, PathW, PathH, Rounded) ; If BorderColor and BorderWidth are specified, 'draw' the border (not for Mode 7) If (BorderColor <> "") && (BorderWidth > 0) && (Mode <> 7) { ; Create a SolidBrush DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", BorderColor, "PtrP", PBRUSH) ; Fill the path DllCall("Gdiplus.dll\GdipFillPath", "Ptr", PGRAPHICS, "Ptr", PBRUSH, "Ptr", PPATH) ; Free the brush DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr", PBRUSH) ; Reset the path DllCall("Gdiplus.dll\GdipResetPath", "Ptr", PPATH) ; Add a new 'inner' path PathX := PathY := BorderWidth, PathW -= BorderWidth, PathH -= BorderWidth, Rounded -= BorderWidth If (Rounded < 1) ; the path is a rectangular rectangle This.PathAddRectangle(PPATH, PathX, PathY, PathW - PathX, PathH - PathY) Else ; the path is a rounded rectangle This.PathAddRoundedRect(PPATH, PathX, PathY, PathW, PathH, Rounded) ; If a BorderColor has been drawn, BkgColors must be opaque BkgColor1 := 0xFF000000 | BkgColor1 BkgColor2 := 0xFF000000 | BkgColor2 } PathW -= PathX PathH -= PathY PBRUSH := 0 If (Mode = 0) { ; the background is unicolored ; Create a SolidBrush DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", BkgColor1, "PtrP", PBRUSH) ; Fill the path DllCall("Gdiplus.dll\GdipFillPath", "Ptr", PGRAPHICS, "Ptr", PBRUSH, "Ptr", PPATH) } Else If (Mode = 1) || (Mode = 2) { ; the background is bicolored ; Create a LineGradientBrush This.SetRectF(RECTF, PathX, PathY, PathW, PathH) DllCall("Gdiplus.dll\GdipCreateLineBrushFromRect", "Ptr", &RECTF , "UInt", BkgColor1, "UInt", BkgColor2, "Int", Mode & 1, "Int", 3, "PtrP", PBRUSH) DllCall("Gdiplus.dll\GdipSetLineGammaCorrection", "Ptr", PBRUSH, "Int", 1) ; Set up colors and positions This.SetRect(COLORS, BkgColor1, BkgColor1, BkgColor2, BkgColor2) ; sorry for function misuse This.SetRectF(POSITIONS, 0, 0.5, 0.5, 1) ; sorry for function misuse DllCall("Gdiplus.dll\GdipSetLinePresetBlend", "Ptr", PBRUSH , "Ptr", &COLORS, "Ptr", &POSITIONS, "Int", 4) ; Fill the path DllCall("Gdiplus.dll\GdipFillPath", "Ptr", PGRAPHICS, "Ptr", PBRUSH, "Ptr", PPATH) } Else If (Mode >= 3) && (Mode <= 6) { ; the background is a gradient ; Determine the brush's width/height W := Mode = 6 ? PathW / 2 : PathW ; horizontal H := Mode = 5 ? PathH / 2 : PathH ; vertical ; Create a LineGradientBrush This.SetRectF(RECTF, PathX, PathY, W, H) DllCall("Gdiplus.dll\GdipCreateLineBrushFromRect", "Ptr", &RECTF , "UInt", BkgColor1, "UInt", BkgColor2, "Int", Mode & 1, "Int", 3, "PtrP", PBRUSH) DllCall("Gdiplus.dll\GdipSetLineGammaCorrection", "Ptr", PBRUSH, "Int", 1) ; Fill the path DllCall("Gdiplus.dll\GdipFillPath", "Ptr", PGRAPHICS, "Ptr", PBRUSH, "Ptr", PPATH) } Else { ; raised mode DllCall("Gdiplus.dll\GdipCreatePathGradientFromPath", "Ptr", PPATH, "PtrP", PBRUSH) ; Set Gamma Correction DllCall("Gdiplus.dll\GdipSetPathGradientGammaCorrection", "Ptr", PBRUSH, "UInt", 1) ; Set surround and center colors VarSetCapacity(ColorArray, 4, 0) NumPut(BkgColor1, ColorArray, 0, "UInt") DllCall("Gdiplus.dll\GdipSetPathGradientSurroundColorsWithCount", "Ptr", PBRUSH, "Ptr", &ColorArray , "IntP", 1) DllCall("Gdiplus.dll\GdipSetPathGradientCenterColor", "Ptr", PBRUSH, "UInt", BkgColor2) ; Set the FocusScales FS := (BtnH < BtnW ? BtnH : BtnW) / 3 XScale := (BtnW - FS) / BtnW YScale := (BtnH - FS) / BtnH DllCall("Gdiplus.dll\GdipSetPathGradientFocusScales", "Ptr", PBRUSH, "Float", XScale, "Float", YScale) ; Fill the path DllCall("Gdiplus.dll\GdipFillPath", "Ptr", PGRAPHICS, "Ptr", PBRUSH, "Ptr", PPATH) } ; Free resources DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr", PBRUSH) DllCall("Gdiplus.dll\GdipDeletePath", "Ptr", PPATH) } Else { ; Create a bitmap from HBITMAP or file If This.IsInt(Image) If (Opt[3] = "HICON") DllCall("Gdiplus.dll\GdipCreateBitmapFromHICON", "Ptr", Image, "PtrP", PBM) Else DllCall("Gdiplus.dll\GdipCreateBitmapFromHBITMAP", "Ptr", Image, "Ptr", 0, "PtrP", PBM) Else DllCall("Gdiplus.dll\GdipCreateBitmapFromFile", "WStr", Image, "PtrP", PBM) ; Draw the bitmap DllCall("Gdiplus.dll\GdipDrawImageRectI", "Ptr", PGRAPHICS, "Ptr", PBM, "Int", 0, "Int", 0 , "Int", BtnW, "Int", BtnH) ; Free the bitmap DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", PBM) } ; ------------------------------------------------------------------------------------------------------------- ; Draw the caption If (BtnCaption <> "") { ; Create a StringFormat object DllCall("Gdiplus.dll\GdipStringFormatGetGenericTypographic", "PtrP", HFORMAT) ; Text color DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", TxtColor, "PtrP", PBRUSH) ; Horizontal alignment HALIGN := (BtnStyle & BS_CENTER) = BS_CENTER ? SA_CENTER : (BtnStyle & BS_CENTER) = BS_RIGHT ? SA_RIGHT : (BtnStyle & BS_CENTER) = BS_Left ? SA_LEFT : SA_CENTER DllCall("Gdiplus.dll\GdipSetStringFormatAlign", "Ptr", HFORMAT, "Int", HALIGN) ; Vertical alignment VALIGN := (BtnStyle & BS_VCENTER) = BS_TOP ? 0 : (BtnStyle & BS_VCENTER) = BS_BOTTOM ? 2 : 1 DllCall("Gdiplus.dll\GdipSetStringFormatLineAlign", "Ptr", HFORMAT, "Int", VALIGN) ; Set render quality to system default DllCall("Gdiplus.dll\GdipSetTextRenderingHint", "Ptr", PGRAPHICS, "Int", 0) ; Set the text's rectangle VarSetCapacity(RECT, 16, 0) NumPut(BtnW, RECT, 8, "Float") NumPut(BtnH, RECT, 12, "Float") ; Draw the text DllCall("Gdiplus.dll\GdipDrawString", "Ptr", PGRAPHICS, "WStr", BtnCaption, "Int", -1 , "Ptr", PFONT, "Ptr", &RECT, "Ptr", HFORMAT, "Ptr", PBRUSH) } ; ------------------------------------------------------------------------------------------------------------- ; Create a HBITMAP handle from the bitmap and add it to the array DllCall("Gdiplus.dll\GdipCreateHBITMAPFromBitmap", "Ptr", PBITMAP, "PtrP", HBITMAP, "UInt", 0X00FFFFFF) This.BitMaps[Idx] := HBITMAP ; Free resources DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr", PBRUSH) DllCall("Gdiplus.dll\GdipDeleteStringFormat", "Ptr", HFORMAT) } ; Now free remaining the GDI+ objects DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", PBITMAP) DllCall("Gdiplus.dll\GdipDeleteGraphics", "Ptr", PGRAPHICS) DllCall("Gdiplus.dll\GdipDeleteFont", "Ptr", PFONT) This.Delete("Bitmap") This.Delete("Graphics") This.Delete("Font") ; ---------------------------------------------------------------------------------------------------------------- ; Create the ImageList HIL := DllCall("Comctl32.dll\ImageList_Create" , "UInt", BtnW, "UInt", BtnH, "UInt", ILC_COLOR32, "Int", 6, "Int", 0, "Ptr") Loop, % (This.BitMaps.MaxIndex() > 1 ? 6 : 1) { HBITMAP := This.BitMaps.HasKey(A_Index) ? This.BitMaps[A_Index] : This.BitMaps.1 DllCall("Comctl32.dll\ImageList_Add", "Ptr", HIL, "Ptr", HBITMAP, "Ptr", 0) } ; Create a BUTTON_IMAGELIST structure VarSetCapacity(BIL, 20 + A_PtrSize, 0) ; Get the currently assigned image list DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", BCM_GETIMAGELIST, "Ptr", 0, "Ptr", &BIL) IL := NumGet(BIL, "UPtr") ; Create a new BUTTON_IMAGELIST structure VarSetCapacity(BIL, 20 + A_PtrSize, 0) NumPut(HIL, BIL, 0, "Ptr") Numput(BUTTON_IMAGELIST_ALIGN_CENTER, BIL, A_PtrSize + 16, "UInt") ; Hide buttons's caption ControlSetText, , , ahk_id %HWND% Control, Style, +%BS_BITMAP%, , ahk_id %HWND% ; Remove the currently assigned image list, if any If(IL) IL_Destroy(IL) ; Assign the ImageList to the button DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", BCM_SETIMAGELIST, "Ptr", 0, "Ptr", 0) DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", BCM_SETIMAGELIST, "Ptr", 0, "Ptr", &BIL) ; Free the bitmaps This.FreeBitmaps() ; ---------------------------------------------------------------------------------------------------------------- ; All done successfully Return True } ; =================================================================================================================== ; Set the default GUI color SetGuiColor(GuiColor) { ; GuiColor - RGB integer value (0xRRGGBB) or HTML color name ("Red"). If !(GuiColor + 0) && !This.HTML.HasKey(GuiColor) Return False This.DefGuiColor := (This.HTML.HasKey(GuiColor) ? This.HTML[GuiColor] : GuiColor) & 0xFFFFFF Return True } ; =================================================================================================================== ; Set the default text color SetTxtColor(TxtColor) { ; TxtColor - RGB integer value (0xRRGGBB) or HTML color name ("Red"). If !(TxtColor + 0) && !This.HTML.HasKey(TxtColor) Return False This.DefTxtColor := (This.HTML.HasKey(TxtColor) ? This.HTML[TxtColor] : TxtColor) & 0xFFFFFF Return True } } UseGDIP(Params*) { ; Loads and initializes the Gdiplus.dll at load-time ; GET_MODULE_HANDLE_EX_FLAG_PIN = 0x00000001 Static GdipObject := "" , GdipModule := "" , GdipToken := "" Static OnLoad := UseGDIP() If (GdipModule = "") { If !DllCall("LoadLibrary", "Str", "Gdiplus.dll", "UPtr") UseGDIP_Error("The Gdiplus.dll could not be loaded!`n`nThe program will exit!") If !DllCall("GetModuleHandleEx", "UInt", 0x00000001, "Str", "Gdiplus.dll", "PtrP", GdipModule, "UInt") UseGDIP_Error("The Gdiplus.dll could not be loaded!`n`nThe program will exit!") VarSetCapacity(SI, 24, 0), NumPut(1, SI, 0, "UInt") ; size of 64-bit structure If DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", GdipToken, "Ptr", &SI, "Ptr", 0) UseGDIP_Error("GDI+ could not be startet!`n`nThe program will exit!") GdipObject := {Base: {__Delete: Func("UseGDIP").Bind(GdipModule, GdipToken)}} } Else If (Params[1] = GdipModule) && (Params[2] = GdipToken) DllCall("Gdiplus.dll\GdiplusShutdown", "Ptr", GdipToken) } UseGDIP_Error(ErrorMsg) { MsgBox, 262160, UseGDIP, %ErrorMsg% ExitApp } ================================================ FILE: Lib/Classes/Class_RichEdit.ahk ================================================ ; ====================================================================================================================== ; Scriptname: Class_RichEdit.ahk ; Namespace: RichEdit ; Author: just me ; AHK Version: 1.1.21.03 (Unicode) ; OS Version: Win 8.1 (x64) ; Function: The class provides some wrapper functions for rich edit controls (v4.1 Unicode). ; Change History: ; 0.1.05.00 2015-04-14/just me - fixed LoadRTF() not closing the file after reading ; 0.1.04.00 2014-08-27/just me - fixed SetParaIndent() and changed indentation sample ; 0.1.03.00 2014-03-03/just me - added GetTextRange() ; 0.1.02.00 2013-12-01/just me - changed SetText() to handle RTF formatted text properly ; 0.1.01.00 2013-11-29/just me - bug fix -> GetSelText() ; 0.1.00.00 2013-11-17/just me - initial beta release ; Credits: ; corrupt for cRichEdit: ; http://www.autohotkey.com/board/topic/17869-crichedit-standard-richedit-control-for-autohotkey-scripts/ ; jballi for HE_Print: ; http://www.autohotkey.com/board/topic/45513-function-he-print-wysiwyg-print-for-the-hiedit-control/ ; majkinetor for Dlg: ; http://www.autohotkey.com/board/topic/15836-module-dlg-501/ ; ====================================================================================================================== Class RichEdit { ; =================================================================================================================== ; Class variables - do not change !!! ; =================================================================================================================== ; RichEdit v4.1 (Unicode) Static Class := "RICHEDIT50W" ; RichEdit v4.1 (Unicode) Static DLL := "Msftedit.dll" ; DLL handle Static Instance := DllCall("Kernel32.dll\LoadLibrary", "Str", RichEdit.DLL, "UPtr") ; Callback function handling RichEdit messages Static SubclassCB := 0 ; Number of controls/instances Static Controls := 0 ; =================================================================================================================== ; Instance variables - do not change !!! ; =================================================================================================================== GuiName := "" GuiHwnd := "" HWND := "" DefFont := "" ; =================================================================================================================== ; CONSTRUCTOR ; =================================================================================================================== __New(GuiName, Options, MultiLine := True) { Static WS_TABSTOP := 0x10000, WS_HSCROLL := 0x100000, WS_VSCROLL := 0x200000, WS_VISIBLE := 0x10000000 , WS_CHILD := 0x40000000 , WS_EX_CLIENTEDGE := 0x200, WS_EX_STATICEDGE := 0x20000 , ES_MULTILINE := 0x0004, ES_AUTOVSCROLL := 0x40, ES_AUTOHSCROLL := 0x80, ES_NOHIDESEL := 0x0100 , ES_WANTRETURN := 0x1000, ES_DISABLENOSCROLL := 0x2000, ES_SUNKEN := 0x4000, ES_SAVESEL := 0x8000 , ES_SELECTIONBAR := 0x1000000 ; Check for Unicode If !(SubStr(A_AhkVersion, 1, 1) > 1) && !(A_IsUnicode) { MsgBox, 16, % A_ThisFunc, % This.__Class . " requires a unicode version of AHK!" Return False } ; Do not instantiate instances of RichEdit If (This.Base.HWND) Return False ; Determine the HWND of the GUI Gui, %GuiName%:+LastFoundExist GuiHwnd := WinExist() If !(GuiHwnd) { ErrorLevel := "ERROR: Gui " . GuiName . " does not exist!" Return False } ; Load library if necessary If (This.Base.Instance = 0) { This.Base.Instance := DllCall("Kernel32.dll\LoadLibrary", "Str", This.Base.DLL, "UPtr") If (ErrorLevel) { ErrorLevel := "ERROR: Error loading " . This.Base.DLL . " - " . ErrorLevel Return False } } ; Specify default styles & exstyles Styles := WS_TABSTOP | WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL If (MultiLine) Styles |= WS_HSCROLL | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_NOHIDESEL | ES_WANTRETURN | ES_DISABLENOSCROLL | ES_SAVESEL ; | ES_SELECTIONBAR does not work properly ExStyles := WS_EX_STATICEDGE ; Create the control CtrlClass := This.Class Gui, %GuiName%:Add, Custom, Class%CtrlClass% %Options% hwndHWND +%Styles% +E%ExStyles% If (MultiLine) { ; Adjust the formatting rectangle for multiline controls to simulate a selection bar ; EM_GETRECT = 0xB2, EM_SETRECT = 0xB3 VarSetCapacity(RECT, 16, 0) SendMessage, 0xB2, 0, &RECT, , ahk_id %HWND% NumPut(NumGet(RECT, 0, "Int") + 10, RECT, 0, "Int") NumPut(NumGet(RECT, 4, "Int") + 2, RECT, 4, "Int") SendMessage, 0xB3, 0, &RECT, , ahk_id %HWND% ; Set advanced typographic options ; EM_SETTYPOGRAPHYOPTIONS = 0x04CA (WM_USER + 202) ; TO_ADVANCEDTYPOGRAPHY = 1, TO_ADVANCEDLAYOUT = 8 ? not documented SendMessage, 0x04CA, 0x01, 0x01, , ahk_id %HWND% } ; Initialize control ; EM_SETLANGOPTIONS = 0x0478 (WM_USER + 120) ; IMF_AUTOKEYBOARD = 0x01, IMF_AUTOFONT = 0x02 SendMessage, 0x0478, 0, 0x03, , ahk_id %HWND% ; Subclass the control to get Tab key and prevent Esc from sending a WM_CLOSE message to the parent window. ; One of majkinetor's splendid discoveries! ; Initialize SubclassCB If (This.Base.SubclassCB = 0) This.Base.SubclassCB := RegisterCallback("RichEdit.SubclassProc") DllCall("Comctl32.dll\SetWindowSubclass", "Ptr", HWND, "Ptr", This.Base.SubclassCB, "Ptr", HWND, "Ptr", 0) This.GuiName := GuiName This.GuiHwnd := GuiHwnd This.HWND := HWND This.DefFont := This.GetFont(1) This.DefFont.Default := 1 ; Correct AHK font size setting, if necessary If (Round(This.DefFont.Size) <> This.DefFont.Size) { This.DefFont.Size := Round(This.DefFont.Size) This.SetDefaultFont() } This.Base.Controls += 1 ; Initialize the print margins This.GetMargins() ; Initialize the text limit This.LimitText(2147483647) } ; =================================================================================================================== ; DESTRUCTOR ; =================================================================================================================== __Delete() { If (This.HWND) { DllCall("Comctl32.dll\RemoveWindowSubclass", "Ptr", This.HWND, "Ptr", This.Base.SubclassCB, "Ptr", 0) DllCall("User32.dll\DestroyWindow", "Ptr", This.HWND) This.HWND := 0 This.Base.Controls -= 1 If (This.Base.Controls = 0) { DllCall("Kernel32.dll\FreeLibrary", "Ptr", This.Base.Instance) This.Base.Instance := 0 } } } ; =================================================================================================================== ; =================================================================================================================== ; INTERNAL CLASSES ================================================================================================== ; =================================================================================================================== ; =================================================================================================================== Class CF2 { ; CHARFORMAT2 structure -> http://msdn.microsoft.com/en-us/library/bb787883(v=vs.85).aspx __New() { Static CF2_Size := 116 This.Insert(":", {Mask: {O: 4, T: "UInt"}, Effects: {O: 8, T: "UInt"} , Height: {O: 12, T: "Int"}, Offset: {O: 16, T: "Int"} , TextColor: {O: 20, T: "Int"}, CharSet: {O: 24, T: "UChar"} , PitchAndFamily: {O: 25, T: "UChar"}, FaceName: {O: 26, T: "Str32"} , Weight: {O: 90, T: "UShort"}, Spacing: {O: 92, T: "Short"} , BackColor: {O: 96, T: "UInt"}, LCID: {O: 100, T: "UInt"} , Cookie: {O: 104, T: "UInt"}, Style: {O: 108, T: "Short"} , Kerning: {O: 110, T: "UShort"}, UnderlineType: {O: 112, T: "UChar"} , Animation: {O: 113, T: "UChar"}, RevAuthor: {O: 114, T: "UChar"} , UnderlineColor: {O: 115, T: "UChar"}}) This.Insert(".") This.SetCapacity(".", CF2_Size) Addr := This.GetAddress(".") DllCall("Kernel32.dll\RtlZeroMemory", "Ptr", Addr, "Ptr", CF2_Size) NumPut(CF2_Size, Addr + 0, 0, "UInt") } __Get(Name) { Addr := This.GetAddress(".") If (Name = "CF2") Return Addr If !This[":"].HasKey(Name) Return "" Attr := This[":"][Name] If (Name <> "FaceName") Return NumGet(Addr + 0, Attr.O, Attr.T) Return StrGet(Addr + Attr.O, 32) } __Set(Name, Value) { Addr := This.GetAddress(".") If !This[":"].HasKey(Name) Return "" Attr := This[":"][Name] If (Name <> "FaceName") NumPut(Value, Addr + 0, Attr.O, Attr.T) Else StrPut(Value, Addr + Attr.O, 32) Return Value } } ; ------------------------------------------------------------------------------------------------------------------- Class PF2 { ; PARAFORMAT2 structure -> http://msdn.microsoft.com/en-us/library/bb787942(v=vs.85).aspx __New() { Static PF2_Size := 188 This.Insert(":", {Mask: {O: 4, T: "UInt"}, Numbering: {O: 8, T: "UShort"} , StartIndent: {O: 12, T: "Int"}, RightIndent: {O: 16, T: "Int"} , Offset: {O: 20, T: "Int"}, Alignment: {O: 24, T: "UShort"} , TabCount: {O: 26, T: "UShort"}, Tabs: {O: 28, T: "UInt"} , SpaceBefore: {O: 156, T: "Int"}, SpaceAfter: {O: 160, T: "Int"} , LineSpacing: {O: 164, T: "Int"}, Style: {O: 168, T: "Short"} , LineSpacingRule: {O: 170, T: "UChar"}, OutlineLevel: {O: 171, T: "UChar"} , ShadingWeight: {O: 172, T: "UShort"}, ShadingStyle: {O: 174, T: "UShort"} , NumberingStart: {O: 176, T: "UShort"}, NumberingStyle: {O: 178, T: "UShort"} , NumberingTab: {O: 180, T: "UShort"}, BorderSpace: {O: 182, T: "UShort"} , BorderWidth: {O: 184, T: "UShort"}, Borders: {O: 186, T: "UShort"}}) This.Insert(".") This.SetCapacity(".", PF2_Size) Addr := This.GetAddress(".") DllCall("Kernel32.dll\RtlZeroMemory", "Ptr", Addr, "Ptr", PF2_Size) NumPut(PF2_Size, Addr + 0, 0, "UInt") } __Get(Name) { Addr := This.GetAddress(".") If (Name = "PF2") Return Addr If !This[":"].HasKey(Name) Return "" Attr := This[":"][Name] If (Name <> "Tabs") Return NumGet(Addr + 0, Attr.O, Attr.T) Tabs := [] Offset := Attr.O - 4 Loop, 32 Tabs[A_Index] := NumGet(Addr + 0, Offset += 4, "UInt") Return Tabs } __Set(Name, Value) { Addr := This.GetAddress(".") If !This[":"].HasKey(Name) Return "" Attr := This[":"][Name] If (Name <> "Tabs") { NumPut(Value, Addr + 0, Attr.O, Attr.T) Return Value } If !IsObject(Value) Return "" Offset := Attr.O - 4 For Each, Tab In Value NumPut(Tab, Addr + 0, Offset += 4, "UInt") Return Tabs } } ; =================================================================================================================== ; =================================================================================================================== ; PRIVATE METHODS =================================================================================================== ; =================================================================================================================== ; =================================================================================================================== GetBGR(RGB) { ; Get numeric BGR value from numeric RGB value or HTML color name Static HTML := {BLACK: 0x000000, SILVER: 0xC0C0C0, GRAY: 0x808080, WHITE: 0xFFFFFF , MAROON: 0x000080, RED: 0x0000FF, PURPLE: 0x800080, FUCHSIA: 0xFF00FF , GREEN: 0x008000, LIME: 0x00FF00, OLIVE: 0x008080, YELLOW: 0x00FFFF , NAVY: 0x800000, BLUE: 0xFF0000, TEAL: 0x808000, AQUA: 0xFFFF00} If HTML.HasKey(RGB) Return HTML[RGB] Return ((RGB & 0xFF0000) >> 16) + (RGB & 0x00FF00) + ((RGB & 0x0000FF) << 16) } ; ------------------------------------------------------------------------------------------------------------------- GetRGB(BGR) { ; Get numeric RGB value from numeric BGR-Value Return ((BGR & 0xFF0000) >> 16) + (BGR & 0x00FF00) + ((BGR & 0x0000FF) << 16) } ; ------------------------------------------------------------------------------------------------------------------- GetMeasurement() { ; Get locale measurement (metric / inch) ; LOCALE_USER_DEFAULT = 0x0400, LOCALE_IMEASURE = 0x0D, LOCALE_RETURN_NUMBER = 0x20000000 Static Metric := 2.54 ; centimeters , Inches := 1.00 ; inches , Measurement := "" , Len := A_IsUnicode ? 2 : 4 If (Measurement = "") { VarSetCapacity(LCD, 4, 0) DllCall("Kernel32.dll\GetLocaleInfo", "UInt", 0x400, "UInt", 0x2000000D, "Ptr", &LCD, "Int", Len) Measurement := NumGet(LCD, 0, "UInt") ? Inches : Metric } Return Measurement } ; ------------------------------------------------------------------------------------------------------------------- SubclassProc(M, W, L, I, R) { ; RichEdit subclassproc ; Left out first parameter HWND, will be found in "This" when called by system ; See -> http://msdn.microsoft.com/en-us/library/bb776774%28VS.85%29.aspx If (M = 0x87) ; WM_GETDLGCODE Return 4 ; DLGC_WANTALLKEYS Return DllCall("Comctl32.dll\DefSubclassProc", "Ptr", This, "UInt", M, "Ptr", W, "Ptr", L) } ; =================================================================================================================== ; =================================================================================================================== ; PUBLIC METHODS ==================================================================================================== ; =================================================================================================================== ; =================================================================================================================== ; ------------------------------------------------------------------------------------------------------------------- ; Methods to be used by advanced users only ; ------------------------------------------------------------------------------------------------------------------- GetCharFormat() { ; Retrieves the character formatting of the current selection. ; For details see http://msdn.microsoft.com/en-us/library/bb787883(v=vs.85).aspx. ; Returns a 'CF2' object containing the formatting settings. ; EM_GETCHARFORMAT = 0x043A CF2 := New This.CF2 SendMessage, 0x043A, 1, % CF2.CF2, , % "ahk_id " . This.HWND Return (CF2.Mask ? CF2 : False) } ; ------------------------------------------------------------------------------------------------------------------- SetCharFormat(CF2) { ; Sets character formatting of the current selection. ; For details see http://msdn.microsoft.com/en-us/library/bb787883(v=vs.85).aspx. ; CF2 : CF2 object like returned by GetCharFormat(). ; EM_SETCHARFORMAT = 0x0444 SendMessage, 0x0444, 1, % CF2.CF2, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- GetParaFormat() { ; Retrieves the paragraph formatting of the current selection. ; For details see http://msdn.microsoft.com/en-us/library/bb787942(v=vs.85).aspx. ; Returns a 'PF2' object containing the formatting settings. ; EM_GETPARAFORMAT = 0x043D PF2 := New This.PF2 SendMessage, 0x043D, 0, % PF2.PF2, , % "ahk_id " . This.HWND Return (PF2.Mask ? PF2 : False) } ; ------------------------------------------------------------------------------------------------------------------- SetParaFormat(PF2) { ; Sets the paragraph formatting for the current selection. ; For details see http://msdn.microsoft.com/en-us/library/bb787942(v=vs.85).aspx. ; PF2 : PF2 object like returned by GetParaFormat(). ; EM_SETPARAFORMAT = 0x0447 SendMessage, 0x0447, 0, % PF2.PF2, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- ; Control specific ; ------------------------------------------------------------------------------------------------------------------- IsModified() { ; Has the control been modified? ; EM_GETMODIFY = 0xB8 SendMessage, 0xB8, 0, 0, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- SetModified(Modified := False) { ; Sets or clears the modification flag for an edit control. ; EM_SETMODIFY = 0xB9 SendMessage, 0xB9, % !!Modified, 0, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- SetEventMask(Events := "") { ; Set the events which shall send notification codes control's owner ; Events : Array containing one or more of the keys defined in 'ENM'. ; For details see http://msdn.microsoft.com/en-us/library/bb774238(v=vs.85).aspx ; EM_SETEVENTMASK = 0x0445 Static ENM := {NONE: 0x00, CHANGE: 0x01, UPDATE: 0x02, SCROLL: 0x04, SCROLLEVENTS: 0x08, DRAGDROPDONE: 0x10 , PARAGRAPHEXPANDED: 0x20, PAGECHANGE: 0x40, KEYEVENTS: 0x010000, MOUSEEVENTS: 0x020000 , REQUESTRESIZE: 0x040000, SELCHANGE: 0x080000, DROPFILES: 0x100000, PROTECTED: 0x200000 , LINK: 0x04000000} If !IsObject(Events) Events := ["NONE"] Mask := 0 For Each, Event In Events { If ENM.HasKey(Event) Mask |= ENM[Event] Else Return False } SendMessage, 0x0445, 0, %Mask%, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- ; Loading and storing RTF format ; ------------------------------------------------------------------------------------------------------------------- GetRTF(Selection := False) { ; Gets the whole content of the control as rich text. ; Selection = False : whole contents (default) ; Selection = True : current selection ; EM_STREAMOUT = 0x044A ; SF_TEXT = 0x1, SF_RTF = 0x2, SF_RTFNOOBJS = 0x3, SF_UNICODE = 0x10, SF_USECODEPAGE = 0x0020 ; SFF_PLAINRTF = 0x4000, SFF_SELECTION = 0x8000 ; UTF-8 = 65001, UTF-16 = 1200 Static GetRTFCB := 0 Flags := 0x4022 | (1200 << 16) | (Selection ? 0x8000 : 0) GetRTFCB := RegisterCallback("RichEdit.GetRTFProc") VarSetCapacity(ES, (A_PtrSize * 2) + 4, 0) ; EDITSTREAM structure NumPut(This.HWND, ES, 0, "Ptr") ; dwCookie NumPut(GetRTFCB, ES, A_PtrSize + 4, "Ptr") ; pfnCallback SendMessage, 0x044A, %Flags%, &ES, , % "ahk_id " . This.HWND DllCall("Kernel32.dll\GlobalFree", "Ptr", GetRTFCB) Return This.GetRTFProc("Get", 0, 0) } ; ------------------------------------------------------------------------------------------------------------------- GetRTFProc(pbBuff, cb, pcb) { ; Callback procedure for GetRTF ; left out first parameter dwCookie, will be passed in "This" when called by system Static RTF := "" If (cb > 0) { RTF .= StrGet(pbBuff, cb, "CP0") Return 0 } If (pbBuff = "Get") { Out := RTF VarSetCapacity(RTF, 0) Return Out } Return 1 } ; ------------------------------------------------------------------------------------------------------------------- LoadRTF(FilePath, Selection := False) { ; Loads RTF file into the control. ; FilePath = file path ; Selection = False : whole contents (default) ; Selection = True : current selection ; EM_STREAMIN = 0x0449 ; SF_TEXT = 0x1, SF_RTF = 0x2, SF_RTFNOOBJS = 0x3, SF_UNICODE = 0x10, SF_USECODEPAGE = 0x0020 ; SFF_PLAINRTF = 0x4000, SFF_SELECTION = 0x8000 ; UTF-16 = 1200 Static LoadRTFCB := RegisterCallback("RichEdit.LoadRTFProc") Flags := 0x4002 | (Selection ? 0x8000 : 0) ; | (1200 << 16) If !(File := FileOpen(FilePath, "r")) Return False VarSetCapacity(ES, (A_PtrSize * 2) + 4, 0) ; EDITSTREAM structure NumPut(File.__Handle, ES, 0, "Ptr") ; dwCookie NumPut(LoadRTFCB, ES, A_PtrSize + 4, "Ptr") ; pfnCallback SendMessage, 0x0449, %Flags%, &ES, , % "ahk_id " . This.HWND Result := ErrorLevel File.Close() Return Result } ; ------------------------------------------------------------------------------------------------------------------- LoadRTFProc(pbBuff, cb, pcb) { ; Callback procedure for LoadRTF ; Left out first parameter dwCookie, will be passed in "This" when called by system Return !DllCall("ReadFile", "Ptr", This, "Ptr", pbBuff, "UInt", cb, "Ptr", pcb, "Ptr", 0) } ; ------------------------------------------------------------------------------------------------------------------- ; Scrolling ; ------------------------------------------------------------------------------------------------------------------- GetScrollPos() { ; Obtains the current scroll position. ; Returns on object with keys 'X' and 'Y' containing the scroll position. ; EM_GETSCROLLPOS = 0x04DD VarSetCapacity(PT, 8, 0) SendMessage, 0x04DD, 0, &PT, , % "ahk_id " . This.HWND Return {X: NumGet(PT, 0, "Int"), Y: NumGet(PT, 4, "Int")} } ; ------------------------------------------------------------------------------------------------------------------- SetScrollPos(X, Y) { ; Scrolls the contents of a rich edit control to the specified point. ; X : x-position to scroll to. ; Y : y-position to scroll to. ; EM_SETSCROLLPOS = 0x04DE VarSetCapacity(PT, 8, 0) NumPut(X, PT, 0, "Int") NumPut(Y, PT, 4, "Int") SendMessage, 0x04DE, 0, &PT, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- ScrollCaret() { ; Scrolls the caret into view. ; EM_SCROLLCARET = 0x00B7 SendMessage, 0x00B7, 0, 0, , % "ahk_id " . This.HWND Return True } ; ------------------------------------------------------------------------------------------------------------------- ShowScrollBar(SB, Mode := True) { ; Shows or hides one of the scroll bars of a rich edit control. ; SB : Identifies which scroll bar to display: horizontal or vertical. ; This parameter must be 1 (SB_VERT) or 0 (SB_HORZ). ; Mode : Specify TRUE to show the scroll bar and FALSE to hide it. ; EM_SHOWSCROLLBAR = 0x0460 (WM_USER + 96) SendMessage, 0x0460, %SB%, %Mode%, , % "ahk_id " . This.HWND Return True } ; ------------------------------------------------------------------------------------------------------------------- ; Text and selection ; ------------------------------------------------------------------------------------------------------------------- FindText(Find, Mode := "") { ; Finds Unicode text within a rich edit control. ; Find : Text to search for. ; Mode : Optional array containing one or more of the keys specified in 'FR'. ; For details see http://msdn.microsoft.com/en-us/library/bb788013(v=vs.85).aspx. ; Returns True if the text was found; otherwise false. ; EM_FINDTEXTEXW = 0x047C, EM_SCROLLCARET = 0x00B7 Static FR:= {DOWN: 1, WHOLEWORD: 2, MATCHCASE: 4} Flags := 0 For Each, Value In Mode If FR.HasKey(Value) Flags |= FR[Value] Sel := This.GetSel() Min := (Flags & FR.DOWN) ? Sel.E : Sel.S Max := (Flags & FR.DOWN) ? -1 : 0 VarSetCapacity(FTX, 16 + A_PtrSize, 0) NumPut(Min, FTX, 0, "Int") NumPut(Max, FTX, 4, "Int") NumPut(&Find, FTX, 8, "Ptr") SendMessage, 0x047C, %Flags%, &FTX, , % "ahk_id " . This.HWND S := NumGet(FTX, 8 + A_PtrSize, "Int"), E := NumGet(FTX, 12 + A_PtrSize, "Int") If (S = -1) && (E = -1) Return False This.SetSel(S, E) This.ScrollCaret() Return } ; ------------------------------------------------------------------------------------------------------------------- FindWordBreak(CharPos, Mode := "Left") { ; Finds the next word break before or after the specified character position ; or retrieves information about the character at that position. ; CharPos : Character position. ; Mode : Can be one of the keys specified in 'WB'. ; Returns the character index of the word break or other values depending on 'Mode'. ; For details see http://msdn.microsoft.com/en-us/library/bb788018(v=vs.85).aspx. ; EM_FINDWORDBREAK = 0x044C (WM_USER + 76) Static WB := {LEFT: 0, RIGHT: 1, ISDELIMITER: 2, CLASSIFY: 3, MOVEWORDLEFT: 4, MOVEWORDRIGHT: 5, LEFTBREAK: 6 , RIGHTBREAK: 7} Option := WB.HasKey(Mode) ? WB[Mode] : 0 SendMessage, 0x044C, %Option%, %CharPos%, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- GetSelText() { ; Retrieves the currently selected text as plain text. ; Returns selected text. ; EM_GETSELTEXT = 0x043E, EM_EXGETSEL = 0x0434 VarSetCapacity(CR, 8, 0) SendMessage, 0x0434, 0, &CR, , % "ahk_id " . This.HWND L := NumGet(CR, 4, "Int") - NumGet(CR, 0, "Int") + 1 If (L > 1) { VarSetCapacity(Text, L * 2, 0) SendMessage, 0x043E, 0, &Text, , % "ahk_id " . This.HWND VarSetCapacity(Text, -1) } Return Text } ; ------------------------------------------------------------------------------------------------------------------- GetSel() { ; Retrieves the starting and ending character positions of the selection in a rich edit control. ; Returns an object containing the keys S (start of selection) and E (end of selection)). ; EM_EXGETSEL = 0x0434 VarSetCapacity(CR, 8, 0) SendMessage, 0x0434, 0, &CR, , % "ahk_id " . This.HWND Return {S: NumGet(CR, 0, "Int"), E: NumGet(CR, 4, "Int")} } ; ------------------------------------------------------------------------------------------------------------------- GetText() { ; Gets the whole content of the control as plain text. ; EM_GETTEXTEX = 0x045E Text := "" If (Length := This.GetTextLen() * 2) { VarSetCapacity(GTX, (4 * 4) + (A_PtrSize * 2), 0) ; GETTEXTEX structure NumPut(Length + 2, GTX, 0, "UInt") ; cb NumPut(1200, GTX, 8, "UInt") ; codepage = Unicode VarSetCapacity(Text, Length + 2, 0) SendMessage, 0x045E, >X, &Text, , % "ahk_id " . This.HWND VarSetCapacity(Text, -1) } Return Text } ; ------------------------------------------------------------------------------------------------------------------- GetTextLen() { ; Calculates text length in various ways. ; EM_GETTEXTLENGTHEX = 0x045F VarSetCapacity(GTL, 8, 0) ; GETTEXTLENGTHEX structure NumPut(1200, GTL, 4, "UInt") ; codepage = Unicode SendMessage, 0x045F, >L, 0, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- GetTextRange(Min, Max) { ; Retrieves a specified range of characters from a rich edit control. ; Min : Character position index immediately preceding the first character in the range. ; Integer value to store as cpMin in the CHARRANGE structure. ; Max : Character position immediately following the last character in the range. ; Integer value to store as cpMax in the CHARRANGE structure. ; CHARRANGE -> http://msdn.microsoft.com/en-us/library/bb787885(v=vs.85).aspx ; EM_GETTEXTRANGE = 0x044B If (Max <= Min) Return "" VarSetCapacity(Text, (Max - Min) << !!A_IsUnicode, 0) VarSetCapacity(TEXTRANGE, 16, 0) ; TEXTRANGE Struktur NumPut(Min, TEXTRANGE, 0, "UInt") NumPut(Max, TEXTRANGE, 4, "UInt") NumPut(&Text, TEXTRANGE, 8, "UPtr") SendMessage, 0x044B, 0, % &TEXTRANGE, , % "ahk_id " . This.HWND VarSetCapacity(Text, -1) ; Länge des Zeichenspeichers korrigieren Return Text } ; ------------------------------------------------------------------------------------------------------------------- HideSelection(Mode) { ; Hides or shows the selection. ; Mode : True to hide or False to show the selection. ; EM_HIDESELECTION = 0x043F (WM_USER + 63) SendMessage, 0x043F, %Mode%, 0, , % "ahk_id " . This.HWND Return True } ; ------------------------------------------------------------------------------------------------------------------- LimitText(Limit) { ; Sets an upper limit to the amount of text the user can type or paste into a rich edit control. ; Limit : Specifies the maximum amount of text that can be entered. ; If this parameter is zero, the default maximum is used, which is 64K characters. ; EM_EXLIMITTEXT = 0x435 (WM_USER + 53) SendMessage, 0x0435, 0, %Limit%, , % "ahk_id " . This.HWND Return True } ; ------------------------------------------------------------------------------------------------------------------- ReplaceSel(Text := "") { ; Replaces the selected text with the specified text. ; EM_REPLACESEL = 0xC2 SendMessage, 0xC2, 1, &Text, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- SetText(ByRef Text := "", Mode := "") { ; Replaces the selection or the whole content of the control. ; Mode : Option flags. It can be any reasonable combination of the keys defined in 'ST'. ; For details see http://msdn.microsoft.com/en-us/library/bb774284(v=vs.85).aspx. ; EM_SETTEXTEX = 0x0461, CP_UNICODE = 1200 ; ST_DEFAULT = 0, ST_KEEPUNDO = 1, ST_SELECTION = 2, ST_NEWCHARS = 4 ??? Static ST := {DEFAULT: 0, KEEPUNDO: 1, SELECTION: 2} Flags := 0 For Each, Value In Mode If ST.HasKey(Value) Flags |= ST[Value] CP := 1200 BufAddr := &Text ; RTF formatted text has to be passed as ANSI!!! If (SubStr(Text, 1, 5) = "{\rtf") || (SubStr(Text, 1, 5) = "{urtf") { Len := StrPut(Text, "CP0") VarSetCapacity(Buf, Len, 0) StrPut(Text, &Buf, "CP0") BufAddr := &Buf CP := 0 } VarSetCapacity(STX, 8, 0) ; SETTEXTEX structure NumPut(Flags, STX, 0, "UInt") ; flags NumPut(CP , STX, 4, "UInt") ; codepage SendMessage, 0x0461, &STX, BufAddr, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- SetSel(Start, End) { ; Selects a range of characters. ; Start : zero-based start index ; End : zero-beased end index (-1 = end of text)) ; EM_EXSETSEL = 0x0437 VarSetCapacity(CR, 8, 0) NumPut(Start, CR, 0, "Int") NumPut(End, CR, 4, "Int") SendMessage, 0x0437, 0, &CR, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- ; Appearance, styles, and options ; ------------------------------------------------------------------------------------------------------------------- AutoURL(On) { ; Turn AutoURLDetection on/off ; EM_AUTOURLDETECT = 0x45B SendMessage, 0x45B, % !!On, 0, , % "ahk_id " . This.HWND WinSet, Redraw, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- GetOptions() { ; Retrieves rich edit control options. ; Returns an array of currently the set options as the keys defined in 'ECO'. ; For details see http://msdn.microsoft.com/en-us/library/bb774178(v=vs.85).aspx. ; EM_GETOPTIONS = 0x044E Static ECO := {AUTOWORDSELECTION: 0x01, AUTOVSCROLL: 0x40, AUTOHSCROLL: 0x80, NOHIDESEL: 0x100 , READONLY: 0x800, WANTRETURN: 0x1000, SAVESEL: 0x8000, SELECTIONBAR: 0x01000000 , VERTICAL: 0x400000} SendMessage, 0x044E, 0, 0, , % "ahk_id " . This.HWND O := ErrorLevel Options := [] For Key, Value In ECO If (O & Value) Options.Insert(Key) Return Options } ; ------------------------------------------------------------------------------------------------------------------- GetStyles() { ; Retrieves the current edit style flags. ; Returns an object containing keys as defined in 'SES'. ; For details see http://msdn.microsoft.com/en-us/library/bb788031(v=vs.85).aspx. ; EM_GETEDITSTYLE = 0x04CD (WM_USER + 205) Static SES := {1: "EMULATESYSEDIT", 1: "BEEPONMAXTEXT", 4: "EXTENDBACKCOLOR", 32: "NOXLTSYMBOLRANGE", 64: "USEAIMM" , 128: "NOIME", 256: "ALLOWBEEPS", 512: "UPPERCASE", 1024: "LOWERCASE", 2048: "NOINPUTSEQUENCECHK" , 4096: "BIDI", 8192: "SCROLLONKILLFOCUS", 16384: "XLTCRCRLFTOCR", 32768: "DRAFTMODE" , 0x0010000: "USECTF", 0x0020000: "HIDEGRIDLINES", 0x0040000: "USEATFONT", 0x0080000: "CUSTOMLOOK" , 0x0100000: "LBSCROLLNOTIFY", 0x0200000: "CTFALLOWEMBED", 0x0400000: "CTFALLOWSMARTTAG" , 0x0800000: "CTFALLOWPROOFING"} SendMessage, 0x04CD, 0, 0, , % "ahk_id " . This.HWND Result := ErrorLevel Styles := [] For Key, Value In SES If (Result & Key) Styles.Insert(Value) Return Styles } ; ------------------------------------------------------------------------------------------------------------------- GetZoom() { ; Gets the current zoom ratio. ; Returns the zoom ratio in percent. ; EM_GETZOOM = 0x04E0 VarSetCapacity(N, 4, 0), VarSetCapacity(D, 4, 0) SendMessage, 0x04E0, &N, &D, , % "ahk_id " . This.HWND N := NumGet(N, 0, "Int"), D := NumGet(D, 0, "Int") Return (N = 0) && (D = 0) ? 100 : Round(N / D * 100) } ; ------------------------------------------------------------------------------------------------------------------- SetBkgndColor(Color) { ; Sets the background color. ; Color : RGB integer value or HTML color name or ; "Auto" to reset to system default color. ; Returns the prior background color. ; EM_SETBKGNDCOLOR = 0x0443 If (Color = "Auto") System := True, Color := 0 Else System := False, Color := This.GetBGR(Color) SendMessage, 0x0443, %System%, %Color%, , % "ahk_id " . This.HWND Return This.GetRGB(ErrorLevel) } ; ------------------------------------------------------------------------------------------------------------------- SetOptions(Options, Mode := "SET") { ; Sets the options for a rich edit control. ; Options : Array of options as the keys defined in 'ECO'. ; Mode : Settings mode: SET, OR, AND, XOR ; For details see http://msdn.microsoft.com/en-us/library/bb774254(v=vs.85).aspx. ; EM_SETOPTIONS = 0x044D Static ECO := {AUTOWORDSELECTION: 0x01, AUTOVSCROLL: 0x40, AUTOHSCROLL: 0x80, NOHIDESEL: 0x100, READONLY: 0x800 , WANTRETURN: 0x1000, SAVESEL: 0x8000, SELECTIONBAR: 0x01000000, VERTICAL: 0x400000} , ECOOP := {SET: 0x01, OR: 0x02, AND: 0x03, XOR: 0x04} If !ECOOP.HasKey(Mode) Return False O := 0 For Each, Option In Options { If ECO.HasKey(Option) O |= ECO[Option] Else Return False } SendMessage, 0x044D, % ECOOP[Mode], %O%, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- SetStyles(Styles) { ; Sets the current edit style flags for a rich edit control. ; Styles : Object containing on or more of the keys defined in 'SES'. ; If the value is 0 the style will be removed, otherwise it will be added. ; For details see http://msdn.microsoft.com/en-us/library/bb774236(v=vs.85).aspx. ; EM_SETEDITSTYLE = 0x04CC (WM_USER + 204) Static SES = {EMULATESYSEDIT: 1, BEEPONMAXTEXT: 2, EXTENDBACKCOLOR: 4, NOXLTSYMBOLRANGE: 32, USEAIMM: 64 , NOIME: 128, ALLOWBEEPS: 256, UPPERCASE: 512, LOWERCASE: 1024, NOINPUTSEQUENCECHK: 2048 , BIDI: 4096, SCROLLONKILLFOCUS: 8192, XLTCRCRLFTOCR: 16384, DRAFTMODE: 32768 , USECTF: 0x0010000, HIDEGRIDLINES: 0x0020000, USEATFONT: 0x0040000, CUSTOMLOOK: 0x0080000 , LBSCROLLNOTIFY: 0x0100000, CTFALLOWEMBED: 0x0200000, CTFALLOWSMARTTAG: 0x0400000 , CTFALLOWPROOFING: 0x0800000} Flags := Mask := 0 For Style, Value In Styles { If SES.HasKey(Style) { Mask |= SES[Style] If (Value <> 0) Flags |= SES[Style] } } If (Mask) { SendMessage, 0x04CC, %Flags%, %Mask%, ,, % "ahk_id " . This.HWND Return ErrorLevel } Return False } ; ------------------------------------------------------------------------------------------------------------------- SetZoom(Ratio := "") { ; Sets the zoom ratio of a rich edit control. ; Ratio : Float value between 100/64 and 6400; a ratio of 0 turns zooming off. ; EM_SETZOOM = 0x4E1 SendMessage, 0x4E1, % (Ratio > 0 ? Ratio : 100), 100, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- ; Copy, paste, etc. ; ------------------------------------------------------------------------------------------------------------------- CanRedo() { ; Determines whether there are any actions in the control redo queue. ; EM_CANREDO = 0x0455 (WM_USER + 85) SendMessage, 0x0455, 0, 0, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- CanUndo() { ; Determines whether there are any actions in an edit control's undo queue. ; EM_CANUNDO = 0x00C6 SendMessage, 0x00C6, 0, 0, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- Clear() { ; WM_CLEAR = 0x303 SendMessage, 0x303, 0, 0, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- Copy() { ; WM_COPY = 0x301 SendMessage, 0x301, 0, 0, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- Cut() { ; WM_CUT = 0x300 SendMessage, 0x300, 0, 0, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- Paste() { ; WM_PASTE = 0x302 SendMessage, 0x302, 0, 0, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- Redo() { ; EM_REDO := 0x454 SendMessage, 0x454, 0, 0, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- Undo() { ; EM_UNDO = 0xC7 SendMessage, 0xC7, 0, 0, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- SelAll() { ; Select all Return This.SetSel(0, -1) } ; ------------------------------------------------------------------------------------------------------------------- Deselect() { ; Deselect all Sel := This.GetSel() Return This.SetSel(Sel.S, Sel.S) } ; ------------------------------------------------------------------------------------------------------------------- ; Font & colors ; ------------------------------------------------------------------------------------------------------------------- ChangeFontSize(Diff) { ; Change font size ; Diff : any positive or negative integer, positive values are treated as +1, negative as -1. ; Returns new size. ; EM_SETFONTSIZE = 0x04DF ; Font size changes by 1 in the range 4 - 11 pt, by 2 for 12 - 28 pt, afterward to 36 pt, 48 pt, 72 pt, 80 pt, ; and by 10 for > 80 pt. The maximum value is 160 pt, the minimum is 4 pt Font := This.GetFont() If (Diff > 0 && Font.Size < 160) || (Diff < 0 && Font.Size > 4) SendMessage, 0x04DF, % (Diff > 0 ? 1 : -1), 0, , % "ahk_id " . This.HWND Else Return False Font := This.GetFont() Return Font.Size } ; ------------------------------------------------------------------------------------------------------------------- GetFont(Default := False) { ; Get current font ; Set Default to True to get the default font. ; Returns an object containing current options (see SetFont()) ; EM_GETCHARFORMAT = 0x043A ; BOLD_FONTTYPE = 0x0100, ITALIC_FONTTYPE = 0x0200 ; CFM_BOLD = 1, CFM_ITALIC = 2, CFM_UNDERLINE = 4, CFM_STRIKEOUT = 8, CFM_PROTECTED = 16, CFM_SUBSCRIPT = 0x30000 ; CFM_BACKCOLOR = 0x04000000, CFM_CHARSET := 0x08000000, CFM_FACE = 0x20000000, CFM_COLOR = 0x40000000 ; CFM_SIZE = 0x80000000 ; CFE_SUBSCRIPT = 0x10000, CFE_SUPERSCRIPT = 0x20000, CFE_AUTOBACKCOLOR = 0x04000000, CFE_AUTOCOLOR = 0x40000000 ; SCF_SELECTION = 1 Static Mask := 0xEC03001F Static Effects := 0xEC000000 CF2 := New This.CF2 CF2.Mask := Mask CF2.Effects := Effects SendMessage, 0x043A, % (Default ? 0 : 1), % CF2.CF2, , % "ahk_id " . This.HWND Font := {} Font.Name := CF2.FaceName Font.Size := CF2.Height / 20 CFS := CF2.Effects Style := (CFS & 1 ? "B" : "") . (CFS & 2 ? "I" : "") . (CFS & 4 ? "U" : "") . (CFS & 8 ? "S" : "") . (CFS & 0x10000 ? "L" : "") . (CFS & 0x20000 ? "H" : "") . (CFS & 16 ? "P" : "") Font.Style := Style = "" ? "N" : Style Font.Color := This.GetRGB(CF2.TextColor) If (CF2.Effects & 0x04000000) Font.BkColor := "Auto" Else Font.BkColor := This.GetRGB(CF2.BackColor) Font.CharSet := CF2.CharSet Return Font } ; ------------------------------------------------------------------------------------------------------------------- SetDefaultFont(Font := "") { ; Set default font ; Font : Optional object - see SetFont(). If IsObject(Font) { For Key, Value In Font If This.DefFont.HasKey(Key) This.DefFont[Key] := Value } Return This.SetFont(This.DefFont) } ; ------------------------------------------------------------------------------------------------------------------- SetFont(Font) { ; Set current/default font ; Font : Object containing the following keys ; Name : optional font name ; Size : optional font size in points ; Style : optional string of one or more of the following styles ; B = bold, I = italic, U = underline, S = strikeout, L = subscript ; H = superschript, P = protected, N = normal ; Color : optional text color as RGB integer value or HTML color name ; "Auto" for "automatic" (system's default) color ; BkColor : optional text background color (see Color) ; "Auto" for "automatic" (system's default) background color ; CharSet : optional font character set ; 1 = DEFAULT_CHARSET, 2 = SYMBOL_CHARSET ; Empty parameters preserve the corresponding properties ; EM_SETCHARFORMAT = 0x0444 ; SCF_DEFAULT = 0, SCF_SELECTION = 1 CF2 := New This.CF2 Mask := Effects := 0 If (Font.Name != "") { Mask |= 0x20000000, Effects |= 0x20000000 ; CFM_FACE, CFE_FACE CF2.FaceName := Font.Name } Size := Font.Size If (Size != "") { If (Size < 161) Size *= 20 Mask |= 0x80000000, Effects |= 0x80000000 ; CFM_SIZE, CFE_SIZE CF2.Height := Size } If (Font.Style != "") { Mask |= 0x3001F ; all font styles If InStr(Font.Style, "B") Effects |= 1 ; CFE_BOLD If InStr(Font.Style, "I") Effects |= 2 ; CFE_ITALIC If InStr(Font.Style, "U") Effects |= 4 ; CFE_UNDERLINE If InStr(Font.Style, "S") Effects |= 8 ; CFE_STRIKEOUT If InStr(Font.Style, "P") Effects |= 16 ; CFE_PROTECTED If InStr(Font.Style, "L") Effects |= 0x10000 ; CFE_SUBSCRIPT If InStr(Font.Style, "H") Effects |= 0x20000 ; CFE_SUPERSCRIPT } If (Font.Color != "") { Mask |= 0x40000000 ; CFM_COLOR If (Font.Color = "Auto") Effects |= 0x40000000 ; CFE_AUTOCOLOR Else CF2.TextColor := This.GetBGR(Font.Color) } If (Font.BkColor != "") { Mask |= 0x04000000 ; CFM_BACKCOLOR If (Font.BkColor = "Auto") Effects |= 0x04000000 ; CFE_AUTOBACKCOLOR Else CF2.BackColor := This.GetBGR(Font.BkColor) } If (Font.CharSet != "") { Mask |= 0x08000000, Effects |= 0x08000000 ; CFM_CHARSET, CFE_CHARSET CF2.CharSet := Font.CharSet = 2 ? 2 : 1 ; SYMBOL|DEFAULT } If (Mask != 0) { Mode := Font.Default ? 0 : 1 CF2.Mask := Mask CF2.Effects := Effects SendMessage, 0x0444, %Mode%, % CF2.CF2, , % "ahk_id " . This.HWND Return ErrorLevel } Return False } ; ------------------------------------------------------------------------------------------------------------------- ToggleFontStyle(Style) { ; Toggle single font style ; Style : one of the following styles ; B = bold, I = italic, U = underline, S = strikeout, L = subscript, H = superschript, P = protected, ; N = normal (reset all other styles) ; EM_GETCHARFORMAT = 0x043A, EM_SETCHARFORMAT = 0x0444 ; CFM_BOLD = 1, CFM_ITALIC = 2, CFM_UNDERLINE = 4, CFM_STRIKEOUT = 8, CFM_PROTECTED = 16, CFM_SUBSCRIPT = 0x30000 ; CFE_SUBSCRIPT = 0x10000, CFE_SUPERSCRIPT = 0x20000, SCF_SELECTION = 1 CF2 :=This.GetCharFormat() CF2.Mask := 0x3001F ; FontStyles If (Style = "N") CF2.Effects := 0 Else CF2.Effects ^= Style = "B" ? 1 : Style = "I" ? 2 : Style = "U" ? 4 : Style = "S" ? 8 : Style = "H" ? 0x20000 : Style = "L" ? 0x10000 : 0 SendMessage, 0x0444, 1, % CF2.CF2, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- ; Paragraph formatting ; ------------------------------------------------------------------------------------------------------------------- AlignText(Align := 1) { ; Set paragraph's alignment ; Note: Values greater 3 doesn't seem to work though they should as documented ; Align: may contain one of the following numbers: ; PFA_LEFT 1 ; PFA_RIGHT 2 ; PFA_CENTER 3 ; PFA_JUSTIFY 4 // New paragraph-alignment option 2.0 (*) ; PFA_FULL_INTERWORD 4 // These are supported in 3.0 with advanced ; PFA_FULL_INTERLETTER 5 // typography enabled ; PFA_FULL_SCALED 6 ; PFA_FULL_GLYPHS 7 ; PFA_SNAP_GRID 8 ; EM_SETPARAFORMAT = 0x0447, PFM_ALIGNMENT = 0x08 If (Align >= 1) && (ALign <= 8) { PF2 := New This.PF2 ; PARAFORMAT2 struct PF2.Mask := 0x08 ; dwMask PF2.Alignment := Align ; wAlignment SendMessage, 0x0447, 0, % PF2.PF2, , % "ahk_id " . This.HWND Return True } Return False } ; ------------------------------------------------------------------------------------------------------------------- SetBorder(Widths, Styles) { ; Set paragraph's borders ; Borders are not displayed in RichEdit, so the call of this function has no visible result. ; Even WordPad distributed with Win7 does not show them, but e.g. Word 2007 does. ; Widths : Array of the 4 border widths in the range of 1 - 15 in order left, top, right, bottom; zero = no border ; Styles : Array of the 4 border styles in the range of 0 - 7 in order left, top, right, bottom (see remarks) ; Note: ; The description on MSDN at http://msdn.microsoft.com/en-us/library/bb787942(v=vs.85).aspx is wrong! ; To set borders you have to put the border width into the related nibble (4 Bits) of wBorderWidth ; (in order: left (0 - 3), top (4 - 7), right (8 - 11), and bottom (12 - 15). The values are interpreted as ; half points (i.e. 10 twips). Border styles are set in the related nibbles of wBorders. ; Valid styles seem to be: ; 0 : \brdrdash (dashes) ; 1 : \brdrdashsm (small dashes) ; 2 : \brdrdb (double line) ; 3 : \brdrdot (dotted line) ; 4 : \brdrhair (single/hair line) ; 5 : \brdrs ? looks like 3 ; 6 : \brdrth ? looks like 3 ; 7 : \brdrtriple (triple line) ; EM_SETPARAFORMAT = 0x0447, PFM_BORDER = 0x800 If !IsObject(Widths) Return False W := S := 0 For I, V In Widths { If (V) W |= V << ((A_Index - 1) * 4) If Styles[I] S |= Styles[I] << ((A_Index - 1) * 4) } PF2 := New This.PF2 PF2.Mask := 0x800 PF2.BorderWidth := W PF2.Borders := S SendMessage, 0x0447, 0, % PF2.PF2, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- SetLineSpacing(Lines) { ; Sets paragraph's line spacing. ; Lines : number of lines as integer or float. ; SpacingRule = 5: ; The value of dyLineSpacing / 20 is the spacing, in lines, from one line to the next. Thus, setting ; dyLineSpacing to 20 produces single-spaced text, 40 is double spaced, 60 is triple spaced, and so on. ; EM_SETPARAFORMAT = 0x0447, PFM_LINESPACING = 0x100 PF2 := New This.PF2 PF2.Mask := 0x100 PF2.LineSpacing := Abs(Lines) * 20 PF2.LineSpacingRule := 5 SendMessage, 0x0447, 0, % PF2.PF2, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- SetParaIndent(Indent := "Reset") { ; Sets space left/right of the paragraph. ; Indent : Object containing up to three keys: ; - Start : Optional - Absolute indentation of the paragraph's first line. ; - Right : Optional - Indentation of the right side of the paragraph, relative to the right margin. ; - Offset : Optional - Indentation of the second and subsequent lines, relative to the indentation ; of the first line. ; Values are interpreted as centimeters/inches depending on the user's locale measurement settings. ; Call without passing a parameter to reset indentation. ; EM_SETPARAFORMAT = 0x0447 ; PFM_STARTINDENT = 0x0001 ; PFM_RIGHTINDENT = 0x0002 ; PFM_OFFSET = 0x0004 Static PFM := {STARTINDENT: 0x01, RIGHTINDENT: 0x02, OFFSET: 0x04} Measurement := This.GetMeasurement() PF2 := New This.PF2 If (Indent = "Reset") PF2.Mask := 0x07 ; reset indentation Else If !IsObject(Indent) Return False Else { PF2.Mask := 0 If (Indent.HasKey("Start")) { PF2.Mask |= PFM.STARTINDENT PF2.StartIndent := Round((Indent.Start / Measurement) * 1440) } If (Indent.HasKey("Offset")) { PF2.Mask |= PFM.OFFSET PF2.Offset := Round((Indent.Offset / Measurement) * 1440) } If (Indent.HasKey("Right")) { PF2.Mask |= PFM.RIGHTINDENT PF2.RightIndent := Round((Indent.Right / Measurement) * 1440) } } If (PF2.Mask) { SendMessage, 0x0447, 0, % PF2.PF2, , % "ahk_id " . This.HWND Return ErrorLevel } Return False } ; ------------------------------------------------------------------------------------------------------------------- SetParaNumbering(Numbering := "Reset") { ; Numbering : Object containing up to four keys: ; - Type : Options used for bulleted or numbered paragraphs. ; - Style : Optional - Numbering style used with numbered paragraphs. ; - Tab : Optional - Minimum space between a paragraph number and the paragraph text. ; - Start : Optional - Sequence number used for numbered paragraphs (e.g. 3 for C or III) ; Tab is interpreted as centimeters/inches depending on the user's locale measurement settings. ; Call without passing a parameter to reset numbering. ; EM_SETPARAFORMAT = 0x0447 ; PARAFORMAT numbering options ; PFN_BULLET 1 ; tomListBullet ; PFN_ARABIC 2 ; tomListNumberAsArabic: 0, 1, 2, ... ; PFN_LCLETTER 3 ; tomListNumberAsLCLetter: a, b, c, ... ; PFN_UCLETTER 4 ; tomListNumberAsUCLetter: A, B, C, ... ; PFN_LCROMAN 5 ; tomListNumberAsLCRoman: i, ii, iii, ... ; PFN_UCROMAN 6 ; tomListNumberAsUCRoman: I, II, III, ... ; PARAFORMAT2 wNumberingStyle options ; PFNS_PAREN 0x0000 ; default, e.g., 1) ; PFNS_PARENS 0x0100 ; tomListParentheses/256, e.g., (1) ; PFNS_PERIOD 0x0200 ; tomListPeriod/256, e.g., 1. ; PFNS_PLAIN 0x0300 ; tomListPlain/256, e.g., 1 ; PFNS_NONUMBER 0x0400 ; used for continuation w/o number ; PFNS_NEWNUMBER 0x8000 ; start new number with wNumberingStart ; PFM_NUMBERING 0x0020 ; PFM_NUMBERINGSTYLE 0x2000 ; PFM_NUMBERINGTAB 0x4000 ; PFM_NUMBERINGSTART 0x8000 Static PFM := {Type: 0x0020, Style: 0x2000, Tab: 0x4000, Start: 0x8000} Static PFN := {Bullet: 1, Arabic: 2, LCLetter: 3, UCLetter: 4, LCRoman: 5, UCRoman: 6} Static PFNS := {Paren: 0x0000, Parens: 0x0100, Period: 0x0200, Plain: 0x0300, None: 0x0400, New: 0x8000} PF2 := New This.PF2 If (Numbering = "Reset") PF2.Mask := 0xE020 Else If !IsObject(Numbering) Return False Else { If (Numbering.HasKey("Type")) { PF2.Mask |= PFM.Type PF2.Numbering := PFN[Numbering.Type] } If (Numbering.HasKey("Style")) { PF2.Mask |= PFM.Style PF2.NumberingStyle := PFNS[Numbering.Style] } If (Numbering.HasKey("Tab")) { PF2.Mask |= PFM.Tab PF2.NumberingTab := Round((Numbering.Tab / This.GetMeasurement()) * 1440) } If (Numbering.HasKey("Start")) { PF2.Mask |= PFM.Start PF2.NumberingStart := Numbering.Start } } If (PF2.Mask) { SendMessage, 0x0447, 0, % PF2.PF2, , % "ahk_id " . This.HWND Return ErrorLevel } Return False } ; ------------------------------------------------------------------------------------------------------------------- SetParaSpacing(Spacing := "Reset") { ; Set space before / after the paragraph ; Spacing : Object containing one or two keys: ; - Before : additional space before the paragraph in points ; - After : additional space after the paragraph in points ; Call without passing a parameter to reset spacing to zero. ; EM_SETPARAFORMAT = 0x0447 ; PFM_SPACEBEFORE = 0x0040 ; PFM_SPACEAFTER = 0x0080 Static PFM := {Before: 0x40, After: 0x80} PF2 := New This.PF2 If (Spacing = "Reset") PF2.Mask := 0xC0 ; reset spacing Else If !IsObject(Spacing) Return False Else { If (Spacing.Before >= 0) { PF2.Mask |= PFM.Before PF2.SpaceBefore := Round(Spacing.Before * 20) } If (Spacing.After >= 0) { PF2.Mask |= PFM.After PF2.SpaceAfter := Round(Spacing.After * 20) } } If (PF2.Mask) { SendMessage, 0x0447, 0, % PF2.PF2, , % "ahk_id " . This.HWND Return ErrorLevel } Return False } ; ------------------------------------------------------------------------------------------------------------------- SetDefaultTabs(Distance) { ; Set default tabstops ; Distance will be interpreted as inches or centimeters depending on the current user's locale. ; EM_SETTABSTOPS = 0xCB Static DUI := 64 ; dialog units per inch , MinTab := 0.20 ; minimal tab distance , MaxTab := 3.00 ; maximal tab distance IM := This.GetMeasurement() StringReplace, Distance, Distance, `,, . Distance := Round(Distance / IM, 2) If (Distance < MinTab) Distance := MinTab If (Distance > MaxTab) Distance := MaxTab VarSetCapacity(TabStops, 4, 0) NumPut(Round(DUI * Distance), TabStops, "Int") SendMessage, 0xCB, 1, &TabStops, , % "ahk_id " . This.HWND Result := ErrorLevel DllCall("User32.dll\UpdateWindow", "Ptr", This.HWND) Return Result } ; ------------------------------------------------------------------------------------------------------------------- SetTabStops(TabStops := "Reset") { ; Set paragraph's tabstobs ; TabStops is an object containing the integer position as hundredth of inches/centimeters as keys ; and the alignment ("L", "C", "R", or "D") as values. ; The position will be interpreted as hundredth of inches or centimeters depending on the current user's locale. ; Call without passing a parameter to reset to default tabs. ; EM_SETPARAFORMAT = 0x0447, PFM_TABSTOPS = 0x10 Static MinT := 30 ; minimal tabstop in hundredth of inches Static MaxT := 830 ; maximal tabstop in hundredth of inches Static Align := {L: 0x00000000 ; left aligned (default) , C: 0x01000000 ; centered , R: 0x02000000 ; right aligned , D: 0x03000000} ; decimal tabstop Static MAX_TAB_STOPS := 32 IC := This.GetMeasurement() PF2 := New This.PF2 PF2.Mask := 0x10 If (TabStops = "Reset") { SendMessage, 0x0447, 0, % PF2.PF2, , % "ahk_id " . This.HWND Return !!(ErrorLevel) } If !IsObject(TabStops) Return False TabCount := 0 Tabs := [] For Position, Alignment In TabStops { Position /= IC If (Position < MinT) Or (Position > MaxT) Or !Align.HasKey(Alignment) Or (A_Index > MAX_TAB_STOPS) Return False Tabs[A_Index] := (Align[Alignment] | Round((Position / 100) * 1440)) TabCount := A_Index } If (TabCount) { PF2.TabCount := TabCount PF2.Tabs := Tabs SendMessage, 0x0447, 0, % PF2.PF2, , % "ahk_id " . This.HWND Return ErrorLevel } Return False } ; ------------------------------------------------------------------------------------------------------------------- ; Line handling ; ------------------------------------------------------------------------------------------------------------------- GetLineCount() { ; Get the total number of lines ; EM_GETLINECOUNT = 0xBA SendMessage, 0xBA, 0, 0, , % "ahk_id " . This.HWND Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- GetCaretLine() { ; Get the line containing the caret ; EM_LINEINDEX = 0xBB, EM_EXLINEFROMCHAR = 0x0436 SendMessage, 0xBB, -1, 0, , % "ahk_id " . This.HWND SendMessage, 0x0436, 0, %ErrorLevel%, , % "ahk_id " . This.HWND Return ErrorLevel + 1 } ; ------------------------------------------------------------------------------------------------------------------- ; Statistics ; ------------------------------------------------------------------------------------------------------------------- GetStatistics() { ; Get some statistic values ; Get the line containing the caret, it's position in this line, the total amount of lines, the absulute caret ; position and the total amount of characters. ; EM_GETSEL = 0xB0, EM_LINEFROMCHAR = 0xC9, EM_LINEINDEX = 0xBB, EM_GETLINECOUNT = 0xBA Stats := {} VarSetCapacity(GTL, 8, 0) ; GETTEXTLENGTHEX structure SB := 0 SendMessage, 0xB0, &SB, 0, , % "ahk_id " . This.HWND SB := NumGet(SB, 0, "UInt") + 1 SendMessage, 0xBB, -1, 0, , % "ahk_id " . This.HWND Stats.LinePos := SB - ErrorLevel SendMessage, 0xC9, -1, 0, , % "ahk_id " . This.HWND Stats.Line := ErrorLevel + 1 SendMessage, 0xBA, 0, 0, , % "ahk_id " . This.HWND Stats.LineCount := ErrorLevel Stats.CharCount := This.GetTextLen() Return Stats } ; ------------------------------------------------------------------------------------------------------------------- ; Layout ; ------------------------------------------------------------------------------------------------------------------- WordWrap(On) { ; Turn wordwrapping on/off ; EM_SCROLLCARET = 0xB7, EM_SETTARGETDEVICE = 0x0448 Sel := This.GetSel() SendMessage, 0x0448, 0, % (On ? 0 : -1), , % "ahk_id " . This.HWND This.SetSel(Sel.S, Sel.E) SendMessage, 0xB7, 0, 0, % "ahk_id " . This.HWND Return On } ; ------------------------------------------------------------------------------------------------------------------- WYSIWYG(On) { ; Show control as printed (WYSIWYG) ; Text measuring is based on the default printer's capacities, thus changing the printer may produce different ; results. See remarks/comments in Print() also. ; EM_SCROLLCARET = 0xB7, EM_SETTARGETDEVICE = 0x0448 ; PD_RETURNDC = 0x0100, PD_RETURNDEFAULT = 0x0400 Static PDC := 0 Static PD_Size := (A_PtrSize = 4 ? 66 : 120) Static OffFlags := A_PtrSize * 5 Sel := This.GetSel() If !(On) { DllCall("User32.dll\LockWindowUpdate", "Ptr", This.HWND) DllCall("Gdi32.dll\DeleteDC", "Ptr", PDC) SendMessage, 0x0448, 0, -1, , % "ahk_id " . This.HWND This.SetSel(Sel.S, Sel.E) SendMessage, 0xB7, 0, 0, % "ahk_id " . This.HWND DllCall("User32.dll\LockWindowUpdate", "Ptr", 0) Return ErrorLevel } Numput(VarSetCapacity(PD, PD_Size, 0), PD) NumPut(0x0100 | 0x0400, PD, A_PtrSize * 5, "UInt") ; PD_RETURNDC | PD_RETURNDEFAULT If !DllCall("Comdlg32.dll\PrintDlg", "Ptr", &PD, "Int") Return DllCall("Kernel32.dll\GlobalFree", "Ptr", NumGet(PD, A_PtrSize * 2, "UPtr")) DllCall("Kernel32.dll\GlobalFree", "Ptr", NumGet(PD, A_PtrSize * 3, "UPtr")) PDC := NumGet(PD, A_PtrSize * 4, "UPtr") DllCall("User32.dll\LockWindowUpdate", "Ptr", This.HWND) Caps := This.GetPrinterCaps(PDC) ; Set up page size and margins in pixel UML := This.Margins.LT ; user margin left UMR := This.Margins.RT ; user margin right PML := Caps.POFX ; physical margin left PMR := Caps.PHYW - Caps.HRES - Caps.POFX ; physical margin right LPW := Caps.HRES ; logical page width ; Adjust margins UML := UML > PML ? (UML - PML) : 0 UMR := UMR > PMR ? (UMR - PMR) : 0 LineLen := LPW - UML - UMR SendMessage, 0x0448, %PDC%, %LineLen%, , % "ahk_id " . This.HWND This.SetSel(Sel.S, Sel.E) SendMessage, 0xB7, 0, 0, % "ahk_id " . This.HWND DllCall("User32.dll\LockWindowUpdate", "Ptr", 0) Return ErrorLevel } ; ------------------------------------------------------------------------------------------------------------------- ; File handling ; ------------------------------------------------------------------------------------------------------------------- LoadFile(File, Mode = "Open") { ; Load file ; File : file name ; Mode : Open / Add / Insert ; Open : Replace control's content ; Append : Append to conrol's content ; Insert : Insert at / replace current selection If !FileExist(File) Return False SplitPath, File, , , Ext If (Ext = "rtf") { If (Mode = "Open") { Selection := False } Else If (Mode = "Insert") { Selection := True } Else If (Mode = "Append") { This.SetSel(-1, -2) Selection := True } This.LoadRTF(File, Selection) } Else { FileRead, Text, %File% If (Mode = "Open") { This.SetText(Text) } Else If (Mode = "Insert") { This.ReplaceSel(Text) } Else If (Mode = "Append") { This.SetSel(-1, -2) This.ReplaceSel(Text) } } Return True } ; ------------------------------------------------------------------------------------------------------------------- SaveFile(File) { ; Save file ; File : file name ; Returns True on success, otherwise False. GuiName := This.GuiName Gui, %GuiName%:+OwnDialogs SplitPath, File, , , Ext Text := Ext = "rtf" ? This.GetRTF() : This.GetText() If IsObject(FileObj := FileOpen(File, "w")) { FileObj.Write(Text) FileObj.Close() Return True } Return False } ; ------------------------------------------------------------------------------------------------------------------- ; Printing ; THX jballi -> http://www.autohotkey.com/board/topic/45513-function-he-print-wysiwyg-print-for-the-hiedit-control/ ; ------------------------------------------------------------------------------------------------------------------- Print() { ; ---------------------------------------------------------------------------------------------------------------- ; Static variables Static PD_ALLPAGES := 0x00, PD_SELECTION := 0x01, PD_PAGENUMS := 0x02, PD_NOSELECTION := 0x04 , PD_RETURNDC := 0x0100, PD_USEDEVMODECOPIES := 0x040000, PD_HIDEPRINTTOFILE := 0x100000 , PD_NONETWORKBUTTON := 0x200000, PD_NOCURRENTPAGE := 0x800000 , MM_TEXT := 0x1 , EM_FORMATRANGE := 0x0439, EM_SETTARGETDEVICE := 0x0448 , DocName := "AHKRichEdit" , PD_Size := (A_PtrSize = 8 ? (13 * A_PtrSize) + 16 : 66) ErrorMsg := "" ; ---------------------------------------------------------------------------------------------------------------- ; Prepare to call PrintDlg ; Define/Populate the PRINTDLG structure VarSetCapacity(PD, PD_Size, 0) Numput(PD_Size, PD, 0, "UInt") ; lStructSize Numput(This.GuiHwnd, PD, A_PtrSize, "UPtr") ; hwndOwner ; Collect Start/End select positions Sel := This.GetSel() ; Determine/Set Flags Flags := PD_ALLPAGES | PD_RETURNDC | PD_USEDEVMODECOPIES | PD_HIDEPRINTTOFILE | PD_NONETWORKBUTTON | PD_NOCURRENTPAGE If (Sel.S = Sel.E) Flags |= PD_NOSELECTION Else Flags |= PD_SELECTION Offset := A_PtrSize * 5 NumPut(Flags, PD, Offset, "UInt") ; Flags ; Page and copies NumPut( 1, PD, Offset += 4, "UShort") ; nFromPage NumPut( 1, PD, Offset += 2, "UShort") ; nToPage NumPut( 1, PD, Offset += 2, "UShort") ; nMinPage NumPut(-1, PD, Offset += 2, "UShort") ; nMaxPage NumPut( 1, PD, Offset += 2, "UShort") ; nCopies ; Note: Use -1 to specify the maximum page number (65535). ; Programming note: The values that are loaded to these fields are critical. The Print dialog will not ; display (returns an error) if unexpected values are loaded to one or more of these fields. ; ---------------------------------------------------------------------------------------------------------------- ; Print dialog box ; Open the Print dialog. Bounce If the user cancels. If !DllCall("Comdlg32.dll\PrintDlg", "Ptr", &PD, "UInt") { ErrorLevel := "Function: " . A_ThisFunc . " - DLLCall of 'PrintDlg' failed." Return False } ; Get the printer device context. Bounce If not defined. If !(PDC := NumGet(PD, A_PtrSize * 4, "UPtr")) { ; hDC ErrorLevel := "Function: " . A_ThisFunc . " - Couldn't get a printer's device context." Return False } ; Free global structures created by PrintDlg DllCall("Kernel32.dll\GlobalFree", "Ptr", NumGet(PD, A_PtrSize * 2, "UPtr")) DllCall("Kernel32.dll\GlobalFree", "Ptr", NumGet(PD, A_PtrSize * 3, "UPtr")) ; ---------------------------------------------------------------------------------------------------------------- ; Prepare to print ; Collect Flags Offset := A_PtrSize * 5 Flags := NumGet(PD, OffSet, "UInt") ; Flags ; Determine From/To Page If (Flags & PD_PAGENUMS) { PageF := NumGet(PD, Offset += 4, "UShort") ; nFromPage (first page) PageL := NumGet(PD, Offset += 2, "UShort") ; nToPage (last page) } Else { PageF := 1 PageL := 65535 } ; Collect printer capacities Caps := This.GetPrinterCaps(PDC) ; Set up page size and margins in Twips (1/20 point or 1/1440 of an inch) UML := This.Margins.LT ; user margin left UMT := This.Margins.TT ; user margin top UMR := This.Margins.RT ; user margin right UMB := This.Margins.BT ; user margin bottom PML := Caps.POFX ; physical margin left PMT := Caps.POFY ; physical margin top PMR := Caps.PHYW - Caps.HRES - Caps.POFX ; physical margin right PMB := Caps.PHYH - Caps.VRES - Caps.POFY ; physical margin bottom LPW := Caps.HRES ; logical page width LPH := Caps.VRES ; logical page height ; Adjust margins UML := UML > PML ? (UML - PML) : 0 UMT := UMT > PMT ? (UMT - PMT) : 0 UMR := UMR > PMR ? (UMR - PMR) : 0 UMB := UMB > PMB ? (UMB - PMB) : 0 ; Define/Populate the FORMATRANGE structure VarSetCapacity(FR, (A_PtrSize * 2) + (4 * 10), 0) NumPut(PDC, FR, 0, "UPtr") ; hdc NumPut(PDC, FR, A_PtrSize, "UPtr") ; hdcTarget ; Define FORMATRANGE.rc ; rc is the area to render to (rcPage - margins), measured in twips (1/20 point or 1/1440 of an inch). ; If the user-defined margins are smaller than the printer's margins (the unprintable areas at the edges of each ; page), the user margins are set to the printer's margins. In addition, the user-defined margins must be adjusted ; to account for the printer's margins. ; For example: If the user requests a 3/4 inch (19.05 mm) left margin but the printer's left margin is 1/4 inch ; (6.35 mm), rc.Left is set to 720 twips (1/2 inch or 12.7 mm). Offset := A_PtrSize * 2 NumPut(UML, FR, Offset += 0, "Int") ; rc.Left NumPut(UMT, FR, Offset += 4, "Int") ; rc.Top NumPut(LPW - UMR, FR, Offset += 4, "Int") ; rc.Right NumPut(LPH - UMB, FR, Offset += 4, "Int") ; rc.Bottom ; Define FORMATRANGE.rcPage ; rcPage is the entire area of a page on the rendering device, measured in twips (1/20 point or 1/1440 of an inch) ; Note: rc defines the maximum printable area which does not include the printer's margins (the unprintable areas ; at the edges of the page). The unprintable areas are represented by PHYSICALOFFSETX and PHYSICALOFFSETY. NumPut(0, FR, Offset += 4, "Int") ; rcPage.Left NumPut(0, FR, Offset += 4, "Int") ; rcPage.Top NumPut(LPW, FR, Offset += 4, "Int") ; rcPage.Right NumPut(LPH, FR, Offset += 4, "Int") ; rcPage.Bottom ; Determine print range. ; If "Selection" option is chosen, use selected text, otherwise use the entire document. If (Flags & PD_SELECTION) { PrintS := Sel.S PrintE := Sel.E } Else { PrintS := 0 PrintE := -1 ; (-1 = Select All) } Numput(PrintS, FR, Offset += 4, "Int") ; cr.cpMin NumPut(PrintE, FR, Offset += 4, "Int") ; cr.cpMax ; Define/Populate the DOCINFO structure VarSetCapacity(DI, A_PtrSize * 5, 0) NumPut(A_PtrSize * 5, DI, 0, "UInt") NumPut(&DocName, DI, A_PtrSize, "UPtr") ; lpszDocName NumPut(0 , DI, A_PtrSize * 2, "UPtr") ; lpszOutput ; Programming note: All other DOCINFO fields intentionally left as null. ; Determine MaxPrintIndex If (Flags & PD_SELECTION) { PrintM := Sel.E } Else { PrintM := This.GetTextLen() } ; Be sure that the printer device context is in text mode DllCall("Gdi32.dll\SetMapMode", "Ptr", PDC, "Int", MM_TEXT) ; ---------------------------------------------------------------------------------------------------------------- ; Print it! ; Start a print job. Bounce If there is a problem. PrintJob := DllCall("Gdi32.dll\StartDoc", "Ptr", PDC, "Ptr", &DI, "Int") If (PrintJob <= 0) { ErrorLevel := "Function: " . A_ThisFunc . " - DLLCall of 'StartDoc' failed." Return False } ; Print page loop PageC := 0 ; current page PrintC := 0 ; current print index While (PrintC < PrintM) { PageC++ ; Are we done yet? If (PageC > PageL) Break If (PageC >= PageF) && (PageC <= PageL) { ; StartPage function. Break If there is a problem. If (DllCall("Gdi32.dll\StartPage", "Ptr", PDC, "Int") <= 0) { ErrorMsg := "Function: " . A_ThisFunc . " - DLLCall of 'StartPage' failed." Break } } ; Format or measure page If (PageC >= PageF) && (PageC <= PageL) Render := True Else Render := False SendMessage, %EM_FORMATRANGE%, %Render%, &FR, , % "ahk_id " . This.HWND PrintC := ErrorLevel If (PageC >= PageF) && (PageC <= PageL) { ; EndPage function. Break If there is a problem. If (DllCall("Gdi32.dll\EndPage", "Ptr", PDC, "Int") <= 0) { ErrorMsg := "Function: " . A_ThisFunc . " - DLLCall of 'EndPage' failed." Break } } ; Update FR for the next page Offset := (A_PtrSize * 2) + (4 * 8) Numput(PrintC, FR, Offset += 0, "Int") ; cr.cpMin NumPut(PrintE, FR, Offset += 4, "Int") ; cr.cpMax } ; ---------------------------------------------------------------------------------------------------------------- ; End the print job DllCall("Gdi32.dll\EndDoc", "Ptr", PDC) ; Delete the printer device context DllCall("Gdi32.dll\DeleteDC", "Ptr", PDC) ; Reset control (free cached information) SendMessage %EM_FORMATRANGE%, 0, 0, , % "ahk_id " . This.HWND ; Return to sender If (ErrorMsg) { ErrorLevel := ErrorMsg Return False } Return True } ; ------------------------------------------------------------------------------------------------------------------- GetMargins() { ; Get the default print margins Static PSD_RETURNDEFAULT := 0x00000400, PSD_INTHOUSANDTHSOFINCHES := 0x00000004 , I := 1000 ; thousandth of inches , M := 2540 ; hundredth of millimeters , PSD_Size := (4 * 10) + (A_PtrSize * 11) , PD_Size := (A_PtrSize = 8 ? (13 * A_PtrSize) + 16 : 66) , OffFlags := 4 * A_PtrSize , OffMargins := OffFlags + (4 * 7) If !This.HasKey("Margins") { VarSetCapacity(PSD, PSD_Size, 0) ; PAGESETUPDLG structure NumPut(PSD_Size, PSD, 0, "UInt") NumPut(PSD_RETURNDEFAULT, PSD, OffFlags, "UInt") If !DllCall("Comdlg32.dll\PageSetupDlg", "Ptr", &PSD, "UInt") Return false DllCall("Kernel32.dll\GobalFree", UInt, NumGet(PSD, 2 * A_PtrSize, "UPtr")) DllCall("Kernel32.dll\GobalFree", UInt, NumGet(PSD, 3 * A_PtrSize, "UPtr")) Flags := NumGet(PSD, OffFlags, "UInt") Metrics := (Flags & PSD_INTHOUSANDTHSOFINCHES) ? I : M Offset := OffMargins This.Margins := {} This.Margins.L := NumGet(PSD, Offset += 0, "Int") ; Left This.Margins.T := NumGet(PSD, Offset += 4, "Int") ; Top This.Margins.R := NumGet(PSD, Offset += 4, "Int") ; Right This.Margins.B := NumGet(PSD, Offset += 4, "Int") ; Bottom This.Margins.LT := Round((This.Margins.L / Metrics) * 1440) ; Left in twips This.Margins.TT := Round((This.Margins.T / Metrics) * 1440) ; Top in twips This.Margins.RT := Round((This.Margins.R / Metrics) * 1440) ; Right in twips This.Margins.BT := Round((This.Margins.B / Metrics) * 1440) ; Bottom in twips } Return True } ; ------------------------------------------------------------------------------------------------------------------- GetPrinterCaps(DC) { ; Get printer's capacities Static HORZRES := 0x08, VERTRES := 0x0A , LOGPIXELSX := 0x58, LOGPIXELSY := 0x5A , PHYSICALWIDTH := 0x6E, PHYSICALHEIGHT := 0x6F , PHYSICALOFFSETX := 0x70, PHYSICALOFFSETY := 0x71 , Caps := {} ; Number of pixels per logical inch along the page width and height LPXX := DllCall("Gdi32.dll\GetDeviceCaps", "Ptr", DC, "Int", LOGPIXELSX, "Int") LPXY := DllCall("Gdi32.dll\GetDeviceCaps", "Ptr", DC, "Int", LOGPIXELSY, "Int") ; The width and height of the physical page, in twips. Caps.PHYW := Round((DllCall("Gdi32.dll\GetDeviceCaps", "Ptr", DC, "Int", PHYSICALWIDTH, "Int") / LPXX) * 1440) Caps.PHYH := Round((DllCall("Gdi32.dll\GetDeviceCaps", "Ptr", DC, "Int", PHYSICALHEIGHT, "Int") / LPXY) * 1440) ; The distance from the left/right edge (PHYSICALOFFSETX) and the top/bottom edge (PHYSICALOFFSETY) of the ; physical page to the edge of the printable area, in twips. Caps.POFX := Round((DllCall("Gdi32.dll\GetDeviceCaps", "Ptr", DC, "Int", PHYSICALOFFSETX, "Int") / LPXX) * 1440) Caps.POFY := Round((DllCall("Gdi32.dll\GetDeviceCaps", "Ptr", DC, "Int", PHYSICALOFFSETY, "Int") / LPXY) * 1440) ; Width and height of the printable area of the page, in twips. Caps.HRES := Round((DllCall("Gdi32.dll\GetDeviceCaps", "Ptr", DC, "Int", HORZRES, "Int") / LPXX) * 1440) Caps.VRES := Round((DllCall("Gdi32.dll\GetDeviceCaps", "Ptr", DC, "Int", VERTRES, "Int") / LPXY) * 1440) Return Caps } } ================================================ FILE: Lib/Language.ahk ================================================ ;//////////////////////////////////////////////////////////////////////////////////////////////////// /* GUI Interface Keys-Words {English} */ ;//////////////////////////////////////////////////////////////////////////////////////////////////// _1 := "CASH MANAGER" _2 := "CONTINUE" _3 := "QUIT" _4 := "CASH REGISTER" _5 := "DEFINE" _6 := "STOCKPILE" _7 := "PROFITS" _8 := "ENSURE DOT" _9 := "SUBMIT" _10 := "CAN'T DOWNLOAD THE UPDATE PACKAGE!" _11 := "CAN'T EXTRACT FILES INSIDE THE UPDATE PACKAGE!" _12 := "CAN'T UPDATE THE PROGRAM FILES!" _13 := "ERROR" _14 := "COMMANDLINE CALL" _16 := "UPDATE" _17 := "A NEW UPDATE IS AVAILABLE NOW!" _18 := "DOWNLOAD AND INSTALL NOW?" _19 := "SELL OPERATION WAS DONE AT" _20 := "NEW VERSION" _21 := "DO YOU WISH TO DOWNLOAD THE NEW VERSION" _22 := "STARTING..." _23 := "CHECKING FOR UPDATES..." _24 := "WAIT FOR THE USER DESCISION..." _25 := "WORKING ON IT.." _26 := "DOWNLOADING..." _27 := "BARCODE" _28 := "MANAGEMENT" _29 := "KRIDI" _30 := "SET THIS DEFINITION" _31 := "CHECK FOR UPDATES AT APP STARTING" _32 := "REMEMBER MY INPUTS" _33 := "1`N2`N3`N4`N5" _34 := "SAVE IT AS KRIDI" _35 := "LOGIN" _36 := "OK" _37 := "ITEMS" _38 := "NAME" _39 := "SELL PRICE" _40 := "BUY PRICE" _41 := "PROFIT MADE" _42 := "OVERALL PROFIT" _43 := "FIX THE TOOLTIP GUI" _44 := "CHECK FOR UPDATES" _45 := "NO NEW UPDATES!" _46 := "NOW DOWNLOADING..." _47 := "DOWNLOAD PROGRESS" _48 := "COULD NOT CREATE THE JSON CONFIGURATION KEY!" _49 := "COULD NOT GET CURRENT AVAILABLE VERSION FROM THE DATABASE!" _50 := "VERSION IS AVAILABLE!" _51 := "DO YOU WISH TO DOWNLOAD THE NEW VERSION" _52 := "COULD NOT CREATE THE DOWNLOAD LINK!" _53 := "COULD NOT GET THE UPDATE PACKAGE LOCATION!" _54 := "COMPLETE" _55 := "UPDATE TOOL IS NOT FOUND!" _56 := "DEFINE BARCODE" _57 := "DEFINE NAME" _58 := "DEFINE BUY PRICE" _59 := "DEFINE SELL PRICE" _60 := "DEFINE QUANTITY" _61 := "STOCK CHANGE" _62 := "SAVE CHANGES" _63 := "BARCODE" _64 := "SUM CALCULATION" _65 := "SELECTION OF ALL PRODUCTS IN THE SAME STOCK" _66 := "SUM FLOW" _67 := "ERROR" _68 := "QUANTITY" _69 := "PRICE" _70 := "FILE NAME" _71 := "USERNAME AND TIME" _72 := "DATE" _73 := "RELOG" _74 := "ALL" _75 := "ENTER THE REGISTERED USERNAME AND THE PASSWORD TO CONTINUE" _76 := "A USERNAME IS REQUIRED TO CONTINUE!" _77 := "A PASSWORD IS REQUIRED TO CONTINUE!" _78 := "THE USERNAME OR THE PASSWORD IS/ARE WRONG" _79 := "SOLD PRODUCTS" _80 := "FINDS" _81 := "MORE DETAILS ABOUT THE SELL" _82 := "SEARCH RESULTS" _83 := "STATISTIC INFO" _84 := "SELLS" _85 := "CALCULATE ALL" _86 := "SORTED BY THE SOLD QUANTITY" _87 := "USERNAME" _88 := "PASSWORD" _89 := "ADD USER" _90 := "EDIT USER" _91 := "REMOVE USER" _92 := "*NEW USERNAME" _93 := "*NEW PASSWORD" _94 := "SUBMITTED" _95 := "NOT YET SUBMITTED" _96 := "SELLS WAS FOUND" _97 := "SELL WAS FOUND" _98 := "TRANSACTION SUCESSFUL!" _99 := "AT" _100 := "WAITING FOR" _101 := "SUBMISSION" _102 := "ADMIN PASSWORD" _103 := "PLEASE RE-ENTER YOUR PASSWORD TO CONFIRM THIS OPERATION" _104 := "ENABLE DEBUG MODE FOR TESTING" _105 := "SEND FEEDBACK" _106 := "UPDATE CHECK" _107 := "BY NAME SEARCH" _108 := "START UP" _109 := "LOG IN" _110 := "CREATE A USERNAME" _111 := "CREATE A PASSWORD" _112 := "UN-VALID" _113 := "PLEASE MAKE SURE THE INPUT DOESN'T CONTAIN THE FOLLOWING CHARACTERS `;/" _114 := "PLEASE RE-CHECK YOUR LOGGING INFO, SOMETHING SEEMS WRONG!" _115 := "SELL" _116 := "ENSURE" _117 := "DEFINE" _118 := "STOCK" _119 := "REVIEW" _120 := "MANAGE" _121 := "KRIDI" _122 := "TOTAL PRICE" _123 := "DISCOUNT" _124 := "CLIENT NAME" _125 := "NOTES" _126 := "DETAILS" _127 := "ADD MORE INFO" _128 := "PROFIT" _129 := "PROFIT" _130 := "DELETE" _131 := "EDIT" _132 := "APPLY" _133 := "SOLD WITH" _134 := "BOUGHT WITH" _135 := "THE MADE PROFIT" _136 := "SELECT A PICTURE" _137 := "ADD A PICTURE" _138 := "COST PRICE" _139 := "SEARCH BY BARCODE OR NAME" _140 := "ADD" _141 := "TOTAL" _142 := "RESET ALL" _143 := "RESET SELECTED" _144 := "SURE?" _145 := "YOU ARE ABOUT TO RESET ALL THE STOCK! CONTINUE?" _146 := "DONE!" _147 := "THE STOCK SHOULD BE RESETTED BY NOW!" _148 := "THE FOLLOWING STOCK IS ABOUT TO BE RESETTED! CONTINUE?" _149 := "THE FOLLOWING STOCK SHOULD BE RESETTED BY NOW!" _150 := "NEW USER" _151 := "THE ADMIN LOGGING INPUTS ARE WRONG!" _152 := "THIS USER ALREADY EXIST! IT SHOULD BE SELECTED IN THE LIST SHOWING THE USERS LIST." _156 := "USERS" _157 := "OVER ALL SELL PRICE" _158 := "OVER ALL COST PRICE" _159 := "OVER ALL COST PROFIT" _160 := "UNVALID SELL DATA!" _161 := "SEARCH BY NAME" _162 := "HOTKEYS" _163 := "PROGRESS" _164 := "THIS PAYEMENT" _165 := "FAILED TO DOWNLOAD FROM GITHUB!" _166 := "INVALID INPUT DATA!" _167 := "ADD CART" _168 := "SUBMIT" _169 := "CANCEL" _170 := "SHOW MORE" _171 := "SHOW LESS" _172 := "LOOK UP" _173 := "CHART" _174 := "CONFIRM PLEASE!" _175 := "ARCHIVE THE LISTED SELLS?" _176 := "DEFINED STOCK" _177 := "DUPLICATE" _178 := "ALREADY DEFINED!" _179 := "NOT ACCEPTED!" _180 := "PLEASE MAKE SURE THE INPUT DOESN'T CONTAIN THE FOLLOWING CHARACTERS `;" _181 := "EMPTY INPUT" _182 := "PLEASE MAKE SURE TO WRITE SOMETHING FIRST!" _183 := "ADD (TO) GROUP" _184 := "GROUP OF PRODUCTS" _185 := "WRITE DOWN A GROUP NAME" _186 := "PAY" _187 := "QUESTION" _188 := "PAYS" _189 := "CONFIRM?" _190 := "WILL BE CLEARED OUT!" _191 := "CLEAR OUT!" _192 := "UPDATE!" _193 := "FILL FORMS" _194 := "ARE YOU SURE TO DELETE" _195 := "DELETE GROUP" _196 := "REGISTER" _197 := "ADD VALUE OF" _198 := "+ NEW PERSON" _199 := "INVALID INPUTS!" _200 := "GROUPS" _201 := "#########" _202 := "INFO TYPE" _203 := "NORMAL" _204 := "MORE DETAILS" _205 := "HELP LIST" _206 := "NAME" _207 := "LEVEL" _208 := "VIEW" _209 := "VIEW ALL" _210 := "ELIMINATE GROUPS" _211 := "USER INFORMATION" _212 := "ADMIN" _213 := "USER" _214 := "PICTURE" _215 := "PREVILIGES" _216 := "ACCESS TO THE SELL SECTION" _217 := "ACCESS TO THE SUBMIT SECTION" _218 := "ACCESS TO THE DEFINE SECTION" _219 := "ACCESS TO THE REVIEW SECTION" _220 := "ACCESS TO THE KRIDI SECTION" _221 := "ACCESS TO THE USERS SECTION" _222 := "BE ABLE TO DO KRIDI" _223 := "BE ABLE TO VIEW STOCK CHANGES" _224 := "THERE IS NO ADMINS LEFT IN THE USER LIST, COMTINUE?" _225 := "PLEASE RE-CHECK YOUR ENTERED INFORMATION!" ;//////////////////////////////////////////////////////////////////////////////////////////////////// ================================================ FILE: README.md ================================================ ================================================ FILE: StartUp.ahk ================================================ #Requires AutoHotkey v1.1 #SingleInstance, Force SetBatchLines, -1 #NoEnv SetWorkingDir, % A_ScriptDir #Include, Lib\Classes\Class_CtlColors.ahk #Include, Lib\Classes\Class_ImageButton.ahk #Include, Lib\Classes\Class_GDIplus.ahk #Include, Lib\Language.ahk FolderSet() Colors := [0, 1, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F"] Gui, +HwndMain Gui, Margin, 10, 15 Gui, Color, 0xE6E6E6 Gui, Font, s12 Bold, Consolas If (Acc := FileExist("Sets\Acc.chu")) { Account := {} FileRead, RawAccount, Sets\Acc.chu TextAccount := b64Decode(RawAccount) For Each, User in StrSplit(TextAccount, ",") { LOG := StrSplit(User, "|") Account[LOG[1]] := [LOG[2], LOG[3]] } } Gui, Add, Pic,, Img\Keys.png Gui, Add, Text, xm+65 yp+5 w140 Center, % (Acc ? _87 : _92) ":" Gui, Add, Edit, xp+140 yp-3 w200 vUserName -E0x200 Border Gui, Add, Text, xp-140 yp+35 w140 Center, % (Acc ? _88 : _93) ":" Gui, Add, Edit, xp+140 yp-3 w200 vPassWord -E0x200 Border Gui, Add, Button, % "xp+100 yp+35 w100 HwndHCtrl vLogin g" (Acc ? E := "Next" : E := "NewNext"), % Acc ? _109 : _196 ImageButton.Create(HCtrl, [[3, 0x80FF80, 0x5ABB5A, 0x000000, 2,, 0x008000, 1] , [3, 0x44DB44, 0x2F982F, 0x000000, 2,, 0x008000, 1] , [3, 0x1AB81A, 0x107410, 0x000000, 2,, 0x008000, 1] , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0x999999, 1]]*) Gui, Font, s10 Gui, Add, CheckBox, % "xm yp+35 vRL", % _32 If (!Acc) { GuiControl, Disabled, CN GuiControl, Disabled, RL } FileRead, CV, Version.txt Gui, Add, Text, vCV w50, % "v" CV Gui, Show,, LOGIN GUI If FileExist("Sets\RAcc.chu") { FileRead, RawRL, Sets\RAcc.chu TextRL := StrSplit(b64Decode(RawRL), "|") If (Account[TextRL[1]][1] = TextRL[2]) { GuiControl, Focus, UserName SendInput, % TextRL[1] GuiControl, Focus, PassWord SendInput, % TextRL[2] GuiControl,, RL, 1 } } If IsConnected() { ;URLDownloadToFile, https://raw.githubusercontent.com/FreeP4lestine/Cassier/main/Program/Release/Version.txt, LVersion.txt ;If (!ErrorLevel) { ; FileRead, LV, LVersion.txt ; LV := Trim(LV, "`n") ; If (StrReplace(LV, ".") > StrReplace(CV, ".")) { ; Gui, Add, Button, xp+70 yp-5 wp+100 gUpdate HwndHCtrl vUpdate, % "[" LV "] - " _192 ; ImageButton.Create(HCtrl, [[3, 0xFF6F6F, 0xBC5454, 0x000000, 2,, 0xFF0000, 1] ; , [3, 0xDC6262, 0x9C4545, 0x000000, 2,, 0xFF0000, 1] ; , [3, 0xBF5454, 0x8A3C3C, 0x000000, 2,, 0xFF0000, 1] ; , [3, 0xCCCCCC, 0xCCCCCC, 0x000000, 2,, 0xFF0000, 1]]*) ; } ;} } Return #If WinActive("ahk_id " Main) Enter:: GoSub, % E Return #If GuiClose: IniRead, PIDs, Sets\PID.ini, PID Loop, Parse, PIDs, `n, `r { Process, Close, % StrSplit(A_LoopField, "=")[2] } ExitApp Update: ;Gui, Hide ;Run, % "GUIUpdate" (A_IsCompiled ? ".exe" : ".ahk"),,, PID ;URLDownloadToFile, https://github.com/FreeP4lestine/Cassier/raw/main/Installer/Install.exe, % A_Temp "\Install.exe" ;Process, Close, % PID ;Run, % A_Temp "\Install.exe" ;ExitApp Return NewNext: GuiControlGet, UserName,, UserName GuiControlGet, PassWord,, PassWord If (UserName != "") && (PassWord != "") { If (Obj := FileOpen("Sets\Acc.chu", "w")) { Obj.Write(b64Encode(UserName "|" PassWord "|Admin")).Close() Reload } } Return Next: GuiControlGet, UserName,, UserName GuiControlGet, PassWord,, PassWord If (UserName != "") && (PassWord == Account[UserName][1]) { If (Account[UserName][1] != "") { GuiControlGet, RL,, RL If (RL) { FileOpen("Sets\RAcc.chu", "w").Write(b64Encode(UserName "|" PassWord)).Close() } Else { FileDelete, Sets\RAcc.chu } Gui, Destroy Gui, +HwndMain Gui, Margin, 10, 10 Gui, Color, 0xE6E6E6 Gui, Font, s12 Bold, Consolas Gui, Add, Button, w140 h90 gGUISell HwndHCtrl, % "`n`n`n" _115 ImageButton.Create(HCtrl, [[0, "Img\OM\1.png"] , [0, "Img\OM\2.png",, 0x0080FF] , [0, "Img\OM\3.png",, 0xFF0000] , [0, "Img\OM\4.png"]]*) If (Account[UserName][2] = "Admin") { Gui, Add, Button, xp+150 yp w140 h90 gGUISubmit HwndHCtrl, % "`n`n`n" _116 ImageButton.Create(HCtrl, [ [0, "Img\ED\1.png"] , [0, "Img\ED\2.png",, 0x0080FF] , [0, "Img\ED\3.png",, 0xFF0000] , [0, "Img\ED\4.png"]]*) Gui, Add, Button, xp+150 yp w140 h90 gGUIDefine HwndHCtrl, % "`n`n`n" _117 ImageButton.Create(HCtrl, [ [0, "Img\DE\1.png"] , [0, "Img\DE\2.png",, 0x0080FF] , [0, "Img\DE\3.png",, 0xFF0000] , [0, "Img\DE\4.png"]]*) Gui, Add, Button, xp+150 yp w140 h90 gGUIReview HwndHCtrl, % "`n`n`n" _119 ImageButton.Create(HCtrl, [ [0, "Img\PR\1.png"] , [0, "Img\PR\2.png",, 0x0080FF] , [0, "Img\PR\3.png",, 0xFF0000] , [0, "Img\PR\4.png"]]*) Gui, Add, Button, xp+150 yp w140 h90 gGUIKridiM HwndHCtrl, % "`n`n`n" _121 ImageButton.Create(HCtrl, [ [0, "Img\KR\1.png"] , [0, "Img\KR\2.png",, 0x0080FF] , [0, "Img\KR\3.png",, 0xFF0000] , [0, "Img\KR\4.png"]]*) Gui, Add, Button, xp+150 yp w140 h90 gGUIUser HwndHCtrl, % "`n`n`n" _156 ImageButton.Create(HCtrl, [ [0, "Img\AM\1.png"] , [0, "Img\AM\2.png",, 0x0080FF] , [0, "Img\AM\3.png",, 0xFF0000] , [0, "Img\AM\4.png"]]*) } Gui, Show,, START UP GUI OnMessage(0x1000, "Message") FileOpen("Sets\Login.Hwnd", "w").Write(Main).Close() } } Return GUISell: Run, % "GUISell" (A_IsCompiled ? ".exe" : ".ahk") " " UserName " " PassWord,,, PID IniWrite, % PID, Sets\PID.ini, PID, GUISell Return GUISubmit: Run, % "GUISubmit" (A_IsCompiled ? ".exe" : ".ahk") " " UserName " " PassWord,,, PID IniWrite, % PID, Sets\PID.ini, PID, GUISubmit Return GUIDefine: Run, % "GUIDefine" (A_IsCompiled ? ".exe" : ".ahk") " " UserName " " PassWord,,, PID IniWrite, % PID, Sets\PID.ini, PID, GUIDefine Return GUIReview: Run, % "GUIReview" (A_IsCompiled ? ".exe" : ".ahk") " " UserName " " PassWord,,, PID IniWrite, % PID, Sets\PID.ini, PID, GUIReview Return GUIKridiM: Run, % "GUIKridiM" (A_IsCompiled ? ".exe" : ".ahk") " " UserName " " PassWord,,, PID IniWrite, % PID, Sets\PID.ini, PID, GUIKridiM Return GUIUser: Run, % "GUIUser" (A_IsCompiled ? ".exe" : ".ahk") " " UserName " " PassWord,,, PID IniWrite, % PID, Sets\PID.ini, PID, GUIUser Return b64Encode(string) { VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1 if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", 0, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) VarSetCapacity(buf, size << 1, 0) if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", &buf, "uint*", size)) throw Exception("CryptBinaryToString failed", -1) return StrGet(&buf) } b64Decode(string) { if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", 0, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) VarSetCapacity(buf, size, 0) if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", &buf, "uint*", size, "ptr", 0, "ptr", 0)) throw Exception("CryptStringToBinary failed", -1) return StrGet(&buf, size, "UTF-8") } FolderSet() { Array := [ "Curr" , "Sets" , "Sets\Def" , "Valid" , "Dump" , "Kr" , "Unvalid" , "Hist" ] For Every, Folder in Array { If !FolderExist(Folder) { FileCreateDir, % Folder } } } FolderExist(Folder) { Return InStr(FileExist(Folder), "D") } IsConnected() { Return DllCall("Wininet.dll\InternetGetConnectedState", "Str", 0x40, "Int", 0) } Message() { Global Account, UserName, PassWord FileRead, Message, Sets\Login.Request MsgData := StrSplit(Message, "|") If (MsgData[1] = "Run") { If (Account[UserName][2] = "Admin") { Run, % MsgData[2] " " UserName " " PassWord } Else If InStr(MsgData[2], "GUISell") { Run, % MsgData[2] " " UserName " " PassWord } } Else If (MsgData[1] = "Reload") { IniRead, PIDs, Sets\PID.ini, PID Loop, Parse, PIDs, `n, `r { Process, Close, % StrSplit(A_LoopField, "=")[2] } Reload } } RandomColor(Colors) { Color := "" Loop, 6 { Random, Index, 1, 16 Color .= Colors[Index] } Return, Color } ================================================ FILE: Template.css ================================================ .highcharts-figure, .highcharts-data-table table { min-width: 360px; max-width: 100%; margin: 1em auto; } .highcharts-data-table table { font-family: Verdana, sans-serif; border-collapse: collapse; border: 1px solid #ebebeb; margin: 10px auto; text-align: center; width: 100%; max-width: 500px; } .highcharts-data-table caption { padding: 1em 0; font-size: 1.2em; color: #555; } .highcharts-data-table th { font-weight: 600; padding: 0.5em; } .highcharts-data-table td, .highcharts-data-table th, .highcharts-data-table caption { padding: 0.5em; } .highcharts-data-table thead tr, .highcharts-data-table tr:nth-child(even) { background: #a0a0a0; } .highcharts-data-table tr:hover { background: #5a78a0; } ================================================ FILE: Template.html ================================================
A HighChart demo adapted
================================================ FILE: Template.js ================================================ Highcharts.chart('container', { chart: { type: 'line', }, title: { text: 'CASH HELPER CHART VIEW', align: 'left' }, subtitle: { text: 'A graphic resume of your sells', align: 'left' }, yAxis: { title: { text: 'Amount in millims' } }, xAxis: { categories: ['2023/02/21','2023/02/25','2023/03/04','2023/03/05','2023/06/01','2023/06/02','2023/06/03','2023/06/04'], }, series: [{ name: 'SELLS', color: '#008000', data: [29550,31250,6000,45250,475650,540450,572000,264550], }, { name: 'COSTS', color: '#FF0000', data: [25984,25926,4913,39566,411282,460238,482860,224345] }, { name: 'PROFITS', color: '#0066FF', data: [3566,5324,1087,5684,64368,80212,89140,40205] }], responsive: { rules: [{ condition: { maxWidth: 500 }, chartOptions: { legend: { layout: 'horizontal', align: 'center', verticalAlign: 'bottom' } } }] } }); ================================================ FILE: Uninstall.ahk ================================================ #Requires AutoHotkey v1.1 #SingleInstance, Force SetBatchLines, -1 SetWorkingDir, % A_ScriptDir FileInstall, Uninstall.png, Uninstall.png, 1 Gui, -MinimizeBox Gui, Font, s20 Bold, Calibri Gui, Color, White Gui, Add, Text, Center BackgroundTrans w400, Cash Helper Gui, Add, Pic, xm yp-10 w64 h64 BackgroundTrans, Uninstall.png Gui, Font, Norm Gui, Font, s10 Bold Gui, Add, Edit, ReadOnly w400 vLoc, % A_ScriptDir IS := InstallState() Gui, Add, Button, w100 vUB, % IS[1] If (IS[1] = "Not Installed") { GuiControl, Disabled, UB } Gui, Add, Progress, vPB w100 -Smooth h15 w400 Hidden Gui, Font, s8 Gui, Add, Text, xp yp+17 wp Center vPercent BackgroundTrans Gui, Show Return GuiClose: ExitApp ButtonUninstall: GuiControl, Disabled, UB RegDelete, HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Cash Helper FileDelete, % A_Desktop "\Cash Helper.lnk" GuiControlGet, Loc FileRemoveDir, % Loc, 1 FileOpen(A_Temp "\CH_Uninstall.bat", "w").Write("timeout 1`nrd /s /q """ Loc """").Close() MsgBox,, Complete, Uninstall Complete! Run, % A_Temp "\CH_Uninstall.bat",, Hide ExitApp Return InstallState() { RegRead, IC, HKLM, SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Cash Helper, InstallLocation GuiControlGet, Loc IS := (IC = Loc "\") ? ["Uninstall", "Uninstalling..."] : ["Not Installed", ""] GuiControl,, IB, % IS[1] Return, IS } ================================================ FILE: Version.txt ================================================ 2.0.2.0