메뉴 여닫기
개인 메뉴 토글
로그인하지 않음
만약 지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

Carlet 읽기 -winapi 이용

데브카페

Carlet 읽기 -winapi 이용

#include <WinAPI.au3>
#include <SendMessage.au3>
#include <GuiEdit.au3>

; ====== 메시지 상수 정의 ======
;~ Global Const $EM_GETSEL       = 0x00B0
;~ Global Const $EM_LINEFROMCHAR = 0x00C9
;~ Global Const $EM_LINEINDEX    = 0x00BB
;~ Global Const $EM_LINELENGTH   = 0x00C1

; ====== 핫키 등록 (Ctrl+Shift+R : 캐럿 텍스트 읽기) ======
HotKeySet("^+r", "ReadCaretText")
ConsoleWrite("아무 편집창에서나 커서를 원하는 위치에 두신 후 Ctrl+Shift+R을 눌러주세요." & @CRLF)
ConsoleWrite("종료하려면 Ctrl+Shift+X를 누르세요." & @CRLF)
HotKeySet("^+x", "_Exit")

While 1
    Sleep(100)
WEnd

Func _Exit()
    Exit
EndFunc

; ====== 캐럿 위치 텍스트 읽기 메인 함수 ======
Func ReadCaretText()
    ; 1. 현재 활성(최상위) 윈도우 핸들
    Local $hWin = WinGetHandle("[ACTIVE]")
    If @error Or $hWin = 0 Then
        MsgBox(16, "오류", "활성 윈도우를 찾을 수 없습니다.")
        Return
    EndIf

    ; 2. 캐럿(키보드 포커스)이 위치한 실제 컨트롤 핸들 구하기 (다른 프로세스도 지원)
    Local $hEdit = _GetFocusedControlHandle()
    If $hEdit = 0 Then
        MsgBox(16, "오류", "포커스된 컨트롤을 찾을 수 없습니다.")
        Return
    EndIf

    ; 3. 현재 캐럿(커서) 위치 가져오기 - EM_GETSEL
    Local $iResult = _SendMessage($hEdit, $EM_GETSEL, 0, 0, 0, "int", "int", "int")
    Local $iCaretPos = BitAND($iResult, 0xFFFF)  ; LOWORD 추출 = 캐럿 위치

    ; 4. 캐럿이 위치한 줄 번호 확인
    Local $iLineIndex = _SendMessage($hEdit, $EM_LINEFROMCHAR, $iCaretPos, 0)

    ; 5. 해당 줄의 시작 문자 위치(offset) 확인
    Local $iLineStart = _SendMessage($hEdit, $EM_LINEINDEX, $iLineIndex, 0)

    ; 6. 해당 줄의 길이 확인
    Local $iLineLength = _SendMessage($hEdit, $EM_LINELENGTH, $iLineStart, 0)

    ; 7. 전체 텍스트를 가져와서 해당 줄만 추출
    Local $sFullText = ControlGetText($hWin, "", $hEdit)
    Local $sLineText = StringMid($sFullText, $iLineStart + 1, $iLineLength)

    ; 8. 현재 단어도 함께 추출
    Local $sWord = GetWordAtPosition($sFullText, $iCaretPos)

    ; 결과 출력
    ConsoleWrite("=== 캐럿 위치 정보 ===" & @CRLF)
    ConsoleWrite("윈도우 핸들: " & $hWin & @CRLF)
    ConsoleWrite("컨트롤 핸들: " & $hEdit & @CRLF)
    ConsoleWrite("줄 번호: " & ($iLineIndex + 1) & @CRLF)
    ConsoleWrite("캐럿 위치(전체 기준): " & $iCaretPos & @CRLF)
    ConsoleWrite("현재 줄 텍스트: " & $sLineText & @CRLF)
    ConsoleWrite("현재 단어: " & $sWord & @CRLF)
    ConsoleWrite("=====================" & @CRLF & @CRLF)

    ; 툴팁으로도 표시
    ToolTip("줄: " & $sLineText & @CRLF & "단어: " & $sWord, MouseGetPos(0), MouseGetPos(1) - 60)
    Sleep(2000)
    ToolTip("")
EndFunc

; ====== 캐럿(키보드 포커스)이 위치한 실제 컨트롤 핸들 구하기 ======
; GetGUIThreadInfo API는 다른 프로세스의 스레드 정보도 가져올 수 있어서
; 활성 프로그램이 메모장이 아니어도 동작합니다.
Func _GetFocusedControlHandle()
    Local $hActive = _WinAPI_GetForegroundWindow()
    If @error Or $hActive = 0 Then Return 0

    Local $aCall = DllCall("user32.dll", "dword", "GetWindowThreadProcessId", "hwnd", $hActive, "ptr", 0)
    If @error Then Return 0
    Local $iThreadId = $aCall[0]

    Local $tGUI = DllStructCreate( _
            "dword cbSize;" & _
            "dword flags;" & _
            "hwnd hwndActive;" & _
            "hwnd hwndFocus;" & _
            "hwnd hwndCapture;" & _
            "hwnd hwndMenuOwner;" & _
            "hwnd hwndMoveSize;" & _
            "hwnd hwndCaret;" & _
            "long left;long top;long right;long bottom")
    DllStructSetData($tGUI, "cbSize", DllStructGetSize($tGUI))

    Local $aResult = DllCall("user32.dll", "bool", "GetGUIThreadInfo", _
            "dword", $iThreadId, "ptr", DllStructGetPtr($tGUI))
    If @error Or Not $aResult[0] Then Return 0

    Local $hFocus = DllStructGetData($tGUI, "hwndFocus")
    If $hFocus = 0 Then $hFocus = $hActive ; 포커스 정보가 없으면 활성 윈도우 자체를 사용

    Return $hFocus
EndFunc

; ====== 특정 위치의 단어 추출 함수 ======
Func GetWordAtPosition($sText, $iPos)
    Local $iStart = $iPos
    Local $iEnd = $iPos
    While $iStart > 0
        Local $sChar = StringMid($sText, $iStart, 1)
        If $sChar = " " Or $sChar = @CR Or $sChar = @LF Or $sChar = @TAB Then
            ExitLoop
        EndIf
        $iStart -= 1
    WEnd
    While $iEnd < StringLen($sText)
        Local $sChar = StringMid($sText, $iEnd + 1, 1)
        If $sChar = " " Or $sChar = @CR Or $sChar = @LF Or $sChar = @TAB Then
            ExitLoop
        EndIf
        $iEnd += 1
    WEnd
    Return StringMid($sText, $iStart + 1, $iEnd - $iStart)
EndFunc

Comments