|
May I remind you, gentle reader, that this forum was once a place for open-ended discussions of C# language issues ?
I'm working on something I intend to publish on CP. Wanting to make sure it works using FrameWork 4.0 I am:
1. using a Microsoft supplied weirdness that runs using the Microsoft.Win32 library: [^]. I've slightly modified this to set a global static flag if version 4.0 or greater of the FrameWork is available.
2. using an ingenious hack by Thomas Levesque that enables the various special Property Attributes, like 'CallerMemberName to work in 4.0: [^].
Wanting to make sure I can serialize data that includes Controls that may be inside any ContainerControl on any Form (and, which may have identical Names inside said different hosts), I am working around DataContract's (and all other serializers I know of except one) limitation of not being able to serialize WinForms Controls. So, I do a dance of transforming a bunch of static data into a Dictionary that represents a Control as List of strings of the form:
outmostcontainername ... container#n name ... controlname
And, after serialization I can resurrect these back into the appropriate object instances.
So yeah, I can serialize and de-serialize, paying a penalty to save Control references in this way, and then resurrect them back to instances at run-time.
And, now ... Rant Begin
1. what bs that MS no longer makes Environment.Version return different values for FrameWork 4.0 and 4.5 !
2. what a pain in the butt to have to use a work-around to get CallerMemberName usable in 4.0. Yeah, I know, I shouldn't complain about about that: after all, it was announced as new "feature" with 4.5, and the fact that T. Levesque got it working is ... well, our good fortune.
3. not being able to serialize Control instances without the kind of dance I do here is annoying. while, as I said, there is one serializer that seems to be able to do it (here on CodeProject), I feel I can't rely on it. Reference on request, and, no, it's not Mehdi Gholam's serializer.
4. using the DataContract/DataMember serializer is certainly so much easier, for me, than the previous critters from MS, and JSON, etc. however, it seems "sensitive" to unknown context issues, and will, at times, fail with no obvious reason.
The work-around I've found is to (any, or all, of these):
a. clear any saved file the serializer may point at before invoking the serializer
b. re-compile all the various pieces of the app, and then close, and restart, Visual Studio 2013.
5. I also encounter the problem of a compile somehow not synching non-UI Projects with the UI main project: yep, I've set the "DependsOn" setting in the UI main project to the non-ui Class Library. I usually discover this when I set a break-point somewhere in the Class Library, and it doesn't get hit ... which cues me I need to re-compile the Class Library.
... Rant End
Now that's off my chest: I can say, honestly, that these are great tools to work with that I could never have imagined even twenty years ago being available to a "mere mortal" like me These issues I rave about are, viewed in the larger frame, just pimples on paradise's angels.
However, lest I sound too fan-boiish, let me say that MSDN documentation, and its implementation in the Help system for Visual Studio, and on-line, is a fetter, a snare, a pustulous canker, a travesty, a daily water-boarding for those who use it, etc.
Your thoughts, reactions, comments, corrections ?
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
|
|
|
|
|
Quote: is a fetter, a snare, a pustulous canker, a travesty, a daily water-boarding for those who use it, I couldn't possibly improve on that!
|
|
|
|
|
I got a little confused with the Bitmap.LockBits() function. Though I can see that my code achieves what I want it to do with good performance, I do not fully understand how it works...
public unsafe ushort[,] GetDataFromBitmap(Bitmap source, Rectangle rect)
{
ushort[,] result = new ushort[rect.Width, rect.Height];
BitmapData bmpData = source.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
byte* scan0 = (byte*)bmpData.Scan0.ToPointer();
int bytesPerPixel = 3;
int stride = bmpData.Stride;
for (int y = 0; y < rect.Height; y++)
{
for (int x = 0; x < rect.Width; x++)
{
byte* bluePointer = scan0 + y*stride + x*bytesPerPixel;
byte blue = *bluePointer;
source is a bitmap of 2736x3648 pixels of 24bit RGB, and rect has a size of 240x320, positioned somewhere within the source image.
The value of stride is 10944 - that is 4 *2736. That is source.Width , not rect.Width . Also ...bluePointer = scan0 + y*stride... somehow indicates that the locked bytes do not represent the "new" image defined by the rectangle, but that scan0 just points to a position in the original image corresponding to the top left corner of the rectangle. Why do I need a Rectangle , when a Point could do so also?
bytesPerPixel is 3 (corresponding to 1 byte RGB each), while stride/source.Width is 4 (i.e. alignment to 32=2^5 bits), but it is ...bluePointer = x*bytesPerPixel + ... .
Now I am confused. Can someone explain those strange parameters and values?
|
|
|
|
|
Ok...
LockBits effectively prevents the Garbage Collector from moving the data in memory - so pointers and so forth can be used directly instead of having to de-reference every time you wanted to use it. Because the GC is outside your direct control, if you don't use LockBits then the data you are pointing at can be "moved" in memory at will, rendering your pointers invalid. But it doesn't copy the memory - it just locks it in place.
Your data may be 3 bytes per pixel (i.e. has no Alpha channel) but that's inefficient to access: 32 bit quantities are a lot faster to throw around than 24 bit values, so your image is "padded" to 32bits with a default "solid" alpha channel.
stride is 4*2736 because it's a bytes count, rather than a pixel count - and a pixel is a 32 bit quantity (ARGB, with each "part" occupying a byte). So each row in your image of 2736 pixels takes stride bytes - i.e. to advance from one row in your rectangle to the same relative position in the next row means advancing by the width of your image, not the width of your rectangle:
-------------------
|C ------ |
|D |A |E |
| |B | |
| ------ |
| |
------------------- If C is (0,0) on your image, and D is (0,1); A is (0,0) in your rect, and B is (0,1) in your rect (A is (5,1) in your image, B is (5,2)) then to move from the memory byte starting the rect A to the memory byte starting rect B, means adding the number of bytes in a whole row of the image - adding the bytes in the rect width would move you to E instead.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Thanks for your explanations.
So LockBits pins all the bytes of the original bitmap, not only a selected amount of them, doesn't it?
And I see another point of confusion. Stride=10944=4*source.Height=3*source.Width . And the latter multiplication is the correct way of determining Stride , the former one only happened to coincide (due to the 4x3 format of my camera). Now I understand why it is the coordinate of Height (y ) which gets multiplied with stride ; with the other interpretation it does not make sense. And looks like there is no padding.
But I still do not understand why I have to pass a Rectangle instead of a Point .
|
|
|
|
|
Bernhard Hiller wrote: But I still do not understand why I have to pass a Rectangle instead of a Point .
You'd have to ask Microsoft about that!
But it's probably because it's not something you logically want to do: locking a single pixel isn't going to be more efficient than GetPixel / SetPixel. Logically, you want to access a rectangle (which will be the whole bitmap often as not) rather than a single dot.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Not to challenge, but to ask, but isn't LockBits a GDI+ call and nothing to do with .NET and hence garbage collection?
Regards,
Rob Philpott.
|
|
|
|
|
Challenge away!
That's not how it was explained to me, but a quick look through the reference sources says you're right: it's just a wrapper for a call to GDI+
Interesting...
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
string[] s = data.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
what does it mean?
|
|
|
|
|
It means that the Split method is invoked on the data class, with a new string array as parameters (containing only a newline), without any additional options (like removing empty items from the array), and assigning the result to a string-array called s .
There are easier ways to learn a language than by copy/pasting the parts you don't recognize. I'd recommend Head First C#
--edit; forgot a closing tag
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Take a string and split it based on any new lines in it. Can I suggest that now would be a good time for you to:
a. Invest in a basic C# book - your questions have all been very basic so this leads me to suspect you have no experience in the language
and
b. Learn how to Google - again, your questions could all have been answered with a quick search.
This space for rent
|
|
|
|
|
I already showed you where to look for this sort of information. Please make an effort to do your own studying and research.
|
|
|
|
|
There's a IntelliSense-description for every standard .NET method which Visual Studio will show to you when you type the opening bracket.
There's the MSDN online documentation which you can easily invoke by placing the cursor onto the class or method name in question and pressing F1.
And here's a good, free PDF-book on programming in C#:
Introduction to Programming with C# / Java Books[^]
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
It means that you need to read C# documentation and learn to use Google !
Patrice
“Everything should be made as simple as possible, but no simpler.” Albert Einstein
|
|
|
|
|
Simple. Just input a string and split it with new line with no special split options like 'RemoveEmptyEntries' (The return value does not include array elements that contain an empty string)
Find More .Net development tips at : .NET Tips
The only reason people get lost in thought is because it's unfamiliar territory.
|
|
|
|
|
what is the difference between "string data = sp_gsm.ReadExisting();" and "string data2 = sp_rf.ReadLine();"
|
|
|
|
|
|
how do I find the execution path of C# code using antlr for AST generation
|
|
|
|
|
Sorry, no idea. This is the C# forum.
|
|
|
|
|
what does "cmd.ExecuteNonQuery();"mean?
|
|
|
|
|
|
It means your SQL command string doesn't return any SELECT information: it's an INSERT, UPDATE, or similar instead.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
0
down vote
favorite
I was able to serialize a List of objects (List) using this code:
public static string Serialize(object obj)
{
using (MemoryStream memoryStream = new MemoryStream())
using (StreamReader reader = new StreamReader(memoryStream))
{
DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
serializer.WriteObject(memoryStream, obj);
memoryStream.Position = 0;
return reader.ReadToEnd();
}
}
However, I'm not able to deserialize using this code:
public static object Deserialize(string xml, Type toType)
{
using (Stream stream = new MemoryStream())
{
byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
stream.Write(data, 0, data.Length);
stream.Position = 0;
DataContractSerializer deserializer = new DataContractSerializer(toType);
return deserializer.ReadObject(stream);
}
}
I'm not able to understand the problem. I'm using the last method by calling it with:
Deserialize(SerializedObject, List), but I'm getting an error saying List<FilesToProcess> is a type, which is not valid in the given context
Could anyone help? I'm a bit over my head with this.
|
|
|
|
|
Sooo, I have the doubtful honor of answering my own question.
The problem was that I was trying to assign the output of
`public static object Deserialize(string xml, Type toType)`
to a List<filestoprocess> generic called listOfFiles, when I should have assigned to an object and then cast to a `List<filestoprocess>` using
List
|
|
|
|
|
Hello
I need a project about convert of bonary to decimal and vice versa in C#
Modify the calculator by method project to convector of Binary to Decimal and vice versa.
The user should be only able to enter the 1 and 0 in binary textbox, and decimal numbers in decimal textbox.
modified 4-May-16 1:28am.
|
|
|
|
|