注册 登录
编程论坛 VFP论坛

Win10输入法“中”“英”切换源码(2023.01.14 支持第三方输入法)代码在二楼

kangss 发布于 2023-01-12 18:43, 5476 次点击
只有本站会员才能查看附件,请 登录


代码思路:https://bbs.bccn.net/thread-511088-1-1.html

多键盘布局模式:2个输入法图标
只有本站会员才能查看附件,请 登录


【2023.01.14 支持第三方输入法 代码在二楼】

程序代码:

*****************************************************
* win10输入法([color=#800000]1) &&打开输入法[/color]
* win10输入法([color=#800000]0) &&关闭输入法[/color]
* VFP自身的IMESTATUS([color=#800000]0)对win7有毛病,不支持[/color]
* win10 IME 改为 TFS 模式
* [color=#800000]2023.01.13 增加多键盘布局模式(2个输入法图标)[/color]
*****************************************************
PARAMETERS m._Mode

AGETFILEVERSION(aFile, "ntdll.dll")

IF VAL(aFile(4)) >= 10            && VFP自身的“OS()”在win10中也失灵了
    ******************
    * 判断“中”“英”
    ******************
    *!*    #include <iostream>
    *!*    #include <Windows.h>
    *!*    #pragma comment (lib, "imm32.lib")
    *!*    #define IMC_GETOPENSTATUS 0x0005
    *!*    using namespace std;

    *!*    int main() {
    *!*        while (true) {
    *!*            HWND hIME = ImmGetDefaultIMEWnd(GetForegroundWindow());
    *!*            LRESULT status = SendMessage(hIME, WM_IME_CONTROL, IMC_GETOPENSTATUS, 0);
    *!*            cout << (status ? "Korean" : "English") << endl;
    *!*            Sleep(100);
    *!*        }
    *!*        return 0;
    *!*    }
    #DEFINE WM_IME_CONTROL                0x283
    #DEFINE IMC_GETCONVERSIONMODE        0x0005

    LOCAL m.lnHwnd, m._IME状态    && 0:“英”,否则是“中”或其它

    IF win10鼠标点击切换中英(0) > 1
        DECLARE INTEGER ImmGetContext IN imm32.DLL LONG
        */* DECLARE INTEGER ImmGetOpenStatus IN imm32.DLL LONG
        DECLARE INTEGER ImmSetConversionStatus IN imm32.DLL LONG,LONG iMode,LONG iSentence

        m.lnHwnd = ImmGetContext(_VFP.HWND)
        
*/* m._IME状态 = ImmGetOpenStatus(m._m)
        */* ? IIF(m._IME状态 = 0, "英", "中")
        *!*    中文输入-半角-中文符号    1025
        *!*    中文输入-全角-中文符号    1033
        *!*    中文输入-半角-英文符号    1
        *!*    中文输入-全角-英文符号    9
        *!*    英文输入-半角-中文符号    1024
        *!*    英文输入-全角-中文符号    1032
        *!*    英文输入-半角-英文符号    0
        *!*    英文输入-全角-英文符号    8

        ImmSetConversionStatus(m.lnHwnd, IIF(m._mode = 1,1025, 0), 8)

        CLEAR DLLS ImmSetConversionStatus, ImmGetContext
        RETURN
    ENDIF

    DECLARE INTEGER ImmGetDefaultIMEWnd IN Imm32 LONG
   
*/* DECLARE INTEGER SendMessage IN WIN32API AS "ls_SendMessage" LONG HWND, LONG Msg, LONG wParam, INTEGER
    */* lnHwnd = ImmGetDefaultIMEWnd(_VFP.HWND)        && 输入法会给每个窗口发消息
   
*/* m._IME状态 =  ls_SendMessage(lnHwnd, WM_IME_CONTROL, IMC_GETCONVERSIONMODE, 0)    && m.lcText:任务栏输入指示

    DECLARE INTEGER ImmGetContext IN imm32.DLL LONG
    lnHwnd  = ImmGetContext(_VFP.HWND)
    m._IME状态 = ImmGetOpenStatus(lnHwnd)
    ******************

    IF m._Mode = 0        && 置“英”
        IF m._IME状态 != 0
            win10鼠标点击切换中英()
        ENDIF
    ELSE                && 置“中”
        IF m._IME状态 = 0
            win10鼠标点击切换中英()
        ENDIF
    ENDIF

    CLEAR DLLS "ImmGetDefaultIMEWnd", "ls_SendMessage"
    RETURN
ENDIF

FUNCTION win10鼠标点击切换中英(m._ime_num)
    DECLARE INTEGER FindWindow IN user32 AS "ls_FindWindow" STRING, STRING
    DECLARE INTEGER FindWindowEx IN user32 AS "ls_FindWindowEx" INTEGER, INTEGER, STRING, STRING
    DECLARE INTEGER PostMessage IN user32 AS "ls_PostMessage" INTEGER, INTEGER, INTEGER, INTEGER

    LOCAL m.lnHwnd1, lnHwnd2, m.lnHwnd3, m.lnHwnd4, m.lnHwnd5
    m.lnHwnd1 = ls_FindWindow("Shell_TrayWnd", 0)
    m.lnHwnd2 = ls_FindWindowEx(m.lnHwnd1, 0, "TrayNotifyWnd", NULL)
    m.lnHwnd3 = ls_FindWindowEx(m.lnHwnd2, 0, "TrayInputIndicatorWClass", NULL)
    m.lnHwnd4 = ls_FindWindowEx(m.lnHwnd3, 0, "IMEModeButton", NULL)
    m.lnHwnd5 = ls_FindWindowEx(m.lnHwnd3, 0, "InputIndicatorButton", NULL)    &&

    ************************
    * 检查单键盘、双键盘布局
    ************************
    IF TYPE("_ime_num") = "N"
        LOCAL m._IME布局1, lpRect1, lnWidth1, m._IME布局2, lpRect2, lnWidth2
        lpRect1 = REPLI(CHR(0), 16)
        lpRect2 = REPLI(CHR(0), 16)
        DECLARE SHORT GetWindowRect IN user32 INTEGER HWND, STRING @ lpRect
        GetWindowRect (lnHwnd4, @lpRect1)
        lnWidth1 = CTOB(SUBS(lpRect1,9,4),'4rs') - CTOB(SUBS(lpRect1,1,4),'4rs')
        GetWindowRect (lnHwnd4, @lpRect2)
        lnWidth2 = CTOB(SUBS(lpRect1,9,4),'4rs') - CTOB(SUBS(lpRect2,1,4),'4rs')

        CLEAR DLLS "ls_FindWindow", "ls_FindWindowEx", "ls_PostMessage"

        IF lnWidth1 > 0 AND lnWidth2 > 0
            m._ime_num = 2
        ELSE
            m._ime_num = 1
        ENDIF

        RETURN m._ime_num
    ENDIF
    ************************

    #DEFINE WM_MOUSEMOVE             0x0200
    #DEFINE WM_NCLBUTTONDOWN        0x00A1
    #DEFINE WM_LBUTTONDOWN            0x0201
    #DEFINE WM_LBUTTONUP            0x0202
    #DEFINE MK_LBUTTON                0x0001
    *!* #DEFINE WM_GETTEXT                0x000D

    ls_PostMessage(m.lnHwnd4, WM_LBUTTONDOWN, MK_LBUTTON, 1)        && 按下左键
    ls_PostMessage(m.lnHwnd4, WM_LBUTTONUP, MK_LBUTTON, 1)        && 放开左键

    CLEAR DLLS "ls_FindWindow", "ls_FindWindowEx", "ls_PostMessage"
ENDFUNC



[此贴子已经被作者于2023-1-14 13:26编辑过]

55 回复
#52
吹水佬2023-01-30 08:28
模拟鼠标点击有些第三方还不能完美支持
有些第三方除了支持Shift切换,还支持Ctrl+Space切换。
用Ctrl+Space切换后用鼠标点击切换无效?
只有本站会员才能查看附件,请 登录




[此贴子已经被作者于2023-1-30 08:37编辑过]

#53
kangss2023-01-31 14:54
以下是引用吹水佬在2023-1-30 08:28:48的发言:

模拟鼠标点击有些第三方还不能完美支持
有些第三方除了支持Shift切换,还支持Ctrl+Space切换。
用Ctrl+Space切换后用鼠标点击切换无效?

看视频最后的【D】输入法,感觉“中”“英”的皮肤“激活状态”不一样。
只有本站会员才能查看附件,请 登录


第三方输入法,会把自己的皮肤、菜单等“注入”到win10的“中英”托盘图标上

二楼代码中“ActivateKeyboardLayout(hLayout, KLF SETFORPROCESS)”就是“唤醒”“激活”“中英”托盘的
只有本站会员才能查看附件,请 登录


用你的输入法试试对【D】输入法是否有效
#54
kangss2023-01-31 15:45
单键盘布局:托盘处1个【中】,然后添加搜狗拼音、搜狗五笔形成多键盘布局。托盘出2个输入法图标
只有本站会员才能查看附件,请 登录
#55
吹水佬2023-01-31 18:28
以下是引用kangss在2023-1-31 14:54:50的发言:

看视频最后的【D】输入法,感觉“中”“英”的皮肤“激活状态”不一样。


【D】输入法自身定义是Shift切换,切换后可用鼠标点击切换。
但windows的设定的Ctrl+Space也可以切换,但Ctrl+Space切换后不能用鼠标点击切换。手动点击也无效,代码模拟点击应该也无效。

[此贴子已经被作者于2023-1-31 18:30编辑过]

#56
吹水佬2023-01-31 18:40
以下是引用kangss在2023-1-31 14:54:50的发言:

二楼代码中“ActivateKeyboardLayout(hLayout, KLF SETFORPROCESS)”就是“唤醒”“激活”“中英”托盘的

用你的输入法试试对【D】输入法是否有效


ActivateKeyboardLayout 这个相当于键盘开关切换。
12