Setting dialog fields from a thread

On 19/03/2014 at 02:57, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R15 
Platform:   Windows  ;   
Language(s) :     C++  ;

I have a command plugin with a dialog.
In this dialog I start up another thread._<_o:_<_o:p_>_o:p>
To monitor the progress, I want – in the thread – to update a slider in my dialog.
Thus, I want to use – again in my thread – followi_<_o:_<_o:p_>_

d = Float(pctDone) / 100.0;  
dlg->SendMessage(1002, msg);					//send message to dialog with progress info

However, how to pass the dlg, the pointer to the dialog, to the thread?
Here some snippets of the code

class DownloadProgress : public CkHttpProgress
         virtual ~DownloadProgress(void);
         void PercentDone(int pctDone, bool *abort);
		 static Bool downloadAsynchrone(void);
void DownloadProgress::PercentDone(int pctDone, bool *abort)
         BaseContainer msg(BFM_SETSTATUSBAR);
         Float d = Float(pctDone) / 100.0;
         msg.SetFloat(BFM_STATUSBAR_PROGRESS, d);
         dlg->SendMessage(1002, msg);
Bool DownloadProgress::downloadAsynchrone(void)
    // start thread and monitor progress using DownloadProgress::PercentDone
	return true;
class MainDialog : public GeDialog
	virtual ~MainDialog(void);
	virtual Bool CreateLayout(void);
	virtual Bool InitValues(void);
	virtual Bool Command(Int32 id, const BaseContainer& msg);
	virtual Int32 Message(const BaseContainer& msg, BaseContainer& result);
Bool MainDialog::Command(Int32 id, const BaseContainer& msg)
	switch (id) 
		case 1000:		//do command	
	return true;
class MyPlugin : public CommandData
	MainDialog dlg;
	//static MainDialog dlg;
	virtual Bool Execute(BaseDocument* doc);
	virtual Bool RestoreLayout(void* secret);
Bool MyPlugin::Execute(BaseDocument* doc)
	return dlg.Open(DLG_TYPE_ASYNC, ID_PIM, -1, -1); 
Bool MyPlugin::RestoreLayout(void* secret)
	return dlg.RestoreLayout(ID_PIM, 0, secret);
Bool RegisterMyPlugin(void)
	return RegisterCommandPlugin(ID_PIM, "Dialog - Threading", 0, AutoBitmap("icon.tif"), String("Chilkat Threading"), NewObjClear(MyPlugin));

Thanks to Steve for his previous help on the threading part.

On 19/03/2014 at 07:47, xxxxxxxx wrote:

There's a threads example on my site that increments a text gizmo like a counter using a custom thread.
Which should be easily changed to moving a slider with a minor code change.



On 19/03/2014 at 09:39, xxxxxxxx wrote:

Yes and your example is working perfectly! Thanks.
But it is very frustrating that I cannot get in to work in the way I describe.
I know it must work, but I can't get it to work.


On 19/03/2014 at 15:56, xxxxxxxx wrote:

I haven't looked at Scotts example, but the usual way is to use SpecialEventAdd(), catch that message
in the dialog, and instead of making the thread work on the dialog, let the dialog update the progress
state itself by asking the thread.

Calling SpecialEventAdd() is thread-safe.

On 20/03/2014 at 05:44, xxxxxxxx wrote:

Scotts example is working real great, but I am trying to figure out other ways.

At this moment I am using GeSyncMessage(pluginid, 9001, 9001, pctDone) and that is working great on Windows. However on Mac it seems as if the threat blocks cinema until down.
After the thread finishes I receive ALL GeSyncMessage in one go.
On windows the GeSyncMessage messages are received when the thread is running (not after as on the mac).

I am going to try SpecialEventAdd().


On 20/03/2014 at 08:05, xxxxxxxx wrote:

OK, I tried the following:

GeSyncMessage(EVMSG_ASYNCEDITORMOVE, 0, 9001, pctDone);
Working under Windows. Messages are received while the tread is running
Not working under Windows. Messages are NOT received while the tread is running. Only after the thread is stopped.

Note: instead of EVMSG_ASYNCEDITORMOVE, I can also use the pluginid (ID_PIM)
It is has not effect on the outcome. Windows ok, Mac not ok.

SpecialEventAdd(ID_PIM, 9001, pctDone);
Not working under Mac. Messages are NOT received while the tread is running. Only after the thread is stopped.
Not working under Mac. Messages are NOT received while the tread is running. Only after the thread is stopped.

On 23/03/2014 at 20:37, xxxxxxxx wrote:

I've made a quick test in Python, there is no difference regarding the implementation of
SpecialEventAdd, it all goes through the place of the application.

import c4d
import time
import threading
PLUGIN_ID = 100234324
class Dialog(c4d.gui.GeDialog) :
    def __init__(self) :
        super(Dialog, self).__init__()
        self.lock = threading.Lock()
        self.num = 0
    def Funk(self) :
        for i in xrange(10) :
            with self.lock:
                self.num += 1
    def CreateLayout(self) :
        self.AddButton(1000, 0, name="Make Action!")
        self.AddStaticText(1001, 0, name="<empty>")
        return True
    def Command(self, param, msg) :
        if param == 1000:
        return True
    def CoreMessage(self, id, msg) :
        if id == PLUGIN_ID:
            with self.lock:
                self.SetString(1001, '***' * self.num)
        return True
dlg = Dialog()

Works perfectly fine on Mac and Windows.