PERSEUS SDR : Frequency direct input + small window

Posted by @XYZ •
#1 @XYZ
Frequency direct input + small window with a 5-item history I am currently using this, but as it is for research purposes, no support is provided. ・This code runs on AutoHotkey v2. https://www.autohotkey.com/v2/ ・Place the file in the same folder as PERSEUS, giving it an appropriate name (e.g., "perseussmallwindow.ahk"—the ".ahk" file extension is required). ・Running this file will launch PERSEUS, followed by the appearance of a small window. When you enter a number (a frequency), it is buffered and stored internally until you press the Enter key to confirm. Once the Enter key is pressed, the software will tune to the specified frequency. ・You can also tune to a frequency by clicking the corresponding button in the small window's history list. ・To hide the small window, press "Shift + Ctrl + H." Pressing the same key combination again will make the window reappear. #Requires AutoHotkey v2.0 #SingleInstance Force SetDefaultMouseSpeed 0 ; Move the mouse instantly. SetTitleMatchMode "RegEx" global FreqBuffer := "" global FreqHistory := [] ; Array to store frequency history (Max 5 items) global HistoryButtons := [] global PerseusGui := "" ;*** BEGIN of the PLAYBACK parameter section *** global playback_step := 10 ; seconds global playback_minutes := 5 global playback_seconds := 0 global playback_bar_start := 180 global playback_bar_end := 1011 global playback_bar_vpos := 603 global playback_position := playback_bar_start global playback_last_timestamp := 0 PlaybackJump(seconds) { return (playback_bar_end - playback_bar_start) / (((playback_minutes * 60) + playback_seconds) / seconds) } ;*** END of the PLAYBACK parameter section *** sendBufferToFreqWnd(unitKey := "") { global FreqBuffer, FreqHistory if (FreqBuffer = "") { Click(100, 245, 2) if !WinWait("ahk_class #32770",, 2) return if !WinActive("ahk_class #32770") WinActivate("ahk_class #32770") Click(110, 45) Send("{Space}{BS}") return } ; Add frequency to history (Max 5 items) unitStr := (unitKey = "m") ? " MHz" : " kHz" fullFreqStr := FreqBuffer . unitStr AddFreqToHistory(fullFreqStr, FreqBuffer, unitKey) CoordMode("Mouse", "Screen") MouseGetPos(&cxpos, &cypos) CoordMode("Mouse", "Window") Click(100, 245, 2) if !WinWait("ahk_class #32770",, 2) { FreqBuffer := "" return } ControlFocus("Edit1", "ahk_class #32770") ControlClick("Edit1", "ahk_class #32770",,,, "LEFT") if !WinActive("ahk_class #32770") WinActivate("ahk_class #32770") Click(110, 45) SendText(FreqBuffer) FreqBuffer := "" if (unitKey = "k" || unitKey = "Enter") { Click(64, 184) Click(104, 186) } else if (unitKey = "m") { Click(33, 184) Click(104, 186) } CoordMode("Mouse", "Screen") Click(cxpos, cypos, 0) CoordMode("Mouse", "Window") return } ; Safe background mouse operation function UnnoticeableClick(xpos, ypos, attr := "", clicks := 1) { perseusWin := "Perseus ahk_class (Afx:400000:2028:|Afx:00400000:2028:)" if WinExist(perseusWin) && !WinActive(perseusWin) { WinActivate(perseusWin) Sleep(50) } CoordMode("Mouse", "Screen") MouseGetPos(&cxpos, &cypos) CoordMode("Mouse", "Window") ; Branching click operations based on attributes (e.g., "WD", "WU") if (attr = "WD") { Click(xpos, ypos, "WheelDown", clicks) } else if (attr = "WU") { Click(xpos, ypos, "WheelUp", clicks) } else { Click(xpos, ypos, clicks) } CoordMode("Mouse", "Screen") Click(cxpos, cypos, 0) CoordMode("Mouse", "Window") return } ; Exit program logic ExitPerseusAndScript() { UnnoticeableClick(1010, 12) ExitApp() } ; Toggle GUI logic ToggleGui() { global PerseusGui if (PerseusGui) { if DllCall("IsWindowVisible", "Ptr", PerseusGui.Hwnd) PerseusGui.Hide() else PerseusGui.Show("NoActivate") } } ; Activate Perseus if it isn't already active perseusWin := "Perseus ahk_class (Afx:400000:2028:|Afx:00400000:2028:)" if WinExist(perseusWin) { WinActivate(perseusWin) WinWaitActive(perseusWin,, 2) } else { try { Run("Perseus",,, &NewPID) ProcessSetPriority("Realtime", NewPID) WinWait(perseusWin) WinActivate(perseusWin) WinWaitActive(perseusWin,, 3) } catch { MsgBox("Can't find the Perseus program.`n`nCheck PerseusKeyboard and the Perseus software`nare located in the same directory.") ExitApp() } } ; --- Automatically click Noise Limiter (n key) ON right after startup --- Sleep(800) UnnoticeableClick(969, 402) ; ------------------------------------------------------------------------- ; ============================================================================== ; PERSEUS GUI Companion Panel Creation ; ============================================================================== PerseusGui := Gui("+AlwaysOnTop -Caption +Owner", "PERSEUS Companion") PerseusGui.BackColor := "181825" ; Enable window dragging by clicking anywhere on the panel OnMessage(0x0201, WM_LBUTTONDOWN) WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) { if (hwnd = PerseusGui.Hwnd) PostMessage(0xA1, 2,,, PerseusGui.Hwnd) } ; Header Title PerseusGui.SetFont("s9 bold c89B4FA", "Segoe UI") PerseusGui.Add("Text", "x10 y8 w200 h20 Center", "PERSEUS SDR") ; Shortcut control buttons PerseusGui.SetFont("s8 bold cCDD6F4", "Segoe UI") PerseusGui.Add("Button", "x10 y32 w96 h24", "Hide (Shift+Ctrl+H)").OnEvent("Click", (*) => ToggleGui()) PerseusGui.Add("Button", "x114 y32 w96 h24", "EXIT (Shift+Q)").OnEvent("Click", (*) => ExitPerseusAndScript()) ; Frequency History Group (Top 5) PerseusGui.SetFont("s8 cCDD6F4", "Segoe UI") PerseusGui.Add("GroupBox", "x8 y62 w204 h150 c45475A", " Freq History (Top 5) ") Loop 5 { yPos := 80 + ((A_Index - 1) * 26) btn := PerseusGui.Add("Button", "x16 y" . yPos . " w188 h22 Hidden", "") btn.OnEvent("Click", OnHistoryBtnClick) HistoryButtons.Push(btn) } ; Relative positioning based on Perseus main window coordinates (X+750, Y+30) if WinExist(perseusWin) { WinGetPos(&pX, &pY,,, perseusWin) targetX := pX + 750 targetY := pY + 30 PerseusGui.Show("x" . targetX . " y" . targetY . " w220 h220 NoActivate") } else { PerseusGui.Show("x750 y30 w220 h220 NoActivate") } ; --- Frequency History Management Functions --- AddFreqToHistory(labelStr, val, unitKey) { global FreqHistory, HistoryButtons for idx, item in FreqHistory { if (item.label = labelStr) { FreqHistory.RemoveAt(idx) break } } FreqHistory.InsertAt(1, {label: labelStr, val: val, unitKey: unitKey}) if (FreqHistory.Length > 5) FreqHistory.Pop() for i, btn in HistoryButtons { if (i <= FreqHistory.Length) { btn.Text := FreqHistory[i].label btn.Visible := true } else { btn.Visible := false } } } ; Open frequency input window directly and send frequency when history button is clicked OnHistoryBtnClick(btn, *) { global FreqHistory, FreqBuffer for i, item in FreqHistory { if (btn.Text = item.label) { perseusWin := "Perseus ahk_class (Afx:400000:2028:|Afx:00400000:2028:)" if WinExist(perseusWin) WinActivate(perseusWin) FreqBuffer := item.val sendBufferToFreqWnd(item.unitKey) break } } } ; --- Global Hotkeys --- +^h::ToggleGui() ; Shift + Ctrl + H to Hide/Show panel #HotIf WinActive("Perseus ahk_class (Afx:400000:2028:|Afx:00400000:2028:)") ;*** Frequency Control *** Left::Click(192, 309) Right::Click(987, 308) Up::Click(587, 290, "WheelDown") Down::Click(587, 290, "WheelUp") PgDn:: { Loop 10 { UnnoticeableClick(587, 290, "WD") Sleep(1) } } Delete:: { Loop 10 { UnnoticeableClick(587, 290, "WU") Sleep(1) } } [::UnnoticeableClick(135, 295) ]::UnnoticeableClick(150, 295) -::UnnoticeableClick(130, 333) _::UnnoticeableClick(155, 334) /:: NumpadDiv::UnnoticeableClick(133, 152) *:: NumpadMult::UnnoticeableClick(157, 152) t:: +t::UnnoticeableClick(227, 309) w:: +w::UnnoticeableClick(263, 309) b:: +b::UnnoticeableClick(518, 403) End:: n:: +n::UnnoticeableClick(969, 402) 0:: Numpad0::global FreqBuffer := FreqBuffer . "0" 1:: Numpad1::global FreqBuffer := FreqBuffer . "1" 2:: Numpad2::global FreqBuffer := FreqBuffer . "2" 3:: Numpad3::global FreqBuffer := FreqBuffer . "3" 4:: Numpad4::global FreqBuffer := FreqBuffer . "4" 5:: Numpad5::global FreqBuffer := FreqBuffer . "5" 6:: Numpad6::global FreqBuffer := FreqBuffer . "6" 7:: Numpad7::global FreqBuffer := FreqBuffer . "7" 8:: Numpad8::global FreqBuffer := FreqBuffer . "8" 9:: Numpad9::global FreqBuffer := FreqBuffer . "9" Enter:: NumpadEnter::sendBufferToFreqWnd("Enter") m:: +m:: { if (FreqBuffer != "") { sendBufferToFreqWnd("m") } else { UnnoticeableClick(1002, 405) } } k:: +k:: { if (FreqBuffer != "") { sendBufferToFreqWnd("k") } else { UnnoticeableClick(380, 546) } } l:: +L:: NumPadSub::UnnoticeableClick(408, 353) u:: +U:: NumPadAdd::UnnoticeableClick(455, 353) a:: +A::UnnoticeableClick(204, 353) s:: +S::UnnoticeableClick(259, 353) +c:: c::UnnoticeableClick(310, 353) r:: +R::UnnoticeableClick(362, 353) f:: +F::UnnoticeableClick(508, 353) d:: +D::UnnoticeableClick(561, 353) e:: +E::UnnoticeableClick(594, 353) j:: +j::UnnoticeableClick(562, 458) y:: +y::UnnoticeableClick(260, 546) h:: +h::UnnoticeableClick(300, 546) g:: +g::UnnoticeableClick(340, 546) x:: +x::UnnoticeableClick(23, 422) Home::UnnoticeableClick(300, 310) ;Wave file change z:: +z:: { global playback_position, playback_last_timestamp UnnoticeableClick(playback_bar_end, playback_bar_vpos) playback_position := playback_bar_start playback_last_timestamp := A_TickCount Sleep(1000) } ;*** PLAYBACK hotkey section *** Tab:: { global playback_last_timestamp, playback_position playback_current_timestamp := A_TickCount if (playback_last_timestamp = 0 || playback_last_timestamp > playback_current_timestamp) playback_last_timestamp := playback_current_timestamp playback_position += PlaybackJump((playback_current_timestamp - playback_last_timestamp) / 1000) playback_last_timestamp := playback_current_timestamp if (playback_position > (playback_bar_end - 1)) playback_position := playback_bar_start + Mod(playback_position - playback_bar_start, playback_bar_end - playback_bar_start) playback_position += PlaybackJump(playback_step) if (playback_position > (playback_bar_end - 1)) playback_position := playback_bar_start UnnoticeableClick(playback_position, playback_bar_vpos) Sleep(100) } +Tab:: { global playback_last_timestamp, playback_position playback_current_timestamp := A_TickCount if (playback_last_timestamp = 0 || playback_last_timestamp > playback_current_timestamp) playback_last_timestamp := playback_current_timestamp playback_position += PlaybackJump((playback_current_timestamp - playback_last_timestamp) / 1000) playback_last_timestamp := playback_current_timestamp if (playback_position > (playback_bar_end - 1)) playback_position := playback_bar_start + Mod(playback_position - playback_bar_start, playback_bar_end - playback_bar_start) if (playback_position > (playback_bar_start + PlaybackJump(1))) { playback_position -= PlaybackJump(playback_step) if (playback_position < playback_bar_start) playback_position := playback_bar_start UnnoticeableClick(playback_position, playback_bar_vpos) } Sleep(100) } ^Tab:: { global playback_step, playback_minutes, playback_seconds IB1 := InputBox("Step (in seconds)", "PLAYBACK", "W160 H130", playback_step) if (IB1.Result = "Cancel") return if !IsInteger(IB1.Value) || Number(IB1.Value) <= 0 { MsgBox("Step invalid", "Error", 0x10) return } playback_step := Number(IB1.Value) IB2 := InputBox("Minutes", "PLAYBACK", "W160 H130", playback_minutes) if (IB2.Result = "Cancel") return if !IsInteger(IB2.Value) || Number(IB2.Value) < 0 || Number(IB2.Value) > 59 { MsgBox("Minutes invalid", "Error", 0x10) return } playback_minutes := Number(IB2.Value) IB3 := InputBox("Seconds", "PLAYBACK", "W160 H130", playback_seconds) if (IB3.Result = "Cancel") return if !IsInteger(IB3.Value) || Number(IB3.Value) < 0 || Number(IB3.Value) > 59 { MsgBox("Seconds invalid", "Error", 0x10) return } playback_seconds := Number(IB3.Value) } ;Close Perseus and the script +q:: !F4:: { ExitPerseusAndScript() } #HotIf #HotIf WinActive("Frequency ahk_class #32770") Enter:: NumpadEnter:: k:: +k:: { Click(64, 184) Click(104, 186) } m:: +m:: { Click(33, 184) Click(104, 186) } #HotIf
002.png

You must be logged in to reply to this radio discussion.