当前位置: 首页 > news >正文

emscripten编译cocos2dx项目输入框支持中文

网页运行emscripten编译的cocos2dx项目,cocos的ui::TextField无法输入中文,查找资料无果,只能自己实现了。

方案:c++调用js创建网页的输入框,并将内容传给c++


#ifndef __jsInput__
#define __jsInput__#include <string>
#include <functional>typedef std::function<void(std::string)> jsInputCb;class jsInput
{
public:jsInput();static jsInput*getInstance();struct inputParam {std::string nameStr="";int posX = 0;int posY = 0;int width = 100;int height = 25;};void removeLastInput(const std::string nameStr="");void updateInput(const inputParam& parm);void setInputStr(const std::string& str);void setJsInputCallBack(const jsInputCb& cb);const jsInputCb& getJsInputCallBack();int getCanvasWidth();int getCanvasHeight();int getCanvasLeft();
private:jsInputCb m_cbFx;
};#endif /* defined(__jsInput__) */
#include "jsInput.h"
#include "cocos2d.h"#if (CC_PLATFORM_EMSCRIPTEN == CC_TARGET_PLATFORM)
#include <emscripten.h>
#include <emscripten/html5.h>
#endifstatic jsInput *instance = nullptr;
jsInput *jsInput::getInstance()
{if (!instance){instance = new jsInput();}return instance;
}#if (CC_PLATFORM_EMSCRIPTEN == CC_TARGET_PLATFORM)
EM_BOOL on_webResize(int eventType, const EmscriptenUiEvent* e, void* userData) {/*int width = e->windowInnerWidth;int height = e->windowInnerHeight;*/cocos2d::__NotificationCenter::getInstance()->postNotification("ui_js_web_size_change");return EM_TRUE;
}extern "C" {void EMSCRIPTEN_KEEPALIVE handleJsInput(const char* text) {// 在这里处理输入auto cb = jsInput::getInstance()->getJsInputCallBack();if (cb) {cb(text);}}
}
#endifjsInput::jsInput()
:m_cbFx(nullptr)
{
#if (CC_PLATFORM_EMSCRIPTEN == CC_TARGET_PLATFORM)emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,NULL,EM_TRUE,on_webResize);
#endif
}void jsInput::removeLastInput(const std::string nameStr)
{m_cbFx = nullptr;
#if (CC_PLATFORM_EMSCRIPTEN == CC_TARGET_PLATFORM)const char* js_code = R"(var input = document.getElementById("myChatInput");if(input!=null){input.remove();	})";emscripten_run_script(js_code);
#endif
}void jsInput::updateInput(const inputParam& param)
{
#if (CC_PLATFORM_EMSCRIPTEN == CC_TARGET_PLATFORM)// 创建/更新输入框的 JavaScript 代码const char* js_code = R"(var input = document.getElementById("myChatInput");if(input==null){input = document.createElement('input');input.type = 'text';input.id = 'myChatInput';var divElement=document.querySelector('.emscripten_border');divElement.appendChild(input);input.addEventListener('input', (event) => {Module.ccall('handleJsInput', 'void', ['string'], [event.target.value]);});}input.style = 'position:absolute;left:%dpx; top:%dpx;width:%dpx;height:%dpx;opacity:1;';)";char buff[1024] = { 0 };sprintf(buff, js_code, param.posX, param.posY, param.width, param.height);emscripten_run_script(buff);
#endif
}void jsInput::setInputStr(const std::string& str)
{
#if (CC_PLATFORM_EMSCRIPTEN == CC_TARGET_PLATFORM)const char* js_code = R"(var input = document.getElementById("myChatInput");input.value='%s';)";char buff[1024] = { 0 };sprintf(buff, js_code, str.c_str());emscripten_run_script(buff);
#endif
}void jsInput::setJsInputCallBack(const jsInputCb& cb)
{m_cbFx = cb;
}const jsInputCb& jsInput::getJsInputCallBack()
{return m_cbFx;
}int jsInput::getCanvasWidth() {
#if (CC_PLATFORM_EMSCRIPTEN == CC_TARGET_PLATFORM)const char* id = "canvas";char script[256] = {0};snprintf(script, sizeof(script),"document.getElementById('%s').getBoundingClientRect().width", id);return emscripten_run_script_int(script);
#endifreturn 100;
}int jsInput::getCanvasHeight() {
#if (CC_PLATFORM_EMSCRIPTEN == CC_TARGET_PLATFORM)const char* id = "canvas";char script[256] = { 0 };snprintf(script, sizeof(script),"document.getElementById('%s').getBoundingClientRect().height", id);return emscripten_run_script_int(script);
#endifreturn 100;
}

注意:如果添加输入框之后,发现无法删除字符,找到glfw模块生成js的模版文件 【emsdk\upstream\emscripten\src\library_glfw.js】,将glfw监测keyDown事件中关于backspace键的特殊处理注释掉。

如下图:

http://www.dtcms.com/a/270149.html

相关文章:

  • MySQL 全库表记录统计与空间估算教程
  • 猿人学js逆向比赛第一届第十五题
  • SpringAI学习笔记-MCP服务器简单示例
  • 软考(软件设计师)数据库原理-SQL
  • HTML+JS+CSS制作一个数独游戏
  • CSS揭秘:9.自适应的椭圆
  • 记一次mount point is busy问题排查
  • 数据结构 —— 栈(stack)在算法思维中的巧妙运用
  • C++进阶—二叉树进阶
  • 笔记/TCP/IP四层模型
  • Fence-音视频设备资源同步
  • IT 技术领域创作者三周年纪念日
  • 【CodeTop】每日练习 2025.7.8
  • Java 阻塞队列:7种类型全解析
  • 起重机械的工作循环门限值计算逻辑
  • 容器技术入门与Docker环境部署
  • Ntfs!LfsRestartLogFile函数分析之两次调用Ntfs!LfsReadRestart函数的目的
  • (生活比喻-图文并茂)http2.0和http3.0的队头阻塞,http2.0应用层解决,TCP层存在,3.0就是彻底解决,到底怎么理解区别???
  • AI健康小屋“15分钟服务圈”:如何重构社区健康生态?
  • MyBatis-Plus:深入探索与最佳实践
  • C#,js如何对网页超文本内容按行拆分,选择第A-B个字符返回HTM?
  • stack_queue扩展学习 --- 反向迭代器
  • 戴尔3670装win11和ubuntu双系统踩坑教程
  • 自动驾驶传感器的标定与数据融合
  • 【Android】组件及布局介绍
  • CAN主站转Modbus TCP网关:高铁门控系统的“毫秒级响应”密码
  • 【ZYNQ Linux开发】BRAM的几种驱动方式
  • 微服务集成snail-job分布式定时任务系统实践
  • Mac安装Docker(使用orbstack代替)
  • 单机分布式一体化数据库的架构设计与优化