Dynamically changing the configuration of the spacepilot

Post questions, comments and feedback to our 3Dconnexion Windows Development Team.

Moderator: Moderators

Post Reply
Michel
Posts: 9
Joined: Thu Oct 11, 2007 7:09 am

Dynamically changing the configuration of the spacepilot

Post by Michel »

Hi, I just bought a spacepilot and am trying to write a nice .NET control that processes all events and controls the configuration.

From what I understand from the manual and earlier posts in the forum, there is no easy way to change the LCD-contents and the LEDS .. how strange!

Now I figured I could work around this by using different config files and changing the application name dynamically. This should cause the spacepilot to dynamically change the config allowing me to build up a menu-structure. But when I call LoadPreferences from within my application the spacepilot seems to walk through some configurations but never ends up in the one I asked for.

Can anyone please tell me how and when the LoadPreferences call should be used?
I already matched the application-names with names in the registry, but is just doesn't work.

Thanks!

Michel
mbonk
Moderator
Moderator
Posts: 181
Joined: Mon Dec 04, 2006 4:06 am

Post by mbonk »

Hi Michel

To get this to work you could do the following:

First you need to create scg files for the various configurations you would like loaded i.e. Copy any.scg in the 3dxware\en_us\profiles\default to say MyApp1.scg. Change the APPLICATION_NAME= line to something like "MyApp congif 1" and change the EXECUTABLES = {""} line to{ "MyApp.exe/classname=3dxinput:preferences" }. MyApp.exe is the name of the executable and 'preferences' is the string used in the call to LoadPreferences("");

When you call LoadPreferences() you need to be careful that you are not executing from within a device event handler.

A modified AtlCube3D C++ version would look like:

AtlCube3D0.scg snippet - I also created a AtlCube3D1.scg and AtlCube3D2.scg

Code: Select all

[IDENTIFICATION]
APPLICATION_NAME = "atlcube3d0"
OWNER = 3DCONNEXION
PLATFORM = WINDOWS
LEVEL = BEGINNER
ORIENTATION = HORIZONTAL
DRIVER_TYPE = "Any"

[CONFIGURATION]
HIDE_FILE = FALSE
2D_ONLY = FALSE
MACRO_MECHANISM = 0
APP_CONTROLS_BUTTONS = FALSE
TRANSPORT_PROTOCOL = NO_TRANSPORT
ICON = "Default_3Dx_16x16.ico"
TIPS_AND_TRICKS_URL = "http://www.3Dconnexion.com/TipsAndTricks.htm"
3DX_HELP = "AnyApplicationHelp.htm"
EXECUTABLES = { "atlcube3d.exe/classname=3dxinput:atlcube3d0" }
The modified CCubeWindow message map

Code: Select all

#define WM_LOADPREFERENCES (WM_USER +1)
   BEGIN_MSG_MAP(CCubeWindow)
      MESSAGE_HANDLER (WM_CREATE, OnCreate)
      MESSAGE_HANDLER (WM_NCDESTROY, OnNcDestroy)
      MESSAGE_HANDLER (WM_PAINT, OnPaint)
      MESSAGE_HANDLER (WM_LOADPREFERENCES, OnLoadPreferences)
      COMMAND_HANDLER (IDM_About, 0, OnAbout)
      COMMAND_HANDLER (IDM_Exit, 0, OnExit)
   END_MSG_MAP()

 
   LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
   LRESULT OnLoadPreferences(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
The new OnKeyDown

Code: Select all

HRESULT CCubeWindow::OnKeyDown(int keyCode )
{

   HRESULT result = S_OK;
   static int n=0;

   AtlTrace (_T("CCubeWindow::OnKeyDown(keyCode =%d)\n"), keyCode);
   switch (keyCode)
   {

   case 31: // Fit
      MathFrameTranslation( &FrameCube, 0.0, 0.0, -10. );
      MathFrameRotation( &FrameCube, 0., 0., 0. );
      DisplayCube( (HWND)*this, &FrameCube, &VGAVideo );
      break;

   case 1: // test LoadPreferences
         PostMessage (WM_LOADPREFERENCES, n++, 0);
         n%=3;
      break;
   }

   return result;
}
and the message handler

Code: Select all

LRESULT CCubeWindow::OnLoadPreferences(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
   CComPtr<IDispatch> _3DxDevice;

   // Get the device object
   m_pIKeyboard->get_Device(&_3DxDevice);
   CComPtr<ISimpleDevice> _3DxSimpleDevice;

   HRESULT hr = _3DxDevice.QueryInterface(&_3DxSimpleDevice);
   if (SUCCEEDED(hr))
   {
      // Set the preferences we want to use
      switch (wParam)
      {

      case 0: _3DxSimpleDevice->LoadPreferences(_T("AtlCube3D0")); break;

      case 1: _3DxSimpleDevice->LoadPreferences(_T("AtlCube3D1")); break;

      case 2: _3DxSimpleDevice->LoadPreferences(_T("AtlCube3D2")); break;

      }
   }
   return 0;
}
Hope this helps
Markus
lhmncantoni
Posts: 18
Joined: Wed May 28, 2008 11:35 am

Post by lhmncantoni »

ok, so I've read through this post and I am having a different problem. My issues are with actually calling the LoadPreferences method. What name do you put in there? I saw that you have an extra clause in your .exe declaration in the config files:
{ "MyApp.exe/classname=3dxinput:preferences" }. MyApp.exe is the name of the executable and 'preferences' is the string used in the call to LoadPreferences("");
So, "/classname=3dxinput:" will always be the same and the thing that changes is your executable name and the "preferences"? And this "preferences" is what you put as the argument to LoadPreferences()?

Thanks in advance,
~Nick~
"Know something about eveyrthing, and everything about something."
jwick
Moderator
Moderator
Posts: 3345
Joined: Wed Dec 20, 2006 2:25 pm
Location: USA
Contact:

Post by jwick »

Yes.
lhmncantoni
Posts: 18
Joined: Wed May 28, 2008 11:35 am

Post by lhmncantoni »

Thanks a bunch guys. I'm sorry, it seems like I keep bouncing from problem to problem.

I'm not using event handlers for the buttons and the joystick info. I have it set up to receive a button press then update the LCD accordingly. This works for only one button press.

When I press any button from the beginning the correct configuration gets loaded, however, from there on out whenever I push a button no preferences will load. I have put some debug textIO in, so I know it is getting to the loadPreferences call, it's just not calling it(or calling it correctly). I'm kind of thinking it is because once I load the new configuration the Device object I instantiated at the beginning (with which I will call loadPreferences again), does not take action, or does not affect the device as it should.

Thank you in advance for your help,
~Nick~
"Know something about eveyrthing, and everything about something."
mist-sc
Posts: 5
Joined: Sun Mar 30, 2008 11:36 pm
Location: Russia, Novosibirsk

Post by mist-sc »

Hello!

I need to change SpacePilot display text dynamically. Do perform this I create my config file and use it in LoadPreferences() function. But then I change some buttons titles in config file during my program runtime. As I understand, I should reload preference page from config file. So I call LoadPreferences() once more, it returns S_OK, but there is no effect until I manually reload preferences file in 3DConnexion Control Pannel.

According to lhmncantoni, I am not the only one who have such problem.

Thank you!
mist-sc
Posts: 5
Joined: Sun Mar 30, 2008 11:36 pm
Location: Russia, Novosibirsk

Post by mist-sc »

LoadPreferences() returns S_OK even if I stop driver before the call.

Here is my code, maybe someone can help me to find out what is wrong.

Code: Select all

HRESULT hr;
CComPtr<IUnknown> _3DxDevice;

// Create the device object
hr = _3DxDevice.CoCreateInstance(__uuidof(Device));
if (SUCCEEDED(hr))
{
            //CComPtr<ISimpleDevice> _3DxSimpleDevice;
	hr = _3DxDevice.QueryInterface(&_3DxSimpleDevice);
	if (SUCCEEDED(hr))
	{
	   // Get the interfaces to the sensor and the keyboard;
	   g3DSensor = _3DxSimpleDevice->Sensor;
	   g3DKeyboard = _3DxSimpleDevice->Keyboard;

	   // Associate a configuration with this device
	  if(PathFileExists(filename.GetString()))
               {
		_3DxSimpleDevice->LoadPreferences(_T("NameFromEXECUTABLES"));
	   }
	   // Connect to the driver
               _3DxSimpleDevice->Connect();
 	   _3DxSimpleDevice->get_Type(&type);
            }
	else
	{
	   return _EMPTY;
	}
}
else 
             return _EMPTY;
return _OK; 
After this I have my config loaded and everything is OK.

But then I modify congif file and want to reload it:

Code: Select all

CComPtr<IDispatch> _3DxDeviceN; 

// Get the device object 
g3DKeyboard->get_Device(&_3DxDeviceN); 
CComPtr<ISimpleDevice> _3DxSimpleDeviceN; 

HRESULT hr = _3DxDeviceN.QueryInterface(&_3DxSimpleDeviceN);
if (SUCCEEDED(hr))
{
	HWND HdriverWindow = 0;
	_3DxSimpleDeviceN->LoadPreferences(_T("NameFromEXECUTABLES"));
}
LoadPreferences() returns S_OK but nothing happens. I'he tried to load configs of other programs -> no results.

I've tried to close the driver and call CoCreateInstance again, but my application crashed or hung during the call.
jwick
Moderator
Moderator
Posts: 3345
Joined: Wed Dec 20, 2006 2:25 pm
Location: USA
Contact:

Post by jwick »

I have to STRONGLY discourage you from editing the scg files outside of the driver. They will no longer be used in the next major release.

The only supported way to access the LCD is via the "old" 3DxWare SDK (in the archive section of the download page). This mechanism will be ported to the new driver.
mist-sc
Posts: 5
Joined: Sun Mar 30, 2008 11:36 pm
Location: Russia, Novosibirsk

Post by mist-sc »

Thanks, jwick!
Post Reply