Community
3ds Max Programming
Welcome to Autodesk’s 3ds Max Forums. Share your knowledge, ask questions, and explore popular 3ds Max SDK, Maxscript and Python topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Change Spinner EditType at Runtime

19 REPLIES 19
SOLVED
Reply
Message 1 of 20
tim-bot
736 Views, 19 Replies

Change Spinner EditType at Runtime

I looked through all the samples and the howto projects, but i'm not finding anything.

 

What i'd like to do is when a value changes in my parameters, to change the edit type of another parameter between EDITTYPE_UNIVERSE and EDITTYPE_FLOAT. What I have is a dropdown that for certain options changes how some distance values are interpreted, one being relative, the rest being world coordinates. I just want the distance to reflect percentage of bounding box as either 0.0 - 1.0 or 0% to 100% maybe even better. i'm just not sure how to make that change during runtime. I tried to get the ParamDef and change the spin_type, but that didn't work. i'm thinking it may be something like getting the controls by their HWND and then modifying it there or something. but I just don't know how to go about that. if there's anybody out there that's dealt with this before I would be most appreciative of some information. thanks!

 

 

19 REPLIES 19
Message 2 of 20
istan
in reply to: tim-bot

When I sometimes need either a combobox OR an edit field, I add both controls to the dialog and hide the one I don't need.

Message 3 of 20
tim-bot
in reply to: tim-bot

yeah, I tried to think up some way to just hide/show what I need, but i'm just not sure how to do that without having multiple parameters for the same thing. which i'd like to avoid.

 

I have a partially working solution, it's just not updating the interface unless I deselect the item and then reselect it again, then the spin_type gets updated on the spinners.

 

in my ParamMap2UserDlgProc::DlgProg

 

case WM_COMMAND:

{

switch (LOWORD(wParam))

{

case IDC_Opt_TransformRange_ComboBox:

{

SetEditType(map, t);

....

 

Then

 

void SetEditType(IParamMap2* map, TimeValue t)

{

static std::vector<APBIDs> RangeAffected = { APBIDs::AdvArrayOffset };

IParamBlock2* pb = map->GetParamBlock();

TransformRange TR = (TransformRange)pb->GetInt(APBIDs::AdvArrayOptTransformRange, t);

EditSpinnerType ST = EditSpinnerType::EDITTYPE_INT;

switch (TR)

{

case AdvArray::TransformRange::Absolute: ST = EditSpinnerType::EDITTYPE_UNIVERSE; break;

case AdvArray::TransformRange::Reletive: ST = EditSpinnerType::EDITTYPE_FLOAT; break;

case AdvArray::TransformRange::Extents: ST = EditSpinnerType::EDITTYPE_UNIVERSE; break;

}

if (ST != EditSpinnerType::EDITTYPE_INT)

{

for (int i = 0; i < RangeAffected.size(); i++)

{

ParamDef& pDef = pb->GetParamDef(RangeAffected[i]);

if (pDef.spin_type != ST)

{

pDef.spin_type = ST;

}

}

map->Invalidate();

map->SetParamBlock(pb);

map->UpdateUI(t);

}

}

 

Which does change the spin_type, but it's not updating the UI while the item is selected. i'm certain it's got to be possible, as changing the units updates the type while it's selected. i'm just not sure what to do to get the UI to refresh

 

Message 4 of 20
tim-bot
in reply to: tim-bot

wow, oops, happy robot

that line should read:

ParamMap2UserDlgProc : : DlgProc(...

Message 5 of 20
istan
in reply to: tim-bot

Since in the end these are simple windows controls, have you also tried InvalidateRect() or similar?

Message 6 of 20
istan
in reply to: istan

btw: you could also try a kill/setfocus() action. helps also sometimes.

 

Message 7 of 20
tim-bot
in reply to: tim-bot

Thanks for the suggestions, I tried them out, but it doesn't appear to be a redraw issue. as changing the spinner value continues to use the current type until the whole panel gets rebuilt after deselecting and reselecting.

Message 8 of 20
istan
in reply to: tim-bot

Long time ago I created customized spinner controls - afair the source code of the spinner can be found in the debug release.

I have another idea: why don't you directly access the spinner control?

Message 9 of 20
tim-bot
in reply to: tim-bot

You know, I was thinking that too, I wasn't sure what to do to the control though. I see the control ids on the paramdef that I figured could be used for such a task.
Message 10 of 20
denisT.MaxDoctor
in reply to: tim-bot

The Spinner Control is 'combined' control which includes an 'edit' control and 'buttons' control.

You can change the type of a spinner using ISpinnerControl::LinkToEdit or directly assinging ((SpinnerControl*)sp)->spin_type, but it doesn't rebuild the Edit control automatically, and you can't see the difference. It's because the current Edit control was created using previous type (settings), and it continue be a part of whole Spinner control.

 

The only way is to force rebuild UI with all included controls... 

 

 

Message 11 of 20

finally i found the way to change and update a spinner type on the fly:

			sp->LinkToEdit(hwnd, type);
			((SpinnerControl*)control)->spin_type = type;
			control->Reload();
			control->InvalidateUI();

 

where:

 

control is SpinnerControl

sp is ISpinnerControl of control

hwnd is previous window to control's HWND (hwnd of spinner's CustEdit control)

 

Message 12 of 20
tim-bot
in reply to: denisT.MaxDoctor

awesome! thanks for that, I'll plug that in and let you know how it goes!

Message 13 of 20
tim-bot
in reply to: denisT.MaxDoctor

ok, I've got this most of the way setup, but i'm having trouble getting my hands on the SpinnerControl. I see that defined in rollouts.h as the correct one? I just can't seem to find where to get that from the data I have. any help with resolving that and I think I could get this working. thanks!

 

Message 14 of 20
denisT.MaxDoctor
in reply to: tim-bot

what data do you have?

Message 15 of 20
tim-bot
in reply to: denisT.MaxDoctor

I might be digging myself in a hole here. in my class derived from ParamMap2UserDlgProc, in the DlgProc:

 

INT_PTR DlgProc(TimeValue t, IParamMap2* map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

 

I was trying to use that hWnd to get the ISpinnerControl. but the spinner controls are actually on different rollout panels, so it's returning null. I thought maybe if I stored the HWND's for each panel during WM_INITDIALOG would work, but LOWORD(wParam) doesn't give the same results as I get during WM_COMMAND. bummer... hopefully you know a better way of getting that at that time or if there's another better way to be going about this whole business.

 

I was looking at some of the samples, and I see some of them creating their rollups manually and handling the dialog process there, which gives them the HWND to the actual rollup during BeginEditParams. do you think I should be going that direction here?

 

thanks again for helping me out with this!

 

Message 16 of 20
denisT.MaxDoctor
in reply to: tim-bot

i think that you have to know your parameter in param block2. Using ParamBlockDesc2 you can get an associated with the parameter control. If it's spinner control you can change its type 

Message 17 of 20
tim-bot
in reply to: denisT.MaxDoctor

ok, thanks for all the suggestions, I finally got it working!

 

I ended up using this code, which basically i'm getting the correct map associated with each of the spinners I want to adjust using the IParamBlock2->GetMap function, then I get the HWND using the IParamMap2->GetHWnd function and use that in the GetDlgItem function to get the spinner and custom edit box. and I don't even need to call any invalidate ui functions for it to work B)

 

for each (EditTypeChangeInfo eInfo in ChangeInfos)
{
	ParamDef& pDef = pbd->GetParamDef(eInfo.Id);
	if (pDef.spin_type != ST)
	{
		pDef.spin_type = ST;
		IParamMap2* pMap = pb->GetMap((MapID)eInfo.RollID);
		if (pMap)
		{
			HWND pHwnd = pMap->GetHWnd();
			if (pHwnd)
			{
				for each (SpinnerIDPair sIdP in eInfo.SpinnerPairIDs)
				{
					ISpinnerControl* Sp = GetISpinner(GetDlgItem(pHwnd, sIdP.SpinnerID));
					if (Sp)
					{
						Sp->LinkToEdit(GetDlgItem(pHwnd, sIdP.EditID), ST);
						ReleaseISpinner(Sp);
					}
				}
			}
		}
	}
}

 

still needs a little work as the next time the modifier is created it still maintains the spin_type set here, so i'll just need to make the adjustments during initialization as well.

 

thanks again for all the help!

Message 18 of 20
denisT.MaxDoctor
in reply to: tim-bot

What is ChangeInfos?

 

is it something you store at creation time?

Message 19 of 20
tim-bot
in reply to: denisT.MaxDoctor

yeah, just a couple of stucts that I have to match my spinner pairs with their parameter ids and roll ids. just so I don't have to have a massive switch statement, I can instead just loop through them.

 

struct SpinnerIDPair
{
	int SpinnerID;
	int EditID;
};
struct EditTypeChangeInfo
{
	APBIDs Id;
	RollIDs RollID;
	std::vector<SpinnerIDPair> SpinnerPairIDs;
};
static std::vector<EditTypeChangeInfo> ChangeInfos = 
{ 
	{APBIDs::AdvArrayOffset, RollIDs::Params, {
		{ IDC_OffsetX_Spinner, IDC_OffsetX_EditBox },
		{ IDC_OffsetY_Spinner, IDC_OffsetY_EditBox },
		{ IDC_OffsetZ_Spinner, IDC_OffsetZ_EditBox } } },
	{ APBIDs::AdvArrayCenOffset, RollIDs::Center,{
		{ IDC_Cen_OffsetX_Spinner, IDC_Cen_OffsetX_EditBox },
		{ IDC_Cen_OffsetY_Spinner, IDC_Cen_OffsetY_EditBox },
		{ IDC_Cen_OffsetZ_Spinner, IDC_Cen_OffsetZ_EditBox } } },
	{ APBIDs::AdvArrayPreOffset, RollIDs::PreTransform,{
		{ IDC_Pre_OffsetX_Spinner, IDC_Pre_OffsetX_EditBox },
		{ IDC_Pre_OffsetY_Spinner, IDC_Pre_OffsetY_EditBox },
		{ IDC_Pre_OffsetZ_Spinner, IDC_Pre_OffsetZ_EditBox } } },
	{ APBIDs::AdvArrayRndOffset, RollIDs::Random,{
		{ IDC_Rnd_OffsetX_Spinner, IDC_Rnd_OffsetX_EditBox },
		{ IDC_Rnd_OffsetY_Spinner, IDC_Rnd_OffsetY_EditBox },
		{ IDC_Rnd_OffsetZ_Spinner, IDC_Rnd_OffsetZ_EditBox } } },
	{ APBIDs::AdvArrayOscPosAmp, RollIDs::Oscillate,{
		{ IDC_Osc_Pos_AmpX_Spinner, IDC_Osc_Pos_AmpX_EditBox },
		{ IDC_Osc_Pos_AmpY_Spinner, IDC_Osc_Pos_AmpY_EditBox },
		{ IDC_Osc_Pos_AmpZ_Spinner, IDC_Osc_Pos_AmpZ_EditBox } } }
};
Message 20 of 20
tim-bot
in reply to: tim-bot

in case you were curious, here's what ultimately came of this

https://apps.autodesk.com/ACD/en/Detail/Index?id=7221085778557027350&appLang=en&os=Win64

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report