Notifications
Clear all

[Closed] Question: On Creating Exporter Dialog

I have very little experience in programming Windows Dialogs (…and by little I mean none!)– if it weren’t for the samples in the SDK I’d be lost…

Anyway, I’m creating a new Exporter plugin for an old game engine… and in my Export Dialog I wish to have a section for an animation segment range that is initially disabled and grayed-out until you select the “Export Segment” checkbox.

I have the WM_INITDIALOG initializing the dialog properly… the segment from/to fields and spinners are initially disabled, but I don’t know how to make them be grayed-out initially. I’m sure it’s a simple matter… would someone please help give me directions to achieve this?

Thanks!

24 Replies

are we talking about c++ SDK?
if so… go to the dialog resource file, select a spinner control (which is three controls actually), go to their properties, and set all them three do disabled state (Disabled property has to be True)

you need to add a WM_COMMAND case at the same level as the WM_INITDIALOG then test the low word of the wParam of dialog proc to catch user interaction with the export segment checkbox something like…


case WM_COMMAND:

	switch (LOWORD(wParam)) 
	{

		case IDC_EXPORTSEGMENT_CHK:
		{
			int ison = IsDlgButtonChecked(hWnd, IDC_EXPORTSEGMENT_CHK)
			ToggleSpinner(hWnd, IDC_FROM_SPIN, ison);
			EnableWindow(GetDlgItem(hWnd, IDC_FROM_STATIC), ison);
			return TRUE;
		}
	}


toggle spinner could look like…

void ToggleSpinner(HWND hWnd, int ctrlID, BOOL ison)
{
	ISpinnerControl* spinner = GetISpinner(GetDlgItem(hWnd ,ctrlID));
	ison ? spinner->Enable(): spinner->Disable();
	ReleaseISpinner(spinner);
}

though inline is just as easy the EnableWindow will disable static text though sometimes has iffy font graying out.

@denisT – yes, C++ SDK. And I have the CustEdit boxes and spinners initially disabled in the resource editor.

I basically copied the spinner set up from the ASCII export sample. Of Course I don’t have all the code finished– no WM_COMMAND case yet… just working on WM_INITDIALOG.

@Klunk-1 – I’m away from my computer now… but I will post a code snippet and try your suggestions this evening.

Also, for the dialog… I have created a class ExportOptions, which will hold the variables for the dialog. E.g. – g_ExportOptions.bExportSegment = FALSE ;

Thanks guys for your help.

@Klunk-1 and @denisT – the below code is what I currently have… I’ve not made any changes yet… still need to look at Klunk’s snippets more closely:

static INT_PTR CALLBACK ROFFexportOptionsDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{
 
static ROFFexport *exp = NULL;
 
Interval animRange;
 
ISpinnerControl *spin;
 
Interface *ipCore = GetCOREInterface();
 
//
 
switch(message)
{
 case WM_INITDIALOG:
  exp = (ROFFexport *)lParam;
  CenterWindow(hWnd,GetParent(hWnd));
  //
  // Set the export options
  //
 
  animRange = ipCore->GetAnimRange();
  CheckDlgButton(hWnd, IDC_NOTES, g_ExportOptions.bNoteTracks);
  CheckDlgButton(hWnd, IDC_ASCII, g_ExportOptions.bWriteASCII);
  CheckDlgButton(hWnd, IDC_SEGMENT, g_ExportOptions.bExportSegment);
   // Setup the spinner control for the segment_FROM frame#
   spin = GetISpinner(GetDlgItem(hWnd, IDC_FROM_FRAME_SPIN)); 
   spin->LinkToEdit(GetDlgItem(hWnd,IDC_FROM_FRAME), EDITTYPE_INT ); 
   spin->SetLimits(animRange.Start() / GetTicksPerFrame(), animRange.End() / GetTicksPerFrame(), TRUE); 
   spin->SetScale(1.0f);
   spin->SetValue(g_ExportOptions.nSegFrom, FALSE);
   ReleaseISpinner(spin);
   // Setup the spinner control for the segment_TO frame#
   spin = GetISpinner(GetDlgItem(hWnd, IDC_TO_FRAME_SPIN)); 
   spin->LinkToEdit(GetDlgItem(hWnd,IDC_TO_FRAME), EDITTYPE_INT ); 
   spin->SetLimits(animRange.Start() / GetTicksPerFrame(), animRange.End() / GetTicksPerFrame(), TRUE); 
   spin->SetScale(1.0f);
   spin->SetValue(g_ExportOptions.nSegTo, FALSE);
   ReleaseISpinner(spin);
 
  if ( g_ExportOptions.bExportSegment )
  {
   EnableWindow ( GetDlgItem ( hWnd, IDC_FROM_FRAME ), TRUE );
   EnableWindow ( GetDlgItem ( hWnd, IDC_TO_FRAME ), TRUE );
   EnableWindow ( GetDlgItem ( hWnd, IDC_FROM_FRAME_SPIN ), TRUE );
   EnableWindow ( GetDlgItem ( hWnd, IDC_TO_FRAME_SPIN ), TRUE );
  }
  else 
  {
   //disables but does not gray-out
   EnableWindow ( GetDlgItem ( hWnd, IDC_FROM_FRAME ), FALSE );
   EnableWindow ( GetDlgItem ( hWnd, IDC_TO_FRAME ), FALSE );
   EnableWindow ( GetDlgItem ( hWnd, IDC_FROM_FRAME_SPIN ), FALSE );
   EnableWindow ( GetDlgItem ( hWnd, IDC_TO_FRAME_SPIN ), FALSE );
  }
 
  break;
 case WM_COMMAND:
  switch(LOWORD(wParam))
  {
  case IDC_about:
   DialogBox(hInstance, MAKEINTRESOURCE(IDD_ABOUT_DLG), hWnd, AboutBoxDlgProc); 
   break;
  case IDC_CANCEL:
   EndDialog(hWnd, 0);
   break;
  }
  break;
 case WM_CLOSE:
  EndDialog(hWnd, 0);
  break;
 default:
  return FALSE;
 }
 return TRUE;
}

WTF?! I HATE the way this website’s forum displays pasted code… it always disrespects my tabs! Or changes paragraph spacing… am I doing something wrong?

try something like…

static INT_PTR CALLBACK ROFFexportOptionsDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
 {
 static ROFFexport *exp = NULL;
 Interval animRange;
 ISpinnerControl *spin;
 Interface *ipCore = GetCOREInterface();
  
 //
  
 switch(message)
 {
  case WM_INITDIALOG:
 	  exp = (ROFFexport *)lParam;
 	  CenterWindow(hWnd,GetParent(hWnd));
 	 
 	  animRange = ipCore->GetAnimRange();
	  int start = animRange.Start() / GetTicksPerFrame();
 	  int end = animRange.End() / GetTicksPerFrame();
 

 	  CheckDlgButton(hWnd, IDC_NOTES, g_ExportOptions.bNoteTracks);
 	  CheckDlgButton(hWnd, IDC_ASCII, g_ExportOptions.bWriteASCII);
 	  CheckDlgButton(hWnd, IDC_SEGMENT, g_ExportOptions.bExportSegment);
 	   
 
 // Setup the spinner control for the segment_FROM frame#
 
 	   spin = SetupIntSpinner(hWnd, IDC_FROM_FRAME_SPIN, IDC_FROM_FRAME, start, end,g_ExportOptions.nSegFrom);
 	   g_ExportOptions.bExportSegment ?  spin->Enable() : spin->Disable();
 	   ReleaseISpinner(spin);
 	   
 // Setup the spinner control for the segment_TO frame#
 
 	   spin = SetupIntSpinner(hWnd, IDC_TO_FRAME_SPIN, IDC_TO_FRAME , start, end,g_ExportOptions.nSegTo);
 	   g_ExportOptions.bExportSegment ?  spin->Enable() : spin->Disable();
 	   ReleaseISpinner(spin);	
 
   break;
  case WM_COMMAND:
 
 	  switch(LOWORD(wParam))
 	  {
 		  case   IDC_SEGMENT:
 		   {
 				int ison = IsDlgButtonChecked(hWnd, IDC_SEGMENT);
 
 				ISpinnerControl* spinner = GetISpinner(GetDlgItem(hWnd ,IDC_FROM_FRAME_SPIN));
 				ison ? spinner->Enable(): spinner->Disable();
 				ReleaseISpinner(spinner);
 
 				spinner = GetISpinner(GetDlgItem(hWnd ,IDC_TO_FRAME_SPIN));
 				ison ? spinner->Enable(): spinner->Disable();
 				ReleaseISpinner(spinner);
 				break;
 			}
 		  case IDC_about:
 		   DialogBox(hInstance, MAKEINTRESOURCE(IDD_ABOUT_DLG), hWnd, AboutBoxDlgProc); 
 		   break;
 		  case IDC_CANCEL:
 		   EndDialog(hWnd, 0);
 		   break;
 	  }
 	  break;
  case WM_CLOSE:
 	  EndDialog(hWnd, 0);
 	  break;
  default:
   return FALSE;
  }
  return TRUE;
 }

ninja edit

@Klunk-1 – I will certainly give this a try today. Thank you all so much for the help! One thing I was wondering is… should I create a pointer variable for each spinner? Rather than recycle the one pointer in both WM_INITDIALOG and WM_COMMAND? What are the pros/cons?

there probably are no pro’s or con’s as such just coding choices and a few bytes here and there on the stack. I added the code as a copy and paste and didn’t really care about previous variable declarations in the code I don’t even know if it will compile that for you to find out.

as an addendum to this the general rule of thumb in c++ is to declare variables as and when you, or as close to, need them. The reason for this is some objects could have default constructors which are, shall we just say, not as expected. Having a call to a slow function at the start of a function that may not use the object the function is called on is just bad form and a little sloppy. Obviously if you can keep the constructor call out of loops and such like, base types like int, float etc have very little overhead so can be declared most places.

@Klunk-1… it does compile. However, the dialog initially pops up with:

“Export Segment” unchecked

To field showing: 0 (appearing normal but disabled)
From field showing: 100 (appearing normal but disabled)

If I toggle the “Export Segment” checkbox then the numbers gray-out.

If I modify the default values and close/re-open… they don’t stay sticky in the g_ExportOptions variables. I need to add some dialog messages to update these globals based on dialog changes. With what you’ve given me… I think I can sort it out. I will post my snippet once I do get it sorted out.

Unfortunately, for now the yard-work beckons… 🙁

Thanks!

you need to add the IDOK (or what ever the ID is on the Export button) case to the loword wparam switch and in that
set your global variables from the current state of the dialog.

with…


  g_ExportOptions.bExportSegment = IsDlgButtonChecked(hWnd, IDC_SEGMENT);
  ISpinnerControl* spinner = GetISpinner(GetDlgItem(hWnd ,IDC_FROM_FRAME_SPIN)); 
 g_ExportOptions.nSegFrom = spinner->GetIVal(); 
 ReleaseISpinner(spinner);
Page 1 / 3