Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] toggle im mode option #3

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/.vs
/x64
/AIMSwitcher/x64
130 changes: 86 additions & 44 deletions AIMSwitcher/main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <iostream>
#include <string>

#undef UNICODE
#include <Windows.h>

#pragma comment(lib, "imm32.lib")
Expand All @@ -9,61 +9,103 @@
#define IMC_SETCONVERSIONMODE 0x02

int GetCurrentInputMethod() {
HWND hWnd = GetForegroundWindow();
DWORD threadId = GetWindowThreadProcessId(hWnd, nullptr);
HKL hKL = GetKeyboardLayout(threadId);
uintptr_t langId = reinterpret_cast<uintptr_t>(hKL) & 0xFFFF;
return static_cast<int>(langId);
HWND hWnd = GetForegroundWindow();
DWORD threadId = GetWindowThreadProcessId(hWnd, nullptr);
HKL hKL = GetKeyboardLayout(threadId);
uintptr_t langId = reinterpret_cast<uintptr_t>(hKL) & 0xFFFF;
return static_cast<int>(langId);
}

void SwitchInputMethod(int langId) {
HWND hWnd = GetForegroundWindow();
PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, 0, static_cast<LPARAM>(langId));
HWND hWnd = GetForegroundWindow();
PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, 0, static_cast<LPARAM>(langId));
}

int GetCurrentInputMethodMode() {
HWND hWnd = GetForegroundWindow();
HWND hIMEWnd = ImmGetDefaultIMEWnd(hWnd);
LRESULT mode = SendMessage(hIMEWnd, WM_IME_CONTROL, IMC_GETCONVERSIONMODE, 0);
return static_cast<int>(mode);
HWND hWnd = GetForegroundWindow();
HWND hIMEWnd = ImmGetDefaultIMEWnd(hWnd);
LRESULT mode = SendMessage(hIMEWnd, WM_IME_CONTROL, IMC_GETCONVERSIONMODE, 0);
return static_cast<int>(mode);
}

void SwitchInputMethodMode(int mode) {
HWND hWnd = GetForegroundWindow();
HWND hIMEWnd = ImmGetDefaultIMEWnd(hWnd);
SendMessage(hIMEWnd, WM_IME_CONTROL, IMC_SETCONVERSIONMODE, static_cast<LPARAM>(mode));
HWND hWnd = GetForegroundWindow();
HWND hIMEWnd = ImmGetDefaultIMEWnd(hWnd);
SendMessage(hIMEWnd, WM_IME_CONTROL, IMC_SETCONVERSIONMODE, static_cast<LPARAM>(mode));
}

void ShowUsage() {
std::cout
<< "AIMSwitcher, An Input Method Switcher\n"
<< "Usage: AIMSwitcher [OPTION]... [ARG]...\n"
<< "\n"
<< " --im [INPUTMETHOD] show the current input method if INPUTMETHOD is omitted,\n"
<< " otherwise switch to the specified input method\n"
<< " --imm [INPUTMETHODMODE] show the current input method mode if INPUTMETHODMODE is omitted,\n"
<< " otherwise switch to the specified input method mode\n"
<< std::endl;
// ȫ�ֹ��Ӿ��
HHOOK hKeyboardHook;

// �ص��������ڲ���ָ���Ŀ�ݼ����ʱִ��
void OnWinSpacePressed() {
std::cout << "Win + Space pressed!" << std::endl;
// �ڴ˴�������ϣ��ִ�еĺ����߼�

int mode1 = 0;
int mode2 = 1025;
int curMode = GetCurrentInputMethodMode();
if (curMode == mode1) {
SwitchInputMethodMode(mode2);
}
else {
SwitchInputMethodMode(mode1);
}
}

// �ͼ����̹��ӻص�����
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION && wParam == WM_KEYDOWN) {
KBDLLHOOKSTRUCT* pKeyboard = (KBDLLHOOKSTRUCT*)lParam;

// ����Ƿ�����Win��
bool bIsWinPressed = (GetAsyncKeyState(VK_LWIN) & 0x8000) || (GetAsyncKeyState(VK_RWIN) & 0x8000);

// ����Ƿ�����Space��
bool bIsSpacePressed = (pKeyboard->vkCode == VK_SPACE);

if (bIsWinPressed && bIsSpacePressed) {
OnWinSpacePressed();
return 1; // ijЩ��ϼ�������Ҫ����1�Է�ֹ���ݵ����������ϵͳ
}
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}

bool InstallHook() {
// ����ȫ�ֵͼ����̹���
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0);
if (!hKeyboardHook) {
std::cerr << "Failed to install hook!" << std::endl;
return false;
}

std::cout << "Hook installed. Press Win + Space to trigger the function. Press Ctrl+C to exit." << std::endl;

return true;
}

void UninstallHook() {
// ж�ع���
if (hKeyboardHook != NULL) {
UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = NULL;
}
}

int main(int argc, char** argv) {
if (argc == 1) {
ShowUsage();
}
else if (strcmp(argv[1], "--im") == 0) {
if (argc == 2)
std::cout << GetCurrentInputMethod() << std::endl;
else
SwitchInputMethod(atoi(argv[2]));
}
else if (strcmp(argv[1], "--imm") == 0) {
if (argc == 2)
std::cout << GetCurrentInputMethodMode() << std::endl;
else
SwitchInputMethodMode(atoi(argv[2]));
}
else {
ShowUsage();
}
return 0;
if (!InstallHook()) {
return 1;
}

// ��Ϣѭ��
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}

UninstallHook();

return 0;
}