|
It will be .NET 2.0, not 1.2. The file versions are only labeled as 1.2, just like the file versions for 1.1 are 1.1 but the assembly versions are still 1.0.5500.0. ".NET 2.0" is mentioned in many places on Microsoft et. al. sites.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Oh really? I didn't know that; I knew C# would be C# 2.0, but I was under the impression it was .NET 1.2.
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
Here's one current reference: http://msdn.microsoft.com/vstudio/productinfo/roadmap.aspx#2005[^].
I believed they used ".NET 1.2" for a while but that started changing a few months ago.
[EDIT] Oh, and rightly so. A LOT (as I'm sure you know) is changing between 1.1 and 2.0, unlikes the few changes between 1.0 and 1.1. It's still mostly backward compatible, but it includes a lot of bug fixes, performance enhancements, control adapters (new way to provide owner-drawing that's truly aweseom!), many new ASP.NET enhancements including some for WSS/SPS, and - of course - generics.
[/EDIT]
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Try this:
void Foo(ref object boolean)
{
if (boolean == null)
else
{
bool value = (bool) boolean;
}
}
top secret
|
|
|
|
|
Hey all...ok, let me set things up...here is the prototype of the function i'm trying to use in an unmanaged dll within C#:
void myfunc(int a, int b, pvoid* output);
Ok, so the return here (output) will be a pointer to an array of pointers....within that array, each pointer is to point at the following structure:
struct MYSTRUCT{<br />
DWORD size,<br />
PWSTR aString,<br />
PWSTR anotherString<br />
} MYSTRUCT, *PMYSTRUCT;
I read on ms site that in order to handle the strings in the array, I need to define it as such:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]<br />
public struct MYSTRUCT<br />
{<br />
public uint size;<br />
public String aString;<br />
public String anotherString;<br />
public MYSTRUCT(uint size, String aString, String anotherString)<br />
{<br />
this.aString= aString;<br />
this.anotherString= anotherString;<br />
this.size= size;<br />
}<br />
}
Here is my imported function:
[DllImport("mydll.dll")]<br />
public static extern void myfunc(int a, int b, out MYSTRUCT[] output);
Now...this doesn't work, I don't even get returned the correct size of MYSTRUCT[]. I've tried quite a number of different variations as well. I've tried passing an array of IntPtr too, all to no avail. How does one deal with this? Do I need to get back the array of pointers and actually deal with the pointers themselves?
Jason
|
|
|
|
|
Here's[^] an excellent resource for understanding pointers and indirection through interop.
John
"You said a whole sentence with no words in it, and I understood you!" -- my wife as she cries about slowly becoming a geek.
|
|
|
|
|
Cool, thanks...I got it figured out, it was a toughy. Here's how it's done:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]<br />
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]<br />
public classMYSTRUCT<br />
{<br />
public uint size;<br />
public String aString;<br />
public String anotherString;<br />
public MYSTRUCT()<br />
{<br />
this.aString= null;<br />
this.anotherString= null;<br />
this.size= 0;<br />
}<br />
}<br />
<br />
[StructLayout(LayoutKind.Sequential)]<br />
public class ArrayOfPtrs<br />
{<br />
public IntPtr ptr;<br />
public ArrayOfPtrs()<br />
{<br />
ptr = IntPtr.Zero;<br />
}<br />
}
And here is the call (allong with forming up the data after the call is made:
IntPtr outArray;<br />
BaseP2P.PeerGetNextItem(something, numItems, out outArray);<br />
<br />
MYSTRUCT[] pairs = new MYSTRUCT[numItems];<br />
ArrayOfPtrs ptrs;<br />
<br />
IntPtr current = outArray;<br />
IntPtr structure;<br />
<br />
for(int i=0; i < numItems; i++)<br />
{<br />
pairs[i] = new MYSTRUCT();<br />
ptrs = new WinP2P.BaseP2P.ArrayOfPtrs();<br />
<br />
Marshal.PtrToStructure(current, ptrs);<br />
structure = ptrs.ptr;<br />
Marshal.PtrToStructure(structure, pairs[i]);<br />
current = (IntPtr)((int)current + Marshal.SizeOf(ptrs));<br />
}
That works great. There should be a call to Marshal.DestroyStructure(...) made in there to clear up the unmanaged memory, but there is a function in the dll that clears this memory for me, so I do not use Marshal.DestroyStructure(...).
Jason
|
|
|
|
|
You should declare MYSTRUCT as a struct, not a class. Structs (value types) are allocated on the stack while classes (reference types) are allocated in the heap. When you pass this struct around, you don't want to keep a reference to it in most cases. As a struct (value type), it is passed by-value unless ref or out is used.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I think it has to be declared as a class because of me using:
Marshal.PtrToStructure(structure, pairs[i]);
If you declare it as a struct, you get the following exception:
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll
Additional information: The structure must not be a value class.
|
|
|
|
|
I have 2 questions concerning a DataGrid. Basically, I have a DataTable with 8 DataColumns. The table is initially empty, and the user fills in the information at run-time. Here are my questions:
1) I don't want every column being the same width at startup. How can I programatically change the column widths directly after I set the DataSource?
2) Each time a new row is created in my table, all of the cells contain "(null)". I want the cells to just be initially empty. How is this done?
These will probably be 2 very easy questions to answer. I appreciate the help!
|
|
|
|
|
i cant answer the first one!
u cant make empty variables! when u create them and do not assign them a value they are null. u can try assinging them an empty string like
code>string empty = "";<
|
|
|
|
|
Assigning empty strings worked just fine. Thank you for your post!
|
|
|
|
|
The answer to both questions is to apply a DataGridTableStyle .
DataGridTableStyle style = new DataGridTableStyle();
style.MappingName = "MyTableName";
DataGridColumnStyle colStyle = new DataGridTextBoxColumn();
colStyle.Width = 85;
colStyle.NullText = "";
colStyle.MappingName = "Column1";
colStyle.HeaderText = "First Name";
style.GridColumnStyles.Add(colStyle);
dataGrid1.TableStyles.Add(style);
Charlie
if(!curlies){ return; }
|
|
|
|
|
As an answer to your first question: you can add DataGridStyles to your Grid, in the designer and in code. Do this before you point the Grid to its datasource. If you program the available columns manually, you can set their Width and headertext too. All columns you want invisible, set the respective widths to 0.
You can also define a methodthat returns a DataGridStyle and add that to the Grids style, possibly deleting the old style (DataSource has to be null to do that I believe)
|
|
|
|
|
Hi!.
I wrote an application that start a thread that read some data from the communication port. The problem is that I want to put the data in a textbox, (text1), and I don't know how to do that . In C++ I just use a global variable, but how can I define a global variable in Visual C#.
How can I get data from the thread?.
Thank you very much.
Demian.
|
|
|
|
|
Global variables are looked down upon in the object-oriented world, and are not allowed in Java or C#. If you want to place text inside the textbox, just pass your textbox instance to the object reading your communication port.
Also note that Windows Forms controls are single threaded in nature; it's a no-no to modify them from a thread other than the thread that owns the handle to the control (ie the thread that the control was created on). Fortunately for you and I, all Windows Forms controls contain a method called .Invoke that lets you call a method on the control using the thread that owns the handle.
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
sorry judah didnt get that last part! could u exemplify! thx in advance i was needing this for another app
|
|
|
|
|
See Heath's post below.
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
Use Control.InvokeRequired and Control.Invoke from threads other than the thread on which the control was created. Global variables are also not a very good way unless you use good locking when reading/writing from/to them (the lock keyword in C# is a simple way to do this using a monitor). To use a global variable, you can always use a static property or, if your threaded method is a method defined on the Control class that contains your TextBox , just use a private variable (and be sure to lock it).
To write to the text box, make sure your thread class or procedure has a reference to your TextBox (for example, you could thread a single method in your class which contains the TextBox reference). If you're not sure if your method would be threaded or not, use the code below (otherwise eliminate the check for Control.InvokeRequired ):
private void ReadFromPort()
{
string value = value from port;
if (text1.InvokeRequired)
{
Type t = text1.GetType();
MethodInfo info = t.GetProperty("Text").GetSetMethod();
Delegate d = Delegate.CreateDelegate(t, info);
text1.Invoke(d, new object[] {value});
}
else text1.Text = value;
}
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Keeping in mind that was example code, FYI that snippet won't work; Delegate.CreateDelegate takes a Type parameter for delegate types only. You might want to try this instead:
private delegate void SetTextDelegate(TextBox tb, string text);
private void ReadFromPort(TextBox tb)
{
string portData = ...
this.SetText(tb, portData);
}
private void SetText(TextBox tb, string text)
{
if(tb.InvokeRequired)
{
tb.Invoke(new SetTextDelegate(SetText), new object[] {tb, text});
}
else tb.Text = text;
}
I *think* that should work.
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
thx for the help guys appreciate it
|
|
|
|
|
Hi Lao.
Thank you for you help.
But, the thread method is the method that read the comm. port, so can I pass a parameter to it?, a parameter like TextBox tb?.
That method is in another class, no in the class that holds the textbox, and should I pass every control as parameter that I want to write, (with data from the comm port)?.
Thank you again for your time.
Demian.
|
|
|
|
|
The code works fine.
But I must pass a textbox reference to the class constructor. And this is a very particular case, 'cause I don't know how many controls I will have, to show the data that the thread read from the comm port.
Thank you Judah.
Demian.
|
|
|
|
|
This is only if your thread method is in a different class. More than likely, there's no need to do that. In both Judah's and my examples, we assumed the method that will be invoked in another thread was part of the same class, so it already has a reference to the TextBox . This is preferred unless you have some good reason for changing it. If you do, then create a new instance of another class - passing the TextBox reference into the constructor - and start a thread on a method of that class. This is unnecessary, though, because you're creating another class just to run a method in another thread? Why go to the trouble if you don't have to.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi!
Well, I have a class hierarchy, and theses classes must keep a communication "alive" with a devices pluged in the comm port. The device, if it has no heceived a command stop the communication.
That is the trouble, the thread method is a method deep int the hierarchy.
Thank you for your time.
Demian.
|
|
|
|