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

    Message for link set

    SDK Help
    0
    4
    359
    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 07/05/2015 at 19:14, xxxxxxxx wrote:

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

      ---------
      I have a bit of code where I check if a link has been...or perhaps is about to be set and I use that link to setup other links:

      	switch (msg.GetId())
      	{
      		case BFM_DRAGRECEIVE:
      		{
      			if (msg.GetInt32(BFM_DRAG_FINISHED)) {
      				Int32 activeTab;
      				GetInt32(IDC_TAB_1, activeTab); //Get current active tab
        
      				for(maxon::HashMap<UInt, objEntry>::Iterator i = _objTable.Begin(); i != _objTable.End(); ++i) {
      					Bool bFound = false;
      					Int32 guiID = 0;
        
      					if(activeTab == IDC_GRP_TAB1) {
      						guiID = i.GetValue().GetsObjID();
      						bFound = CheckDropArea(guiID, msg, TRUE, TRUE);
      					}
      					else if(activeTab == IDC_GRP_TAB2) {
      						guiID = i.GetValue().GettObjID();
      						bFound = CheckDropArea(guiID, msg, TRUE, TRUE);
      					}
        
      					if(bFound) {
      						//GePrint("Object dragged to: " + String::IntToString(guiID));
      						void* obj = nullptr;
      						Int32 type = 0;
      							
      						GetDragObject(msg, &type, &obj);
      						if((type == DRAGTYPE_ATOMARRAY) && (((AtomArray* )obj)->GetCount() == 1) && ((AtomArray* )obj)->GetIndex(0)) {
      							AutoFillObj(guiID, (BaseObject* )((AtomArray* )obj)->GetIndex(0));
      						}	
      					}
      				}
      			}
      			
      			break;
      		}
      	}
      

      Thing is, the LinkBoxGui's update but when I use these objects later I find that they don't actually exist. It's as if when I call SetLink in my AutoFillObj function the Gui's get updated but the links aren't propagated. Also when I use the picker (pickwhip, selection thingy) for the link box's to pick an object the  BFM_DRAGRECEIVE event doesn't run. Obviously because it's not a drag and drop. I think I can fix this if I knew what event in general happens when a link is set in a LinkBoxGui.

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

        On 07/05/2015 at 23:31, xxxxxxxx wrote:

        Hi,

        Never filter BFM_DRAGRECEIVE nor check BFM_DRAG_FINISHED for gadgets in a dialog: this is automatically handled by Cinema.

        To dynamically check the objects that can be accepted for a link gadget in a dialog, listen for MSG_DESCRIPTION_CHECKDRAGANDDROP in GeDialog::Message(). See LINK documentation.
        To be notified after an object has been set for a link in a dialog, listen for BFM_ACTION in GeDialog::Message(). See BFM_ACTION documentation.

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

          On 08/05/2015 at 14:49, xxxxxxxx wrote:

          Cool cool, so I got that and it's great that the code is shorter and more clean, but when I set links in my auto fill function they still don't work later in the program:

          	switch (msg.GetId())
          	{
                  case BFM_ACTION:
                  {
                      Int32 guiID = msg.GetInt32(BFM_ACTION_ID);
                              
                      GePrint("Action performed on GuiID: " + String::IntToString(msg.GetInt32(BFM_ACTION_ID)));
          			LinkBoxGui* linkGui = (LinkBoxGui* )FindCustomGui(guiID, CUSTOMGUI_LINKBOX);
          			if(linkGui)
          				AutoFillObj(guiID, (BaseObject * )linkGui->GetLink(GetActiveDocument()));
            
          			break;
                  }
          	}
            
          	return GeDialog::Message(msg, result);
            
          void someDialog::AutoFillObj(Int32 guiID, BaseObject* dropObj)
          {
          	BaseDocument* doc = GetActiveDocument();
          	Bool bCharFound = false;
          	Bool bNumFound = false;
          	Int32 charPos = -1;
          	String sName = dropObj->GetName();
          	String rootObjName;
          	String aObjName;
          	String bObjName;
            
          	//GePrint("Object dropped is: " + sName);
            
          	// let's check and see if 'a' is at the beginning of the name, if not we will check for 'alpha'
          	bCharFound = sName.Left(1) == "a";
          	charPos = 1;
          	
          	if(!bCharFound && sName.GetLength() > 4) {
          		bCharFound = sName.Left(4) == "Alpha;
          		charPos = 4;
          	}
          	
          	// let's parse the string if we found a l or Left and then see if a number is on the end
          	if(bCharFound) {
          		rootObjName = sName.SubStr(charPos, sName.GetLength()-1);
          		bNumFound = sName.Right(1) == "1";
          		if(bNumFound) rootObjName = rootObjName.SubStr(0,rootObjName.GetLength()-1);
            
          		// so now we know there's a prefix and maybe a number, we have the root name of the object
          		// so we'll rebuild the name depending on if there's numbers or not, and SetLinks 
          		// automatically for the user
          		
          		//GePrint("Found an a or Alpha." ); //debug
          		if(guiID > 2999 && guiID < 4000) {
          			//GePrint("Name with prefix/postfix removed: " + rootObjName); //debug
            
          			if(bNumFound){
          				for(int i = 0; i < 3; i++) {
          					if(i > 0) {
          						if(charPos == 1)
          							aObjName = "a" + rootObjName + String::IntToString(i+1);
          						else if(charPos == 4)
          							aObjName = "Alpha" + rootObjName + String::IntToString(i+1);
          						BaseObject* aObj = doc->SearchObject(aObjName);
          						LinkBoxGui* aObjLink = (LinkBoxGui* )FindCustomGui(guiID + i, CUSTOMGUI_LINKBOX);
          						if(leftObj) aObjLink->SetLink(leftObj);
          					}
            
          					if(charPos == 1)
          						rightObjName = "r" + rootObjName + String::IntToString(i+1);
          					else if(charPos == 4)
          						rightObjName = "Right" + rootObjName + String::IntToString(i+1);
          					BaseObject* bObj = doc->SearchObject(bObjName);
          					LinkBoxGui* bObjLink = (LinkBoxGui* )FindCustomGui(guiID + 1000 + i, CUSTOMGUI_LINKBOX);
          					if(rightObj) bObjLink->SetLink(rightObj);
          				}
          			}
          			else {
          				if(charPos == 1)
          					bObjName = "b" + rootObjName;
          				else if(charPos == 4)
          					bObjName = "Beta" + rootObjName;
          				BaseObject* bObj = doc->SearchObject(bObjName);
          				LinkBoxGui* bObjLink = (LinkBoxGui* )FindCustomGui(guiID + 1000, CUSTOMGUI_LINKBOX);
          				if(rightObj) bObjLink->SetLink(bObj);
          			}
          		}
          	}
            
          	return;
          }
          

          Is this an issue with something being dirty or me not running some event or message after these SetLinks? Basically only the objects I manually drag into Linkbox's have links, the ones I'm auto filling for the user don't seem to be used later on even though the GUI updates in Cinema showing that the links are there.

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

            On 11/05/2015 at 09:10, xxxxxxxx wrote:

            It's hard to tell without being able to debug such piece of code.
            But EventAdd() should be definitely called after the link is set so that Cinema is notified  to update the active document.

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