Using Request and winuser.h with Max/SDK ?


    Jul 26 2009 | 9:21 pm
    Hello,
    Sorry for my - i guess - odd title. My issue is not easy to define.
    I am developping an Max5 external in WinXP, VC++. The goal of the object is to be an interface between Max and a multitouch surface Lumio.
    Dialog between client object and surface server is based on Windows framework : RegisterWindowMessage() and PostMessage() mainly, from Winuser.h
    Nothing magic till there.
    My object first asks for server :
    void *lumio_new(long num)
    {
    	t_lumio *lumioObject;
    	lumioObject = (t_lumio *)newobject(lumio_class);
    
    	lumioObject->uiGlobal_MsgID_LumioDiscover = RegisterWindowMessage((LPCTSTR)"LumioCTAPIDiscover");
    	lumioObject->uiGlobal_MsgID_LumioAttach = RegisterWindowMessage((LPCTSTR)"LumioCTAPIAttach");
    
    	return lumioObject;
    }
    
    void lumio_connect(t_lumio *x)
    {
    	//first time connection
    	WPARAM m_hWnd = 0;//id du serveur en get
    	PostMessage( HWND_BROADCAST, x->uiGlobal_MsgID_LumioDiscover, (WPARAM)m_hWnd, 0);
    }
    /*The message is posted to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows. The message is not posted to child windows.*/
    
    Till here ok. But now, I need a callback to catch server answer of course. What is proposed is to overwrite CWnd::onWndMsg(...) , what expects to make some C++ I guess : =
    CWnd::OnWndMsg(_THE CATCHED ANSWER_)
    At this point, I'm totally lost.
    Is any generous soul can help me ?
    Is coding my external in C# not a better idea ?
    Thank you.
    AsR

    • Jul 27 2009 | 12:16 am
      First, writing externals in C# is not currently an option (though I'm working on it). There is a topic about this in this forum.
      Second, why are you posting system-wide window messages? There has got to be a more direct route. Is this "surface server" a running windowed application? It appears that this technology works with Macs, so they must be doing something else there.
    • Jul 27 2009 | 10:08 am
      That's right, there is "CCmdTarget.class" that is lower-levelled than working with windows.
      Quote: Is this "surface server" a running windowed application?
      Nope. But the client is invited to code as if. I think serveur app is probably a CCmdTarget. But all that are MFC functions, and first I did not work often in windows, then I'm totally new with MFC... Finally, I'm making a C++ class in a C-external. Party !
      I'll make one for OSX, probably based on TUIO.
    • Jul 27 2009 | 11:39 am
      I know some folks have run into trouble with the details of setting up a C++ project on Windows. In the next version of the Max SDK there will be an example project.
      In case it is helpful, I am attaching that sample project (called collect) here. Hope this helps... Tim
    • Jul 27 2009 | 2:21 pm
      Thanks. I took a look at.
      Actually I managed to solve some things with MFC. I renamed my_object.c to my_object.cpp. Things about C++ stop here, cause I just need to use a MFC::CWnd attribute in my obect structure.
      Now I'm in trouble with afxwin.h and ext.h, and the dllmain_win.c There are conflicts, CWnd is not recognised.
      ...
      in progress
      //external
      //#include 
      #include 
      #include "Winuser.h"
      #include "ext.h"//contains afxwin.h
      #include "string.h"
      
      //class for interecepting messages
      //todo by inheriting CWnd or CDialog form MFC
      
      //MAX EXTERNAL
      typedef struct {
      	t_object m_ob;
      	UINT uiGlobal_MsgID_LumioDiscover;
      	UINT uiGlobal_MsgID_LumioAttach;
      	void *l_out;
      	//CWnd *l_virtualWnd;
      } t_lumio;
      
      void lumio_bang(t_lumio *x);
      void lumio_connect(t_lumio *x);
      void lumio_disconnect(t_lumio *x);
      char*  lumio_messageOut(t_lumio *x, t_symbol *s, short argc, t_atom *argv);
      void lumio_free(t_lumio *x);
      void *lumio_new(long num);
      void *lumio_class;
      
      int main()
      {
      	setup((t_messlist **)&lumio_class, (method)lumio_new, (method)lumio_free, (short)sizeof(t_lumio), 0L, A_DEFLONG, 0);//instancie la classe (pas l'objet)
      	addmess((method)lumio_connect, "connect", 0);
      	addmess((method)lumio_disconnect, "disconnect", 0);
      	addbang((method)lumio_bang);
      	return 0;
      }
      
      ////////////////////////////////////////////////////////////////////////////////
      //new LUMIO
      void *lumio_new(long num)
      {
      
      	t_lumio *lumioObject;
      	lumioObject = (t_lumio *)newobject(lumio_class);
      	lumioObject->l_out = intout(lumioObject);
      	//lumioObject->uiGlobal_MsgID_LumioDiscover = RegisterWindowMessage((LPCTSTR)"LumioCTAPIDiscover");
      	//lumioObject->uiGlobal_MsgID_LumioAttach = RegisterWindowMessage((LPCTSTR)"LumioCTAPIAttach");
      
      	//l_vWindow = new CVirtualDialog(...aremplir...);
      
      	return lumioObject;
      }
      
      //~LUMIO
      void lumio_free(t_lumio *x)
      {
      	//delete l_vWindow
      }
      ////////////////////////////////////////////////////////////////////////////////////
      
      // IN (callback) /****************************/
      
      //connexion
      void lumio_connect(t_lumio *x)
      {
      	//first time connection
      	WPARAM m_hWnd = 0;//id du serveur en get
      	//l_vWindow->
      	::PostMessage( HWND_BROADCAST, /*The message is posted to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows. The message is not posted to child windows.*/
      		//						x->uiGlobal_MsgID_LumioDiscover,
      		0, (WPARAM)m_hWnd, 0);
      }
      
      //deconnexion
      void lumio_disconnect(t_lumio *x)
      {
      	//deconnection
      	WPARAM m_hWnd = 0;//id du serveur en get
      	//l_vWindow->PostMessage( HWND_BROADCAST, /*The message is posted to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows. The message is not posted to child windows.*/
      		//						x->uiGlobal_MsgID_LumioDiscover, (WPARAM)m_hWnd, 0);
      }
      
      //bang pour tester
      void lumio_bang(t_lumio *x)
      {
      	t_atom a;
      
      	a.a_type = A_LONG;
      	a.a_w.w_long = 0L;
      	//lumio_atom(x,&a);
      	post("bang in");
      }
      
      // End - IN (callback) /****************************/
      
      // OUTLET
      
      char* lumio_messageOut(t_lumio *x, t_symbol *s, short argc, t_atom *argv)
      {
      	return "hi";
      }
    • Jul 27 2009 | 9:18 pm
      asair wrote on Mon, 27 July 2009 10:21
      //external
      //#include 
      #include 
      #include "Winuser.h"
      #include "ext.h"//contains afxwin.h
      #include "string.h"
      
      ext.h is the standard max header, it doesn't contain afxwin.h (unless you modified it, which is really really not a good idea, or there's another ext.h file that's being included instead of the normal one).
    • Jul 27 2009 | 11:16 pm
      Nope youre right, it does not contains afxwin. However it does "windows.h".
      Which conflicted with afxwin.h depending on the order of calls.
      But, i red somewhere ext.h should actually be called first, what did not match #ifndef with afxwin.
      Anyway, I andonned this way of dev.
      TuioClient.mxe is ho so relevant for such needs.