문서 편집 권한이 없습니다. 다음 이유를 확인해주세요:
요청한 명령은 다음 권한을 가진 사용자에게 제한됩니다: 사용자.
== Windows 에서 커서(Caret)가 위치 텍스트 출력 프로그램 == * Windows 에서 캐럿(커서) 위치의 텍스트를 출력하는 C++과 AutoIt ,Python 소스 예제입니다. === C++ 버전 === <source lang=c> #include <windows.h> #include <iostream> #include <string> std::string GetTextAroundCaret(HWND hWnd) { DWORD startPos, endPos; CHAR buffer[1024] = {0}; // 현재 포커스가 있는 윈도우 핸들 가져오기 if (hWnd == NULL) { hWnd = GetFocus(); } // Edit 컨트롤인지 확인 char className[256]; GetClassNameA(hWnd, className, sizeof(className)); if (strcmp(className, "Edit") != 0) { return "Not an Edit control"; } // 현재 선택 영역 가져오기 SendMessageA(hWnd, EM_GETSEL, (WPARAM)&startPos, (LPARAM)&endPos); // 텍스트 길이 가져오기 int textLength = GetWindowTextLengthA(hWnd); // 전체 텍스트 가져오기 GetWindowTextA(hWnd, buffer, textLength + 1); // 캐럿 주변 텍스트 추출 (예: 캐럿 앞 10자, 뒤 10자) int start = max(0, (int)startPos - 10); int end = min(textLength, (int)startPos + 10); return std::string(buffer + start, buffer + end); } int main() { std::cout << "Caret 위치 텍스트를 가져오는 프로그램 (10초간 실행)" << std::endl; for (int i = 0; i < 10; i++) { HWND foregroundWindow = GetForegroundWindow(); HWND focusWindow = GetFocus(); std::string text = GetTextAroundCaret(focusWindow); std::cout << "Caret 주변 텍스트: " << text << std::endl; Sleep(1000); // 1초 대기 } return 0; } </source> === AutoIt 버전 === <source lang=autoit> #include <WinAPI.au3> #include <EditConstants.au3> #include <Math.au3> Func GetCaretText() Local $hWnd = _WinAPI_GetFocus() If $hWnd = 0 Then Return "포커스된 창이 없습니다." ; 클래스 이름 확인 Local $sClass = _WinAPI_GetClassName($hWnd) If $sClass <> "Edit" Then Return "Edit 컨트롤이 아닙니다: " & $sClass ; 현재 선택 위치 가져오기 Local $iStart = _SendMessage($hWnd, $EM_GETSEL) Local $iEnd = BitShift($iStart, 16) $iStart = BitAND($iStart, 0xFFFF) ; 전체 텍스트 가져오기 Local $sText = ControlGetText("[ACTIVE]", "", $hWnd) If @error Then Return "텍스트를 가져올 수 없습니다." ; 캐럿 주변 텍스트 추출 (앞 10자, 뒤 10자) Local $iTextLen = StringLen($sText) Local $iFrom = _Max(0, $iStart - 10) Local $iTo = _Min($iTextLen, $iStart + 10) Return StringMid($sText, $iFrom + 1, $iTo - $iFrom) EndFunc ; 메인 프로그램 ToolTip("캐럿 위치 텍스트를 가져오는 AutoIt 프로그램 (10초간 실행)", 0, 0) For $i = 1 To 10 Local $sText = GetCaretText() ConsoleWrite("캐럿 주변 텍스트: " & $sText & @CRLF) Sleep(1000) Next Exit </source> === 프로그램 사용 방법 === ** C++ 버전: **: - Visual Studio 등으로 컴파일 후 실행 **: - 10초 동안 1초 간격으로 포커스된 Edit 컨트롤의 캐럿 위치 주변 텍스트 출력 **: ** AutoIt 버전: **: - AutoIt 스크립트로 저장 후 실행 ++: - 10초 동안 1초 간격으로 콘솔에 캐럿 위치 주변 텍스트 출력 === 주의 사항 === :- 이 프로그램은 표준 Edit 컨트롤에서만 작동합니다. :- RichEdit, Chrome, 워드프로세서 등 다른 컨트롤에서는 작동하지 않을 수 있습니다. :- 관리자 권한이 필요한 경우도 있을 수 있습니다. === Python 버전 === * pywin32 라이브러리 (pip install pywin32) 설치 <source lang=python> pip install pywinauto keyboard import sys import threading import time import tkinter as tk from tkinter import ttk import keyboard import pywinauto from pywinauto.keyboard import send_keys class CaretReaderApp: def __init__(self, root): self.root = root self.root.title("Caret Reader v1.1") self.root.geometry("320x130") self.root.attributes("-topmost", True) # 창을 항상 위에 유지 self.root.resizable(False, False) # UI 스타일 설정 style = ttk.Style() style.theme_use("clam") # UI 요소 배치 self.label_info = ttk.Label(root, text="[Ctrl + Shift + F12]를 누르면\n커서 위치의 문자를 읽습니다.", justify="center", font=("Malgun Gothic", 10)) self.label_info.pack(pady=12) self.label_result = ttk.Label(root, text="읽은 문자: 없음", font=("Malgun Gothic", 12, "bold"), foreground="#0078D7") self.label_result.pack(pady=5) # 단축키 리스너 등록 (데몬 스레드) self.hotkey_thread = threading.Thread(target=self.setup_hotkey, daemon=True) self.hotkey_thread.start() def setup_hotkey(self): # 전역 단축키 매핑 keyboard.add_hotkey("ctrl+shift+f12", self.trigger_caret_reading) keyboard.wait() def trigger_caret_reading(self): # 무거운 키보드/UI 매크로 작업 시 GUI 멈춤을 방지하기 위해 스레드 분리 threading.Thread(target=self.read_caret_pipeline, daemon=True).start() def read_caret_pipeline(self): print("\n[이벤트] 단축키 감지! 커서 위치 분석 시작...") # 1단계: 정석적인 UI Automation (UIA) 시도 character = self.try_uia_backend() # 2단계: UIA 실패 시, 질문하신 '커서 + 라이트키 + 클립보드' 매크로 보안책 가동 if not character: print("[UIA 실패] -> 커서 + Right Key 매크로 우회(Fallback)를 시작합니다.") character = self.try_cursor_right_fallback() # GUI 화면 레이블 업데이트 if character and character.strip() != "": cleaned_char = character.replace("\n", "\\n").replace("\r", "\\r") self.root.after(0, lambda: self.label_result.config(text=f"읽은 문자: '{cleaned_char}'")) print(f"[성공] 최종 가져온 문자: '{cleaned_char}'") else: self.root.after(0, lambda: self.label_result.config(text="읽은 문자: 추출 실패")) print("[실패] 문자를 읽지 못했습니다.") def try_uia_backend(self): try: # 활성화된 앱 내부에서 포커스된 컨트롤 찾기 app = pywinauto.Application(backend="uia").connect(active_only=True) focused_control = app.top_window().set_focus() text_pattern = focused_control.get_text_block() selection = text_pattern.get_selection() if selection: caret_range = selection caret_range.expand_to_enclosing_unit("Character") return caret_range.get_text() except Exception as e: # UIA를 안 만들어둔 일반 창이나 게임 등에서는 예외 발생 -> 자연스럽게 폴백으로 이동 pass return None def try_cursor_right_fallback(self): try: import win32clipboard # 기존 클립보드 문자열 백업 (유저 데이터 보호) original_text = "" try: win32clipboard.OpenClipboard() if win32clipboard.IsClipboardFormatAvailable(win32clipboard.CF_UNICODETEXT): original_text = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT) win32clipboard.CloseClipboard() except Exception: pass # 1. 클립보드를 깔끔하게 비우기 (이전 데이터 오염 방지) win32clipboard.OpenClipboard() win32clipboard.EmptyClipboard() win32clipboard.CloseClipboard() # 2. Shift + Right Arrow 전송 (커서 기준 오른쪽 한 글자 블록 선택) send_keys("+{RIGHT}") time.sleep(0.06) # 타겟 프로그램이 텍스트 선택 영역을 갱신할 시간 부여 # 3. Ctrl + C 전송 (복사) send_keys("^c") time.sleep(0.06) # 클립보드에 데이터가 올라갈 때까지 대기 # 4. 클립보드에서 가로챈 문자열 열기 target_char = None win32clipboard.OpenClipboard() try: if win32clipboard.IsClipboardFormatAvailable(win32clipboard.CF_UNICODETEXT): target_char = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT) except Exception as ce: print(f"클립보드 읽기 에러: {ce}") finally: win32clipboard.CloseClipboard() # 5. Left Arrow 전송 (블록 지정을 풀고 원래 커서 위치로 원위치 복구) send_keys("{LEFT}") time.sleep(0.02) # 6. 백업해 뒀던 원래 유저의 클립보드 데이터 복원 if original_text: try: win32clipboard.OpenClipboard() win32clipboard.EmptyClipboard() win32clipboard.SetClipboardText(original_text, win32clipboard.CF_UNICODETEXT) win32clipboard.CloseClipboard() except Exception: pass return target_char except Exception as e: print(f"매크로 로직 내부 에러: {e}") return None if __name__ == "__main__": # OS 전역 키 입력을 제어하므로 반드시 '관리자 권한'으로 실행해야 끊김이 없습니다. root = tk.Tk() app = CaretReaderApp(root) root.mainloop() </source> ==== 코드 설명 ==== * 필요한 모듈: pywin32를 사용하여 Windows API를 호출합니다. * 포커스된 창 확인: GetForegroundWindow로 현재 포커스된 창의 핸들을 가져옵니다. * 텍스트 컨트롤 확인: 창의 클래스 이름이 Edit 또는 RichEdit인지 확인하여 텍스트 입력 창인지 판단합니다. * 텍스트 가져오기: WM_GETTEXT 메시지로 창의 전체 텍스트를 가져오고, EM_GETSEL 메시지로 캐럿의 시작/끝 위치를 가져옵니다. * 캐럿 주변 텍스트 추출: 캐럿 위치를 기준으로 앞뒤 10자 내의 텍스트를 추출합니다. * 실행: 프로그램 실행 후 5초 대기하여 사용자가 원하는 텍스트 창(예: 메모장)에 포커스를 맞출 시간을 줍니다. ==== 사용 방법 ==== * Python 환경에 pywin32를 설치합니다: pip install pywin32 *: 위 코드를 .py 파일로 저장합니다(예:caret_text.py). * 메모장이나 다른 텍스트 편집기(예: Notepad++, Word 등)를 열고 텍스트를 입력한 뒤 커서를 원하는 위치에 놓습니다. * 코드를 실행하면 5초 후 현재 캐럿 위치 주변의 텍스트와 전체 텍스트를 출력합니다. ==== 주의사항 ==== * 이 코드는 Windows의 기본 텍스트 편집 컨트롤(Edit, RichEdit)에서 작동합니다. 일부 응용프로그램(예: 웹 브라우저의 텍스트 입력란)은 다른 방식으로 구현될 수 있어 작동하지 않을 수 있습니다. * 웹 브라우저나 특수 응용프로그램의 경우, 추가로 UIAutomation이나 pyautogui 같은 라이브러리가 필요할 수 있습니다. * 코드 실행 전, 포커스된 창이 텍스트 입력 창인지 확인하세요(예: 메모장). ==== pywinauto 이용 ==== 만약 더 복잡한 응용프로그램(예: 브라우저)에서 캐럿 위치의 텍스트를 가져오고 싶다면, Microsoft의 UI Automation 프레임워크를 사용할 수 있습니다. 아래는 pywinauto를 사용한 간단한 예제입니다: <source lang=python> from pywinauto import Application import time def get_caret_text_uia(): try: app = Application().connect(focused=True) focused_window = app.window(focused=True) # 텍스트 컨트롤 찾기 text_control = focused_window.child_window(control_type="Edit") if text_control.exists(): text = text_control.window_text() caret_pos = text_control.get_selection()[0] caret_text = text[max(0, caret_pos-10):caret_pos+10] return f"캐럿 위치 텍스트: {caret_text}\n전체 텍스트: {text}\n캐럿 위치: {caret_pos}" else: return "텍스트 컨트롤을 찾을 수 없습니다." except Exception as e: return f"오류 발생: {str(e)}" if __name__ == "__main__": print("5초 후에 현재 캐럿 위치의 텍스트를 조회합니다...") time.sleep(5) result = get_caret_text_uia() print(result) </source> * 추가 설치 <source lang=python> pip install pywinauto </source> ==== 참고 ==== ** pywin32 방식은 가볍고 빠르지만 기본 Windows 컨트롤에 한정됩니다. ** pywinauto는 더 복잡한 응용프로그램에서 작동할 가능성이 높지만 설정이 더 복잡할 수 있습니다. [[category:python]] [[category:autoit]] [[category:c]] [[category:개발]] [[category:프롣그래밍]]
문서 저장 미리 보기 차이 보기 취소