Hello @c4ds,
thank you for reaching out to us.
GetInputState()
Just as a FYI, while you not might remember me, I was actually already around on the old forum 😉 So, I had a look again, looking at our:
Codebase: Nothing is using BFM_INPUT_CHANNEL in this manner, not even really, really, really old code.
Plugin Café History: Yes, there are some mentions of GetInputState(BFM_INPUT_KEYBOARD, BFM_INPUT_CHANNEL, but these come exclusively from users who
a. Have problems with retreiveing the pressed key
b. Not use the method to retreive any speciifc key and are only intersted in modifiers or other data provided in the response container.
I did not find any code examples posted by Maxon using this form.
I do not want to be rude here, but what you are doing is not correct and likely never was. This code floated around on Plugin Café and apparently people were copying each other but the code is at least now simply wrong (when one is interested in polling specific keys).
Yes, you can use GetInputState(BFM_INPUT_KEYBOARD, BFM_INPUT_CHANNEL, bc) and this will not crash or any thing, but it is also meaningless. You could also call GetInputState(BFM_INPUT_KEYBOARD, 123456789, bc) and it would be as meaningful. If you are not interested in a specfic key being pressed, than this will also 'work' for you as the askchannel argument is then irrelevant.
But we should really stop indicating that this is the right way to go, because that is where all the confusion comes from. Find a Python script at the end of the posting which in detail demonstrates this. Please stop indicating that this is a valid approach, as people will read this and then the cycle starts over again.
Input Events Page for the C++ Documentation
Thank you for making me aware of this. The target of these links, page_input_events has long been removed. I still have access to that archived page, and while the page was not too useful, I can only speculate why it has been done in this form. I will fix this this in an upcoming release. In the meantime, you should look at:
the
BFM Symbol Group: This however does not contain only input event symbols, but all GUI related event symbols. Input event related symbols folllow the form BFM_INPUT_... plus things like the
KEY symbols or
the
Input Events page of the Python docs which is much better. Something like this unfournetely never existed in C++ the old C++ page was entierly different. Maybee it got removed in order to make room for something similar to the Python page, and then things were somehow not carried out?
Long story short, I will provide a meaningful input events page for C++ in the upcoming release. In the meantime I would recommend the Python page.
Cheers,
Ferdinand
The code for GetInputState(BFM_INPUT_KEYBOARD, BFM_INPUT_CHANNEL, bc) being not a meaningful thing:
"""Demonstrates that #BFM_INPUT_CHANNEL does not carry any meaning as the argument #askchannel for
GetInputState.
"""
import c4d
def main() -> None:
"""
"""
bc: c4d.BaseContainer = c4d.BaseContainer()
if not (c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD, c4d.BFM_INPUT_CHANNEL, bc)):
raise RuntimeError("Could not poll input event.")
# Iterate over the container, there is nothing meaningful in there when you want to query a
# specific key.
print ("\nThe result container:")
for key, value in bc:
print (f"key: {key}, value: {value}")
# And here some selected values to be a bit more verbose.
print ("\nSelected values:")
print (f"{bc[c4d.BFM_INPUT_CHANNEL] = }") # Will return 1768973153, i.e., itself.
print (f"{bc[c4d.BFM_INPUT_VALUE] = }") # Will return False.
print (f"{bc[c4d.BFM_INPUT_ASC] = }") # Will return the empty string.
# We can of course still use the result container to poll for things that are also evaluated as
# for example modifier keys (or the mouse position in case of the mouse device).
print ("\nThe container is still valid for other stuff, but BFM_INPUT_CHANNEL is" +
"meaningless in that context:")
print (f"BFM_INPUT_CHANNEL: {bc[c4d.BFM_INPUT_MODIFIERS] = }")
# But we would not have to use BFM_INPUT_CHANNEL for that, we also just could do this here:
bc: c4d.BaseContainer = c4d.BaseContainer()
if not (c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD, 123456789, bc)):
raise RuntimeError("Could not poll input event.")
print (f"123456789: {bc[c4d.BFM_INPUT_MODIFIERS] = }")
# And just for completeness, in case someone is just reading this snippet, here is how you
# should use these functions:
print ("\nHow it should be done:")
bc: c4d.BaseContainer = c4d.BaseContainer()
# Querying for a specific key with GetInputState.
print ("\nQuerying a specific input state:")
# Note that you must poll for upper case characters, e.g., X instead of x.
if not c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD, ord ("X"), bc):
raise RuntimeError("Failed to query input events.")
# Test if the queried key is indeed being pressed.
print (f"{bc[c4d.BFM_INPUT_VALUE] == 1 = }")
# Test if this did co-occur with a CTRL button press.
print (f"{bc[c4d.BFM_INPUT_QUALIFIER] == c4d.QUALIFIER_CTRL = }")
# Querying for the general state with key with GetInputEvent, i.e., capturing all inputs and
# not only a specific one.
print ("\nQuerying the current input state:")
bc: c4d.BaseContainer = c4d.BaseContainer()
if not c4d.gui.GetInputEvent(c4d.BFM_INPUT_KEYBOARD, bc):
raise RuntimeError("Failed to query input events.")
# Get the key which is currently be pressed as an ASCII value.
print (f"{bc[c4d.BFM_INPUT_CHANNEL] = } ({chr (bc[c4d.BFM_INPUT_CHANNEL])})")
# We can still read all the other things which are written into an input event container, as
# for example a modifier key state.
print (f"{bc[c4d.BFM_INPUT_QUALIFIER] == c4d.QUALIFIER_CTRL = }")
if __name__ == '__main__':
main()
An example output for pressing CTRL + X while running the script:
The result container:
key: 1768973430, value: 1801812322
key: 1768973153, value: 1768973153
key: 1768976737, value: 2
key: 1768975727, value: 258
key: 1768978017, value: 0
key: 1768977985, value: 0.0
key: 1801548643, value:
Selected values:
bc[c4d.BFM_INPUT_CHANNEL] = 1768973153
bc[c4d.BFM_INPUT_VALUE] = 0
bc[c4d.BFM_INPUT_ASC] = ''
The container is still valid for other stuff, but BFM_INPUT_CHANNEL ismeaningless in that context:
BFM_INPUT_CHANNEL: bc[c4d.BFM_INPUT_MODIFIERS] = 258
123456789: bc[c4d.BFM_INPUT_MODIFIERS] = 258
How it should be done:
Querying a specific input state:
bc[c4d.BFM_INPUT_VALUE] == 1 = True
bc[c4d.BFM_INPUT_QUALIFIER] == c4d.QUALIFIER_CTRL = True
Querying the current input state:
bc[c4d.BFM_INPUT_CHANNEL] = 88 (X)
bc[c4d.BFM_INPUT_QUALIFIER] == c4d.QUALIFIER_CTRL = True
>>>