How to get the Fit button event.

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

Moderator: Moderators

Post Reply
harem
Posts: 15
Joined: Tue Jun 04, 2019 4:17 pm

How to get the Fit button event.

Post by harem »

I'm getting confused by everything I read on this topic. How should I detect when the "Fit" button is pressed?

There are various constants, but I don't know what to do with them:

SI_APP_FIT - an event that applications should respond to according to the SDK documentation. But it's not one of the SiEventType constants and I'm not getting any mystery events that it could be.

SI_FIT_BUTTON - a reserved button function mentioned in the SDK documentation but I can't find it in the Test SiApp example's code.

V3DK_FIT - seems to be obsolete and conflicts with another button. ??

V3DCMD_VIEW_FIT - seems to be recommended and seems like it should come in a SI_CMD_EVENT event, but I'm not receiving that event apparently because my application doesn't have it registered it with the driver as a supported command. It looks like my application is supposed to place an XML file in %PROGRAMDATA%\3Dconnexion\3DxWare\Cfg but what's the format for this file and what are the recommended/safe ways to manage it for things like name conflicts, modifying during use, deleting on uninstall, versioning, etc? I'm not very comfortable installing files into another application's Program Data folder and this also prevents my application from being able to be xcopy installed safely. So I would prefer to avoid doing this if at all possible. I notice that something generates a file for my application in %APPDATA%/3Dconnexion/3DxWare/Cfg so should I use that location instead? If both files exist, which one will the driver use? Generally, there's a lot of mystery around these Cfg files and I'm looking for a clear picture of how to use them safely, or better, avoid touching them altogether.

SI_APP_EVENT - I can get this working by registering an action using ActionCache and assigning a physical button to that action in the driver, but it looks like the driver doesn't know that my "Fit" action has any special meaning, so I guess it wouldn't automatically assign it to any hardware Fit button. It doesn't respond to the software Fit button on the radial menu. My guess is that SI_APP_EVENT is mainly intended for the LCD screen on the SpaceMouse Enterprise, is that right?
jwick
Moderator
Moderator
Posts: 3331
Joined: Wed Dec 20, 2006 2:25 pm
Location: USA
Contact:

Re: How to get the Fit button event.

Post by jwick »

Hello harem,

Sorry for the confusion.

You are correct, V3DCMD_VIEW_FIT is the recommended way to get Fit button events.
And you are also correct that it is probably not being sent.

Since you are not supplying a cfg file for your app (and you don't need to), the driver will select a cfg file for you. But more than likely you are getting an older-style cfg file. You have to tell the driver to use the more recent default cfg that sends V3DCMDs.

You do this by changing your open slightly. You add a hint.

Code: Select all

  SiOpenWinInitEx (&oData, hWndMain);

  // Tell the driver we want to receive V3DCMDs instead of V3DKeys
  SiOpenWinAddHintBoolEnum(&oData, SI_HINT_USESV3DCMDS, SPW_TRUE);

  /* open data, which will check for device type and return the device handle
  to be used by this function */
  if ((devHdl = SiOpenEx(L"harems application name", SI_ANY_DEVICE, SI_NO_MASK, SI_EVENT, &oData)) == NULL)
  ...
  continue on as you did before.
Now the driver will pick AppDefCfg_S80_V3DCMDs.xml as the default file. And you will receive SI_CMD_EVENTs with V3DCMD_VIEW_FIT when the user presses the fit button. If you have a two button device, Fit is on one of the Radial Menus.

You could provide a ProgramData file, but it isn't necessary. For basic usage, the default file is a good starting point.
When users make changes in the GUI, only the diff is saved in %appdata%. Anything they didn't change comes from AppDefCfg_S80_V3DCMDs.xml.

SI_APP_EVENT is very interesting and something for you to consider. It does indeed help us support the LCD but it also makes the GUI infinitely more useful for your users. You can export all your commands to our GUI, localized and with icons. It's a bit of work but provides a great deal of flexibility to your customers. Please give it some consideration.

AppCommands work in conjunction with V3DCMDs. AppCommands are only your application commands and they would get assigned to generic function buttons 1-12, for example, on the SpaceMouse Enterprise. The V3DCMDs are for responding to prelabeled 3Dx device buttons (like Save/Restore views (1,2,3), Left View, Right View, ...). A user should be able to rely on those doing what the button says.
harem
Posts: 15
Joined: Tue Jun 04, 2019 4:17 pm

Re: How to get the Fit button event.

Post by harem »

Thanks jwick

I've implemented it but it behaves exactly the same as without the hints or the Ex functions. The radial menu's fit button still only causes SI_BUTTON_* events (1,12,13). It also generates exactly the same (except for dates) Cfg file. How can I diagnose the problem?

I'm using .Net and added these definitions for interop to Siapp.cs from the Test Siapp sample which I've compiled as a class library:

Code: Select all

    [StructLayout(LayoutKind.Sequential)]
    public struct SiHints
    {
        public int version;
        public int hintSize;
        public IntPtr phints;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public class SiOpenDataEx
    {
        public IntPtr hWnd;
        public IntPtr transCtl;
        public int processID;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
        public string exeFile;

        public int libFlag;
        public SiHints hints;
    }

    public enum SiHintEnum : int
    {
        SI_HINT_UNKNOWN = 0,
        SI_HINT_SDKVERSION = 1,
        SI_HINT_DRIVERVERSION = 2,
        SI_HINT_USESV3DCMDS = 3,
        SI_HINT_TEST_BOOL = 4,
        SI_HINT_TEST_INT = 5,
        SI_HINT_TEST_FLOAT = 6,
        SI_HINT_TEST_STRING = 7,
        SI_HINT_USES3DXINPUT = 8,
        SI_HINT_USESNAVLIB = 9,
        SI_HINT_USESFILESYNC = 10,
    }

    [DllImport(SI_DLL)]
    public static extern void SiOpenWinInitEx([In, Out] SiOpenDataEx pData, [In] IntPtr hWnd);

    [DllImport(SI_DLL)]
    public static extern void SiOpenWinAddHintBoolEnum([In, Out] SiOpenDataEx pData, SiHintEnum hint, int value);

    [DllImport(SI_DLL)]
    public static extern IntPtr SiOpenEx([MarshalAs(UnmanagedType.LPWStr)] string pAppName, int devID, [In] IntPtr pTMask, int mode, [In, Out] SiOpenDataEx pData);
and called them from vb.net like this:

Code: Select all

                Dim openData As SiApp.SiOpenDataEx = New SiApp.SiOpenDataEx()
                SiApp.SiOpenWinInitEx(openData, hWnd)
                SiApp.SiOpenWinAddHintBoolEnum(openData, SiApp.SiHintEnum.SI_HINT_USESV3DCMDS, 1)
                devHdl = SiApp.SiOpenEx(My.Application.Info.Title, SiApp.SI_ANY_DEVICE, IntPtr.Zero, SiApp.SI_EVENT, openData)
jwick
Moderator
Moderator
Posts: 3331
Joined: Wed Dec 20, 2006 2:25 pm
Location: USA
Contact:

Re: How to get the Fit button event.

Post by jwick »

Ah, little details are important.
Hints don't work in C#.
It's unfortunately more complicated than pinvoking some functions. Clever code, that came back to bite me. It's on my list.

Before we talk about a permanent solution, you can probably edit the %appdata% cfg file.
It will say something like <InheritsFrom>STR_DEFAULT_S80</InheritsFrom>
Change that to STR_DEFAULT_S80_V3DCMD.

Let me know if this works.
harem
Posts: 15
Joined: Tue Jun 04, 2019 4:17 pm

Re: How to get the Fit button event.

Post by harem »

When I edit that file, my application doesn't get the CMD event and the file quickly gets reverted to say STR_DEFAULT_S80 again. I also tried moving the file to %PROGRAMDATA%\3Dconnexion\3DxWare\Cfg but that seems to be ignored and the %APPDATA% one is still regenerated.

What's the reason hints don't work with .Net? Could I work around it by making a native dll that wraps the real one and P/invoke that instead?

Maybe it's OK to use the button events since all old software would be doing this and presumably that will have to keep working with new devices and drivers, won't it? Or do you have a date when those features will stop being supported and old things might start breaking?
jwick
Moderator
Moderator
Posts: 3331
Joined: Wed Dec 20, 2006 2:25 pm
Location: USA
Contact:

Re: How to get the Fit button event.

Post by jwick »

Interesting...
Sure. Could be. The application probably doesn't meet the requirements specified in that cfg. I can test that scenario.

Can you register as a developer if you have not already? Then we can trade email. Reference this forum topic in your email so I can connect the email to this post. (Sorry, I'm on vacation next week).

Then we can discuss the steps going forward. I think you'll need to create a default file (%PROGRAMDATA%) from our default V3DCMDs file, until I implement hints in C#. This gives me a good reason to get on that.

I'm sure you are not the only one experiencing this. Though I think you are the first to bring it up. Thanks for contacting us about it.
jwick
Moderator
Moderator
Posts: 3331
Joined: Wed Dec 20, 2006 2:25 pm
Location: USA
Contact:

Re: How to get the Fit button event.

Post by jwick »

Hello,

My suggestion of changing the Inheritance doesn't work. That would have been so simple.

You have to create a cfg file for your app.

Make a copy of our SDK's Demos\TestSiApp\profile\TestSiapp.xml.
By default the SDK is installed in %LOCALAPPDATA%\Programs\3Dconnexion\3DxWare SDK.

Give it a name of your program (Whatever.xml).
Edit the file and change the <Name> field to be the name of your program.
Change the ExecutableName to be the name of your executable.
Save the file in %PROGRAMDATA%\3Dconnexion\3DxWare\Cfg.
Stop the driver (3DxService.exe).
Delete any previous files for your program in %appdata%/3Dconnexion/3DxWare/Cfg.
Start the driver.
This new cfg should now be used. It contains definitions for sending V3DCMDs for Fit, Menu, etc.

I'll get to work on implementing the Hints for C#.
harem
Posts: 15
Joined: Tue Jun 04, 2019 4:17 pm

Re: How to get the Fit button event.

Post by harem »

I followed your instructions but it's still generating a new .xml file in %appdata% and apparently ignoring the one in %PROGRAMDATA%\3Dconnexion\3DxWare\Cfg. I stopped and started the driver with Stop 3DxWare and Start 3DxWare from the start menu. Is that the right way to do it?

That's great you're adding the hints! When do you expect it'll be ready? Will it be a new SDK download or a new driver for every user to update to or both?
ngomes
Moderator
Moderator
Posts: 3321
Joined: Mon Nov 27, 2006 7:22 am
Contact:

Re: How to get the Fit button event.

Post by ngomes »

Hi harem,
I followed your instructions but it's still generating a new .xml file in %appdata%
This is expected. User-modified and additional driver settings are saved to a file under %APPDATA%\3Dconnexion\3DxWare\Cfg. We call this the user configuration for a file. It will have an <CfgProperties>\<InheritsFrom> element to link back to the default that you created. Is this the case?

and apparently ignoring the one in %PROGRAMDATA%\3Dconnexion\3DxWare\Cfg. I stopped and started the driver with Stop 3DxWare and Start 3DxWare from the start menu. Is that the right way to do it?
That's great you're adding the hints! When do you expect it'll be ready? Will it be a new SDK download or a new driver for every user to update to or both?
We expect this to require a small change on the client side, so changes to both the SDK and the driver are likely. We should know more within the next couple of weeks.
jwick
Moderator
Moderator
Posts: 3331
Joined: Wed Dec 20, 2006 2:25 pm
Location: USA
Contact:

Re: How to get the Fit button event.

Post by jwick »

Hi harem,

You were on the right track. The code is better than I thought.
You need to add an additional Hint for the current SDK version to match the Signature of the default V3DCMDs cfg.

Code: Select all

// Import like this:
    [DllImport(SI_DLL)]
    public static extern void SiOpenWinAddHintStringEnum([In, Out] SiOpenDataEx pData, SiHintEnum hint, [In, MarshalAs(UnmanagedType.LPWStr)] string value);

// Call like this:
      SiApp.SiOpenWinAddHintStringEnum(openData, SiApp.SiHintEnum.SI_HINT_SDKVERSION, "3.4.0");
If this works, you don't need to add a cfg file in %programdata% just to get the V3DCMD_VIEW_FIT button.

To test this, make sure to delete any previous cfg files related to this app from %programdata% or %appdata%.
Restart the driver, make sure they are still gone.
Now start your app and tell me what happens.

If it still does not work, would it be possible for you to send me a stripped down sample that shows the failure? I've been testing this in C#. I believe you are using vb.net.

I'd like to see a 3DxService.log file of the failure also. Turn on logging by right-clicking on the 3Dx systray icon. The log file is at %localappdata%/3Dconnexion/3DxWare/3DxService.log. Restart the driver, start your app, stop the driver, send the log file.

Any information you can give about the environment might be useful. For example, is this application run in a container, or remotely.

It is much easier to share files if you sign up as a developer (if you have not yet done so).

Thanks,
Jim
harem
Posts: 15
Joined: Tue Jun 04, 2019 4:17 pm

Re: How to get the Fit button event.

Post by harem »

That works! Very easy. I hope you can add all this to the SiApp sample. Seems a lot more elegant than messing around with cfg files and all the ways that can go wrong.
jwick
Moderator
Moderator
Posts: 3331
Joined: Wed Dec 20, 2006 2:25 pm
Location: USA
Contact:

Re: How to get the Fit button event.

Post by jwick »

That's good to hear (read).
Let us know if you have other questions.
Post Reply