c++ console application example

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

Moderator: Moderators

Post Reply
mikeda_pro
Posts: 5
Joined: Mon Sep 15, 2014 11:39 pm

c++ console application example

Post by mikeda_pro » Mon Sep 15, 2014 11:42 pm

Hello,

maybe somebody can help me further... I tried following but I couldn't receive useful messages :

Code: Select all

#include"windows.h"
#include <iostream>

#include "spwmacro.h"  /* Common macros used by SpaceWare functions. */
#include "si.h"        /* Required for any SpaceWare support within an app.*/
#include "siapp.h"     /* Required for siapp.lib symbols */


#pragma warning(disable:4700)

int   DispatchLoopNT(SiHdl       devHdl); 
void  SbMotionEvent(SiSpwEvent *pEvent);
void  SbZeroEvent();
void  SbButtonPressEvent(int buttonnumber);
void  SbButtonReleaseEvent(int buttonnumber);
void  HandleDeviceChangeEvent(SiSpwEvent *pEvent);


void ClearScreen() {
  for(unsigned i=0; i<100; ++i) std::cout << std::endl;
}

int SbInit(HWND hwndC, SiHdl devHdl)
{
  int res;                             /* result of SiOpen, to be returned  */
  SiOpenData oData;                    /* OS Independent data to open ball  */ 

  /*init the SpaceWare input library */
  if (SiInitialize() == SPW_DLL_LOAD_ERROR)  {
    std::cout << "Error: Could not load SiAppDll dll files" << std::endl;
  } else {
    std::cout << "SiInitialize() done " << std::endl;
  }

  SiOpenWinInit (&oData, hwndC);    /* init Win. platform specific data  */
  SiSetUiMode(devHdl, SI_UI_ALL_CONTROLS); /* Config SoftButton Win Display */

  /* open data, which will check for device type and return the device handle
  to be used by this function */ 
  if ( (devHdl = SiOpen("cmd.exe", SI_ANY_DEVICE, SI_NO_MASK, SI_EVENT, &oData)) == NULL) {
    std::cout << "SiOpen error:" << std::endl;
    SiTerminate();  /* called to shut down the SpaceWare input library */
    std::cout << "SiTerminate()" << std::endl;
    res = 0;        /* could not open device */
    return res; 
  } else {
    SiDeviceName pname;
    SiGetDeviceName (devHdl, &pname);
    // std::cout << "devicename =  " << pname.name << std::endl;
    res = 1;        /* opened device succesfully */ 
    return res;  
  }  
}


void main (void) {
  
  HWND windowHandle = GetConsoleWindow() ; /* Great!!  This function  cleverly "retrieves the window handle  used by the console associated with the calling process",   as msdn says */
  std::cout << "GetConsoleWindow() found = " << windowHandle << std::endl;

  HINSTANCE hInstC = (HINSTANCE)GetWindowLong( windowHandle, GWL_HINSTANCE );
  std::cout << "GetModuleHandle( 0 ) done = " << hInstC << std::endl;

  SiOpenData oData; 
  SiOpenWinInit(&oData,windowHandle);
  std::cout << "SiOpenWinInit() done = " << windowHandle << std::endl;

  SiHdl       devHdl;       /* Handle to 3D Mouse Device */
  SbInit(windowHandle,devHdl);
  DispatchLoopNT(devHdl);
}

int DispatchLoopNT(SiHdl devHdl) 
{
  int            num;      /* number of button pressed */
  MSG            msg;      /* incoming message to be evaluated */
  BOOL           handled;  /* is message handled yet */ 
  SiSpwEvent     Event;    /* SpaceWare Event */ 
  SiGetEventData EData;    /* SpaceWare Event Data */

  handled = SPW_FALSE;     /* init handled */

  /* start message loop */ 
  //while ( GetMessage( &msg, NULL, 0, 0 ) )
  //{
  //  std::cout << "dispatch loop started" << std::endl;
  //  handled = SPW_FALSE;


 
  //    handled = SPW_TRUE;              /* 3D mouse event handled */ 
  //  }
  while (true) { 

    /* init Window platform specific data for a call to SiGetEvent */
    SiGetEventWinInit(&EData, msg.message, msg.wParam, msg.lParam);

    std::cout << "msg.message=" << msg.message << " " << msg.wParam << " " << msg.lParam << std::endl;

    /* check whether msg was a 3D mouse event and process it */
    if (SiGetEvent (devHdl, SI_AVERAGE_EVENTS, &EData, &Event) == SI_IS_EVENT)
    {
      if (Event.type == SI_MOTION_EVENT)
      {
        SbMotionEvent(&Event);        /* process 3D mouse motion event */     
      }
      if (Event.type == SI_ZERO_EVENT)
      {
        SbZeroEvent();                /* process 3D mouse zero event */     
      }
      if (Event.type == SI_BUTTON_EVENT)
      {
        if ((num = SiButtonPressed (&Event)) != SI_NO_BUTTON)	
        {
          SbButtonPressEvent(num);        /* process 3D mouse button event */
        }
        if ((num = SiButtonReleased (&Event)) != SI_NO_BUTTON)	
        {
          SbButtonReleaseEvent(num);        /* process 3D mouse button event */
        }
      }

      if (Event.type == SI_DEVICE_CHANGE_EVENT)
      {
        HandleDeviceChangeEvent(&Event);
      }

  }

    /* not a 3D mouse event, let windows handle it */
    //if (handled == SPW_FALSE)
    //{
    //  TranslateMessage( &msg );
    //  DispatchMessage( &msg );
    //  std::cout << " not a 3d mouse event..." << std::endl;
    //}
  } 

  return( (int) msg.wParam );
} 


void  SbMotionEvent(SiSpwEvent *pEvent) {
  ClearScreen();
  std::cout << "SbMotionEvent: " << std::endl;
}
void  SbZeroEvent() {
  std::cout << "zeroevent: " << std::endl;

}
void  SbButtonPressEvent(int buttonnumber) {
  ClearScreen();
  std::cout << "Buttonnumber : " << buttonnumber << std::endl;
}
void  SbButtonReleaseEvent(int buttonnumber) {
  std::cout << "Buttonnumber : " << buttonnumber << std::endl;
}

void  HandleDeviceChangeEvent(SiSpwEvent *pEvent) {
  std::cout << "HandleDeviceChangeEvent : " << std::endl;
}


mikeda_pro
Posts: 5
Joined: Mon Sep 15, 2014 11:39 pm

Re: c++ console application example

Post by mikeda_pro » Fri Sep 19, 2014 1:46 am

Hello again,

3Dconnexion took me by the hand and explained me that :
* console applications need a message pump (http://www.codeproject.com/Tips/290875/ ... e-applicat)
* SpaceNavigator Messages are bound to windows
* therefore a (hidden) window is needed
* SiGrabDevice(devHdl, SPW_TRUE); /* PREVENTS OTHER APPLICATIONS FROM RECEIVING 3D CONNEXION DATA !!! */ // helps to bind the device to the application (window,...) exclusively

3Dconnexion proposed following Console Application which works perfectly for us :

Code: Select all

#include"windows.h"
#include <iostream>

#include "spwmacro.h"  /* Common macros used by SpaceWare functions. */
#include "si.h"        /* Required for any SpaceWare support within an app.*/
#include "siapp.h"     /* Required for siapp.lib symbols */

#pragma warning(disable:4700)

SiHdl       devHdl;       /* Handle to 3D Mouse Device */
SiOpenData oData; 
WNDPROC wndProcOrig;

void ClearScreen() {
  for(unsigned i=0; i<100; ++i) std::cout << std::endl;
}

int SbInit(HWND hwndC);
void  SbMotionEvent(SiSpwEvent *pEvent);
void  SbZeroEvent();
void  SbButtonPressEvent(int buttonnumber);
void  SbButtonReleaseEvent(int buttonnumber);
void  HandleDeviceChangeEvent(SiSpwEvent *pEvent);


LRESULT CALLBACK MyWndCBProc(
  HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam)
{
  SiSpwEvent     Event;    /* SpaceWare Event */ 
  SiGetEventData EData;    /* SpaceWare Event Data */

  /* initialize Window platform specific data for a call to SiGetEvent */
  SiGetEventWinInit(&EData, wm, wParam, lParam);

  /* check whether wm was a 3D mouse event and process it */
  //if (SiGetEvent (devHdl, SI_AVERAGE_EVENTS, &EData, &Event) == SI_IS_EVENT)
  SpwRetVal retval = SiGetEvent (devHdl, 0, &EData, &Event);

  if (retval == SI_IS_EVENT)
  {
    if (Event.type == SI_MOTION_EVENT)
    {
      SbMotionEvent(&Event);        /* process 3D mouse motion event */     
    }
    else if (Event.type == SI_ZERO_EVENT)
    {
      SbZeroEvent();                /* process 3D mouse zero event */     
    }
    else if (Event.type == SI_BUTTON_PRESS_EVENT)
    {
      SbButtonPressEvent(Event.u.hwButtonEvent.buttonNumber);  /* process button press event */
    }
    else if (Event.type == SI_BUTTON_RELEASE_EVENT)
    {
      SbButtonReleaseEvent(Event.u.hwButtonEvent.buttonNumber); /* process button release event */
    }
    else if (Event.type == SI_DEVICE_CHANGE_EVENT)
    {
      //SbHandleDeviceChangeEvent(&Event); /* process 3D mouse device change event */
    }
  }

  return DefWindowProc(hwnd, wm, wParam, lParam);
}

void main (void) {
  
  /* Retrieve console application main window using GetConsoleWindow() */
  HWND windowHandle = GetConsoleWindow() ; /* Great!!  This function  cleverly "retrieves the window handle  used by the console associated with the calling process",   as msdn says */

  /* Register a custom window class */
  WNDCLASSEX wcex;
  wcex.cbSize = sizeof(WNDCLASSEX);
  wcex.style      = CS_HREDRAW | CS_VREDRAW;
  wcex.lpfnWndProc  = MyWndCBProc;
  wcex.cbClsExtra    = 0;
  wcex.cbWndExtra    = 0;
  wcex.hInstance    = GetModuleHandle(NULL);
  wcex.hIcon      = NULL;
  wcex.hCursor    = LoadCursor(NULL, IDC_ARROW);
  wcex.hbrBackground  = (HBRUSH)(COLOR_BTNFACE+1);
  wcex.lpszMenuName  = NULL;
  wcex.lpszClassName  = "MyWindowClassName";
  wcex.hIconSm    =  NULL;
  RegisterClassEx(&wcex);

  /* Create a hidden window owned by our process and parented to the console window */
  HWND hWndChild = CreateWindow(wcex.lpszClassName, "MyWindowTitle", WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, wcex.hInstance, NULL);

  /* Initialise 3DxWare access / call to SbInit() */
  SbInit(hWndChild);
   
  /* Implement message loop */
  int bRet;
  MSG msg;      /* incoming message to be evaluated */
  while(bRet = GetMessage(&msg, NULL, 0, 0 ))
  { 
    if (bRet == -1){
      /* handle the error and possibly exit */
      return;
    }else{
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
    } 
  }
}


int SbInit(HWND hwndC)
{
  int res;                             /* result of SiOpen, to be returned  */

  /*init the SpaceWare input library */
  if (SiInitialize() == SPW_DLL_LOAD_ERROR)  {
    std::cout << "Error: Could not load SiAppDll dll files" << std::endl;
  } else {
    //std::cout << "SiInitialize() done " << std::endl;
  }

  SiOpenWinInit (&oData, hwndC);    /* init Win. platform specific data  */

  /* open data, which will check for device type and return the device handle to be used by this function */ 
  if ( (devHdl = SiOpen("AppSpaceMouse.exe", SI_ANY_DEVICE, SI_NO_MASK, SI_EVENT, &oData)) == NULL) {
    std::cout << "SiOpen error:" << std::endl;
    SiTerminate();  /* called to shut down the SpaceWare input library */
    std::cout << "SiTerminate()" << std::endl;
    res = 0;        /* could not open device */
    return res; 
  }

  SiDeviceName pname;
  SiGetDeviceName (devHdl, &pname);
  //std::cout << "devicename =  " << pname.name << std::endl;

  SiSetUiMode(devHdl, SI_UI_ALL_CONTROLS); /* Config SoftButton Win Display */
  SiGrabDevice(devHdl, SPW_TRUE); /* PREVENTS OTHER APPLICATIONS FROM RECEIVING 3D CONNEXION DATA !!! */
  res = 1;        /* opened device succesfully */ 
  return res;   
}

void  SbMotionEvent(SiSpwEvent *pEvent) {
  std:: cout << "TX=" << pEvent->u.spwData.mData[SI_TX] << " TY=" << pEvent->u.spwData.mData[SI_TY] << " TZ=" << pEvent->u.spwData.mData[SI_TZ] << " RX=" << pEvent->u.spwData.mData[SI_RX] << " RY=" << pEvent->u.spwData.mData[SI_RY] << " RZ=" << pEvent->u.spwData.mData[SI_RZ] << std::endl;
}
void  SbZeroEvent() {
  std::cout << "zeroevent: " << std::endl;
}
void  SbButtonPressEvent(int buttonnumber) {
  std::cout << "Buttonnumber : " << buttonnumber << std::endl;
}
void  SbButtonReleaseEvent(int buttonnumber) {
  std::cout << "Buttonnumber : " << buttonnumber << std::endl;
}
void  HandleDeviceChangeEvent(SiSpwEvent *pEvent) {
  std::cout << "HandleDeviceChangeEvent : " << std::endl;

}

Post Reply