Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: sendMessage from a .Net App

  1. #1
    Constant Bitrate ruairi's Avatar
    Join Date
    Jan 2005
    Location
    Spain
    Posts
    165

    sendMessage from a .Net App

    OK, I am stuck . I am trying to talk to RR from a C# application. I want to use sendMessage but I am stuck. sendMessage uses stuff that is unsafe in .Net and also has some pointer data which is a nightmare for me to code. I've looked at the Delphi & VB6 examples and this is as close as I can get the code in C#. So my questions are:

    1. Has anyone written sendMessage for RR in a .Net language?

    2. Guino, is it possible to create a new method that is easier for me to use than sendMesssage.


    Code:
    ...
    
    [StructLayout(LayoutKind.Sequential)]
    	public class COPYDATASTRUCT
    	{
    		public int dwData = 0;//32 bit int to passed. Not used.
    		public int cbData = 0;//length of string. Will be one greater because of null termination.
    		public IntPtr lpData;//string to be passed.
    
    		public COPYDATASTRUCT()
    		{
    		}
    
    		public COPYDATASTRUCT(string Data)
    		{
    			lpData = Data + "/0";   //add null termination
    			cbData = lpData.Length; //length includes null chr so will be one greater
    		}
    	}
    ...
    
    
    [DllImport("User32.dll")] public static extern IntPtr SendMessage( int hwnd, int uMsg, int wParam, COPYDATASTRUCT lParam);
    		
    [DllImport("user32.dll") ]	static extern int FindWindow (string lpClassName,string WindowName);
    
    private static int _messageID = 1163005939;
    		public const int WM_COPYDATA = 0x4A;
    
    		public void PluginSendMessage(string windowname, string className, string message)
    		{
    			
    			int hWnd;
    
    				
    			hWnd = FindWindow ("ThunderRT6FormDC","RoadRunner");
    
    
    			SendMessage(hWnd, WM_COPYDATA, 0, new COPYDATASTRUCT(message));
    			
    	
    		}

    One solution I thought of was to write a DLL in Delphi or VB6 using the slightly modified example code. Then I can add this DLL to the .Net app ad call the DLL to make the sendMessage code. But I don't have Delphi or VB6 tools to create the DLL. Can someone thrash together a small DLL with two public methods:

    int winHandler = FindWindow(string lpClassName,string WindowName)
    SendMessage(int winHandler, string message)

    With this DLL I can call RR or any other App that uses sendMessage.

    All help on this is greatly appreciated! I'm stuck

  2. #2
    Constant Bitrate ruairi's Avatar
    Join Date
    Jan 2005
    Location
    Spain
    Posts
    165
    Updated.

  3. #3
    RoadRunner Mastermind
    Auto Apps:loading...
    guino's Avatar
    Join Date
    Nov 2004
    Location
    Toronto, Canada
    Posts
    9,817
    dwdata Must be 1 (one=string) for it to work... when you can't declare a simple struct type in a language, I truly believe things have blown up to hell ..

    optionally, you can send any command to RR by finding the active (displayed) window and simulating keypresses into it like: "PLAY" or "NEXT" (including quotes). but if you're not detailed enough to select RR's window, it may end up sending keypresses to other applications you don't want to..

    PS: It's not possible to make a DLL to perform what you want because in VB you must compile the application with the appropriate window name or it won't be effective to receive any incomming messages.
    Ride Runner RR's Myspace

    "Being happy is not about having what you want, it's about wanting what you have."
    "The best things in life are always free - but that doesn't mean money can't buy you good things."

  4. #4
    Constant Bitrate ruairi's Avatar
    Join Date
    Jan 2005
    Location
    Spain
    Posts
    165
    Yesssss! Guino you are a star! Changing it to a 1 fixed it.

    C# is an OK language it just likes to make native Windows stuff really nasty to code. It gives little joy when needing Win32 APIs, like sendMessage. If anyone want the stub code I've written in C# use sendMessage with RR PM me.

    -Ruairi

  5. #5
    RoadRunner Mastermind
    Auto Apps:loading...
    guino's Avatar
    Join Date
    Nov 2004
    Location
    Toronto, Canada
    Posts
    9,817
    If you can make a simple example code (like the SDK example) to send/receive messages, I'd like to add it to RR sources (as example).
    Ride Runner RR's Myspace

    "Being happy is not about having what you want, it's about wanting what you have."
    "The best things in life are always free - but that doesn't mean money can't buy you good things."

  6. #6
    Constant Bitrate ruairi's Avatar
    Join Date
    Jan 2005
    Location
    Spain
    Posts
    165
    I'll tidy up that class, it has lost of junk in there right now. I'll PM it to you and add a simple Visual Studio solution test app. It will be Monday before I get it done.

    Cheers again!

  7. #7
    Variable Bitrate warnockm's Avatar
    Join Date
    Jun 2004
    Location
    Virginia
    Posts
    433
    Does anyone want to help me debug this? I'm doing something similar.. My problem is i see a few examples where lpData is an Int and some where it is an IntPtr. I don't know what to send to SendMessage. When i use IntPtr and change the datatype of VarPtr from Int to IntPtr, the message is sent but doesn't do anything. When i change everything to an Int, i don't force any datatypes, but i get the error:

    A call to PInvoke function 'WindowsApplication2!WindowsApplication2.Form1::Se ndMessage' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
    Code:
    public partial class Form1 : Form
        {
            String data = "EXIT";
            public const int WM_COPYDATA = 0x4A;
            int iHandle;
            COPYDATASTRUCT cds;
    
            [StructLayout(LayoutKind.Sequential)]
            struct COPYDATASTRUCT 
            {
                public int dwData;
                public int cbData;
                public int lpData;
            }
    
            [DllImport("user32.dll")]
            public static extern int FindWindow(string lpClassName, string lpWindowName);
    
            [DllImport("user32.dll",CharSet=CharSet.Auto)]
            private static extern int SendMessage(int hWnd, int wMsg, int wParam, COPYDATASTRUCT lParam);
    
            [DllImport("kernel32.dll")]
            public static extern void CopyMemory(byte dst, string src, int len);
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                iHandle = FindWindow("ThunderRT6FormDC", "RoadRunner");
                COPYDATASTRUCT cds;
                //Byte[] buf;
                
                //buf = StrToByteArray(data);
                cds.dwData = 1;
                cds.cbData = data.Length;
                cds.lpData = VarPtr(data);
            }
    
            public static byte[] StrToByteArray(string str)
            {
                System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
                return encoding.GetBytes(str);
            }
    
            public int VarPtr(object e)
            {
                GCHandle GC = GCHandle.Alloc(e, GCHandleType.Pinned);
                //int gc = GC.AddrOfPinnedObject().ToInt32();
                int gc = GC.AddrOfPinnedObject().ToInt32();
                GC.Free();
                return gc;
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                SendMessage(iHandle, WM_COPYDATA, 0, cds);
            }
        }
    Progress - VIA EPIA SP8000 | 120 Opus Power Supply & Case | 1GB Ram | 120GB 2.5" Hard Drive | Bluetooth 2.0 | GPRS/3G | Wifi | Road Runner/LSX 2.0 (waiting for a day skin for 3.0) | iGuidance 4.0 | Lilliput 7"

  8. #8
    RoadRunner Mastermind
    Auto Apps:loading...
    guino's Avatar
    Join Date
    Nov 2004
    Location
    Toronto, Canada
    Posts
    9,817
    My best guess is that you can't Alloc the space for the data you're referencing (with .Alloc) then free the memory before using it on the SendMessage call... you'd probably have to do the .free call AFTER the sendmessage...

    My real question is: is there any particular reason you're not using the COM interface ? It's a lot simpler and just as efficient.. check out this FAQ's section 3 on the RoadRunner.SDK object:
    http://www.mp3car.com/vbulletin/rr-f...cation-rr.html
    Ride Runner RR's Myspace

    "Being happy is not about having what you want, it's about wanting what you have."
    "The best things in life are always free - but that doesn't mean money can't buy you good things."

  9. #9
    Variable Bitrate warnockm's Avatar
    Join Date
    Jun 2004
    Location
    Virginia
    Posts
    433
    2 reasons. i haven't seen an examples of it in c# and i haven't seen how to receive messages, just receive values in RR.
    Progress - VIA EPIA SP8000 | 120 Opus Power Supply & Case | 1GB Ram | 120GB 2.5" Hard Drive | Bluetooth 2.0 | GPRS/3G | Wifi | Road Runner/LSX 2.0 (waiting for a day skin for 3.0) | iGuidance 4.0 | Lilliput 7"

  10. #10
    RoadRunner Mastermind
    Auto Apps:loading...
    guino's Avatar
    Join Date
    Nov 2004
    Location
    Toronto, Canada
    Posts
    9,817
    I am puzzled as to what difference you're making from receiving 'messages' or 'values' from RR.. the only 'messages' you'd receive from RR are those containing 'values' you've requested from it (i.e. using request).. are you trying to use the 'sendmsg' command from the skin to control your application ? is that it ? because if so, there are ways of not needing that and using actually simpler commands for you to execute from your application using the COM SDK... here's a generic example of the COM interface in C# compared to the VB6 interface:

    Code:
    The following VB code:
    
    Public Sub TestSDKVB6()
            Dim SDK As Object 
            Dim RRSCR as String
            Set SDK = CreateObject("RoadRunner.SDK")
            RRSCR = SDK.GetInfo("TRACKNAME")
            SDK.Execute "EXIT"
    End Sub
    
    Converts to the following C# code, using this approach:
    
    public void TestSDKDOTNET()
    {
            System.Type SDKType = System.Type.GetTypeFromProgID("RoadRunned.SDK");
            object SDK = System.Activator.CreateInstance(SDKType);
            RRSCR = SDK.InvokeMember("GetInfo", System.Reflection.BindingFlags.InvokeMethod, null, o, new object[] {"TRACKNAME"});
            SDK.InvokeMember("Execute", System.Reflection.BindingFlags.InvokeMethod, null, o, new object[] {"EXIT"});
    }
    You can probably make procedures to call those functions (.Execute, .GetInfo and .GetInd) just so you avoid typing all that useless stuff.. once you created the SDK object, you can keep it until your program is finished with it.

    in regards to the sendmessage version of this all, here's a supposedly "working" example of how to use the WM_COPYDATA message from C#:

    Code:
    Win32.COPYDATASTRUCT cds;
    
    cds.dwData = new System.IntPtr(sig);
    str = str + '\0';
    cds.cbData = str.Length + 1;
    cds.lpData =
    System.Runtime.InteropServices.Marshal.AllocCoTask Mem(str.Length);
    
    cds.lpData =
    System.Runtime.InteropServices.Marshal.StringToCoT askMemAnsi(str);
    
    System.IntPtr iPtr =
    System.Runtime.InteropServices.Marshal.AllocCoTask Mem(System.Runtime.InteropServices.Marshal.SizeOf( cds));
    System.Runtime.InteropServices.Marshal.StructureTo Ptr(cds,
    iPtr, true);
    
    Win32.SendMessage(handle, Win32.WM_COPYDATA, iHandle,
    iPtr);
    
    System.Runtime.InteropServices.Marshal.FreeCoTaskM em(cds.lpData);
    System.Runtime.InteropServices.Marshal.FreeCoTaskM em(iPtr);
    Note how the Calls to Free the pointers/data are done AFTER the sendmessage.
    Ride Runner RR's Myspace

    "Being happy is not about having what you want, it's about wanting what you have."
    "The best things in life are always free - but that doesn't mean money can't buy you good things."

Page 1 of 2 12 LastLast

Similar Threads

  1. Alpine City Cruise
    By Hell-Stopper in forum RR Skins
    Replies: 170
    Last Post: 02-22-2007, 11:05 PM
  2. problems with ext app
    By xengo in forum Media Engine
    Replies: 0
    Last Post: 04-04-2005, 11:01 AM
  3. Switcher - A little button app to Alt-Tab between two programs.
    By LESLIEx317537 in forum Other Cool Stuff
    Replies: 30
    Last Post: 12-23-2004, 07:47 PM
  4. [HOWTO] Make a custom external app button
    By netsuo in forum NeoCar Media Center
    Replies: 0
    Last Post: 11-15-2004, 06:42 AM
  5. [OT - almost] Looking for best way to save App data - is XML OK
    By kingtut in forum Software & Software Development
    Replies: 8
    Last Post: 07-12-2004, 12:39 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •