#Requires AutoHotkey v2.0 #SingleInstance Force global MainColor := "F8F4E8" global AccentColor := "7D5800" global BgColor := "EDE8D5" global IsHover := false global Queue := [] global Worker := "" global IsCancelled := false global OurWindows := Map() global SelectGui := unset global ProgGui := unset global MsgGui := unset ; ===================================================== ; גרירת חלונות ; ===================================================== OnMessage(0x0201, WM_LBUTTONDOWN) WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) { rootHwnd := DllCall("GetAncestor", "ptr", hwnd, "uint", 2, "ptr") if !OurWindows.Has(rootHwnd) return try { cls := WinGetClass("ahk_id " hwnd) if (cls = "Button" || cls = "Edit") return } PostMessage(0xA1, 2,,, "ahk_id " rootHwnd) } ApplyRounding(guiObj) { guiObj.Opt("+LastFound") DllCall("dwmapi\DwmSetWindowAttribute", "ptr", guiObj.Hwnd, "uint", 33, "ptr*", 2, "uint", 4) } ; ===================================================== ; כפתור הורדה צף ; ===================================================== BtnGui := Gui("+AlwaysOnTop -Caption +ToolWindow +LastFound") BtnGui.BackColor := "EEAA99" WinSetTransColor("EEAA99", BtnGui) BtnGui.SetFont("s22", "Segoe UI Symbol") global BtnTxt := BtnGui.Add("Text", "x0 y0 w60 h50 Center c" AccentColor, "📥") BtnTxt.OnEvent("Click", ShowSelectionMenu) OurWindows[BtnGui.Hwnd] := true TipGui := Gui("-Caption +AlwaysOnTop +ToolWindow") TipGui.BackColor := "2B2B2B" TipGui.SetFont("s9 w800 cWhite", "Segoe UI") TipGui.Add("Text", "x8 y4 w80 h44 Center", "הורדת מאגרי ספרים מותאמים") ApplyRounding(TipGui) OurWindows[TipGui.Hwnd] := true SetTimer(WatchOtzaria, 250) WatchOtzaria() { global IsHover TargetID := WinExist("ahk_exe otzaria.exe") ActiveID := WinActive("A") SelectHwnd := (IsSet(SelectGui) && IsObject(SelectGui)) ? SelectGui.Hwnd : 0 ProgHwnd := (IsSet(ProgGui) && IsObject(ProgGui)) ? ProgGui.Hwnd : 0 MsgHwnd := (IsSet(MsgGui) && IsObject(MsgGui)) ? MsgGui.Hwnd : 0 ; בדיקה האם אנחנו עובדים כרגע על אוצריא או על אחד החלונות שלנו IsOtzariaContext := TargetID && (ActiveID = TargetID || ActiveID = SelectHwnd || ActiveID = BtnGui.Hwnd || ActiveID = ProgHwnd || ActiveID = MsgHwnd) if IsOtzariaContext { WinGetPos(&X, &Y, &W, &H, "ahk_id " TargetID) btnX := X + W - 78 btnY := Y + H - 186 BtnGui.Show("x" btnX " y" btnY " w60 h50 NoActivate") ; החזרת החלונות במידה וחזרנו לאוצריא מתוכנה אחרת if SelectHwnd try SelectGui.Show("NoActivate") if ProgHwnd try ProgGui.Show("NoActivate") MouseGetPos(,, &HoverWin) if (HoverWin = BtnGui.Hwnd) { if !IsHover { TipGui.Show("x" (btnX - 85) " y" (btnY + 5) " NoActivate") IsHover := true } } else if IsHover { TipGui.Hide() IsHover := false } } else { BtnGui.Hide() TipGui.Hide() ; הסתרת חלונות בעת מעבר לתוכנה אחרת (לא סגירה, רק הסתרה) if SelectHwnd try SelectGui.Hide() if ProgHwnd try ProgGui.Hide() } } ; ===================================================== ; חלון בחירת ספרים מעוצב וימין-שמאל (RTL) ; ===================================================== ShowSelectionMenu(*) { BtnTxt.Text := "⏳" try { shell := ComObject("WScript.Shell") exec := shell.Exec("pythonw.exe downloader.py CHECK") res := exec.StdOut.ReadAll() } catch { BtnTxt.Text := "📥" CustomMsgBox("שגיאה: לא ניתן להפעיל את פייתון.", "שגיאת הפעלה") return } BtnTxt.Text := "📥" if !InStr(res, "LIST:") || InStr(res, "EMPTY") { CustomMsgBox("המאגר מעודכן!", "עדכון ספריה") return } global SelectGui := Gui("+AlwaysOnTop -Caption") SelectGui.BackColor := MainColor ApplyRounding(SelectGui) OurWindows[SelectGui.Hwnd] := true SelectGui.SetFont("s15 w700 c" AccentColor, "Segoe UI") SelectGui.Add("Text", "x0 y15 w420 Center", "עדכון ספריה") SelectGui.SetFont("s11 w600 cBlack", "Segoe UI") ; +0x20 ו-Right אחראים על הפיכת הצ'קבוקס לימין שמאלה cbAll := SelectGui.Add("Checkbox", "x20 y+20 w380 Right +0x20", "בחר / בטל הכל (ללא המאגר המלא)") Checkboxes := [] items := StrSplit(StrReplace(res, "LIST:", ""), ";") for item in items { if (Trim(item) = "") { continue } p := StrSplit(item, "|") isFull := (p[1] = "0") SelectGui.SetFont("s11 w400 cBlack", "Segoe UI") cb := SelectGui.Add("Checkbox", (p[1] = "1" ? "Checked " : "") "x20 y+10 w380 Right +0x20", p[2]) Checkboxes.Push({full: item, cb: cb, isFull: isFull}) } cbAll.OnEvent("Click", (self, *) => ToggleAll(self.Value, Checkboxes)) BtnDown := SelectGui.Add("Button", "Default w160 h35 x40 y+25", "הורד") BtnCancel := SelectGui.Add("Button", "w160 h35 x+20", "ביטול") BtnDown.OnEvent("Click", (*) => StartSelectedDownload(SelectGui, Checkboxes)) BtnCancel.OnEvent("Click", (*) => SelectGui.Destroy()) SelectGui.Show("w420 Center") } ToggleAll(val, Checkboxes) { for item in Checkboxes { if !item.isFull item.cb.Value := val } } ; ===================================================== ; הודעה מעוצבת בסגנון אוצריא ; ===================================================== CustomMsgBox(txt, title) { global MsgGui := Gui("-Caption +AlwaysOnTop +Owner") MsgGui.BackColor := MainColor ApplyRounding(MsgGui) OurWindows[MsgGui.Hwnd] := true MsgGui.SetFont("s15 w700 c" AccentColor, "Segoe UI") MsgGui.Add("Text", "x0 y20 w350 Center", title) MsgGui.SetFont("s11 w400 cBlack", "Segoe UI") MsgGui.Add("Text", "x25 y+15 w300 Center +Wrap", txt) BtnOk := MsgGui.Add("Button", "Default w120 h35 x115 y+25", "אישור") BtnOk.OnEvent("Click", (*) => MsgGui.Destroy()) MsgGui.Show("w350 Center") } ; ===================================================== ; חלון התקדמות ; ===================================================== ProgressShow(FileName, Remaining) { global ProgGui, StatusTxt, Bar, PctLabel ProgGui := Gui("-Caption +AlwaysOnTop") ProgGui.BackColor := MainColor ApplyRounding(ProgGui) OurWindows[ProgGui.Hwnd] := true ProgGui.SetFont("s14 w700 c" AccentColor, "Segoe UI") ProgGui.Add("Text", "x0 y20 w400 Center", "הורדה בתהליך") ProgGui.SetFont("s11 w600 c" AccentColor, "Segoe UI") ProgGui.Add("Text", "x25 y+15 w350 Center +Wrap", FileName) ProgGui.SetFont("s12 w700 c" AccentColor, "Segoe UI") StatusTxt := ProgGui.Add("Text", "x0 y+15 w400 Center", "מוריד...") Bar := ProgGui.Add("Progress", "x30 y+12 w340 h18 cGreen Background" BgColor, 0) ProgGui.SetFont("s11 w700 cBlack", "Segoe UI") PctLabel := ProgGui.Add("Text", "x0 y+8 w400 Center", "0%") CancelBtn := ProgGui.Add("Button", "w120 h35 x140 y+20", "ביטול") CancelBtn.OnEvent("Click", CancelDownload) ProgGui.Show("w400 Center") } ; ===================================================== ; ניהול תור הורדות ; ===================================================== StartSelectedDownload(GuiObj, Checkboxes) { global Queue := [], IsCancelled := false for item in Checkboxes { if item.cb.Value Queue.Push(item.full) } GuiObj.Destroy() if Queue.Length > 0 NextDownload() else CustomMsgBox("לא נבחרו ספרים להורדה.", "שים לב") } NextDownload() { global Queue, IsCancelled, Worker if IsCancelled || (Queue.Length = 0) { if !IsCancelled CustomMsgBox("הספריה עודכנה בהצלחה!", "סיום הורדה") return } CurrentItem := Queue.RemoveAt(1) p := StrSplit(CurrentItem, "|") ProgressShow(p[2], Queue.Length) Worker := ComObject("WScript.Shell").Exec('pythonw.exe downloader.py "' CurrentItem '"') SetTimer(CheckStatus, 100) } CheckStatus() { global Worker, ProgGui, StatusTxt, Bar, PctLabel if Worker.StdOut.AtEndOfStream { SetTimer(CheckStatus, 0) try { if IsObject(ProgGui) && (ProgGui != "") { ProgGui.Destroy() ProgGui := unset CustomMsgBox("ההורדה נכשלה.`nבדוק חיבור לאינטרנט.", "שגיאה") } } return } line := Worker.StdOut.ReadLine() if InStr(line, "DL_PROGRESS:") { pct := StrReplace(line, "DL_PROGRESS:", "") Bar.Value := pct PctLabel.Text := pct "%" } else if InStr(line, "DL_FINISHED") { StatusTxt.Text := "מחלץ קבצים..." Bar.Value := 0 } else if InStr(line, "EX_PROGRESS:") { pct := StrReplace(line, "EX_PROGRESS:", "") Bar.Value := pct PctLabel.Text := pct "%" } else if InStr(line, "DONE") { SetTimer(CheckStatus, 0) ProgGui.Destroy() ProgGui := unset NextDownload() } } CancelDownload(*) { global Worker, IsCancelled, ProgGui IsCancelled := true SetTimer(CheckStatus, 0) try Worker.Terminate() ProgGui.Destroy() ProgGui := unset CustomMsgBox("ההורדה בוטלה.", "ביטול") }