|
I just recently downloaded Windows Media Connect 2.0.
There is a DLL inside the installation (C:\Program Files\Windows Media Connect 2\wmcsci.dll) that I've imported as a reference to my C# project. I can see all the classes, and am actually able to do a number of things to interact with the Windows Media Connect server running locally. For example:
using WMCSCI;<br />
...<br />
WMCManager manager = new WMCManager();<br />
Console.WriteLine("WMC status: " + manager.Status);<br />
Devices devices = manager.GetDevices(DeviceAuthorization.AllDevices);<br />
Console.WriteLine("Devices: " + devices.Count);<br />
Libraries libraries = manager.SharedLibraries;<br />
Console.WriteLine("Shared Libraries: " + libraries.Count);<br />
All of the methods and properties seem to work -- with one exception. The COM interface defines get_Item() on a number of the interfaces, namely:
IWMCDevices<br />
IWMCLibraries<br />
IWMCProperties
(Here's a link to the get_Item() API method on IWMCDevices, for example.)
From C#, there are no "Item" or "getItem" methods, and the interfaces are not enumerable either. It requires that I use array notation to access indices in the collection.
object index = 0;<br />
IWMCDevices devices = manager.GetDevices(DeviceAuthorization.AllDevices);<br />
IWMCDevice device = devices[index];
However, the compiler requires a "ref object Index" argument when using this notation. And devices[ref index] doesn't work either.
How can I access the items in these collections? Is there some interop signature I can create to access the original get_Item() method, or is there something else that I'm missing?
Thanks!
David
|
|
|
|
|
dkarlton wrote: There is a DLL inside the installation (C:\Program Files\Windows Media Connect 2\wmcsci.dll) that I've imported as a reference to my C# project.
You should know better.
Use the UPnP COM object rather. Same thing/functionality AFAIK.
xacc-ide 0.0.99-preview7 now with C#, C, C++, IL, XML, Nemerle, IronPython, Perl, Caml, SML, Ruby, Flex, Yacc, Java, Javascript, Lua, Prolog and Boo highlighting support!
|
|
|
|
|
That may be well and good to be able to use the UPnP interface to WMC. And I may be able to get the same functionality. But ultimately I want to use the WMC API, in part because it seems ridiculous that it's not possible to use .NET and C# to cleanly access the COM API's. If the workaround to this issue is "use a different tool" then my gut reaction is "why am I using broken tools in the first place?" Clearly, I am just stubborn. OK, enough of my ranting.
In the meantime, I've made a kludged reflection workaround to handle get_Item(). I'm still hoping there's someone out there who can offer a more elegant solution:
int index = 0;<br />
WMCManager manager = new WMCManager();<br />
Devices devices = manager.GetDevices(DeviceAuthorization.AllDevices);<br />
Device d = (Device)devices.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, devices, new object[]{index});
And by the way, if I wanted to use UPnP instead of the WMC API, there's still an issue of using interop to handle events and asynchronous discovery:
[ComImport, Guid("415A984A-88B3-49F3-92AF-0508BEDF0D6C"),<br />
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]<br />
internal interface IUPnPDeviceFinderCallback<br />
{<br />
void DeviceAdded(int lFindData, IUPnPDevice pDevice);<br />
void DeviceRemoved(int lFindData, string bstrUDN);<br />
void SearchComplete(int lFindData);<br />
}<br />
<br />
[ComImport, Guid("31fadca9-ab73-464b-b67d-5c1d0f83c8b8"),<br />
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]<br />
public interface IUPnPServiceCallback<br />
{<br />
void StateVariableChanged(IUPnPService pus,<br />
[MarshalAs(UnmanagedType.LPWStr)] string pcwszStateVarName, object vaValue);<br />
void ServiceInstanceDied(IUPnPService pus);<br />
}<br />
Cheers,
David
|
|
|
|
|
Oh, and by the way, after further investigation, it is <bold>not possible to share libraries and/or authorize devices via UPnP (which is what we are ultimately trying to do). You can only use the Windows Media Connect application GUI, or the new WMC API. (As far as I can tell. Correct me if I'm wrong.)
David
|
|
|
|
|
I've got an ArrayList of objects. I call up a form to create a new object from one of the objects in the array.
User selects the object to create the new object from.
Now, I need to create a new object from the old object, so I thought this would work:
ArrayList objects = new Arraylist();
objects.Add(obj1);
obects.Add(obj2);
...
MyObject newobject = new MyObject();
{ ... iteratate through arraylist, find correct object }
newobject = correctObjectFromArrayList;
newobject.name = newobjectname;
objects.Add(newobject);
... and now I've modified both objects!
Both objects contain the changes I've made. Why is that?
In C++, if I did this, it would work.
It seems that C# uses references by default? I created a new object, not a pointer to an object.
I'm very confused. Can someone sort me out?
Thanks.
|
|
|
|
|
Why would that work in c++?
First you initialized newobject with a new MyObject instance, and promptly assigned the reference to an existing object in your collection. The new MyObject instance you created now has no reference to it. You haven't modified "both" objects, you've lost the second one and modified the first.
What exactly are you trying to do? Create the second object, initializing it with values from the first? If so, it sounds like you might want to look at the ICloneable interface. In that case, you'd find the object in your list that you want to clone, create a new object that's a clone of it and add that new object to the list. Unless you are intending something else?
Matt Gerrans
|
|
|
|
|
Thank you. I should have realized.
A MyObject object has quite a bit of dynamic data in it, set by the user. I do not want to be assigned a reference of it to another object.
Like you guessed, I need to be copying all the data from the second object, into the first. Sometimes I want to create blank MyObject objects, and sometimes I want to create MyObject objects initialized with data from another object.
I always add that MyObject back into the ArrayList after it's been created.
Will the ICloneable interface work for that? I've never used an interface, though I know a very little bit about them. Where would I start with this?
Thanks.
|
|
|
|
|
If you like the Java idiom, then you can use the IClonable interface and its Clone() method. Your object just needs to implement clone and copy the important elements to the other object.
If you like C++ idioms better, you can overload the equal operator and your assignment would work more like you expected; rather than assign the reference to the other object (the default behavior), it could essentially ocpy the object's attributes (to whatever exent you want it to, of course, since you can implement the operator as you see fit).
Matt Gerrans
|
|
|
|
|
AFAIK, you can't overload the assignment operator. Even if you did, doesn't that go against the reference semantics that other objects follow?
How about making the OP's class a struct instead?
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
Unfortunetly, my MyObject class makes use of quite a few member functions - so it can't be a class.
|
|
|
|
|
budidharma wrote: so it can't be a class.
Did you mean it can't be a struct? structs can also have member functions, so you should be fine.
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
Oh yes, that's what I meant. I didn't know structs could have member functions.
In that case, what's the difference between a struct and a class?
I thought structs were simply structures of data, no member functions allowed.
|
|
|
|
|
This[^] might help you understand structs bettter.
Essentially, structs are passed around by value, classes by reference. For example
struct A
{
public int x;
}
class B
{
public int x;
}
static void Main()
{
A structInstance = new A();
structInstance.x = 1;
A structInstance1 = structInstance;
structInstance1.x = 20;
B classInstance = new B();
classInstance.x = 1;
B classInstance1 = classInstance;
classInstance1.x = 20;
}
After executing the above code, structInstance.x will be 1 and structInstance1.x will be 20. However, classInstance.x and classInstance1.x will be 20. What it means is that when you say A structInstance1 = structInstance; a new instance of A is created and contents are copied from structInstance. When B classInstance1 = classInstance; executes, classInstance1 and classInstance begin referring to the same instance of B, therefore, changing x using any of the two references gets reflected in both.
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
Well, thank you very much for explaining that to me. That makes perfect sense - and yes, you were correct. I merely need to change my class to a struct and it will work the way intended.
Thanks Again.
|
|
|
|
|
Right. I don't know what I was thinking.
So you're left with Clone().
Matt Gerrans
|
|
|
|
|
Hi, Does anyone know an easy way to create a string of characters that are assigned 1 byte for each character, in C#.
I am interfaceing with a rather old API (written in ANSI C, think) from .NET 2005 (beta). The problem is that the normal c# string data type uses unicode encoding, this allocates atleast 8 bytes per char.
I have a Delphi 6 interface for the API that uses PCHAR data type, instead of string, and this works OK.
Also, will I need to declare the API calls with a data type that uses 1 byte per char, instead of just string ?
P.S. this is the MSMAPI32.DLL to connect to Micronetics MSM (MUMPS). Incase there are any MUMPSTER's out there.
Thanx!
Dave Shaw
History admires the wise, but elevates the brave. - Edmund Morris
|
|
|
|
|
Dave Shaw wrote: The problem is that the normal c# string data type uses unicode encoding, this allocates atleast 8 bytes per char.
thats 2 bytes rather...
Use System.Text.Encoding.UTF8.GetBytes() .
xacc-ide 0.0.99-preview7 now with C#, C, C++, IL, XML, Nemerle, IronPython, Perl, Caml, SML, Ruby, Flex, Yacc, Java, Javascript, Lua, Prolog and Boo highlighting support!
|
|
|
|
|
Leppie is right, Unicode is 2-bytes, not 8. Unicode makes room for 65,535 characters in a set (255 * 255). 8 Bytes would allow lots and lots and lots of characters, like (255 ^ 8).
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
Unicode makes room for something like a million characters. Unicode does not take up any "bytes". It just define which "character" is at which number. In order to represent Unicode in memory or on file, you need an encoding of the Unicode character set.
The UTF-16 encoding (which is probably what you refer to as this is what C# use internally) will use 2 or 4 bytes per character.
|
|
|
|
|
well you can always use byte vectors, or pointers to byte in an unsafe part of the code... then you can use normal io.streamwriter for writing and io.streamreader for reading
<- true inside to understand outside ->
|
|
|
|
|
|
Im having a trouble to catch KeyDown event on the form.. it just doesnt work..
any other control on the form can get KeyDown event if ill set it to him
but the form event just doesnt work..
thanks..
|
|
|
|
|
The form itself rarely ever has the focus. The controls on the form have it, so the form's KeyDown event is rarely ever called. Unless, that is, the Form's KeyPreview property is set to true . This will pass all the keyboard events going to the form's control with the focus to the form's handlers first, then pass them on to the control that has the focus. There is a side effect to setting this though. The KeyDown event will fire for every keystroke going to any control on your form.
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
Thanks exactly what i was looking for !
they didnt mention that on MSDN..
|
|
|
|
|
Hi, I'm curious, why would a form need to catch keyboard events? What are you using it for? I can't think of any scenario where this can be used.
/Patric
My C# blog: C# Coach
|
|
|
|
|