Manipulate extended GeDialog from ext methods.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 25/04/2011 at 12:22, xxxxxxxx wrote:

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

    ---------
    Hi

    I have a "strange" problem using win thread and GeDialog.

    I've extended the GeDialog class usually with my own class and in the overrided 'Command' method I've recall a thread using w32 api like this:

    ...
    l_thread_exec->st_f_callback = callbackFun
    l_thread_exec->ref_dialog = this;

    HANDLE l_upload_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFun, l_thread_exec, 0, NULL);
    ...

    The 'callbackFun' is called by the created thread ('ThreadFun') and this is define like this:

    callbackFun(int p_result, GeDialog* p_dialog)

    I want to pass to the 'ThreadFun' parameters the current GeDialog pointer (using 'this' in the 'ref_dialog' structure variable) because in the callback function ('callbackFun') I want to access this dialog to set some properties like button enable/disable and similar stuffs. In effect, in the 'callbackFun' I'm able to call GeDialog methods like this:

    Bool result = p_dialog->Enable(DLG_BTN_UPLOAD_STOP, false);

    I have NO compilation or runtime error, but the propertie isn't set!!! Simple, the 'result' above value is set to false ever and ever! Idem if I use any other GeDialog method like 'HideElement', 'SetString' on 'EditText' control or similar. The GeDialog pointer seems to be correct (same pointer location verified using the vs degubber) but all interface changes have no results!! If I made these changes within a 'GeDialog' method extended class all work fine.

    Finally, I can't pass the GeDialog pointer through the methods to change the UI properties? These changes should be made only within the GeDialog extended class? There are others solutions?

    Many thanks!

    Bye!
    < ="-" ="text/; =utf-8">



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 25/04/2011 at 15:27, xxxxxxxx wrote:

    After others test, I can confirm that the GeDialog methods are "ignored" when called directly or indirectly from a function wrapped with a Win thread. For example you can define a function like this out the extended GeDialog class:

    void testDialog(GeDialog* p_dialog) {
       p_dialog->Enable(SOME_ID_GADGET, true);
    }

    If you call this method from the 'Command' method, for example, passing 'this' as parameter all work fine. But if you call this function from a 'threaded function' (using CreateThread win32 api), the 'Enable' method fails. Something bad happens in the thread, even if the pointer value seems to be correct and no static or dinamic error is raised.

    Incomphrensible for me, and I don't think that this is a SDK issue...someone has never been in a similar case?

    Many thanks! Bye.
    < ="-" ="text/; =utf-8">< ="-" ="text/; =utf-8">



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 26/04/2011 at 05:38, xxxxxxxx wrote:

    sorry but .... did you tried to pass not a GeDialog Pointer but a your "GeDialog Instance" ?
    i am not a win api expert but if you pas the base class you have not the chance to acces your custom features made in your own subclassed dialog.

    i suppose you have some like this :

    class mydialog : public GeDialog
    {
    public:
    ext ext ext.....
    }
    then you fuction should be :

    void testDialog(mydialog* p_dialog)
    {
       p_dialog->Enable(SOME_ID_GADGET, true);
    }

    i am not sure but this can be a possibilities :)
    Franz



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 27/04/2011 at 10:14, xxxxxxxx wrote:

    Hi franz. Thanks for your reply.

    Unfortunatly, this is not the problem because the pointer passed is, in effect, related to my extended class (your mydialog example), simply is passed as base type (Gedialog).

    Returning from thread, I'm able to call any method I want (with a cast to my type, in case...). In effect I'm interested to call only the base class methods, like 'Enable' or similar stuffs. So, even with the "specific" extended instance I've the same problem...sigh...



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/04/2011 at 07:54, xxxxxxxx wrote:

    how you get the dialog pointer outside the plugin ?
    with an extern variable?

    Franz



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/04/2011 at 07:54, xxxxxxxx wrote:

    I am not sure but if I remember correctly it's not allowed to call Cinema's GUI methods from a threading context.

    cheers,
    Matthias



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/04/2011 at 10:11, xxxxxxxx wrote:

    Is my fear! it seems that the GeDialog pointer passed to thread is no longer "valid" in the called thread or in the callback called from thread (even if the address is correct and no runtime error happens).

    Originally posted by xxxxxxxx

    I am not sure but if I remember correctly it's not allowed to call Cinema's GUI methods from a threading context.

    cheers,
    Matthias



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/04/2011 at 10:41, xxxxxxxx wrote:

    < ="-" ="text/; =utf-8">>Originally posted by xxxxxxxx

    how you get the dialog pointer outside the plugin ? 
    with an extern variable?

    Franz

    No. Sorry for my bad english and description, is difficult to explain correctly, I try to explicate the problem again:

    Simply I have my plugin where I've extended the GeDialog class. So, in the overrided 'Command' method of this class, I have to call a Win Thread (I work under Windows) like this (I've omitted some code obviously) :

    virtual Bool Command(LONG id, const BaseContainer &msg) {
    ...
    switch (id) {
     case(...) : {
    ...
    break;
     }

      case(DLG_BTN_X) : {
         struct st_thread_exec\* l_thread_exec = new st_thread_exec();
    

    ...
         l_thread_exec->st_f_callback = C4DSceneCallback;
         l_thread_exec->ref_dialog = this;

         HANDLE hThread = (HANDLE)\_beginthreadex(NULL, 0, &C4DSceneThreading, l_thread_exec, 0, NULL);
    	break;
      }
    

    }

    ....
        DrawViews(DRAWFLAGS_NO_THREAD);
        return TRUE;
        ....
      }
    };

    As you can see, I'm able to call the C4DSceneThreading function passing a struct (l_thread_exec) which old both the callback name function (C4DSceneCallback) and the pointer to the current my own dialog (ref_dialog = this).

    Now, simply, under the C4DSceneThreading I have to call a callback when the (very long!) operations has been terminated inside the thread. The threaded function is declared and implemented like this:

    unsigned __stdcall C4DSceneThreading(void* p_thread_exec) {
            ...
    GeDialog* l_dialog = ((struct st_thread_exec* )p_thread_exec)->ref_dialog;
    void (*l_st_f_callback)(GeDialog* ) = ((struct st_thread_exec* )p_thread_exec)->st_f_callback;
     
    ... Others long operations ...

    //NOW the thread end and I've to call the callback to work on the interface plugin: l_dialog pointer.
    (void)(*l_st_f_callback)(l_res, l_dialog);
    ExitThread(1);
    }

    So, the callback is called and  the code is like this:

    void C4DSceneCallback(GeDialog* p_dialog) {
       ...
       //Generic operations...
       ...

    //WORK ON MY GEDIALOG INTERFACE RETURNED AS POINTER!!
       Bool one = p_dialog->Enable(DLG_BTN_UPLOAD_STOP, false);
       Bool two = p_dialog->Enable(DLG_BTN_UPLOAD, true);
    }

    Simply, 'one' and 'two' boolean return false!! NO static errors or runtime errors are reised, simply the interface (GeDialog pointer) prevents the properties setting!! This happens even I call the 'Enable' (or similar!) methods directly inside the 'C4DSceneThreading' function. Within 'classic' method all work fine. Again, passing trough a thread become impossible to set the GeDialog properties. This is a SDK limit? There is others solutions? I don't think that there is no thread call in C4D :D

    Many many thanks FOR ANY HELP! Sorry for the long description.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 01/05/2011 at 03:31, xxxxxxxx wrote:

    Hi

    Then, I'm definitively desperate :( I've tried to use directly the thread SDK interface (I've seen just today the thread classes....) but the result is the same!

    I've implemented the 'C4DThread' abstract class and inside the 'Main' method I've tried to set the GeDialog properties like this:

    class C4DSS_C4DThread : public C4DThread {
    private:
    st_thread_exec* m_thread_params;

    public:
    C4DSS_C4DThread() { }

    C4DSS_C4DThread(void\* p_thread_params) {
    	m_thread_params = (st_thread_exec\* )p_thread_params;
    }
    
    
    void Main() {
    	C4DSceneThreading(m_thread_params);
    
    
    	Bool 'one' = m_thread_params->ref_dialog->Enable(DLG_BTN_STOP, false);
    	Bool 'two' = m_thread_params->ref_dialog->Enable(DLG_BTN, true);
    }
    
    Bool TestDBreak(void) { return FALSE; }
    
    const CHAR \*GetThreadName(void) {
    	return "\__my_Thread";
    }
    

    };

    No luck!!! The Main thread method is called, 'C4DSceneThreading' is called, 'one' and 'two' boolean are still FALSE!!!! No chance to set the GeDialog interface button or something else!!! Obviously I've tried to move the 'Enable' calls within C4DSceneThreading and others desperates tests....nothing!

    "I'm don't know what fish to catch..."

    Thanks for any other suggestion!

    Bye...
    < ="-" ="text/; =utf-8">



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 02/05/2011 at 06:26, xxxxxxxx wrote:

    Changing dialogs is only allowed in Cinema's main thread, for instance in received messages.

    Trying to change dialogs in own or external threads is strictly forbidden.

    cheers,
    Matthias



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 02/05/2011 at 10:51, xxxxxxxx wrote:

    Hi matthias. 'Nice', this is a fact now. But, what do you mean with "...in received messages."? You can suggest to me a way (a simple example...) to achive my goal?

    Many thanks! Bye.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 03/05/2011 at 03:48, xxxxxxxx wrote:

    With received messages I mean messages received in a plugin's Message method, for instance within CommandData::Message or GeDialog::Message.

    cheers,
    Matthias



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 03/05/2011 at 11:18, xxxxxxxx wrote:

    Hi Matthias, thanks for your suggestion. I've tried now to use the GeDialog::SendMessage call but I've a compile error like:

    error C2039: 'SendMessageA' : is not a member of 'GeDialog'
    1>        c:\program files\maxon\cinema 4d r12\resource\_api\c4d_gui.h(249) : see declaration of 'GeDialog'
    error C2660: 'SendMessageA' : function does not take 2 arguments

    I'm not able to find the redefined method...and I don't know why the compiler try to call this method...What's wrong? Some include conflict can be generate this problem?

    Many thanks!

    Originally posted by xxxxxxxx

    With received messages I mean messages received in a plugin's Message method, for instance within CommandData::Message or GeDialog::Message.

    cheers,
    Matthias


Log in to reply