#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ListViewConstants.au3>
#include <GuiListView.au3>
#include <Array.au3>
#include <SQLite.au3>
#include <SQLite.dll.au3>
; 전역 변수
Global $hGUI, $hListView, $hListViewFavorites, $aClipHistory[11], $iHistoryCount = 0
Global $sLastClip = "", $hTimer, $bAlwaysOnTop = True
Global $hBtnCopy, $hBtnClear, $hBtnHide, $hBtnExit, $hBtnToggleTop, $hBtnAddFav, $hBtnRemoveFav
Global $hTab, $hTabItem1, $hTabItem2
Global $hDB, $sDBPath = @ScriptDir & "\clipboard_history.db"
; 클립보드 히스토리 배열 초기화
For $i = 0 To 10
$aClipHistory[$i] = ""
Next
; SQLite 초기화
InitDatabase()
; GUI 생성
CreateGUI()
; 즐겨찾기 목록 로드
LoadFavorites()
; 타이머 설정 (500ms마다 클립보드 체크)
$hTimer = TimerInit()
; 메인 루프
While 1
; 500ms마다 클립보드 체크
If TimerDiff($hTimer) > 500 Then
CheckClipboard()
$hTimer = TimerInit()
EndIf
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE, $hBtnExit
CleanupAndExit()
Case $GUI_EVENT_MINIMIZE, $hBtnHide
; 최소화시 트레이로 숨김
GUISetState(@SW_HIDE, $hGUI)
Case $hBtnCopy
CopySelectedItem()
Case $hBtnClear
ClearAllHistory()
Case $hBtnToggleTop
ToggleAlwaysOnTop()
Case $hBtnAddFav
AddToFavorites()
Case $hBtnRemoveFav
RemoveFromFavorites()
Case Else
; 리스트뷰 더블클릭 체크
CheckListViewClick()
EndSwitch
Sleep(10)
WEnd
; SQLite 데이터베이스 초기화
Func InitDatabase()
_SQLite_Startup()
If @error Then
MsgBox(16, "오류", "SQLite 초기화 실패")
Exit
EndIf
$hDB = _SQLite_Open($sDBPath)
If $hDB = -1 Then
MsgBox(16, "오류", "데이터베이스 열기 실패")
Exit
EndIf
; 테이블 생성
Local $sQuery = "CREATE TABLE IF NOT EXISTS favorites (" & _
"id INTEGER PRIMARY KEY AUTOINCREMENT, " & _
"content TEXT UNIQUE NOT NULL, " & _
"use_count INTEGER DEFAULT 1, " & _
"first_used DATETIME DEFAULT CURRENT_TIMESTAMP, " & _
"last_used DATETIME DEFAULT CURRENT_TIMESTAMP, " & _
"created_at DATETIME DEFAULT CURRENT_TIMESTAMP)"
_SQLite_Exec($hDB, $sQuery)
EndFunc
; GUI 생성 함수
Func CreateGUI()
$hGUI = GUICreate("클립보드 히스토리 관리자", 600, 500, -1, -1, $WS_OVERLAPPEDWINDOW, $WS_EX_TOPMOST)
; 탭 컨트롤 생성
$hTab = GUICtrlCreateTab(10, 10, 580, 420)
; 탭 1: 최근 히스토리
$hTabItem1 = GUICtrlCreateTabItem("최근 히스토리")
$hListView = GUICtrlCreateListView("번호|시간|내용", 20, 40, 560, 300, _
BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS))
; 컬럼 너비 설정
_GUICtrlListView_SetColumnWidth($hListView, 0, 50) ; 번호
_GUICtrlListView_SetColumnWidth($hListView, 1, 80) ; 시간
_GUICtrlListView_SetColumnWidth($hListView, 2, 420) ; 내용
; 탭 2: 즐겨찾기
$hTabItem2 = GUICtrlCreateTabItem("즐겨찾기 (Top 20)")
$hListViewFavorites = GUICtrlCreateListView("순위|사용횟수|마지막사용|내용", 20, 40, 560, 300, _
BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS))
; 즐겨찾기 컬럼 너비 설정
_GUICtrlListView_SetColumnWidth($hListViewFavorites, 0, 50) ; 순위
_GUICtrlListView_SetColumnWidth($hListViewFavorites, 1, 80) ; 사용횟수
_GUICtrlListView_SetColumnWidth($hListViewFavorites, 2, 100) ; 마지막사용
_GUICtrlListView_SetColumnWidth($hListViewFavorites, 3, 320) ; 내용
GUICtrlCreateTabItem("") ; 탭 종료
; 버튼들
$hBtnCopy = GUICtrlCreateButton("선택한 항목 복사", 20, 440, 100, 25)
$hBtnAddFav = GUICtrlCreateButton("즐겨찾기 추가", 130, 440, 100, 25)
$hBtnRemoveFav = GUICtrlCreateButton("즐겨찾기 삭제", 240, 440, 100, 25)
$hBtnClear = GUICtrlCreateButton("전체 삭제", 350, 440, 80, 25)
$hBtnToggleTop = GUICtrlCreateButton("항상 위 ✓", 440, 440, 80, 25)
$hBtnHide = GUICtrlCreateButton("숨기기", 530, 440, 60, 25)
$hBtnExit = GUICtrlCreateButton("종료", 530, 470, 60, 25)
; 상태표시줄
GUICtrlCreateLabel("클립보드 변화를 모니터링 중... | Ctrl+Shift+V: 토글 | Tab으로 전환", 20, 475, 400, 20)
GUISetState(@SW_SHOW, $hGUI)
; 핫키 등록 (Ctrl+Shift+V로 창 보이기/숨기기)
HotKeySet("^+v", "ToggleGUI")
EndFunc
; 클립보드 체크 함수
Func CheckClipboard()
Local $sCurrentClip = ClipGet()
; 클립보드가 변경되었고, 이전과 다르며, 빈 문자열이 아닌 경우
If $sCurrentClip <> $sLastClip And $sCurrentClip <> "" And StringLen($sCurrentClip) > 0 Then
AddToHistory($sCurrentClip)
$sLastClip = $sCurrentClip
EndIf
EndFunc
; 히스토리에 추가하는 함수
Func AddToHistory($sClipText)
; 이미 같은 내용이 있는지 체크하여 중복 제거
For $i = 1 To $iHistoryCount
If $aClipHistory[$i] = $sClipText Then
; 중복이면 해당 항목을 맨 위로 이동
MoveToTop($i)
UpdateListView()
Return
EndIf
Next
; 배열을 한 칸씩 뒤로 밀기
For $i = 10 To 2 Step -1
$aClipHistory[$i] = $aClipHistory[$i-1]
Next
; 새 항목을 첫 번째에 추가
$aClipHistory[1] = $sClipText
; 카운트 증가 (최대 10)
If $iHistoryCount < 10 Then
$iHistoryCount += 1
EndIf
UpdateListView()
EndFunc
; 항목을 맨 위로 이동
Func MoveToTop($iIndex)
Local $sTemp = $aClipHistory[$iIndex]
For $i = $iIndex To 2 Step -1
$aClipHistory[$i] = $aClipHistory[$i-1]
Next
$aClipHistory[1] = $sTemp
EndFunc
; 리스트뷰 업데이트
Func UpdateListView()
_GUICtrlListView_DeleteAllItems($hListView)
For $i = 1 To $iHistoryCount
Local $sTime = @HOUR & ":" & @MIN & ":" & @SEC
Local $sContent = StringLeft($aClipHistory[$i], 120) ; 120자로 제한
If StringLen($aClipHistory[$i]) > 120 Then $sContent &= "..."
; 개행문자를 공백으로 치환하여 한 줄로 표시
$sContent = StringReplace($sContent, @CRLF, " ")
$sContent = StringReplace($sContent, @LF, " ")
$sContent = StringReplace($sContent, @CR, " ")
_GUICtrlListView_AddItem($hListView, $i & "|" & $sTime & "|" & $sContent)
Next
EndFunc
; 즐겨찾기 로드
Func LoadFavorites()
_GUICtrlListView_DeleteAllItems($hListViewFavorites)
Local $aResult, $iRows, $iColumns
Local $sQuery = "SELECT content, use_count, last_used FROM favorites ORDER BY use_count DESC, last_used DESC LIMIT 20"
_SQLite_GetTable2d($hDB, $sQuery, $aResult, $iRows, $iColumns)
If $iRows > 0 Then
For $i = 1 To $iRows
Local $sContent = StringLeft($aResult[$i][0], 100)
If StringLen($aResult[$i][0]) > 100 Then $sContent &= "..."
; 개행문자 처리
$sContent = StringReplace($sContent, @CRLF, " ")
$sContent = StringReplace($sContent, @LF, " ")
$sContent = StringReplace($sContent, @CR, " ")
Local $sLastUsed = StringLeft($aResult[$i][2], 16) ; YYYY-MM-DD HH:MM
_GUICtrlListView_AddItem($hListViewFavorites, $i & "|" & $aResult[$i][1] & "|" & $sLastUsed & "|" & $sContent)
Next
EndIf
EndFunc
; 즐겨찾기에 추가
Func AddToFavorites()
Local $iCurrentTab = _GUICtrlTab_GetCurSel($hTab)
Local $sContent = ""
If $iCurrentTab = 0 Then ; 최근 히스토리 탭
Local $iSelected = _GUICtrlListView_GetSelectedIndices($hListView)
If $iSelected <> "" Then
Local $iIndex = Int($iSelected) + 1
If $iIndex >= 1 And $iIndex <= $iHistoryCount Then
$sContent = $aClipHistory[$iIndex]
EndIf
EndIf
Else ; 즐겨찾기 탭
ShowTooltip("즐겨찾기 탭에서는 추가할 수 없습니다.")
Return
EndIf
If $sContent = "" Then
ShowTooltip("추가할 항목을 선택해주세요.")
Return
EndIf
; 이미 즐겨찾기에 있는지 확인
Local $aResult, $iRows, $iColumns
Local $sQuery = "SELECT id, use_count FROM favorites WHERE content = ?"
_SQLite_Query($hDB, $sQuery, $aResult)
_SQLite_QueryBindText($aResult, 1, $sContent)
If _SQLite_QueryStep($aResult) = $SQLITE_ROW Then
; 이미 존재하면 사용횟수 증가
Local $iUseCount = _SQLite_QueryGetText($aResult, 1) + 1
_SQLite_QueryFinalize($aResult)
$sQuery = "UPDATE favorites SET use_count = ?, last_used = CURRENT_TIMESTAMP WHERE content = ?"
_SQLite_Exec($hDB, $sQuery, $iUseCount, $sContent)
ShowTooltip("즐겨찾기 사용횟수가 증가했습니다! (" & $iUseCount & ")")
Else
; 새로 추가
_SQLite_QueryFinalize($aResult)
$sQuery = "INSERT INTO favorites (content) VALUES (?)"
_SQLite_Exec($hDB, $sQuery, $sContent)
ShowTooltip("즐겨찾기에 추가되었습니다!")
EndIf
LoadFavorites()
EndFunc
; 즐겨찾기에서 삭제
Func RemoveFromFavorites()
Local $iCurrentTab = _GUICtrlTab_GetCurSel($hTab)
If $iCurrentTab <> 1 Then ; 즐겨찾기 탭이 아니면
ShowTooltip("즐겨찾기 탭에서만 삭제할 수 있습니다.")
Return
EndIf
Local $iSelected = _GUICtrlListView_GetSelectedIndices($hListViewFavorites)
If $iSelected = "" Then
ShowTooltip("삭제할 항목을 선택해주세요.")
Return
EndIf
; 선택된 항목의 내용 가져오기
Local $sSelectedText = _GUICtrlListView_GetItemText($hListViewFavorites, Int($iSelected), 3)
; DB에서 해당 내용 찾기
Local $aResult, $iRows, $iColumns
Local $sQuery = "SELECT content FROM favorites ORDER BY use_count DESC, last_used DESC LIMIT 20"
_SQLite_GetTable2d($hDB, $sQuery, $aResult, $iRows, $iColumns)
If $iRows > Int($iSelected) Then
Local $sFullContent = $aResult[Int($iSelected) + 1][0]
Local $iResult = MsgBox(4, "확인", "선택한 즐겨찾기를 삭제하시겠습니까?" & @CRLF & @CRLF & StringLeft($sFullContent, 100))
If $iResult = 6 Then ; Yes
$sQuery = "DELETE FROM favorites WHERE content = ?"
_SQLite_Exec($hDB, $sQuery, $sFullContent)
ShowTooltip("즐겨찾기에서 삭제되었습니다.")
LoadFavorites()
EndIf
EndIf
EndFunc
; 선택한 항목 복사
Func CopySelectedItem()
Local $iCurrentTab = _GUICtrlTab_GetCurSel($hTab)
Local $sContent = ""
If $iCurrentTab = 0 Then ; 최근 히스토리 탭
Local $iSelected = _GUICtrlListView_GetSelectedIndices($hListView)
If $iSelected <> "" Then
Local $iIndex = Int($iSelected) + 1
If $iIndex >= 1 And $iIndex <= $iHistoryCount Then
$sContent = $aClipHistory[$iIndex]
MoveToTop($iIndex)
UpdateListView()
EndIf
EndIf
Else ; 즐겨찾기 탭
Local $iSelected = _GUICtrlListView_GetSelectedIndices($hListViewFavorites)
If $iSelected <> "" Then
; DB에서 실제 내용 가져오기
Local $aResult, $iRows, $iColumns
Local $sQuery = "SELECT content FROM favorites ORDER BY use_count DESC, last_used DESC LIMIT 20"
_SQLite_GetTable2d($hDB, $sQuery, $aResult, $iRows, $iColumns)
If $iRows > Int($iSelected) Then
$sContent = $aResult[Int($iSelected) + 1][0]
; 사용횟수 증가
$sQuery = "UPDATE favorites SET use_count = use_count + 1, last_used = CURRENT_TIMESTAMP WHERE content = ?"
_SQLite_Exec($hDB, $sQuery, $sContent)
LoadFavorites()
EndIf
EndIf
EndIf
If $sContent <> "" Then
ClipPut($sContent)
ShowTooltip("클립보드에 복사되었습니다!")
Else
ShowTooltip("복사할 항목을 선택해주세요.")
EndIf
EndFunc
; 전체 히스토리 삭제
Func ClearAllHistory()
Local $iCurrentTab = _GUICtrlTab_GetCurSel($hTab)
If $iCurrentTab = 0 Then ; 최근 히스토리
Local $iResult = MsgBox(4, "확인", "모든 최근 히스토리를 삭제하시겠습니까?")
If $iResult = 6 Then ; Yes
For $i = 0 To 10
$aClipHistory[$i] = ""
Next
$iHistoryCount = 0
UpdateListView()
ShowTooltip("모든 최근 히스토리가 삭제되었습니다.")
EndIf
Else ; 즐겨찾기
Local $iResult = MsgBox(4, "확인", "모든 즐겨찾기를 삭제하시겠습니까?")
If $iResult = 6 Then ; Yes
_SQLite_Exec($hDB, "DELETE FROM favorites")
LoadFavorites()
ShowTooltip("모든 즐겨찾기가 삭제되었습니다.")
EndIf
EndIf
EndFunc
; 항상 위 토글
Func ToggleAlwaysOnTop()
$bAlwaysOnTop = Not $bAlwaysOnTop
If $bAlwaysOnTop Then
WinSetOnTop($hGUI, "", 1)
GUICtrlSetData($hBtnToggleTop, "항상 위 ✓")
Else
WinSetOnTop($hGUI, "", 0)
GUICtrlSetData($hBtnToggleTop, "항상 위 ✗")
EndIf
ShowTooltip("항상 위 모드: " & ($bAlwaysOnTop ? "ON" : "OFF"))
EndFunc
; 툴팁 표시
Func ShowTooltip($sMessage)
ToolTip($sMessage, MouseGetPos(0), MouseGetPos(1))
Sleep(1500)
ToolTip("")
EndFunc
; 리스트뷰 클릭 체크
Func CheckListViewClick()
Local $aInfo = GUIGetCursorInfo($hGUI)
Local $iCurrentTab = _GUICtrlTab_GetCurSel($hTab)
If ($aInfo[4] = $hListView Or $aInfo[4] = $hListViewFavorites) And $aInfo[2] = 1 Then ; 더블클릭
CopySelectedItem()
EndIf
EndFunc
; GUI 토글 함수 (핫키용)
Func ToggleGUI()
If BitAND(WinGetState($hGUI), 2) Then ; 창이 보이는 상태
GUISetState(@SW_HIDE, $hGUI)
Else
GUISetState(@SW_SHOW, $hGUI)
; 최상위로 설정하고 활성화
WinSetOnTop($hGUI, "", 1)
WinActivate($hGUI)
WinSetState($hGUI, "", @SW_RESTORE) ; 최소화 상태에서 복원
EndIf
EndFunc
; 정리 및 종료
Func CleanupAndExit()
_SQLite_Close($hDB)
_SQLite_Shutdown()
HotKeySet("^+v") ; 핫키 해제
Exit
EndFunc
; 종료시 정리
OnAutoItExitRegister("CleanupAndExit")