; Timer_Hotkey_Combo.ahk
#Persistent
#SingleInstance Force
CoordMode, Gui, screen
SetTitleMatchMode, 2
SetBatchLines, -1
OnMessage(0x201, "WM_LBUTTONDOWN") ; 마우스 왼쪽버튼 눌림 감지
; 전역 변수
global BaseHour := ""
global BaseMinute := ""
global IntervalMin := 15
global RemainingSeconds := 0
global TimerRunning := false
global isExpanded := false
IniFilePath := A_ScriptDir . "config.ini"
;IniFilePath := A_ScriptDir . "HotkeySettings.ini"
; 핫키용 배열
hotkeys := []
texts := []
; INI에서 시간 관련 설정 불러오기
IniRead, BaseHour, %IniFilePath%, Time, Hour, 12
IniRead, BaseMinute, %IniFilePath%, Time, Minute, 0
IniRead, IntervalMin, %IniFilePath%, Time, Interval, 15
; GUI 구성
Gui, +AlwaysOnTop +ToolWindow -Caption
Gui, Color, 004488
Gui, Font, s12 Bold, Segoe UI
Gui, Add, Button, gExitApp1 vExitBtn x10 y5 w30 h30 c00ffff BackgroundColor, X
Gui, Add, Button, gToggleSettingsSection x+10 y5 w80 h30 c3f7ab5, 설정 열기
Gui, Add, Button, gApplyAll vApplyBtn x+25 y5 w40 h30 cFFFFFF BackgroundTrans, 적용
Gui, Add, Button, gStartTimer vStartBtn x+15 y5 w40 h30 Disabled cFFFFFF BackgroundTrans, 시작
Gui, Add, Button, gStopTimer vStopBtn x+15 y5 w40 h30 Disabled cFFFFFF BackgroundTrans, 정지
Gui, Font, s14 Bold, Segoe UI
Gui, Add, Text, vTimeText x+30 y7 w150 h30 cFFFFFF BackgroundTrans, 현 시간:
Gui, Add, Text, vCountdownText x+1 y7 w440 h30 cFF8E7F BackgroundTrans, 남은 시간:
Gui, Font, s12 Bold, Segoe UI
BaseHour1 := BaseHour+1
BaseMinute1 := BaseMinute+1
Gui, Add, Text, vIntervalLabel1 x10 y60 w160 h30 cFFFFFF BackgroundTrans, 알람기준 시간 : 시_
Gui, Add, DropDownList, vHourDDL x+1 y57 w45 h150 Choose%BaseHour1% cFFFFFF BackgroundTrans, % LoopList(0,23)
Gui, Add, Text, vIntervalLabel2 x+20 y60 w30 h30 cFFFFFF BackgroundTrans, 분_
Gui, Add, DropDownList, vMinuteDDL x+1 y57 w45 h150 Choose%BaseMinute1% cFFFFFF BackgroundTrans, % LoopList(0,59)
Gui, Add, Text, vIntervalLabel3 x+20 y60 w70 h30 cFFFFFF BackgroundTrans, 간격(분)_
Gui, Add, DropDownList, vIntervalDDL x+1 y57 w45 h150 Choose%IntervalMin% cFFFFFF BackgroundTrans, % LoopList(1,59)
; 핫키 설정 GUI - 하단에 텍스트 영역 포함
Gui, Add, Button, x5 y110 w70 h30 c3f7ab5 vHotkeyClear1 gClearHotkey, 핫키삭제
Gui, Add, Text, x90 y110 c0FFFFF vHotkeyLabel, *핫키설정
Gui, Add, Text, x220 y110 c0FFFFF vHotkeyLabel1, *내 용
;Loop, 6 {
; Gui, Add, Hotkey, vHotkey%A_Index% x+10 w80
;}
; 개별 라벨과 핫키 생성
Gui, Add, Text, vLabel1 x10 y150 w70 h25 cFFFFFF, 텍스트 1
Gui, Add, Hotkey, vHotkey1 x+10 w120 gUpdateHotkeyLabel
Gui, Add, Edit, vText1 x+10 w670 Hidden
Gui, Add, Text, vLabel2 x10 y+30 w70 h25 cFFFFFF, 텍스트 2
Gui, Add, Hotkey, vHotkey2 x+10 w120 gUpdateHotkeyLabel
Gui, Add, Edit, vText2 x+10 w670 Hidden
Gui, Add, Text, vLabel3 x10 y+30 w70 h25 cFFFFFF, 텍스트 3
Gui, Add, Hotkey, vHotkey3 x+10 w120 gUpdateHotkeyLabel
Gui, Add, Edit, vText3 x+10 w670 Hidden
Gui, Add, Text, vLabel4 x10 y+30 w70 h25 cFFFFFF, 텍스트 4
Gui, Add, Hotkey, vHotkey4 x+10 w120 gUpdateHotkeyLabel
Gui, Add, Edit, vText4 x+10 w670 Hidden
Gui, Add, Text, vLabel5 x10 y+30 w70 h25 cFFFFFF, 텍스트 5
Gui, Add, Hotkey, vHotkey5 x+10 w120 gUpdateHotkeyLabel
Gui, Add, Edit, vText5 x+10 w670 Hidden
Gui, Add, Text, vLabel6 x10 y+30 w70 h25 cFFFFFF, 텍스트 6
Gui, Add, Hotkey, vHotkey6 x+10 w120 gUpdateHotkeyLabel
Gui, Add, Edit, vText6 x+10 w670 Hidden
; 핫키 INI 불러오기
Loop, 6 {
idx := A_Index
IniRead, hkey, %IniFilePath%, Hotkeys, Hotkey%idx%,
IniRead, txt, %IniFilePath%, Hotkeys, Text%idx%,
if (hkey != "" && hkey != "ERROR") {
GuiControl,, Hotkey%idx%, %hkey%
Hotkey, %hkey%, DoAction%idx%, On
hotkeys[idx] := hkey
}
if (txt != "ERROR") {
GuiControl,, Text%idx%, %txt%
texts[idx] := txt
}
}
Notetext := "*함수 : 현재시간[%now%] /알람시간[%AlarmTime%] / 남은시간[%mins% : %secs%] /알람간격[%IntervalMin%분]"
Gui, Add, Edit, vNotetextEdit x10 y+10 w900 h30 c00FFFF ReadOnly -E0x200, %Notetext%
Gui, Show, x10 y10 w928 h40, D2R타이머
; 처음 실행 시 핫키 설정 라벨, 입력창들 숨기기
GuiControl, Hide, HotkeyLabel
Loop, 6 {
GuiControl, Hide, Hotkey%A_Index%
GuiControl, Hide, Label%A_Index%
GuiControl, Hide, Text%A_Index%
}
GuiControl,, Button2, 설정 열기 ; 버튼 텍스트도 초기화
SetTimer, UpdateTime, 1000
return
; 시간 표시 업데이트
;global AlarmTime := ""
;global mins := 0
;global secs := 0
UpdateTime:
global AlarmTime, mins, secs, RemainingSeconds, IntervalMin
FormatTime, now,, HH:mm
GuiControl,, TimeText, 현 시간: %now%
if (TimerRunning && (BaseHour != "") && (BaseMinute != ""))
{
FormatTime, NowHour,, HH
FormatTime, NowMinute,, mm
FormatTime, NowSecond,, ss
NowTotalSec := (NowHour * 3600) + (NowMinute * 60) + NowSecond
BaseTotalSec := (BaseHour * 3600) + (BaseMinute * 60)
ElapsedSec := NowTotalSec - BaseTotalSec
if (ElapsedSec < 0)
ElapsedSec += 86400
IntervalSec := IntervalMin * 60
NextAlarmInSec := IntervalSec - Mod(ElapsedSec, IntervalSec)
if (NextAlarmInSec = IntervalSec)
NextAlarmInSec := 0
RemainingSeconds := NextAlarmInSec
mins := Floor(RemainingSeconds / 60)
secs := Mod(RemainingSeconds, 60)
AlarmTimeSec := NowTotalSec + RemainingSeconds
if (AlarmTimeSec >= 86400)
AlarmTimeSec -= 86400
AlarmHour := Floor(AlarmTimeSec / 3600)
AlarmMinute := Floor(Mod(AlarmTimeSec, 3600) / 60)
AlarmTime := Format("{:02}:{:02}", AlarmHour, AlarmMinute)
; 남은 시간과 알람시간 표시
FormatTimeText := Format("알람시간: {:02}:{:02} (간격: {:02}분) 남은시간: {:02}분{:02}초", AlarmHour, AlarmMinute, IntervalMin, mins, secs)
GuiControl,, CountdownText, %FormatTimeText%
if (RemainingSeconds = 0) {
ShowNiceTooltip(IntervalMin " 분 단위 알람! 현재시간:"now)
PlayFancyAlarm()
; ⏭ 다음 알람 계산 즉시 수행
BaseTotalSec := AlarmTimeSec
ElapsedSec := 0
RemainingSeconds := IntervalSec
mins := Floor(RemainingSeconds / 60)
secs := Mod(RemainingSeconds, 60)
AlarmTimeSec := BaseTotalSec + IntervalSec
if (AlarmTimeSec >= 86400)
AlarmTimeSec -= 86400
AlarmHour := Floor(AlarmTimeSec / 3600)
AlarmMinute := Floor(Mod(AlarmTimeSec, 3600) / 60)
AlarmTime := Format("{:02}:{:02}", AlarmHour, AlarmMinute)
FormatTimeText := Format("알람시간: {:02}:{:02} 남은시간: {:02}:{:02}", AlarmHour, AlarmMinute, mins, secs)
GuiControl,, CountdownText, %FormatTimeText%
}
}
/*
else
{
; 타이머가 꺼져 있을 경우
AlarmTime := "알람없음"
mins := 0
secs := 0
RemainingSeconds := 0
GuiControl,, CountdownText, 알람 없음
}
*/
return
ApplyAll: ;;===============================================================적용버튼
Gui, Submit, NoHide
; 기준시간 저장
BaseHour := HourDDL
BaseMinute := MinuteDDL
IntervalMin := IntervalDDL
IniWrite, %BaseHour%, %IniFilePath%, Time, Hour
IniWrite, %BaseMinute%, %IniFilePath%, Time, Minute
IniWrite, %IntervalMin%, %IniFilePath%, Time, Interval
GuiControl,, CountdownText, 기준시간: %BaseHour%:%BaseMinute% (간격: %IntervalMin%분)
GuiControl, Enable, StartBtn
SoundBeep, 600, 300
; 핫키 저장
Loop, 6 {
idx := A_Index
hotkeyVar := Hotkey%idx%
textVar := Text%idx%
if (hotkeyVar != "") {
Hotkey, %hotkeyVar%, DoAction%idx%, On
hotkeys[idx] := hotkeyVar
texts[idx] := textVar
IniWrite, %hotkeyVar%, %IniFilePath%, Hotkeys, Hotkey%idx%
IniWrite, %textVar%, %IniFilePath%, Hotkeys, Text%idx%
}
}
return ;;===============================================================적용버튼
ToggleSettingsSection:
isExpanded := !isExpanded
Loop, 3 {
GuiControl, % isExpanded ? "Show" : "Hide", IntervalLabel%A_Index%
}
GuiControl, % isExpanded ? "Show" : "Hide", HourDDL
GuiControl, % isExpanded ? "Show" : "Hide", MinuteDDL
GuiControl, % isExpanded ? "Show" : "Hide", IntervalDDL
GuiControl, % isExpanded ? "Show" : "Hide", HotkeyLabel
GuiControl, % isExpanded ? "Show" : "Hide", HotkeyLabel1
GuiControl, % isExpanded ? "Show" : "Hide", HotkeyClear1
Loop, 6 {
GuiControl, % isExpanded ? "Show" : "Hide", Label%A_Index%
GuiControl, % isExpanded ? "Show" : "Hide", Text%A_Index%
GuiControl, % isExpanded ? "Show" : "Hide", Hotkey%A_Index% ; 추가된 부분
}
GuiControl, % isExpanded ? "Show" : "Hide", NotetextEdit
GuiControl,, Button2, % isExpanded ? "설정 닫기" : "설정 열기"
Gui, Show, AutoSize
return
StartTimer:
TimerRunning := true
GuiControl, Disable, ApplyBtn
GuiControl, Disable, StartBtn
GuiControl, Enable, StopBtn
SoundBeep, 750, 300
return
StopTimer:
TimerRunning := false
GuiControl, Enable, ApplyBtn
GuiControl, Enable, StartBtn
GuiControl, Disable, StopBtn
GuiControl,, CountdownText, 기준시간 적용 필요
SoundBeep, 400, 300
return
ExitApp1:
ExitApp
return
LoopList(min, max) {
list := ""
Loop % (max - min + 1)
list .= (A_Index - 1 + min) "|"
return list
}
ShowNiceTooltip(msg) {
static TooltipGuiExists := false
if (TooltipGuiExists)
Gui, TooltipGuiID: Destroy
TooltipGuiExists := true
Gui, TooltipGuiID: New, +AlwaysOnTop -Caption +ToolWindow +E0x20 +E0x80000 +LastFound
Gui, TooltipGuiID: Color, 59227C
WinSet, Transparent, 127
Gui, TooltipGuiID: Font, s12 Bold, Segoe UI
Gui, TooltipGuiID: Add, Text, cffffff BackgroundTrans Center hwndhText, %msg%
GuiControlGet, Pos, TooltipGuiID: Pos, %hText%
textWidth := PosW + 20
textHeight := PosH + 20
xPos := (A_ScreenWidth - textWidth) / 2
yPos := 80
WinSet, Region, 0-0 W%textWidth% H%textHeight% R10-10, ahk_id %hText%
Gui, TooltipGuiID: Show, x%xPos% y%yPos% w%textWidth% h%textHeight% NoActivate
SetTimer, RemoveSplash, -5000
}
RemoveSplash:
Gui, TooltipGuiID: Destroy
return
PlayFancyAlarm() {
freqs := [800, 1000, 1200, 1400, 1600]
for index, freq in freqs {
SoundBeep, %freq%, 100
Sleep, 50
}
Sleep, 200
freqs := [1600, 1400, 1200, 1000, 800]
for index, freq in freqs {
SoundBeep, %freq%, 100
Sleep, 50
}
Sleep, 200
SoundBeep, 1500, 200
Sleep, 100
SoundBeep, 700, 400
}
DoAction1:
if (texts[1] != "")
HandleHotkey(texts[1])
return
DoAction2:
if (texts[2] != "")
HandleHotkey(texts[2])
return
DoAction3:
if (texts[3] != "")
HandleHotkey(texts[3])
return
DoAction4:
if (texts[4] != "")
HandleHotkey(texts[4])
return
DoAction5:
if (texts[5] != "")
HandleHotkey(texts[5])
return
DoAction6:
if (texts[6] != "")
HandleHotkey(texts[6])
return
HandleHotkey(text) {
FormatTime, now,, HH:mm
expandedText := text
expandedText := StrReplace(expandedText, "%now%", now)
expandedText := StrReplace(expandedText, "%AlarmTime%", AlarmTime)
expandedText := StrReplace(expandedText, "%mins%", mins)
expandedText := StrReplace(expandedText, "%secs%", secs)
expandedText := StrReplace(expandedText, "%RemainingSeconds%", RemainingSeconds)
expandedText := StrReplace(expandedText, "%IntervalMin%", IntervalMin)
Clipboard := expandedText
;Run, notepad.exe
;WinWaitActive, ahk_class Notepad
Send, {Enter}
Sleep, 200
Send, ^v
Sleep, 200
Send, {Enter}
}
ClearHotkey:
loop, 6 {
idx := A_Index
; GUI에서 현재 핫키 가져오기
GuiControlGet, currentHotkey,, Hotkey%idx%
; 기존 핫키 비활성화 (예외 처리)
if (currentHotkey != "") {
try {
Hotkey, %currentHotkey%, Off
}
}
; GUI 초기화
GuiControl,, Hotkey%idx%,
; INI 초기화
IniWrite, % "", %IniFilePath%, Hotkeys, Hotkey%idx%
; 변수 초기화
hotkeys[idx] := ""
}
return
UpdateHotkeyLabel:
Gui, Submit, NoHide
Loop, 6 {
GuiControlGet, currentHotkey,, Hotkey%A_Index%
if (currentHotkey != "") {
newText := "텍스트 " A_Index " (" currentHotkey ")"
} else {
newText := "텍스트 " A_Index
}
GuiControl,, Label%A_Index%, %newText%
}
return
;gui마우스이동 함수
WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) {
MouseGetPos,,, ControlUnderMouse
; 컨트롤 이름을 얻어서, 버튼들 클릭한 경우에는 이동 금지
if (ControlUnderMouse ~= "^(Buttond*)?$") ; 버튼 이름(Button1, Button2 등)일 경우
return
PostMessage, 0xA1, 2,,, A
}