Notifications
Clear all

[Closed] Highlighting pickbutton using SDK?

I thought they were. Turns out I had set the .pdb settings correctly for the 32 bit configurations but not the 64 bit ones. Whoops, KIND OF IMPORTANT! XD

I just got breakpoints working properly with my latest test file, so I’ll copy the settings for the one I’m working on and let you know what results I come up with.

Glad you got them working! Difficult to imagine writing plugins without them

As suggested earlier, my pickbutton is in fact Null. I found that the line causing the error is

void TestUtilPickModeCallback::EnterMode (IObjParam *ip) {
  theTestUtil.pickButton->SetCheck(TRUE);
}

which is causing an unhandled exception error.

I realized that my Init function was never getting called so I added this to my DlgProc function:

    case WM_INITDIALOG: {
      theTestUtil.Init(hWnd);
      break;
    }

Unfortunately, that did not fix the problem. I added a line to my Init function to see if pickButton was being defined.

void TestUtil::Init(HWND hWnd) {
  pickButton = GetICustButton(GetDlgItem(hWnd, IDC_PICKOBJ));
  if (pickButton == NULL) {mprintf("  pickButton is NULL
"); }
};

It is not. So I have found the source of the problem, or at least one of them, but I have no idea why my Init function is not doing what it is supposed to.

For reference, I’m using cppout.cpp as my guide since it is a fairly short file and has what I am looking for. Clearly though, there is something I am not seeing.

Any suggestions??

Don’t add the Init function in WM_INITDIALOG.

Add it like this:


 switch (msg) 
 {
 	  case WM_COMMAND:
 	 {
 		   switch(LOWORD(wParam))
 		  {
 			   case YOUR_BUTTON_IDC:
 			   {
 					 theTestUtil.Init(hWnd);
 					 break;
 			   }
 		   }
 		   break;
 	 }
 }
 

Replace “YOUR_BUTTON_IDC” with the name of your button.

This is assuming you’re registering the dlgProc properly (it should be assigned to your utility rollout when it is first opened).

I eventually realized that the source of my problem was actually in my .rc file, where I was using a “Button” as my… button… instead of a “Custom Control”. So when I tried to apply PickButton->SetType(CBT_CHECK), it crashed Max.

So anyway, I have a working solution which I plan to use as the template for my future pickbutton needs. If anyone sees anything that may bite me in the ass later, or ways to just make the code more efficient, please let me know!

#include "includes.h"

class TestUtil : public UtilityObj {
  public:
	Interface *ip;
	IUtil *iu;
	ICustButton *PickButtonA;
	ICustButton *PickButtonB;
	INode *NodeA;
	INode *NodeB;
	HWND hPanel;
	TestUtil();
	void BeginEditParams (Interface *ip,IUtil *iu);
	void EndEditParams (Interface *ip,IUtil *iu);
	void DeleteThis () { }
	void Init (HWND hWnd);
	void SetNodeA (INode *node);
	void SetNodeB (INode *node);
};
static TestUtil theTestUtil;

class PickButtonACallback : public PickModeCallback {
  public:		
	void EnterMode (IObjParam *ip) {theTestUtil.PickButtonA->SetCheck(TRUE);}
	void ExitMode (IObjParam *ip) {theTestUtil.PickButtonA->SetCheck(FALSE);}
	BOOL HitTest (IObjParam *ip, HWND hWnd, ViewExp *vpt, IPoint2 m, int flags);
	BOOL Pick (IObjParam *ip, ViewExp *vpt);
};
static PickButtonACallback thePickButtonACallback;

BOOL PickButtonACallback::HitTest(IObjParam *ip, HWND hWnd, ViewExp *vpt, IPoint2 m, int flags) {
  return (ip->PickNode(hWnd, m)) ? TRUE : FALSE;
}

BOOL PickButtonACallback::Pick(IObjParam *ip, ViewExp *vpt) {
  INode *node = vpt->GetClosestHit();
  if (node) { theTestUtil.SetNodeA(node); mprintf("
Picked %s as NodeA
", node->GetName()); }
  if (theTestUtil.NodeA != NULL) { mprintf("  NodeA: %s
", theTestUtil.NodeA->GetName()); }
  if (theTestUtil.NodeB != NULL) { mprintf("  NodeB: %s
", theTestUtil.NodeB->GetName()); }
  return TRUE;
}

class PickButtonBCallback : public PickModeCallback {
  public:		
	void EnterMode (IObjParam *ip) {theTestUtil.PickButtonB->SetCheck(TRUE);}
	void ExitMode (IObjParam *ip) {theTestUtil.PickButtonB->SetCheck(FALSE);}
	BOOL HitTest (IObjParam *ip, HWND hWnd, ViewExp *vpt, IPoint2 m, int flags);
	BOOL Pick (IObjParam *ip, ViewExp *vpt);
};
static PickButtonBCallback thePickButtonBCallback;

BOOL PickButtonBCallback::HitTest(IObjParam *ip, HWND hWnd, ViewExp *vpt, IPoint2 m, int flags) {
  return (ip->PickNode(hWnd, m)) ? TRUE : FALSE;
}

BOOL PickButtonBCallback::Pick(IObjParam *ip, ViewExp *vpt) {
  INode *node = vpt->GetClosestHit();
  if (node) { theTestUtil.SetNodeB(node); mprintf("
Picked %s as NodeB
", node->GetName()); }
  if (theTestUtil.NodeA != NULL) { mprintf("NodeA: %s
", theTestUtil.NodeA->GetName()); }
  if (theTestUtil.NodeB != NULL) { mprintf("NodeB: %s
", theTestUtil.NodeB->GetName()); }
  return TRUE;
}

INT_PTR CALLBACK DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
  switch (msg) {
	case WM_INITDIALOG:	{ theTestUtil.Init(hWnd); break; }

	case WM_COMMAND: {
	  switch(LOWORD(wParam)) {
		case IDOK:
		  theTestUtil.NodeA = NULL;
		  theTestUtil.NodeB = NULL;
		  theTestUtil.iu->CloseUtility();
		  break;
		case IDC_PICKBUTTONA: {
		  theTestUtil.ip->SetPickMode(&thePickButtonACallback);
		  break;
		}
		case IDC_PICKBUTTONB: {
		  theTestUtil.ip->SetPickMode(&thePickButtonBCallback);
		  break;
		}
	  }
	  break;
	}
	default: return FALSE;
  }
  return TRUE;
}

TestUtil::TestUtil() {
  iu = NULL;
  ip = NULL;
  hPanel = NULL;
  PickButtonA = NULL;
  PickButtonB = NULL;
  NodeA = NULL;
  NodeB = NULL;
}

void TestUtil::BeginEditParams(Interface *ip, IUtil *iu) {
  this->iu = iu;
  this->ip = ip;
  hPanel = ip->AddRollupPage(hInstance, MAKEINTRESOURCE(IDD_PANEL), DlgProc, GetString(IDS_PARAMS), 0);
}

void TestUtil::EndEditParams(Interface *ip, IUtil *iu) {
  ip->ClearPickMode();
  this->iu = NULL;
  this->ip = NULL;
  ip->DeleteRollupPage(hPanel);
  hPanel = NULL;
}

void TestUtil::Init(HWND hWnd) {
  PickButtonA = GetICustButton(GetDlgItem(hWnd, IDC_PICKBUTTONA));
  PickButtonB = GetICustButton(GetDlgItem(hWnd, IDC_PICKBUTTONB));
  PickButtonA->SetType(CBT_CHECK);
  PickButtonB->SetType(CBT_CHECK);
}

void TestUtil::SetNodeA(INode *node) { NodeA = node; }
void TestUtil::SetNodeB(INode *node) { NodeB = node; }

it’s a style thing really, but the “modern” trend with c++ is to use initializer lists in constructors
so it would be

it actually becomes more useful with stuff like…

alot of the examples have c++ from 20+ yrs ago with some pretty atrocious coding in both style and substance

Page 2 / 2