Jump to content
Xtreme .Net Talk

snarfblam

Leaders
  • Posts

    2156
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by snarfblam

  1. Parsing the data should not be too complicated. If you want to stick it all in one textbox, you can divide the text into individual numbers using the String.Split method. You can use Int32.Parse to convert the strings to integers. If you want to parse them in hex, there is an overload that allows you to specify a number format. (You can also use TryParse if you want to avoid exceptions.) As far as drawing the resulting image, there are options, depending on how complex things become. If the grid size is relatively small and is a constant, and the number of tiles is small, you could use picture boxes and an array of System.Drawing.Bitmap objects, and based on the tile number entered, assign the appropriate bitmap as each picturebox's image. If things get bigger, you probably want to render to a System.Drawing.Bitmap using a System.Drawing.Graphics object (obtained through the Graphics.FromImage method). The Bitmap can be assigned as the image of a picture box. This GDI+ approach would probably suffice. If you are using a large number of small tiles, rendering a real large image, or performance becomes an issue, tile-based graphics can be slow using GDI+, i.e. the System.Drawing.Graphics class (in fact, I actually resorted to writing my own blitting functions for the application I'm writing now). If you need more speed you might want to consider trying out (the old school but more complicated) GDI using the Windows API.
  2. The first exception thrown by an application tends to be very slow, depending on the PC and circumstances it can actually take seconds. All subsequent exceptions are actually handled pretty quickly. This surprises plenty of people because throwing exceptions is, according to documentation, a very slow process. The reality is, though, that it is all relative. If you throw exceptions frequently on a tight loop, the hit will be enormous. In your case, though, they might not even be noticeable. (Not that I advise anything except avoiding exceptions when possible--their speed is not something to depend on and exceptions are one thing that it is important to use for its specified purpose.)
  3. As far as textbox borders go, they don't come with an option for border color and size, but what you can do is put a borderless text box inside another control and use that control as the border. For example, put a text box inside a panel with a two pixel margin around the text box and set the panel backcolor to red. Bingo, two-pixel red border. This is kind of a hack, though. For the forms, what do you want to do? Change the color? Or replace all the graphics? If you want to do the latter, you need to draw your own graphics, of course. Set the form's border style to none and display your own graphics in whatever way makes sense. Make it the BackgroundImage or draw it yourself in the Paint event or override OnPaint. Then the fun stuff: you have to implement your own window dragging, resizing, caption buttons, etc.
  4. What does the try/catch look like? Are you catching all exceptions or only certain exceptions? What is the exception? Does the IDE break in the constructor code or the try/catch block?
  5. Are you tabbing between textboxes? I don't understand exactly how that can happen... unless some intermediate process interrupts the UI thread maybe.
  6. Interfaces allow you to specify functions only (this would include properties).
  7. The descriptor class would add more complexity to the plug-in system. Essentially, however, the descriptor class would be part of the interface (by which I don't mean a .Net interface type, but rather your program's plug-in interface). It doesn't really go against the spirit of the plug-in. It just makes it less painless (a little more like pre-.Net days). The descriptor, though, could be responsible for instantiating the plug-in object. I think that would make things a little simpler. For example, say your plug-in interface is IPlugIn with a descriptor interface IPlugInDescriptor. When you load an assembly you can search the types for IDescriptors and forget about looking for IPlugIns. When the user picks a plug-in based on data from an IPlugInDescriptor, you could call a function, like CreatePlugIng() for example, that would instantiate the plug-in class. interface IPlugInDescriptor{ string GetAuthor(); string GetDate(); string GetCopyright(); IPlugIn CreatePlugIn(); }
  8. You probably want to use reflection. Maybe load the assembly for reflection, find the type(s) you want to examine, and then use the Attribute.GetCustomAttribute function to load the attributes. The attribute type will need to be loaded (and not just for reflection) though in order for this to work. I've never actually done this before so there may be something I've missed.
  9. On recommendation I have then: the reflection namespace and classes have functions that allow loading assemblies for reflection only. This could probably save on resources if you set your plug-in system up so that any describing data you need can be obtained through reflection (custom attributes will probably work).
  10. I'm sorry. I can't make the connection between licensing and multithreading. Am I missing something? Besides, can a thread even run accross multiple processors?
  11. I am just going to (re)reiterate--the loop example is just that. An example. There can be other kinds of benefits from knowing what is going on behind the scenes. Maybe that kind of attention to details is what separates a good programmer from a diligent programmer. Either that or a normal person from a person who has OCD. I like to have a more thorough understanding of what is going on when I write a program (or do anything, for that matter). A richer understanding of details can help you see things in a different light and show you more possibilities.
  12. snarfblam

    Plug-ins

    Is it possible that the deserialization will fail if the assembly is not loaded? Or is there an important detail that I am missing?
  13. It shouldn't. This should, if anything, prevent problems, provided that your users have set their regional settings properly through Windows. This is normally done when Windows is installed. A prompt comes up and asks you this information, so it is kind of hard to forget or neglect to do. When a user has their regional properties configured correctly, they should be able to type the number in as they normally would, and it should parse correctly. For example, if a French user types in "5.432,1" he would expect it to be parsed as five-thousand four-hundred thirty-two and one tenth, and provided that he has Windows property configured, it would be so parsed. And when I type "5,432.1" in, I should get the same result because I know my regional settings are correct. If your application requires portability between different computers and you need culture-neutral parsing there are different overloads for the .Parse methods that let you specify a culture or formatting details. Check out the relevant MSDN docs.
  14. Am I correct in my understanding that even if you only use the descriptor class the entire assembly will still be loaded for all plug-ins?
  15. You can post the code as a .Zip attatchment in this thread.
  16. Something like this should work immediately after you update the text... TextBox1.SelectionStart = TextBox1.Text.Length TextBox1.ScrollToCaret()
  17. We aren't entirely off topic... too far... I hope. First of all, the foreach example was just an example. There are plenty of others. Depending on what you are doing the difference between a foreach and a for loop can be enough to make a difference. A foreach loop requires the instantiation of an IEnumerator (one hit per foreach loop). Then, in order to iterate a call is made to MoveNext, and if that returns true, a call is made Current to obtain the object, which must be stored in a variable. A foreach is also automatically wrapped in a structured exception handling block. The foreach loop (at least in C#... I'm not positive about VB) is optimized for arrays, but for all other IEnumerable types you will see a performance hit. A foreach on an arraylist would compile from this: For Each o As Object In myArrayList If o Is SomeOtherObject Then Return o End If Next to ' IEnumerator instantiation Dim i As IEnumerator = DirectCast(myArrayList, IEnumerator).GetEnumerator(); While i.MoveNext() 'Extra function call Dim o As Object = i.Current If o Is SomeOtherObject Then Return o End If End While There are a little more than half as many IL instructions in the equivalent for loop, and that isn't counting the function calls to GetEnumerator and MoveNext. Using VB8 Express console application, I did a quick benchmark with an unsorted ArrayList of 100,000,000 objects where the ArrayList was searched linearly for a specific object inserted at a random position using a For and For Each loop with a release build, and then repeated the test with For Each first and then For after. The results are as follow: For ForEach Ratio 78 547 7.012820513 94 656 6.978723404 78 547 7.012820513 47 313 6.659574468 31 219 7.064516129 16 46 2.875 63 437 6.936507937 15 157 10.46666667 31 172 5.548387097 47 312 6.638297872 47 281 5.978723404 As you can see, a ForEach loop over an ArrayList takes approximately six to seven times as long as a For loop. I would call that a signifigant difference in performance. The IL for C# and VB ForEach loops would be very similar, so you would see this difference in C# also. Is this essential knowlege? No, but it sure helps. Is this something we should expect a new programmer to know. If you ask me, the answer is eventually.
  18. Encapsulation is all good and well, and obviously, we can't expect a new programmer to learn everything at once, but as time goes on every programmer should eventually come to understand what a "Handles" clause really means and how a foreach loop really works. Sure it is nice when things just magically work, but I think it is nicer when you know how they work. I just think the information should be readily available. Sometimes it is, sometimes it isn't. But if you don't care how a foreach works, just don't read the documentation. It doesn't put more of a load on a novice, it just adds more to the expert's toolbox. Just for a quick example, if you are run into a bottleneck while performing an operation over a large collection, you could save a handful of CPU cycles by understanding that a For Each loop has the overhead of instantiating an IEnumerator and many more function calls than a regular For loop.
  19. What are the bounds of your array? (How is the array declared?)
  20. I'm just going elaborate a little. The way a C++ compiler works is pretty different from the way a C# compiler works. C++ compilers go through the code in one sweep. All of the #includes basically pull all the different code files into one single, long code file at compile time. The compiler goes through once, from beginning to end, so at any given point in the code, the only objects that are known to the compiler are objects that are declared earlier in code. When A depends on B which depends on A the paradox is that you can't declare A before B and declare B before A. C# makes life a little easier. It picks out all the code elements before it starts compiling the statements, so you really don't need to worry about which code elements depend on other code elements.
  21. I hope we aren't getting too off-topic here... Although Microsoft embraces the concept of a common language platform, they also acknowledge that each language is its own language, and they all have their own features. How these features are implemented in terms of IL is not particularly relevant. In just about any language, with the exception of IL or ASM, what you see is not what you get. This may be less the case with .Net than X86, but new features which don't have analogous .Net instructions and classes simply won't look the same in IL as they do in VB, C#, or whatever the language might be. The fact is that when you use the "Handles" keyword, you are asking for automatic event wiring and the compiler is only doing what it must to make that happen. I am of the opinion that a programmer should know what is going on behind the scenes before he uses any particular feature, for the sake of understanding what cost or benefit that feature will ultimately provide. That being said, all the extra "behind the scenes" IL for a "Handles" clause... well that is represented in your code. It is represented by the "Handles" keyword. It isn't being done behind your back, you are telling the compiler to do it. You just need to understand what you are telling the compiler to do. I also think that Microsoft has a responsibility to clarify what is going on behind the scenes in VB so that programmers can understand what their code really means, which they don't do very well--I'll give you that. And that brings me to another point. Microsoft seems to be of the opinion that black-box features are a good thing for VB. Things that just work without any how or why. Things like default instances, Visual Styles, automatic event wiring, and designer created objects. These are all real nice things, but what bothers me is that they seem to almost go out of their way to hide the implementation from you. Many of these features are also present in C#, but the designers and options result in code files presented to you, clear as day. You are free to modify and free to understand. I can't possibly understand what advantage hiding designer-generated code could provide to VB programmers unless you are of the opinion that they need to be protected from themselves, or that they can't handle the complexity of expanding tree nodes in the solution explorer or are not intelligent enough to make use of designer-generated code. And I'm not giving VB programmers a hard time, here. Quite the opposite. I'm saying that they deserve more credit than that. They deserve more than "Here, it works, be happy." If you don't want to see the behind-the-scenes stuff, fair enough. I think it should be an option, though.
  22. If you place __gc class Form1; immediately before public __gc class costForm : public System::Windows::Forms::Form{ and __gc class costForm; immediately before public __gc class Form1 : public System::Windows::Forms::Form { all should go well. Again, I'm no expert, but this worked for me. #include "costForm.h" //this is the child form's header namespace Segmentation { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System:: Data; using namespace System:: Drawing; using namespace System::IO; [color=Red]__gc class costForm;[/color] public __gc class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); } protected: void Dispose(Boolean disposing) { if (disposing && components) { components->Dispose(); } __super:: Dispose(disposing); } private: System::ComponentModel::Container * components; public: static Bitmap* source; public: static double* img; public: static Node* nodes; public: costForm *cform; //declaring the pointer for child //... //... //... //... //... private: System::Void dynamicCostMenuItem_Click(System::Object * sender, System::EventArgs * e) { costselected = true; cform = new costForm(this); //creating an object of thechild with a reference of the //parent form cform->MdiParent = this; this->ClientSize = System:: Drawing::Size(source->Width+ cform->Width, source->Height); (cform->Location).X = (this->pictureBox1->Location).X + cform->Width ; (cform->Location).Y = (this->Location).Y ; cform->Show(); } here i have no problem declaring a pointer of the child and reaching the public members of it from the parent form.. and here is the child's header file in detail #include "Form1.h" // i include the parent's header in child form using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System:: Data; using namespace System:: Drawing; namespace Segmentation { [color=Red]__gc class Form1;[/color] public __gc class costForm : public System::Windows::Forms::Form { public: costForm( Form* f) { InitializeComponent(); parent = f; //equalize the 'parent' member of the child form //to the reference taken before } protected: void Dispose(Boolean disposing) { if (disposing && components) { components->Dispose(); } __super:: Dispose(disposing); } private: Form1 *parent; // declaring the pointer of the parent [/Code]
  23. I'll be honest. Include files hurt my head, especially with circular dependacies (costForm has a Form1 member and Form1 has a costForm member). It seems to me, though, that costForm is being declared before Form1 (by means of an include), so the compiler can't find Form1. I opened C++ 2005, and although it is different, I did manage to reproduced your problem. I made two forms, each of which had a pointer to the other type of form. I tried different includes and found that no matter what both forms would fail to compile; the first would fail because the second isn't declared, then the second would fail because the first failed. Unfortunately, I didn't what one should do in such a situation, so I looked at this Wikipedia article that I found using a google search. The key would be a forward declaration. Something similar to this: __gc class Form1; should be added directly above your costForm declaration to let the compiler know that a Form1 class will be declared so that the compiler will allow you to reference that type. Hope that helps.
  24. Mmmmm... for loop... ' Loop through pics For I As Integer = 0 To PictureArray.Length - 1 'Test for collision If Player.Bounds.InstersectsWith(pictureArray(i).Bounds) Then 'Do things here. i Is the index of the picture with which we collided. MessageBox.Show("Holy Crap! I hit pictureArray(" & i.ToString() & ")") End If Next
  25. Maybe this is a way to protect VB users from themselves, but I can't possibly see it as a convenience. The designer and resource files aren't in the way in C#. You'll only ever see them if you want to see them. It's not like it adds clutter, and I would say that having easy access to the designer code in case you want to tweak it would be more convenient. Besides, as far as I can tell, the designer and event aspects between the two languages are identical with the exception of the VB Handles keyword, but if you manage your event handling through the designer then even this difference is eliminated. On the other hand, it would certainly be inconvenient to have to manually add these files every time you add a designer control, and in that case it would absolutely add clutter. Besides that, the constructor is hidden from you by default. (I would certainly prefer to initialize in the constructor rather than a Form_Load event. We are past the VB6 days.) And suppose a programmer new to VB8 wants to add a constructor overload and doesn't know that he needs to call InitializeComponent seeing as he's never heard of such a function. I can only speak for myself, but when I am creating my own controls, very often I do need to access the designer generated code. When properties and events are modified there is inconsitancy between what was serialized last build and what can be serialized this build, and this often results in designer and compile errors.
×
×
  • Create New...