BitmapButton in GeDialog not clickable

On 28/01/2016 at 15:18, xxxxxxxx wrote:

great example Scotta, also cleaner than my solution "though it should give the same result"

On 29/01/2016 at 04:47, xxxxxxxx wrote:

Thanks Scott & Mohamed but actually I want a clickable button not a toggable button (see my code above). So once I pressed it, it should show the pressed state and once the click releases switch back to non-pressed state. Just like a normal button (which should imo be what the customgui should do by default but it doesn't...which kind of contradicts the purpose of a button).

I check the state initialisation now (though I am not sure how it relates to the automatic button state).

On 29/01/2016 at 04:54, xxxxxxxx wrote:

Setting the toggle state after AddCustomGui didn't change anything unfortunately. So I am still looking for a way to make the bitmap button behave like a normal button.

If I have to do it myself I would need to know how I can detect when the user releases the mouse click. I will try now and see if BitmapButtonCallback can help out here.

If there is no such event or message, I would also need to know so I can go down the route of an own customgui (which would feel like reinventing the wheel).

On 29/01/2016 at 08:22, xxxxxxxx wrote:

Oh that....yeah... they broke the hell out of that in R13.
I asked about it here many times. And they just looked at me like I had bugs crawling out of my teeth.

In R12. When you clicked on a bitmap button. It stayed down automatically.
Another thing that we could do in R12 was use a raised border on the button and it would still animate up/down like how a real physical button works. That got clobbered in R13 too.

I brought this up several times. And people thought I was nuts.
I guess I found another nut.:wink:


On 29/01/2016 at 08:39, xxxxxxxx wrote:

You are not alone.  Toggle buttons (on/off state) work great with two bitmaps.  As you and Katachi noticed, this doesn't work for non-Toggle buttons.  You get a thin down border when you click one but that is it.  Add me to the nut collection.

On 29/01/2016 at 10:21, xxxxxxxx wrote:

Thanks guys, at least I know now that I am nuts and in good company! :D

Btw. I tried using the callback but it is only triggered for right mouse clicks so no solution there either.

On 29/01/2016 at 10:25, xxxxxxxx wrote:

Oooopsy, when looking into this thread this morning, I thought it would actually be solved.
Sorry guys, I will look into this on Monday.

On 29/01/2016 at 14:29, xxxxxxxx wrote:

Ok, after fiddling with this all day and trying all possible combinations, I think I have it working now.

I have wrapped it all into a class too and I have uploaded the code for it into Navié's GitHub repository:

You can decide if the class adds a non-button image, a toggable button or a clickable button.

I tried this only on Windows with C4D R16 yet though. I'd be glad to hear if it works for you as well.
Hopefully this prevents others from suffering in the same way. :)


On 29/01/2016 at 16:34, xxxxxxxx wrote:

Hope that it works more universally.  The amount of T&E; is oft times frustrating for such small gains.  Thank you for the work and frustration!

On 29/01/2016 at 19:23, xxxxxxxx wrote:

I'm having a hard time using that code in R13.
Too many specialized things in there that need to be changed.

All I really need is a way to toggle the border style as well as the IconID.
Something like this:
  settings.SetLong(BITMAPBUTTON_BORDER, btnState == false? BORDER_IN : BORDER_NONE);

But I've never been able to make it work.
Are you doing something like that in your code? Or something different?


On 30/01/2016 at 03:59, xxxxxxxx wrote:

There's not much special to it really. It's just using R15+ SDK and C++11 language features. I am not switching between border styles with this but between two icons (registered with RegisterIcon).

I have updated the github code so it should be compatible with R13 and also to work with non-C++11 compliant compilers (such as VS 2012 and before). See the comments in DialogBitmapButton.h (top of file) for this. Haven't tested it yet though.

On 30/01/2016 at 07:31, xxxxxxxx wrote:

Oh Ok. You're still switching between icons.
The problem that I was referring to (and thought you were referring to) that Maxon broke sing R13 was the button's border.
In older versions. The button's border style could be swapped raised/lowered. But now all we can do is swap the icons. And that sucks.
Now the only way to create an actual real looking animated button is to create 2 images that have painted raised/lowered borders on them. And register them with unique ID#s.
It was much nicer the old way.

Thanks for posting your code.
I've never used the RMB callback before. That might come in handy some day.


On 30/01/2016 at 10:12, xxxxxxxx wrote:

I have updated the class so you it supports what you want (pass false for 'custom_border' variable when calling AddToLayout). This doesn't work with border styles though because the customgui has its own border effect for it (and for switching the border styles manually there is not enough access/messages).

You can also now pass a tooltip string and overwrite fading effect with a background color too.
github repository is updated.

Hope this helps but I will leave this now. I already spent too much time with it. :)

On 30/01/2016 at 10:18, xxxxxxxx wrote:

I found a way to toggle the border of the button. But it's a bit heavy handed and long in the tooth.
I'll post it here in case anyone needs this kind of behavior.

//The SDK BITMAPBUTTON_TOGGLE option does not let you keep the button looking like it's in a pressed state  
//This code creates a GeDialog plugin with a bitmap button on it  
//The button's image and border style toggles like an actual physical button (it stays pressed or unpressed)  
//To make the border style change. I had to use LayoutFlushGroup() to destroy and re-make the entire button  
//It works...But it requires a lot of code for something as trivial as toggeling a button's border  
#include "c4d.h"  
#include "c4d_symbols.h"  
#define PLUGIN_ID 1000006  // be sure to use a unique ID obtained from  
  BTN_GRP           = 10001,  
  MY_BITMAP_BUTTON1 = 10002  
class MyDialog : public GeDialog  
      virtual Bool CreateLayout(void);  
      virtual Bool InitValues(void);          
      virtual Bool Command(LONG id,const BaseContainer &msg);  
      MyDialog *dlg;  
      BitmapButtonCustomGui *myButton;    //The button with an image on it  
      Bool btnState = false;              //The state of the toggle button  
      void ReLayout(void);                //Used to redraw the GeDialog  
      void CreateButton(void);            //Used to create the bitmap button dynamically  
Bool MyDialog::CreateLayout(void)  
  Bool res = TRUE;  
  res = LoadDialogResource(IDS_RESDIALOG,NULL,0);  
  //This is an example of creating a custom button locally(not in the .res file) with AddCustomGui()  
  GroupBegin(BTN_GRP, BFH_LEFT, 2, 0, "MyButtonGroup", 0);  
  return res;  
Bool MyDialog::InitValues(void)  
  if (!GeDialog::InitValues()) return FALSE;  
  return TRUE;  
void MyDialog::ReLayout(void)  
void MyDialog::CreateButton(void)  
  BaseContainer bbc;    //Create a container to hold our custom button gizmo  
  if(btnState == false)  
      bbc.SetString(BITMAPBUTTON_TOOLTIP, "I'm Up");  
      bbc.SetString(BITMAPBUTTON_TOOLTIP, "I'm Down");  
  myButton = static_cast<BitmapButtonCustomGui*>(this->AddCustomGui(MY_BITMAP_BUTTON1, CUSTOMGUI_BITMAPBUTTON, "Bitmap Button", BFH_SCALEFIT | BFH_SCALEFIT, 130, 30, bbc));  
Bool MyDialog::Command(LONG id,const BaseContainer &msg)  
  switch (id)   
      case MY_BITMAP_BUTTON1:  
          GePrint("Bitmap Button Was Pressed");      
          btnState = !btnState;                 //Makes the variable toggle true / false  
          myButton->SetToggleState(btnState);   //Toggles the button image  
          ReLayout();                           //Run the custom method that creates the button dynamically  
  return TRUE;  
class MyDialogCMD : public CommandData   
      MyDialog dlg;  
      virtual Bool Execute(BaseDocument *doc);  
      virtual Bool RestoreLayout(void *secret);          
Bool MyDialogCMD::Execute(BaseDocument *doc)  
  return dlg.Open(DLG_TYPE_ASYNC,PLUGIN_ID, -1, -1, 200,200);  
Bool MyDialogCMD::RestoreLayout(void *secret)  
  return dlg.RestoreLayout(PLUGIN_ID,0,secret);  
Bool RegisterMyDialogCMD(void)  
  String Help = "Toggles Bitmap Button's border style";      //This string appears in the status bar when the user hovers over the plugin name in the menu  
  //Register the plugin  
  return RegisterCommandPlugin(PLUGIN_ID, GeLoadString(IDS_RESDIALOG), 0, AutoBitmap("icon.tif"), Help, gNew MyDialogCMD);  


*Edit- Oops. Cross posted with you there.
Thanks again for the code Katachi