[Sciter系列] MFC下的Sciter–3.Sciter脚本与底层交互
[Sciter系列] MFC下的Sciter–3.Sciter脚本与底层交互,脚本调用底层自定义的方法函数。
本系列文章的目的就是一步步构建出一个功能可用,接口基本完善的基于MFC框架的SciterFrame程序,以此作为以后程序的基础。其中,文章中按照如下逻辑编排(解决如下问题):
1、使用什么环境
2、完成什么功能
3、如何完成
1、工程环境: VS2010 + Sciter-SDK + Win7
建议:HTML页面还使用ANSI编码,UTF-8此时不建议使用。
2、本文完成的功能:HTML页面添加自定义函数调用,在底层将此函数实现,同时演示部分自带函数的使用。
3、具体步骤如下:
一、TS调用自带函数的演示:(即不需要自己编写和实现对应的函数,引擎自带)
TS脚本自身有很多自带的函数,如msgbox(消息框),selectFile(文件选择框),Update等。
这些函数可以在帮助文档里面查看:

简单的HTML测试代码:
<html>
<head>
<title>Hello World</title> <style>
.test{
background-color: black;
color: white;
}
</style>
<script type="text/tiscript">
$(#btnExit).onClick = function () {
stdout.println("退出");
// view.close();
return true;
}
$(#btnUpdate).onClick = function () {
stdout.println("刷新");
view.update();
return true;
}
$(#btnLoad).onClick = function () {
stdout.println("加载");
var fn = view.selectFile(#open,"HTML Files (*.htm,*.html)|*.HTM;*.HTML|All Files (*.*)|*.*" , "html" );
if( fn ) view.load(fn);
return true;
}
</script>
</head>
<body bgcolor="#00AAAA" >
<h1>自带函数测试</h1>
<input #btnExit type="button" value="退出"/>
<input #btnUpdate type="button" value="刷新"/>
<input #btnLoad type="button" value="加载"/>
</body>
</html>
这个代码在Sciter.exe中就可以测试了。
二、设置自定义函数,并且调用对应的函数
我们在之前的HTML代码中添加自定义函数调用部分:
<html>
<head>
<title>Hello World</title> <style>
.test{
background-color: black;
color: white;
}
</style>
<script type="text/tiscript"> $(#btnExit).onClick = function () {
stdout.println("退出");
// view.close();
return true;
}
$(#btnUpdate).onClick = function () {
stdout.println("刷新");
view.update();
return true;
}
$(#btnLoad).onClick = function () {
stdout.println("加载");
var fn = view.selectFile(#open,"HTML Files (*.htm,*.html)|*.HTM;*.HTML|All Files (*.*)|*.*" , "html" );
if( fn ) view.load(fn);
return true;
}
// 调用我们程序自定义方法
$(#btnCall).onClick = function () {
stdout.println("调用自定义函数");
var ret = view.msgbox(#information, "这个函数将调用底层编写的函数addsome()函数,<br/><br/>请确保不是使用测试工具调用的,否则无效!",
"你确定调用?",[ {id:#yes, text:"确定"}, {id:#no, text:"取消"} ] );
if( ret == #yes )
{
stdout.println("确定");
// addsome()是自定义函数,一定要以view.xxxx(xx)方式调用
ret = view.addsome(3,2);
view.msgbox(#information,ret);
}else{
stdout.println("取消");
}
return true;
}
</script>
</head>
<body bgcolor="#00AAAA" >
<h1 .test>Hello World!</h1>
<h2 #test1>你好啊</h2>
<input #btnExit type="button" value="退出"/>
<input #btnUpdate type="button" value="刷新"/>
<input #btnLoad type="button" value="加载"/>
<br/><br/><br/>
<input #btnCall type="button" value="调用底层定义的函数"/>
</body>
</html>
当然,这个自定义函数现在还没有实现,并且如果在Sciter.exe中在弹出的对话框中选择“确定”也不会有下面的那个消息框弹出,因为TS脚本找不到这样一个函数用来调用,通过调试工具查看就会看到报错信息。
下面我们来进行最重要的工作,用VC++实现addsome函数:
首先,我们要明白函数调用的机理:
当TS脚本准备调用一个函数时,他肯定会先查找自身是否拥有这个函数,如果没有就会查找底层是否注册了这个函数,找到后就按照规定的规则调用它,将返回值返回到TS中,完成整个调用过程。
然后,我们通过C++来实现它:
想要完成这个过程,我们需要确保几个问题:
1、我们的程序如何让TS脚本得知实现的接口?
答:首先,我们的窗口类要继承于sciter::event_handle,这个需要头文件 #include "include/sciter-x-host-callback.h" 的支持,在窗口被加载后需要主动注册我们的窗口到TS引擎中,即调用 sciter::attach_dom_event_handler(this->m_hWnd,this); 方法,这样TS脚本就知道可以在我们的窗口中找到对应的函数。但是TS作为一种解释性的脚本语言,不可能直接调用C++的方法,所以我们还需要在做一步工作:
SDK作者早已考虑了这些问题,它使用了类似MFC的消息映射机制,如下所示:
//消息映射的函数
json::value addsome(json::value a,json::value b); // 测试的函数
//Sciter的TiScript消息映射
BEGIN_FUNCTION_MAP
FUNCTION_2("addsome", addsome) // 后面的2表示有2个参数
END_FUNCTION_MAP
这样,当TS脚本调用addsome()函数时,通过窗口类通知给消息映射,然后消息映射调用VC++实现的addsome方法,实现自定义函数的调用。
虽然似乎这个问题已经解决了,因为函数已经可以被调用了,但是问题永远不像想想的那么简单。
2、如何处理被调函数的参数及返回值?
答:这个涉及到json类的使用,需要使用者自行摸索。我给出一个样例:
json::value CHelloWorldDlg::addsome( json::value a,json::value b )
{
int aa = int(a.d) + int(b.d); // xx.d 返回的是int64的整数,可以作为数据类型转换使用
return json::value(aa); // 返回求和后的结果
}
如上所述,自定义函数的声明调用都完成了,至于多线程、资源内置等内容我们在后面讨论。
补充:
相信很多人都想在自己的程序中使用到像Sciter.exe中的调试工具,如何将这个工具添加到自己的程序中去呢?其实很简单!
答:在WindowProc中拦截F12按键按下的消息,使用sciter::inspect()调用即可。需要特别注意的是一定要将sdk中的 inspector32/64.dll 拷贝到程序运行目录下,否则没效果。使用时按下F12键就可以了。
if (message == WM_KEYDOWN && wParam == VK_F12)
{
sciter::inspect(this->m_hWnd);
return 0;
}
---------------
本节源代码下载:
博客:
CSDN:http://blog.csdn.net/bbdxf
cnBlogs: http://www.cnblogs.com/bbdxf
[Sciter系列] MFC下的Sciter–3.Sciter脚本与底层交互的更多相关文章
- [Sciter系列] MFC下的Sciter–5.Sciter中GUI线程研究
[Sciter系列] MFC下的Sciter–5.Sciter中GUI线程研究,目前MFC存在问题,win32没问题. 本系列文章的目的就是一步步构建出一个功能可用,接口基本完善的基于MFC框架的Sc ...
- [Sciter系列] MFC下的Sciter–4.HTML与图片资源内置
[Sciter系列] MFC下的Sciter–4.HTML与图片资源内置,防止代码泄露. 本系列文章的目的就是一步步构建出一个功能可用,接口基本完善的基于MFC框架的SciterFrame程序,以此作 ...
- [Sciter系列] MFC下的Sciter–2.Sciter中的事件,tiscript,语法
[Sciter系列] MFC下的Sciter–2.Sciter中的事件,tiscript,CSS部分自觉学习,重点说明Tiscript部分的常见语法和事件用法. 本系列文章的目的就是一步步构建出一个功 ...
- [Sciter系列] MFC下的Sciter–1.创建工程框架
Sciter SDK中提供的Win32下例程很多,唯独使用很多(对我个人而言)的MFC框架下Sciter程序的构建讲的很少,虽然MFC有这样那样的诟病,但是不可否认的是编写一般的小项目,这仍然是大多数 ...
- [Sciter系列] MFC下的Sciter–1.创建工程框架
Sciter SDK中提供的Win32下例程很多,唯独使用很多(对我个人而言)的MFC框架下Sciter程序的构建讲的很少,虽然MFC有这样那样的诟病,但是不可否认的是编写一般的小项目,这仍然是大 ...
- MFC下OpenGL入门(可以用)
MFC下OpenGL入门 源文件 1, 建一工程文件,我这里命名为first,现在first工程里面我们没有添加任何东西,所有的东西都是MFC自动帮我们创建的. 2, 添加链接库.这一步很关键.打开菜 ...
- MFC下调用控制台和控制台下MFC库的支持
1.MFC下调用控制台 在CWinApp的InitInstance中对话框的DoModal之前加入 AllocConsole(); // 开辟控制台 SetConsoleTitle(_T(" ...
- MFC下的各种字符串类型和相互转换
MFC下的常用字符串数据类型表示的含义: L:Long 长 P:Point 指针 C:Const 常量 W:Wchar_t 宽字符 T:TCHAR STR:String 字符串 在看看MF ...
- VC/MFC 下 递归遍历目录下的所有子目录及文件
在MFC下要实现文件夹的递归遍历,可用CFileFind类,依次读取文件夹下的子文件夹和文件,并判断通过判断是文件夹还是文件来决定递归遍历.递归遍历代码如下: /******************* ...
随机推荐
- HIVE Transform using 用法
select TRANSFORM(*, *, *) using 'python filter.py' as (*, *, *) from t_1 HIVE支持pipe操作,将select出来的字段,用 ...
- ORA-01031:insufficient privileges
描述:oracle11g用scott用户在plsql上以sysdba身份登录显示以上错误,可是在cmd面板中却正常,网上各种找答案不没有对症,最后这位网友的回答解决了我的问题. 原帖网址:http:/ ...
- jquery ajax对特殊字符进行转义防止js注入使用示例
在使用ajax进行留言的时候,出现了一个问题.因为留言内容写完之后,通过ajax提交内容,同时使用js把留言的内容添加到页面上来.浏览留言的时候也是通过ajax请求,然后再显示的.这样,如果有人在留言 ...
- JavaScript高级---装饰者模式设计
一.设计模式 javascript里面给我们提供了很多种设计模式: 工厂.桥.组合.门面.适配器.装饰者.享元.代理.观察者.命令.责任链 在前面我们实现了工厂模式和桥模式 工厂模式 : 核心:为了生 ...
- CSS属性--过渡(transtion)
首先介绍一下transition的属性取值: transition-property : 主要设置对象中的参与过渡的属性,包括(border-color,background-color,color) ...
- ByteArrary(优化数据存储和数据流)
原地址:http://www.unity蛮牛.com/blog-1801-799.html 首页 博客 相册 主题 留言板 个人资料 ByteArrary(优化数据存储和数据流) 分类:unity ...
- lua语言入门之Sublime Text设置lua的Build System
转自: http://blog.csdn.net/wangbin_jxust/article/details/8911956 最近开始学习LUA语言,使用Sublime Text作为编辑器,不得不说, ...
- 玩转图片Base64编码
什么是 base64 编码? 图片的 base64 编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址. 这样做有什么意义呢?我们知道,我们所看到的网页上的每一个图片,都是需要消耗一 ...
- django如何用orm增加manytomany关系字段(自定义表名)
不自定义表名的,网上有现成的,但如果自定义之后,则要变通一下了. app_insert = App.objects.get(name=app_name) site_insert = Site.obje ...
- Unrecognized Windows Sockets error: 0: JVM_Bind异常
根据端口查看 根据PID查看具体的进程 任务管理器->查看-选择列,选中PID 然后查看任务管理器.