Initial Commit
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# windows 0.61.3 — CodeAssist가 쓰는 Win32 표면
|
||||
|
||||
**작성**: 2026-09-09
|
||||
**근거**: 로컬 crate 소스 `%USERPROFILE%/.cargo/registry/src/index.crates.io-*/windows-0.61.3/`에서 직접 확인함.
|
||||
|
||||
## Cargo features
|
||||
|
||||
```toml
|
||||
windows = { version = "0.61.3", features = [
|
||||
"Win32_Foundation",
|
||||
"Win32_System_DataExchange",
|
||||
"Win32_System_Memory",
|
||||
"Win32_System_Threading",
|
||||
"Win32_UI_Input_KeyboardAndMouse",
|
||||
"Win32_UI_WindowsAndMessaging",
|
||||
] }
|
||||
```
|
||||
|
||||
## 직전 창 스냅샷
|
||||
|
||||
```rust
|
||||
GetForegroundWindow() -> HWND
|
||||
GetWindowTextW(HWND, &mut [u16]) -> i32
|
||||
GetWindowThreadProcessId(HWND, Option<*mut u32>) -> u32
|
||||
OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, pid) -> Result<HANDLE>
|
||||
QueryFullProcessImageNameW(HANDLE, PROCESS_NAME_FORMAT, PWSTR, *mut u32) -> Result<()>
|
||||
CloseHandle(HANDLE) -> Result<()>
|
||||
```
|
||||
|
||||
창 핸들은 앱 상태에서 `isize`로 보관한다. `HWND`의 raw pointer를 그대로 앱 상태에 넣으면 Tauri가 요구하는 `Send + Sync` 경계와 부딪힐 수 있다.
|
||||
|
||||
## 유니코드 텍스트 클립보드
|
||||
|
||||
```rust
|
||||
OpenClipboard(None) -> Result<()>
|
||||
EmptyClipboard() -> Result<()>
|
||||
GlobalAlloc(GMEM_MOVEABLE, bytes) -> Result<HGLOBAL>
|
||||
GlobalLock(HGLOBAL) -> *mut c_void
|
||||
GlobalUnlock(HGLOBAL) -> Result<()>
|
||||
SetClipboardData(13, Some(HANDLE(hglobal.0))) -> Result<HANDLE> // 13 = CF_UNICODETEXT
|
||||
CloseClipboard() -> Result<()>
|
||||
```
|
||||
|
||||
`SetClipboardData`가 성공하면 메모리 소유권이 Windows로 넘어간다. 성공 뒤 `GlobalFree`를 부르면 안 된다. 실패한 경우에만 직접 해제한다.
|
||||
|
||||
## 대상 활성화와 Ctrl+V (2026-09-11 갱신)
|
||||
|
||||
```rust
|
||||
SetForegroundWindow(HWND) -> BOOL
|
||||
GetAsyncKeyState(i32) -> i16 // 상위 비트가 1이면 현재 눌린 상태
|
||||
IsWindow(Option<HWND>) -> BOOL
|
||||
SendInput(&[INPUT], size_of::<INPUT>() as i32) -> u32 // 실제 전송한 이벤트 수
|
||||
```
|
||||
|
||||
순서: 클립보드 적재 → 키·마우스 해제 대기(최대 2초, 10ms 간격) → 대상 HWND·PID·thread 재확인 → `SetForegroundWindow` → 활성화·포커스·키 상태 확인(80ms) → `SendInput`으로 Ctrl/V 누름·해제 4개 전송 → 성공 때만 창 숨김. 클립보드는 원복하지 않음.
|
||||
|
||||
- `SetForegroundWindow` 반환 직후에는 대상 활성화가 아직 끝나지 않을 수 있음. 실제 검사에서 약 3ms 뒤 대상이 활성화되는 전환을 관찰함. 첫 활성화 전에는 원래 팔레트나 NULL만 허용하고, 다른 창 또는 활성화 뒤 이탈은 취소함.
|
||||
- 이벤트 4개가 전부 전송되지 않으면 오류. 이미 누른 키의 해제만 정리하고 붙여넣기를 재시도하지 않음. 큐 전송 성공과 대상 편집기의 실제 내용 반영은 별개임.
|
||||
- `paste_code`는 `spawn_blocking`에서 대기·Win32 작업을 실행하므로 UI 스레드를 막지 않음. 대상 잠금은 스냅샷 복사 때만 사용하며, 진행 중 중복 요청은 바로 거절함.
|
||||
- 실패하면 팔레트를 다시 표시하고 오류 안내를 유지. 클립보드 기록 이후 실패에만 원문이 남았다고 안내함.
|
||||
Reference in New Issue
Block a user