Skip to content

Commit

Permalink
feat: locale 식별자가 ko-KR일 경우에만 언어 변경 작업 진행
Browse files Browse the repository at this point in the history
  • Loading branch information
codepage949 committed Jun 11, 2022
1 parent 30722e1 commit c4784d4
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 33 deletions.
23 changes: 15 additions & 8 deletions lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,30 @@ func keyboardHook(nCode int32, wParam uintptr, lParam unsafe.Pointer) uintptr {
}
} else if wParam == winapi.WM_KEYUP {
if lShiftAlone {
// https://stackoverflow.com/questions/64280975/immgetcontext-returns-zero-always
// NOTE: https://stackoverflow.com/questions/64280975/immgetcontext-returns-zero-always
hwnd := winapi.ImmGetDefaultIMEWnd(winapi.GetForegroundWindow())
// COMPOSITIONFORM에 사용하는 CFS_EXCLUDE에 대한 참고 자료가 없으나 실제로 해보면 composition window가 나타나지 않음
cf := winapi.COMPOSITIONFORM{Style: winapi.CFS_EXCLUDE}
_ = winapi.SendMessage(hwnd, winapi.WM_IME_CONTROL, winapi.IMC_SETCOMPOSITIONWINDOW, uintptr(unsafe.Pointer(&cf)))
mode := 1 ^ winapi.SendMessage(hwnd, winapi.WM_IME_CONTROL, winapi.IMC_GETCONVERSIONMODE, 0)
_ = winapi.SendMessage(hwnd, winapi.WM_IME_CONTROL, winapi.IMC_SETCONVERSIONMODE, mode)
tid := uint32(winapi.GetWindowThreadProcessId(hwnd, 0))
lid := winapi.GetKeyboardLayout(tid)

// NOTE: https://docs.microsoft.com/ko-kr/windows/win32/api/winuser/nf-winuser-getkeyboardlayout?redirectedfrom=MSDN#return-value
// locale 식별자가 ko-KR일 경우에만 언어 변경 작업 진행
if lid&0xFFFF == 0x0412 {
// NOTE: COMPOSITIONFORM에 사용하는 CFS_EXCLUDE에 대한 참고 자료가 없으나 실제로 해보면 composition window가 나타나지 않음
cf := winapi.COMPOSITIONFORM{Style: winapi.CFS_EXCLUDE}
_ = winapi.SendMessage(hwnd, winapi.WM_IME_CONTROL, winapi.IMC_SETCOMPOSITIONWINDOW, uintptr(unsafe.Pointer(&cf)))
mode := 1 ^ winapi.SendMessage(hwnd, winapi.WM_IME_CONTROL, winapi.IMC_GETCONVERSIONMODE, 0)
_ = winapi.SendMessage(hwnd, winapi.WM_IME_CONTROL, winapi.IMC_SETCONVERSIONMODE, mode)
}
}
}
} else {
if wParam&0x1 == 0 { // WM_*DOWN
if wParam&0x1 == 0 { // NOTE: WM_*DOWN
if !otherPressedMap[kb.VkCode] {
lShiftAlone = false
otherPressedCount += 1
otherPressedMap[kb.VkCode] = true
}
} else { // WM_*UP
} else { // NOTE: WM_*UP
if otherPressedMap[kb.VkCode] {
otherPressedCount -= 1
otherPressedMap[kb.VkCode] = false
Expand Down
30 changes: 15 additions & 15 deletions winapi/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ type MSG struct {
}

type INPUTUNION struct {
_ [20]byte // fixed
_ uintptr // non-fixed
_ [20]byte // NOTE: fixed
_ uintptr // NOTE: non-fixed
}

type INPUT struct {
Expand All @@ -36,24 +36,24 @@ type KBDLLHOOKSTRUCT struct {
}

type COMPOSITIONFORM struct {
Style uint8
_ [192]byte
Style uint8
_ [192]byte
}

type Hookproc func(int32, uintptr, unsafe.Pointer) uintptr

const (
INPUT_KEYBOARD = 1
WH_KEYBOARD_LL = 13
VK_LSHIFT = 0xA0
VK_HANGUL = 0x15
KEYEVENTF_KEYUP = 0x2
WM_KEYDOWN = 0x100
WM_KEYUP = 0x101
WM_IME_CONTROL = 0x283
INPUT_KEYBOARD = 1
WH_KEYBOARD_LL = 13
VK_LSHIFT = 0xA0
VK_HANGUL = 0x15
KEYEVENTF_KEYUP = 0x2
WM_KEYDOWN = 0x100
WM_KEYUP = 0x101
WM_IME_CONTROL = 0x283
IMC_GETCOMPOSITIONWINDOW = 0xB
IMC_SETCOMPOSITIONWINDOW = 0xC
IMC_GETCONVERSIONMODE = 1
IMC_SETCONVERSIONMODE = 2
CFS_EXCLUDE = 0x80
IMC_GETCONVERSIONMODE = 1
IMC_SETCONVERSIONMODE = 2
CFS_EXCLUDE = 0x80
)
45 changes: 35 additions & 10 deletions winapi/winapi.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ref https://play.golang.org/p/2JzHDalGN7Q
// NOTE: https://play.golang.org/p/2JzHDalGN7Q
package winapi

import (
Expand All @@ -7,12 +7,14 @@ import (
)

var (
user32 = syscall.NewLazyDLL("user32.dll")
_GetMessage = user32.NewProc("GetMessageA")
_SetWindowsHookExA = user32.NewProc("SetWindowsHookExA")
_CallNextHookEx = user32.NewProc("CallNextHookEx")
_GetForegroundWindow = user32.NewProc("GetForegroundWindow")
_SendMessage = user32.NewProc("SendMessageW")
user32 = syscall.NewLazyDLL("user32.dll")
_GetMessage = user32.NewProc("GetMessageA")
_SetWindowsHookExA = user32.NewProc("SetWindowsHookExA")
_CallNextHookEx = user32.NewProc("CallNextHookEx")
_GetForegroundWindow = user32.NewProc("GetForegroundWindow")
_SendMessage = user32.NewProc("SendMessageW")
_GetKeyboardLayout = user32.NewProc("GetKeyboardLayout")
_GetWindowThreadProcessId = user32.NewProc("GetWindowThreadProcessId")
)

func GetMessage(m *MSG, hwnd uintptr, wMsgFilterMin, wMsgFilterMax uint32) int32 {
Expand Down Expand Up @@ -48,13 +50,36 @@ func SendMessage(hwnd uintptr, msg uint32, wparam, lparam uintptr) uintptr {
return r
}

func GetKeyboardLayout(idThread uint32) uintptr {
r, _, _ := _GetKeyboardLayout.Call(uintptr(idThread))

return r
}

func GetWindowThreadProcessId(hwnd uintptr, processId uintptr) uintptr {
r, _, _ := _GetWindowThreadProcessId.Call(hwnd, processId)

return r
}

var (
imm32 = syscall.NewLazyDLL("imm32.dll")
_ImmGetDefaultIMEWnd = imm32.NewProc("ImmGetDefaultIMEWnd")
imm32 = syscall.NewLazyDLL("imm32.dll")
_ImmGetDefaultIMEWnd = imm32.NewProc("ImmGetDefaultIMEWnd")
)

func ImmGetDefaultIMEWnd(hwnd uintptr) uintptr {
r, _, _ := _ImmGetDefaultIMEWnd.Call(hwnd)

return r
}
}

var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
_GetCurrentThreadId = kernel32.NewProc("GetCurrentThreadId")
)

func GetCurrentThreadId() uintptr {
r, _, _ := _GetCurrentThreadId.Call()

return r
}

0 comments on commit c4784d4

Please sign in to comment.