|
DEVMODE dm = new DEVMODE();
dm.dmSize = (short)Marshal.SizeOf(typeof(DEVMODE));
int mode = 0;
while (EnumDisplaySettings(null, mode++, ref dm) != 0)
{
Console.WriteLine("{0}x{1}, {2}bits {3}hz",
dm.dmPelsWidth, dm.dmPelsHeight, dm.dmBitsPerPel, dm.dmDisplayFrequency);
}
[DllImport("user32.dll", CharSet=CharSet.Ansi)]
static extern int EnumDisplaySettings(StringBuilder devname, int mode, ref DEVMODE devmode);
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public short dmOrientation;
public short dmPaperSize;
public short dmPaperLength;
public short dmPaperWidth;
public short dmScale;
public short dmCopies;
public short dmDefaultSource;
public short dmPrintQuality;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string dmFormName;
public short dmLogPixels;
public int dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
}
This works Note the union ???? looks like it combines 2 int 's ???
MYrc : A .NET IRC client with C# Plugin Capabilities. See
http://sourceforge.net/projects/myrc for more info.
|
|
|
|
|
|
Im not really sure what a union in C++ does, it appears to join 2 variables into one, hence the commented dmNup. Can anyone C++ person please explain this in C# terms?
MYrc : A .NET IRC client with C# Plugin Capabilities. See
http://sourceforge.net/projects/myrc for more info.
|
|
|
|
|
A union uses the same piece of memory for two different variables.
For example
struct INTCHARS
{
char hi;
char midhi;
char midlo;
char lo;
};
union FOURBYTES
{
INTCHARS ch;
int i;
};
FOURBYTES four;
four.ch.hi = 1;
four.ch.midhi = 1;
four.ch.midlo = 1;
four.ch.lo = 1;
four.i = 0;
Now each part of four.ch is 0.
Going back a while since I used one of these.
Paul
|
|
|
|
|
Thx,
From what i can see is that unions are class like structures in a struct or class allowing easy retriaval/setting of inner variables. I have been using SequintialLayout classes todo this. Im not sure if we are talking the same thing, but I guess thats why the are not included in C#.
Cheers
MYrc : A .NET IRC client with C# Plugin Capabilities. See
http://sourceforge.net/projects/myrc for more info.
|
|
|
|
|
The big difference between a union and a struct is that changing one inner variable in a union will change all of them because they share the same space in memory.
As C++ came into play, unions became less useful, classes and pointers could be used to the same effect.
When PCs with more than 50 bytes of spare memory came out, unions again lost some usefulness.
Likewise properties haven't done unions any favours, you can now reference the same variable in different ways through get/set properties.
So I wouldn't be surprised if C# didn't have an equivalent, though there are times when it wouldn't go amiss.
Paul
|
|
|
|
|
From what I understand (I also was looking into unions recently -- trying to DllImport DnsQuery_A) a union is a UDT which allows for one datatype or another, so if you specify it with a String or Int32 it would let the value be one of the two. At least that was what I took it to mean
I'm not aware of a native C# equivalent but would be glad to know of one!
--
Paul
"I need the secure packaging of Jockeys. My boys need a house!"
- Kramer, in "The Chinese Woman" episode of Seinfeld
MS Messenger: paul@oobaloo.co.uk
Sonork: 100.22446
|
|
|
|
|
As others have said a union just uses the same memory space to hold each of the types (thus only allowing one of them to be used at a time).
Typically when you are dealing with a union you have to break it out into its own datatype so that you can properly use it in code. Otherwise you could be having to use the same variable for two vastly different things such as a pointer to a string and a byte which will be hard to do when dealing with a single member.
To create a union in C#:
[StructLayout(LayoutKind.Explicit)]
public struct myUnion
{
[FieldOffset(0)] string FieldA;
[FieldOffset(0)] bool FieldB;
[FieldOffset(4)] int FieldC;
[FieldOffset(4)] long FieldD;
[FieldOffset(12)] int Foo;
[FieldOffset(12)] char Bar;
[FieldOffset(12)] float Baz;
} The numbers used will position where in memory each field will be placed, using the technique you can also create multiple unions as I did above (FieldA and FieldB; FieldC and FieldD; and Foo, Bar, and Baz; are all unions, where only one of the members can be used).
Hope that makes sense.
James
"And we are all men; apart from the females." - Colin Davies
|
|
|
|
|
That is very cool, James, nice one!
Paul
|
|
|
|
|
Hi,
I have an old DLL developped on VC++ 6.0. It was designed to work with VB and VC code. The problem always has been two special parameters which where an array of vaules. One was an array of doubles and the other an array of strings.
It was hard, but I solved it using the SAFEARRAY structure, this way:
Method (..., SAFEARRAY FAR *doubleArray, SAFEARRAY FAR *stringArray, ...)
-> To call the library from VB code I only should do:
Dim dbArray() as double<br />
Dim stArray() as string<br />
Redim dbArray(5)<br />
dbArray(0) = 3.4<br />
...<br />
'and so to strings
->To call it from VC it was more difficult:
char sMatriz[1][256];<br />
strcpy (sMatriz[0], "H E L L O ");
LPSAFEARRAY sS = new struct tagSAFEARRAY;<br />
sS->pvData=sMatriz;<br />
sS->rgsabound->cElements = 1;<br />
Method (..., &sD, &sS, ...)
THE PROBLEM:
---------------------
Now I want this library to be used on C# or VB.NET, but I don't know the way to instantiate and pass those parameters. Any chance I get an exception like this:
System.NullReferenceException<br />
Exception Details: Object reference not set to an instance of an object.
I pass those parameters like:
string[] sA = new string[5]; double[] dA = new double[5];<br />
Method (..., dA, sA,...)
...and if I modify the library taking out those params (ignoring them), everything works fine.
Does anyone knew how can I solve this problem? Is there any special way to pass those parameters?, anything before changing the library? I really need those params in the library!
Thank you in advance, (thanks if you read all the text!)
Edgar
Edgar Berengena Moreno
Software Engineer
Appeyron Research
|
|
|
|
|
A SAFEARRAY in C++ like this :
HRESULT GetItems([in] BSTR bstrLocation, [out] SAFEARRAY(VARIANT)* pItems);
is marshalled back and forth with C# declaration like this in your interface :
[ComImport]
[Guid("73EB4AF8-BE9C-4b49-B3A4-24F4FF657B26")]
public interface IMyStorage
{
[DispId(2)]
void GetItems( [In, MarshalAs( UnmanagedType.BStr )] String bstrLocation,
[Out, MarshalAs( UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT )] out Object[] Items );
...
}
Further details.
And I swallow a small raisin.
|
|
|
|
|
Thanks,
...but I can't improve anything with this! I'm trying to pass an Object[] to the library but I'm still getting the same exception.
Is there anymore information or runnig sample which solves this problem?, does anyone know it??
Thank you again,
Edgar
Edgar Berengena Moreno
Software Engineer
Appeyron Research
|
|
|
|
|
Can you try the following code :
string[] MyString = {"Hello", "and", "welcome", "to", "my" , "world!"};
I am not sure the exception you have is a marshalling issue.
And I swallow a small raisin.
|
|
|
|
|
Thank you, Stephane, but It doesn't work. I always thought this was the correct solution, but it gaves me the System.NullReferenceException exception.
If you have any other idea, please let me know.
Thank you,
Edgar
Edgar Berengena Moreno
Software Engineer
Appeyron Research
|
|
|
|
|
Hi maybe I can help.
1. Create arrays, like normal
2. Before calling function, foreach array, allocate mem, copy array to pointer and pass the pointer.
3. when the array returns copy the pointer back to the array.
For example: From MDSN
int[] array2 = new int[ 10 ];
int size = array2.Length;
IntPtr buffer = Marshal.AllocCoTaskMem( Marshal.SizeOf( size )
* array2.Length );
Marshal.Copy( array2, 0, buffer, array2.Length );
int sum2 = LibWrap.TestRefArrayOfInts( ref buffer, ref size );
if( size > 0 )
{
int[] arrayRes = new int[ size ];
Marshal.Copy( buffer, arrayRes, 0, size );
Marshal.FreeCoTaskMem( buffer );
}
Now just do this to each array. Unfortunately u dont give the whole function as defined in a header file, so I cant gaurentee this will work, but it works in my case when normal marshalling wouldnt work
Hope this helps
MYrc : A .NET IRC client with C# Plugin Capabilities. See
http://sourceforge.net/projects/myrc for more info.
|
|
|
|
|
Thanks for your reply, Leppie.
The only problem is that I'm working with string arrays too, so the Copy method of Marshall can't be applied.
I can't say if it works or doesn't work because I need to manage the string array too so keeps receiving the exception...although it seems to work for the double[] (maybe I hope)!!
Any idea for the string array?
PS: the unmanaged DLL parameters (VC++ 6.0 DLL) are defined as
SAFEARRAY FAR *doubleArray, SAFEARRAY FAR *stringArray
...these are the conflicting ones.
Thank you again,
Edgar
Edgar Berengena Moreno
Software Engineer
Appeyron Research
|
|
|
|
|
Hi try this, glad to see double[] works
Try this:
ArrayList tags = new ArrayList();
do
{
string tag = Marshal.PtrToStringUni(ptag);
if (tag == "") break;
else
{
tags.Add(tag);
ptag = new IntPtr(ptag.ToInt32() + Marshal.SizeOf(tag));
}
}
while(true);
This reversse can be done if u need to "feed" the function with the string[].
Hope this works
MYrc : A .NET IRC client with C# Plugin Capabilities. See
http://sourceforge.net/projects/myrc for more info.
|
|
|
|
|
Hi,
I'm trying your second code but I'm having problems and I don't know if I'm doing it quite well. That's what I'm trying now:
For the double[]:
<br />
IntPtr buffer = Marshal.AllocCoTaskMem( Marshal.SizeOf( cantidad ) * sVN.Length);
Marshal.Copy( sVN, 0, buffer, sVN.Length );<br />
...and for the string[]:
<br />
IntPtr ptag = new IntPtr ();<br />
ptag = Marshal.StringToHGlobalAnsi ("maybe...");<br />
ArrayList tags = new ArrayList();<br />
do <br />
{<br />
string tag = Marshal.PtrToStringAnsi (ptag);
if (tag == "") break; <br />
else <br />
{ <br />
tags.Add(tag); <br />
ptag = new IntPtr(ptag.ToInt32() + <br />
Marshal.SizeOf(Marshal.StringToHGlobalAnsi (tag))); <br />
}<br />
}while(true);
And I define the DLL Function like:
Method (..., ref IntPtr sbufN, ArrayList sbufC, ...);
What am I doing wrong?
Thank you again for your dedication,
Edgar
__________________________________________
Edgar Berengena Moreno
Software Engineer
Appeyron Research
|
|
|
|
|
HoHa what a mess
Method (..., IntPtr sbufN, IntPtr sbufC, ...);
string[] strarr = new string[]{"one","two","three","four"};
IntPtr firstpointer;
int counter = 0;
foreach (string str in strarr)
{
IntPtr ptr = Marshal.StringToHGlobalUni(str);
if (counter++ == 0) firstpointer = ptr;
}
Method(..., IntPtr sbufN, firstpointer,...);
for (int i = 0; i < strarr.Length; i++)
{
strarr[i] = Marshal.PtrToStringUni(firstpointer);
firstpointer = new IntPtr(firstpointer.ToInt32() + Marshal.SizeOf(strarr[i]));
}
Ok try that Like I said it is very important to know whether the function will need values from the string array when passing it to the function. What is the function to do / return with the string[] ???
MYrc : A .NET IRC client with C# Plugin Capabilities. See
http://sourceforge.net/projects/myrc for more info.
|
|
|
|
|
A virtual keyboard is a form with keys (buttons) that act as keyboard on touch-screens (for example)
Thanks
Stephane
|
|
|
|
|
There is the UI part and there is virtual key localisation.
About UI, the simplest is to add KeyPress or KeyUp event handlers to your form, so it hooks every key. Then e.KeyCode, or e.Key depending on the handler will return the virtual key code or ANSI code.
Add an imagelist to buttons. And swap images along in event handlers. That will do highlighting.
About localisation, well that's a job that takes time because you'll have to provide cultures keyboard schemes such like AZERTY in French. Which means you have to provide a different set of positioned buttons.
You may of course limit yourself with QWERTY, but ...
My 0.5 cent,
And I swallow a small raisin.
|
|
|
|
|
Just thought I would make people aware of something I noticed, ok it took me a while to work out why and I had to tell somebody ...
I just noticed that if you use the method BringToFront for a label control the index for the control moves.
- James
|
|
|
|
|
I would like to build an application which incoporates 2D graphics. Macromedia / Shockwave jumps to mind in terms of the graphic content I would like to aim for.
I've considered using DirectX but this seems like overkill, and besides there is presently no C# interface to DirectX and I would need to program in C++ to use the SDK (correct me if this statement is wrong, please!).
I'm not out to build a web enabled program and I don't need cross-platform portability.
Does anyone know if there is a 2D graphic engine / library out there which works with .NET? (prefereably C# but C++ is okay).
Thanks in advance!
Only change is constant
|
|
|
|
|
Have you looked into using the System.Drawing.2D namespace? That is .NET's interface to GDI+. If 2D is all you're going to do, you may just want to use that.
David Stone
But Clinton wasn't a predictable, boring, aging, lying, eloquent, maintainer-of-the-status-quo. He was a predictable, boring-but-trying-to-look-hip, aging-and-fat-but-seemingly-oblivious-to-it, lying-but-in-sadly-blatant-ways, not-eloquent-but-trying-to-make-up-for-it-by-talking-even-more, bringer-in-of-scary-and-potentially-dangerous-new-policies. And there was also Al Gore. It just wasn't *right*.
Shog9
|
|
|
|
|
Alastair Stell wrote:
I've considered using DirectX but this seems like overkill, and besides there is presently no C# interface to DirectX and I would need to program in C++ to use the SDK (correct me if this statement is wrong, please!).
I've seen on websites that people has done games in C# using DirectX.... if they're dreaming or what, I don't know!
But I'm pretty sure it is a DirectX for C#!
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C#, ASP.NET and C++!
|
|
|
|
|