[Sciter系列] MFC下的Sciter–5.Sciter中GUI线程研究

[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

CSDN博客:http://blog.csdn.net/bbdxf
CNBlogs: http://www.cnblogs.com/bbdxf
本博客内容为本人原创,如有转载请保留出处!尊重他人就是尊重自己!

原文地址:https://www.cnblogs.com/bbdxf/p/3410720.html