Sponsored links

Go Back   MP3Car.com > Mp3Car Technical > Software & Software Development > Front Ends > Road Runner


Reply
 
Share Thread Tools Display Modes
Old 05-12-2005, 10:41 AM   #1
Constant Bitrate
 
ruairi's Avatar
 
Join Date: Jan 2005
Location: Spain
Posts: 165
ruairi is on a distinguished road
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

Last edited by ruairi; 05-13-2005 at 09:51 AM. Reason: Tried a few things and still not working
ruairi is offline   Reply With Quote
Advertisement
 
Advertisement
Sponsored links

Old 05-13-2005, 09:52 AM   #2
Constant Bitrate
 
ruairi's Avatar
 
Join Date: Jan 2005
Location: Spain
Posts: 165
ruairi is on a distinguished road
Updated.
ruairi is offline   Reply With Quote
Old 05-13-2005, 01:54 PM   #3
RoadRunner Mastermind
 
guino's Avatar
 
Join Date: Nov 2004
Location: Vitória, ES - Brazil
Posts: 9,060
guino will become famous soon enoughguino will become famous soon enough
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."

Last edited by guino; 05-13-2005 at 01:57 PM.
guino is offline   Reply With Quote
Old 05-13-2005, 04:37 PM   #4
Constant Bitrate
 
ruairi's Avatar
 
Join Date: Jan 2005
Location: Spain
Posts: 165
ruairi is on a distinguished road
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
ruairi is offline   Reply With Quote
Old 05-13-2005, 04:50 PM   #5
RoadRunner Mastermind
 
guino's Avatar
 
Join Date: Nov 2004
Location: Vitória, ES - Brazil
Posts: 9,060
guino will become famous soon enoughguino will become famous soon enough
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."
guino is offline   Reply With Quote
Old 05-13-2005, 07:10 PM   #6
Constant Bitrate
 
ruairi's Avatar
 
Join Date: Jan 2005
Location: Spain
Posts: 165
ruairi is on a distinguished road
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!
ruairi is offline   Reply With Quote
Old 09-30-2007, 12:41 AM   #7
Variable Bitrate
 
warnockm's Avatar
 
Join Date: Jun 2004
Location: Virginia
Posts: 433
warnockm is on a distinguished road
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:

Quote:
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"
warnockm is offline   Reply With Quote
Old 09-30-2007, 01:48 AM   #8
RoadRunner Mastermind
 
guino's Avatar
 
Join Date: Nov 2004
Location: Vitória, ES - Brazil
Posts: 9,060
guino will become famous soon enoughguino will become famous soon enough
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."
guino is offline   Reply With Quote
Sponsored links
Advertisement
 
Advertisement
Old 09-30-2007, 10:59 AM   #9
Variable Bitrate
 
warnockm's Avatar
 
Join Date: Jun 2004
Location: Virginia
Posts: 433
warnockm is on a distinguished road
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"
warnockm is offline   Reply With Quote
Old 09-30-2007, 12:02 PM   #10
RoadRunner Mastermind
 
guino's Avatar
 
Join Date: Nov 2004
Location: Vitória, ES - Brazil
Posts: 9,060
guino will become famous soon enoughguino will become famous soon enough
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."
guino is offline   Reply With Quote
Old 09-30-2007, 12:06 PM   #11
Variable Bitrate
 
warnockm's Avatar
 
Join Date: Jun 2004
Location: Virginia
Posts: 433
warnockm is on a distinguished road
I guess i think of a value being: a message(request) sent and that value received. a message received, to me, would be a button pressed, like my custom orb buttons. Am i looking at it wrong?
__________________
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"
warnockm is offline   Reply With Quote
Old 09-30-2007, 12:12 PM   #12
RoadRunner Mastermind
 
guino's Avatar
 
Join Date: Nov 2004
Location: Vitória, ES - Brazil
Posts: 9,060
guino will become famous soon enoughguino will become famous soon enough
No no, you're looking at it right.. and you can use sendmsg to trigger commands on your app.. but you could do that slightly different from the SDK.. for instance, instead of using "SENDMSG" you could use setvar.. and a single variable with your "command".. something like:

"SETVAR;ORBCMD;<COMMAND>" from RR ... then in your c# app you could have a loop/check every so often (i.e. 2-5 times per second for faster response) where you'd do this (VB6/Pseudo Code):

Code:
IF SDK.GetInfo("=$ORBCMD$") <> "" then ORBCMD = SDK.GetInfo("=$ORBCMD$") SDK.Execute("SETVAR;ORBCMD;") Select Case ORBCMD case "PLAY" ... case "AUDIO" ... End Select End If

Also, nothing prevents you from using both interfaces at once (for whatever reason).
__________________
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."
guino is offline   Reply With Quote
Old 09-30-2007, 12:17 PM   #13
Variable Bitrate
 
warnockm's Avatar
 
Join Date: Jun 2004
Location: Virginia
Posts: 433
warnockm is on a distinguished road
THAT helps a lot. I wasn't sure if there was an event that triggered on a message received, or if it was something i had to check for. I'll press on...
__________________
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"
warnockm is offline   Reply With Quote
Old 09-30-2007, 12:43 PM   #14
Variable Bitrate
 
warnockm's Avatar
 
Join Date: Jun 2004
Location: Virginia
Posts: 433
warnockm is on a distinguished road
Quote: Originally Posted by guino View Post
Code:
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"}); }

I'm not sure how this works... InvokeMember is a method of System.Type (i.e., SDKType), not Object. Type.InvokeMember returns an Object. is that what RRSCR is? if so, what is the object "o" in InvokeMember?
__________________
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"
warnockm is offline   Reply With Quote
Old 09-30-2007, 01:06 PM   #15
RoadRunner Mastermind
 
guino's Avatar
 
Join Date: Nov 2004
Location: Vitória, ES - Brazil
Posts: 9,060
guino will become famous soon enoughguino will become famous soon enough
Yes sorry, you're right, when I 'translated' the code I got that wrong.. this is the updated code:

Code:
public void TestSDKDOTNET() { System.Type SDKType = System.Type.GetTypeFromProgID("RoadRunned.SDK"); object SDK = System.Activator.CreateInstance(SDKType); RRSCR = SDKType.InvokeMember("GetInfo", System.Reflection.BindingFlags.InvokeMethod, null, SDK, new object[] {"TRACKNAME"}); SDKType.InvokeMember("Execute", System.Reflection.BindingFlags.InvokeMethod, null, SDK, new object[] {"EXIT"}); }

Please note the SDK object passed as a parameter to InvokeMember.
__________________
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."
guino is offline   Reply With Quote
Sponsored links
Advertisement
 
Advertisement
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


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



All times are GMT -5. The time now is 08:22 PM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.3.2
Copyright © 1999 - 2008 Mp3Car.com Inc.Ad Management by RedTyger
Message Board Statistics