Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Setting dialog fields from a thread

    SDK Help
    0
    7
    613
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      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;  
      msg.SetBool(BFM_STATUSBAR_PROGRESSON, TRUE);  
      msg.SetFloat(BFM_STATUSBAR_PROGRESS, d);  
      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
      {
      public:
               DownloadProgress(void);
               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.SetBool(BFM_STATUSBAR_PROGRESSON, TRUE);
               msg.SetFloat(BFM_STATUSBAR_PROGRESS, d);
               dlg->SendMessage(1002, msg);
               EventAdd(EVENT_FORCEREDRAW);
      }
        
      Bool DownloadProgress::downloadAsynchrone(void)
      {
          ....
          // start thread and monitor progress using DownloadProgress::PercentDone
          ...
      	return true;
      }
        
      class MainDialog : public GeDialog
      {
        
      public:
      	MainDialog(void);
      	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	
      		{
      		  DownloadProgress::downloadAsynchrone();
      		  break;
      		}
      	}
      	return true;
      }
        
          ...
        
      class MyPlugin : public CommandData
      {
      private:
      	MainDialog dlg;
        
      public:
        
      	//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.

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        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.

        ThreadsExampleR12++
        https://sites.google.com/site/scottayersmedia/plugins

        -ScottA

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          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.

          Pim

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            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.

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              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().

              Pim

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                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.

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  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
                              c4d.SpecialEventAdd(PLUGIN_ID)
                              time.sleep(0.3)
                    
                      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:
                              threading.Thread(target=self.Funk).start()
                          return True
                    
                      def CoreMessage(self, id, msg) :
                          if id == PLUGIN_ID:
                              with self.lock:
                                  self.SetString(1001, '***' * self.num)
                              self.LayoutChanged(1001)
                          return True
                    
                  dlg = Dialog()
                  dlg.Open(c4d.DLG_TYPE_ASYNC)
                  

                  Works perfectly fine on Mac and Windows.
                  Best,
                  -Niklas

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post