Sciter UI, basic principles. Calling code behind UI from worker threads.

I’ve updated the SDK with new sample: /sdk/demos/ui-framework .
This sample demonstrates principles outlined in “Sciter UI, application architecture” article.

Sciter demo screenshot

In particular it demonstrates definition of native function (view.execTask() -> window::exec_task()) and call of UI methods (callbacks in this sample) from worker threads.

I’ve explained idea of calling UI code from worker threads in this article but in this demo I am using slightly different mechanism.

The gui_exec function looks like this:

// this function is called from worker threads to 
// execute the gui_block in GUI thread
inline void gui_exec( std::function<void()> gui_block )
{
  sciter::sync::event evt;
  PostThreadMessage(gGUIThreadId, WM_EXEC, WPARAM(&evt),LPARAM(&gui_block));
  evt.wait(); // suspend worker thread until GUI will execute the block.
}

It posts the message into GUI thread input queue. Receiver of WM_EXEC message is Windows WH_GETMESSAGE hook function:

// message hook to handle WM_EXEC in GUI thread
static LRESULT CALLBACK gui_exec_hook_GetMsgProc(int code, WPARAM wParam, LPARAM lParam )
{
  MSG* pmsg = reinterpret_cast<MSG*>(lParam);
  if(pmsg->message == WM_EXEC)
  {
    sciter::sync::event* pe = reinterpret_cast<sciter::sync::event*>(pmsg->wParam);
    gui_block* pf = reinterpret_cast<gui_block*>(pmsg->lParam);
    (*pf)();      // execute the block in this GUI thread
    pe->signal(); // signal that we've done with it
                  // this will resume execution of worker thread.
  }
  return CallNextHookEx(0,code, wParam,lParam);
}

Using hooks allows this mechanism to work reliably even when application is running modal dialog loops.

Leave a Reply

Your email address will not be published. Required fields are marked *

sixteen + six =