文档管理中心
您当前正在浏览新版开发者文档中心,目录分类和层级有所调整。点击左侧当前文档分类名称前的“☰”图标,可切换文档分类。 了解新版目录
指南与API参考指南应用框架ArkUI(方舟UI框架)窗口管理其他开发场景使用WindowManager管理多模输入事件 (C/C++)

使用WindowManager管理多模输入事件 (C/C++)

场景介绍

WindowManager提供应用窗口的管理能力,可以用于管理多模输入事件。

当前支持使用WindowManager进行多模输入事件的过滤,还可以将多模触摸事件注入目标窗口,具体开发步骤可见下文。

过滤多模输入事件

使用WindowManager模块提供的能力去拦截按键事件,让按键事件不往应用内部组件分发。

在CMake脚本中链接动态库

收起
自动换行
深色代码主题
复制
  1. target_link_libraries(entry PUBLIC libnative_window_manager.so libohinput.so)

接口使用说明

展开
接口名 描述
OH_NativeWindowManager_RegisterKeyEventFilter(int32_t windowId, OH_NativeWindowManager_KeyEventFilter keyEventFilter) 为指定的窗口注册过滤回调函数keyEventFilter。
OH_NativeWindowManager_UnregisterKeyEventFilter(int32_t windowId) 取消指定窗口上的过滤回调函数。
  • 应用窗口创建后,使用窗口ID绑定按键事件过滤函数。
  • 应用窗口需要收到按键事件时,才触发按键事件的拦截。
  • 当回调函数返回true表示拦截,false表示不拦截。
  • 同一个窗口ID注册的回调函数只允许一个,最后注册的回调函数会覆盖之前注册过的回调函数。如需过滤多个按键的组合场景,建议在一个回调函数里面处理。

示例代码

以下示例代码中介绍了如何注册过滤函数和取消过滤函数,以过滤ESC退出按键和数字按键为例。

收起
自动换行
深色代码主题
复制
  1. #include "napi/native_api.h"
  2. #include "window_manager/oh_window_comm.h"
  3. #include "window_manager/oh_window_event_filter.h"
  4. #include "multimodalinput/oh_input_manager.h"
  5. #include "multimodalinput/oh_key_code.h"
  6. // 设置过滤函数
  7. static bool filterFunc(Input_KeyEvent *event)
  8. {
  9. auto keyCode = OH_Input_GetKeyEventKeyCode(event);
  10. auto action = OH_Input_GetKeyEventAction(event);
  11. // 过滤escape和数字键的按下
  12. return (keyCode >= Input_KeyCode::KEYCODE_0 && keyCode <= Input_KeyCode::KEYCODE_9
  13. && action == Input_KeyEventAction::KEY_ACTION_DOWN) || (keyCode == Input_KeyCode::KEYCODE_ESCAPE);
  14. }
  15. static napi_value registerFilter(napi_env env, napi_callback_info info)
  16. {
  17. size_t argc = 1;
  18. napi_value args[1] = {nullptr};
  19. napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
  20. int32_t windowId;
  21. napi_get_value_int32(env, args[0], &windowId);
  22. // 向windowId对应的窗口注册filterFunc的过滤函数
  23. auto res = OH_NativeWindowManager_RegisterKeyEventFilter(windowId, filterFunc);
  24. napi_value errCode;
  25. napi_create_int32(env, res, &errCode);
  26. return errCode;
  27. }
  28. static napi_value clearFilter(napi_env env, napi_callback_info info)
  29. {
  30. size_t argc = 1;
  31. napi_value args[1] = {nullptr};
  32. napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
  33. int32_t windowId;
  34. napi_get_value_int32(env, args[0], &windowId);
  35. auto res = OH_NativeWindowManager_UnregisterKeyEventFilter(windowId);
  36. napi_value errCode;
  37. napi_create_int32(env, res, &errCode);
  38. return errCode;
  39. }
  40. EXTERN_C_START
  41. static napi_value Init(napi_env env, napi_value exports)
  42. {
  43. napi_property_descriptor desc[] = {
  44. {"registerFilter", nullptr, registerFilter, nullptr, nullptr, nullptr, napi_default, nullptr},
  45. {"clearFilter", nullptr, clearFilter, nullptr, nullptr, nullptr, napi_default, nullptr}};
  46. napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
  47. return exports;
  48. }
  49. EXTERN_C_END

将多模触摸事件注入给目标窗口

使用WindowManager模块提供的能力为指定窗口注入触摸事件,仅支持同进程窗口。此操作不会触发窗口焦点、层级变化或拖拽,事件会直接发送给ArkUI。

在CMake脚本中链接动态库

收起
自动换行
深色代码主题
复制
  1. target_link_libraries(entry PUBLIC libnative_window_manager.so libohinput.so)

接口使用说明

展开
接口名 描述
OH_WindowManager_InjectTouchEvent(int32_t windowId, Input_TouchEvent* touchEvent, int32_t windowX, int32_t windowY) 为指定的窗口注入触摸事件。
  • 构造事件参数,向目标窗口ID注入事件。

  • 仅支持注入同进程窗口。注入不会触发窗口焦点、层级变化或拖拽,事件直接发送给ArkUI。

  • 接口需要在指定窗口加载UI后调用。

  • 完成窗口和多模触摸事件校验,确保事件参数正确,再将事件发送给ArkUI。具体参数说明如下:

    展开
    参数名 描述
    windowId 目标窗口ID,仅支持同进程的窗口,否则返回错误码1300002。窗口需完成UI加载,否则返回错误码1300003。
    touchEvent 多模触摸事件,具体可见Input_TouchEvent,事件定义在oh_input_manager.h中。调用OH_Input_CreateTouchEvent接口创建touchEvent对象,使用完后调用OH_Input_DestroyTouchEvent接口销毁该对象。具体参数说明见下表。
    windowX 注入事件相对于注入窗口的落点横坐标。参数应为大于等于0的整数,否则返回错误码1300003。
    windowY 注入事件相对于注入窗口的落点纵坐标。参数应为大于等于0的整数,否则返回错误码1300003。

    其中,touchEvent多模触摸事件具体参数说明如下:

    展开
    参数名 方法 描述
    action OH_Input_SetTouchEventAction

    表示事件行为,默认值为0。

    当前只支持0-3的行为,分别表示为:

    - 0:cancel,表示取消事件。

    - 1:down,表示按下事件。

    - 2:move,表示移动事件。

    - 3:up,表示抬起事件。

    - 其他行为会返回错误码1300003。

    id OH_Input_SetTouchEventFingerId

    表示手指ID,默认值为0。

    应为大于等于0的整数,否则返回错误码1300003。

    displayX OH_Input_SetTouchEventDisplayX

    表示事件落点相对于屏幕的横坐标,默认值为0。

    参数应为非负整数,否则返回错误码1300003。建议与windowX保持对应关系,即使不一致也不会返回错误码,仅校验入参合法范围。转换方法推荐使用getWindowProperties()方法获取windowRect属性,通过displayX减去windowRect中窗口左上角横坐标计算对应的windowX。

    displayY OH_Input_SetTouchEventDisplayY

    表示事件落点相对于屏幕的纵坐标,默认值为0。

    参数应为非负整数,否则返回错误码1300003。建议与windowY保持对应关系,即使不一致也不会返回错误码,仅校验入参合法范围。转换方法推荐使用getWindowProperties()方法获取windowRect属性,通过displayY减去windowRect中窗口左上角纵坐标计算对应的windowY。

    actionTime OH_Input_SetTouchEventActionTime 表示时间戳,默认值为-1。参数应为非负整数,否则返回错误码1300003。
    windowId OH_Input_SetTouchEventWindowId 表示事件注入窗口ID,默认值为-1。若参数不为默认值且不等于OH_WindowManager_InjectTouchEvent接口参数windowId,将校验传入参数错误。
    displayId OH_Input_SetTouchEventDisplayId 表示事件注入屏幕ID,默认值为-1。无限制,但是应该尽量保证与OH_WindowManager_InjectTouchEvent接口参数windowId有相互对应关系,推荐使用getWindowProperties()方法获取displayId属性。

示例代码

以下示例代码介绍了如何将多模触摸事件注入目标窗口,以单次事件注入为例。

收起
自动换行
深色代码主题
复制
  1. #include "napi/native_api.h"
  2. #include "window_manager/oh_window.h"
  3. #include "multimodalinput/oh_input_manager.h"
  4. const int32_t ARGS_TWO = 2;
  5. const int32_t ARGS_THREE = 3;
  6. const int32_t ARGS_FOUR = 4;
  7. const int32_t ARGS_FIVE = 5;
  8. const int32_t ARGS_SIX = 6;
  9. const int32_t ARGS_SEVEN = 7;
  10. const int32_t ARGS_EIGHT = 8;
  11. const int32_t ARGS_NINE = 9;
  12. const int32_t ARGS_TEN = 10;
  13. static napi_value injectEvent(napi_env env, napi_callback_info info)
  14. {
  15. size_t argc = ARGS_TEN;
  16. napi_value args[ARGS_TEN] = {nullptr};
  17. napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
  18. int32_t windowId;
  19. napi_get_value_int32(env, args[0], &windowId);
  20. int32_t displayId;
  21. napi_get_value_int32(env, args[1], &displayId);
  22. int32_t windowX;
  23. napi_get_value_int32(env, args[ARGS_TWO], &windowX);
  24. int32_t windowY;
  25. napi_get_value_int32(env, args[ARGS_THREE], &windowY);
  26. int32_t action;
  27. napi_get_value_int32(env, args[ARGS_FOUR], &action);
  28. int32_t fingerId;
  29. napi_get_value_int32(env, args[ARGS_FIVE], &fingerId);
  30. int32_t displayX;
  31. napi_get_value_int32(env, args[ARGS_SIX], &displayX);
  32. int32_t displayY;
  33. napi_get_value_int32(env, args[ARGS_SEVEN], &displayY);
  34. int32_t actionTime;
  35. napi_get_value_int32(env, args[ARGS_EIGHT], &actionTime);
  36. int32_t TE_WindowId;
  37. napi_get_value_int32(env, args[ARGS_NINE], &TE_WindowId);
  38. // 构造多模事件touchEvent
  39. Input_TouchEvent* touchEvent = OH_Input_CreateTouchEvent();
  40. OH_Input_SetTouchEventAction(touchEvent, action);
  41. OH_Input_SetTouchEventFingerId(touchEvent, fingerId);
  42. OH_Input_SetTouchEventDisplayX(touchEvent, displayX);
  43. OH_Input_SetTouchEventDisplayY(touchEvent, displayY);
  44. OH_Input_SetTouchEventActionTime(touchEvent, actionTime);
  45. OH_Input_SetTouchEventWindowId(touchEvent, TE_WindowId);
  46. OH_Input_SetTouchEventDisplayId(touchEvent, displayId);
  47. // 向windowId对应的窗口注入多模触摸事件
  48. auto res = OH_WindowManager_InjectTouchEvent(windowId, touchEvent, windowX, windowY);
  49. // 使用完touchEvent后销毁对象
  50. OH_Input_DestroyTouchEvent(&touchEvent);
  51. napi_value errCode;
  52. napi_create_int32(env, res, &errCode);
  53. return errCode;
  54. }
  55. EXTERN_C_START
  56. static napi_value Init(napi_env env, napi_value exports)
  57. {
  58. napi_property_descriptor desc[] = {
  59. {"injectEvent", nullptr, injectEvent, nullptr, nullptr, nullptr, napi_default, nullptr}};
  60. napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
  61. return exports;
  62. }
  63. EXTERN_C_END