[Sciter系列] MFC下的Sciter–5.Sciter中GUI线程研究,目前MFC存在问题,win32没问题。
本系列文章的目的就是一步步构建出一个功能可用,接口基本完善的基于MFC框架的SciterFrame程序,以此作为以后程序的基础。其中,文章中按照如下逻辑编排(解决如下问题):
1、使用什么环境
2、完成什么功能
3、如何完成
1、工程环境: VS2010 + Sciter-SDK + Win7
建议:HTML页面使用的是Demo中ui-framework的UI界面,执行函数也完全Copy。
2、本文完成的功能:尝试GUI线程调用函数。
3、具体步骤如下:
首先,添加头文件:
#include "include/sciter-x-threads.h"
在窗口类中添加一个变量和一个响应函数:
public: // 只写新添加的 sciter::sync::gui_thread_ctx _; // instance of gui_thread_ctx // it should be created as a variable inside WinMain // gui_thread_ctx is critical for GUI_CODE_START/END to work //消息映射的函数 json::value exec_task(json::value taskId, json::value progressCb, json::value doneCb); //Sciter的TiScript消息映射 BEGIN_FUNCTION_MAP FUNCTION_3("execTask", exec_task); END_FUNCTION_MAP
其中 sciter::sync::gui_thread_ctx _; 是为了线程能够工作必须声明的,exec_task是用来响应线程工作的。
实现部分使用的是Demo的方法:
struct thread_params { json::value taskId; json::value progressCb; json::value doneCb; }; void thread_body(thread_params params) { for(int i = 1; i <= 100; ++i) { ::Sleep(100); GUI_CODE_START params.progressCb.call(i); // report task progress GUI_CODE_END } // report task completion, // we can pass some result data here, for now just taskId GUI_CODE_START params.doneCb.call(params.taskId); GUI_CODE_END } #if 0 // equivalent of the above but wihtout macro void thread_body(thread_params params) { for(int i = 1; i <= 10; ++i) { ::Sleep(1000); sciter::sync::gui_thread_ctx::exec([&]() { params.progressCb.call(i*10); // report task progress }); } // report task completion, // we can pass some result data here, for now just taskId sciter::sync::gui_thread_ctx::exec([&]() { params.doneCb.call(params.taskId); }); } #endif json::value CHelloWorldDlg::exec_task( json::value taskId, json::value progressCb, json::value doneCb ) { thread_params params; params.taskId = taskId; params.progressCb = progressCb; params.doneCb = doneCb; sciter::thread(thread_body,params); return json::value(); // void method }
最后,线程能够工作,但是,也出现了一个新的问题:
当进度条进行一半时,MFC程序会不知为何就死了,有时候有没有问题,希望有这方面研究的童鞋给点建议和方法。
本节源代码下载:(半成品,不提供下载)
HTML源码:
<html> <head> <title></title> <style> div#content { flow:horizontal; size:*; } div#tasks { width:300px; height:*; } div#tasks > select { size:*; display:block; } div#explanation { size:*; padding:20px; overflow:auto; } div#explanation > pre { padding:10px; border:1px dotted #999; background:#ffffef; } </style> <script type="text/tiscript"> var taskNo = 0; $(#start-task).onClick = function() { var taskElem = $(div#tasks > select).$append(<option>Task { ++taskNo }<progress max=100 /> <span.result /></option>); function onProgress(p100) { taskElem.$(progress).value = p100; } function onDone(taskId) { taskElem.$(span.result).text = "Done!"; taskElem.$(progress).remove(); } view.execTask(taskId,onProgress,onDone); } </script> </head> <body> <h2>Sciter UI, basic principles demo</h2> <div #content> <div #tasks> <button #start-task>Start Task</button> <select type=select></select> </div> </div> </body> </html>
C++部分修改:
查看上面的代码!
博客:
CSDN:http://blog.csdn.net/bbdxf
cnBlogs: http://www.cnblogs.com/bbdxf