GeDialog.Message() return value ?

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

On 11/12/2012 at 13:35, xxxxxxxx wrote:

Info : Cinema 4D R14 Windows
Lang: Python

Hiho,

what are we supposed to return from a GeDialog.Message() method ? When i first wrote the
method i just returned a boolean True, causing C4D to crash pretty hard, so i red the c++ and 
python sdk, which both state :

_<_t_<__<_t_<__<_t_<__<_t_<__<_t_<__<_t_<__<_t_<__<_t_<__<_t_<__<_t_<__<_t_<__<_t_<__<_t_<__<_t_>_Returns:|
The return value depends on the message.

---|---

and that it should be long, which doesn't really help. So far i have tried :

# c4d crashes (dialog isn't drawn properly anymore plus constant error ding,
# c4d doesn't accept any input, i had to kill the process(with fire))
def Message (self, msg, result) :
	return super(CSettingsGeDialog, self).Message(self, msg, result)
  
# same as the super call
def Message (self, msg, result) :
	return GeDialog.Message(self, msg, result)
  
# c4d crashes, but in a different way than the parent calls. less colorfull :)
def Message (self, msg, result) :
	return 1
  
# c4d doesn't crash, but all dialog content is gone
def Message (self, msg, result) :
	return 0

I guess i am missing something important again ? I used the forum search, which came up
with some C++ examples, which used my second approach - a direct call to the GeDialog class,
which obviously doesn't work in python. The dialog is modal, created and opened from a 
CommandData.Execute-OptionID() method. The layout is loaded from a ressource file.

a larger code snippet ...

class CSettingsGeDialog(gui.GeDialog) :
  
    def __init__(self, documentPath) :
        self.AddGadget(c4d.DIALOG_NOMENUBAR, 0) #disable menubar
        self.DocumentPath = documentPath
        self.RenderPath = ""
  
    def Command(self, id, msg) :
        return True
  
    def CreateLayout(self) :
        geRessource = plugins.GeResource()
        geRessource.Init(dir)
        return self.LoadDialogResource(10001, geRessource, 0)
  
    def InitValues(self) :
        return True
  
    # Listen for keystrokes
    def Message (self, msg, result) :
        return 1
...........................................................................................................................................
  
    def ExecuteOptionID(self, doc, plugid, subid) :
        self.isActive = True
        if self.settingsDialog is None:
            self.settingsDialog = CSettingsGeDialog(doc.GetDocumentPath())
  
        screen = gui.GeGetScreenDimensions(0, 0, True)
        dialogResult = self.settingsDialog.Open(dlgtype  = c4d.DLG_TYPE_MODAL, 
                                                                       pluginid = PLUGIN_ID,
                                                                       xpos     = int(screen['sx2']/2) - 300, 
                                                                       ypos     = int(screen['sy2']/2) - 300)
	...

edit : Just to be clear, what i want to achieve - I have got a Textbox in my dialog to hold 
a folder path. The dialog accepts absolute and relative paths (relative to the location of 
the active document). I want to listen to the key strokes made while the dialog is open, 
so that when Enter is pressed that the current relative path is turned into an absolute 
path. Maybe there is an easier way to do this, than to listen the to the BFM_INPUT_KEYBOARD 
and BFM_INPUT_CHANNEL messages ?

thanks for your help in advance.

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

On 12/12/2012 at 02:32, xxxxxxxx wrote:

Hi,

Originally posted by xxxxxxxx

what are we supposed to return from a GeDialog.Message() method ? When i first wrote the
method i just returned a boolean True, causing C4D to crash pretty hard, so i red the c++ and 
python sdk, which both state :

Returns:
The return value depends on the message.

and that it should be long, which doesn't really help. So far i have tried:

The Python documentation is incomplete.
If you override GeDialog.Message() you should always call the parent method as last return, otherwise the GeDialog won't work.
It's stated in the C++ documentation but not in the Python one.
I'll fix that.

def Message (self, msg, result) :
	return super(CSettingsGeDialog, self).Message(self, msg, result)

I don't know why super() doesn't work with GeDialog, we get a type error:
TypeError: super(type, obj) : obj must be an instance or subtype of type

def Message (self, msg, result) :
	return GeDialog.Message(self, msg, result)

I think it crashes because GeDialog isn't imported in the global context.
If you only import gui module, you have to call it this way:

def Message (self, msg, result) :
	return gui.GeDialog.Message(self, msg, result)

But at least, CINEMA shouldn't crash just because GeDialog isn't declared. I'll report this as a bug.

Originally posted by xxxxxxxx

edit : Just to be clear, what i want to achieve - I have got a Textbox in my dialog to hold 
a folder path. The dialog accepts absolute and relative paths (relative to the location of 
the active document). I want to listen to the key strokes made while the dialog is open, 
so that when Enter is pressed that the current relative path is turned into an absolute 
path. Maybe there is an easier way to do this, than to listen the to the BFM_INPUT_KEYBOARD 
and BFM_INPUT_CHANNEL messages ?

If you want to get live feedback from an textbox, I posted a code snippet some months ago.

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

On 12/12/2012 at 04:13, xxxxxxxx wrote:

hi,

thanks for your help,

def Message (self, msg, result) :
        print "moo"
        return gui.GeDialog.Message(self, msg, result)

seems to work great - at least for a quick test. c4d doesn't crash anymore. thanks for your
help again, keep up the good (support) work.

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

On 12/12/2012 at 04:22, xxxxxxxx wrote:

Hello Ferdinand and Yannick,

you're both passing self to super().Message. This is wrong. The following
works fine (at least for me) :

class Dlg(c4d.gui.GeDialog) :  
  
  def Message(self, *args) :  
      print "Message%s" % (args,)  
      return super(Dlg, self).Message(*args)

Best,
Niklas

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

On 12/12/2012 at 04:34, xxxxxxxx wrote:

Originally posted by xxxxxxxx

Hello Ferdinand and Yannick,

you're both passing self to super().Message. This is wrong. The following
works fine (at least for me) :

class Dlg(c4d.gui.GeDialog) :  
 
  def Message(self, *args) :  
      print "Message%s" % (args,)  
      return super(Dlg, self).Message(*args)

Best,
Niklas

now as you have written it, it seems pretty obvious, that you shouldn't pass self as super
call argument. i think i have also ran into this problem with GetDeEnabling once. thanks again. 🙂

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

On 16/12/2012 at 23:38, xxxxxxxx wrote:

hi,

i did some other things first, but now i came back to this problem and i thought i would be 
nice if shared my results, if someone might be finding this thread with the search function.
looking for c4d.BFM_GETCURSORINFO gave me this msg BaseContainer , which doesn't really 
help and it is only triggered when the cursor is over the textbox as the name suggests.

----------------------------------------------------------------------------------------------------
<c4d.BaseContainer object at 0x0000000012163C70>
          >id: 3, value: 558
          >id: 4, value: 326
          >id: 1667853926, value: <c4d.BaseContainer object at 0x0000000012169F48>
          >          >id: 1, value: 21
----------------------------------------------------------------------------------------------------

c4d.BFM_INPUT_DEVICE and other ids described in the thread i couldn't find listening to msg. 
but i found c4d.BFM_ACTION_VALUE and c4d.BFM_INPUT_CHANNEL.

the first one is holding kind of the last 'action' in the gui. in case of a textbox the string of 
the textbox. the second one seems to be written if you press keys like F1 and so on. 
however the enter key isn't fired as c4d.BFM_INPUT_CHANNEL, but as c4d.BFM_ACTION_VALUE .

while you are typing 'abcd' c4d.BFM_ACTION_VALUE  is a string (the whole 'abcd'), but when 
you press enter it becomes Long and is 1. so checking for the user pressing enter is simply :

def Message (self, msg, result) :
   if(msg.GetLong(c4d.BFM_ACTION_VALUE) == 1) :
       print 'Enter'
   return gui.GeDialog.Message(self, msg, result)

not sure if this is intended, but it works for me.