Jump to content
Xtreme .Net Talk

snarfblam

Leaders
  • Posts

    2156
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by snarfblam

  1. We have an MDX subforum which has never gotten much activity. I don't think XNA would be a different story. XNA would be included in the scope of "Graphics and Multimedia" anyways. However, I think it would be a very good idea to add XNA to the description for "Graphics and Multimedia."
  2. Re: Generic EventArgs There certainly won't be a generic EventArgs class that can handle all situations, but a small library will cover most situations. C# Code[HorizontalRule]magic hidden text[/HorizontalRule]public partial class Form1:Form { ····public Form1() { ········InitializeComponent(); ········this.label1.TextChanged += new EventHandler(label1_TextChanged); ····} ····void label1_TextChanged(object sender, EventArgs e) { ········// Create a purpose-typed event args object without declaring a new type. ········ValueChangedEventArgs<Label, String> args = new ValueChangedEventArgs<Label, string>(); ········args.Target = label1; ········args.OldValue = chachedLabelValue; ········args.NewValue = label1.Text; ········LabelTextChanged(this, args); ····} ····// Create an event without declaring a new delegate type. ····public event EventHandler<ValueChangedEventArgs<Label, string>> LabelTextChanged; } // Here we have some event args classes. The important thing // here is that these can be reused for any DotNet type. public class TargetEventArgs<T>:EventArgs { ····private T target; ····public T Target { get { return target; } set { target = value; } } } public class ValueChangedEventArgs<TTarget, TValueType>:TargetEventArgs<TTarget> { ····private TValueType oldvalue,newvalue; ····public TValueType OldValue { get { return oldvalue; } set { oldvalue = value; } } ····public TValueType NewValue { get { return newvalue; } set { newvalue = value; } } } [HorizontalRule]Why are you quoting me?[/HorizontalRule]
  3. A good place to find different uses of generics is the DotNet framework. For instance, there is a generic delegate type... public delegate void EventHandler<TEventArgs>( Object sender, TEventArgs e ) where TEventArgs : EventArgs This allows you to create an event with any type of EventArgs without declaring a new delegate type. DotNet doesn't come with a generic EventArgs class, but write your own and you'll be able do add all kinds of events to your object without declaring any new types.
  4. We aren't going to write the program for you. You're going to have to try yourself and/or ask more specific questions.
  5. There is something tricky about the way that Windows Forms designer does window sizes. Even though you specify a Size for the form, internally (in the InitializeComponent method) Visual Studio actually specifies the ClientSize (the size of the window minus the size of the borders). The reason for this is that the border size of a window can vary with different border styles and can also be different on different computers (the larger Windows Xp title bar makes the border much thicker than the smaller "Classic Theme" title bar). Say you specify a 400x300 window and your controls fit perfectly within the window on your computer. If my computer displays with wider borders, your controls will no longer fit in the window; there will be less space for controls because the borders take up more space. By specifying ClientSize instead of Size, the Windows Forms designer ensures that there will always be the same amount of space for controls. So, even though you specify a 400x300 form on your computer, it might end up being 404x314 on mine, which allows me to reduce the window size by 4x14 pixels and make the client area smaller than intended. This is probably the problem you are running into. One workaround could be to check the border sizes and calculate the appropriate minimum size in the constructor. It might be possible to do this by simply setting the MinimumSize property to the Form's current Size after the ClientSize has been specified (in the constructor, or in the FormLoad event if you are using VB).
  6. Re: Not if you have to use Hashtable What are you trying to do, exactly? Do you simply want to be able to grab objects by hash code without manually checking multiple tables?
  7. Re: Maybe you flunked computer science? Round-off error is a fact of life when dealing with floating-point numbers and must always be taken into consideration. Here are a few tips: Never use floating-point numbers for currency. VB6 had a Currency type for this and DotNet has the Decimal type for this. They are represented differently internally and are more appropriate for currency. Don't check for equality. Even if two numbers should theoretically be equal, don't expect them to be exactly equal. Instead compare them with a tolerance, or, in other words, subtract one from the other, and take the absolute value of the result. Generally, if the difference is less than 0.00001, you could consider them equal. (The larger the numbers you are dealing with, though, the bigger the round-off error.) It's often a good idea to round off when displaying numbers. Lots of dozen-digit numbers can get to be hard on the eyes.
  8. The .Net Framework does not have any support for saving vector images. It treats them internally as System.Drawing.Imaging.Metafile objects (as opposed to System.Drawing.Bitmap objects) but the Metafile.Save method does not save a vertor image.
  9. I am 23. It's not a lie. And while I try to figure out whether I was just insulted or complimented, hopefully you will get your program up and running.
  10. There are a couple of considerations here. I like to distribute applications as a single .exe file to keep things simple. I have a "common" project with useful classes. While it does build to a DLL, I typically add individual code files from it to other projects as "links" (this means that the project doesn't keep a local copy of the code file, just a reference to the code file). This allows me to maintain my common classes easily and build them directly into the executables they are used in. This method has its drawbacks, though. Changing the common file in one projects changes it in all projects, which has a potential for disaster. (If I need to make breaking changes, I make a local copy for the one project that needs the changes.) Another problem occurs if the code needs to be shared, since the project will only open and build properly on machines with the common files in the same relative paths, which is very unlikely. Building a separate DLL has its advantages, too. A DLL update can be issued without redistributing the entire program, and allows multiple DLL versions to be easily maintained side-by-side. It really depends on what your needs are.
  11. Chances are that simply passing your application's main window to a plugin could give the plug-in a lot more control than you might want. You would be right to be concerned about what could be done with reflection. Anything connected to the form (which very well could be everything) might be accessible by the plugin, as well as properties of the form that you might not want the plugin to be able to access. My personal recommendation, though I'm no plugin expert, is to provide a wrapper class or interface that allows a less direct method of interacting with the application. Ideally there would be no way to trace a reference from this object back to your application, but you need to balance security and complexity and make considerations such as how many people and what type of users will be using the application, and how important it is to protect your data or program (i.e. is there a legitimate security threat). There also may be a way to execute the plugin code with restricted security permissions (specifically, deny reflection permissions), but my knowledge in this area is extremely limited and I can't really help you there. It could require that the plugin code is executed in a separate application domain or thread, again requiring you to balance security and complexity.
  12. It sounds like you are no longer running your application like a Windows Forms application. One of the biggest differences between a console application and a Windows Forms application (other than the latter having windows) is that a console application doesn't have a "message pump," the program's main loop that processes events and messages from Windows. Without this message pump, your application may not be able to properly interact with Windows or the user (hence the problems you've been having with the NotifyIcon). Since you are loading a Form right off the bat, why not just run your application like a normal Windows Forms application (except don't show the window until it's needed). If you don't want to or can't do that, your best bet would be to create a message pump using a variant of that of a Windows Forms app, something like so: C# Code[HorizontalRule]magic hidden text[/HorizontalRule]// Manages our program for us static class Program { ····static ApplicationContext appContext; ····[STAThread] ····static void Main() { ········// Set us up the program ········appContext = new ApplicationContext(); ········Application.EnableVisualStyles(); ········// Start the message pump ········Application.Run(appContext); ····} ····// Call this method to close the application ····public static void EndApplication() { ········// It might be a good idea to store a reference to your ········// dialog and notify icon in the program class and make ········// sure that they are disposed here. ········appContext.ExitThread(); ····} }[HorizontalRule]Why are you quoting me?[/HorizontalRule]
  13. I probably should have noticed that you used VB and not C# in your posted code, and posted my example in VB. Sorry.
  14. If you use a filestream and just write large blocks from a large byte array it should go just about as fast as anything. For example, C# Code[HorizontalRule]magic hidden text[/HorizontalRule]FileStream fs = new FileStream("E:\\test.txt", FileMode.Create, FileAccess.Write); byte[] bigArray = new byte[1024 * 1024*4]; // 4 megs for(int i = 0; i < 256; i++) { // Write 1 gig ····fs.Write(bigArray, 0, 1024 * 1024 * 4); ····// Update progress bar, etc. ····Application.DoEvents(); } fs.Close();[HorizontalRule]Why are you quoting me?[/HorizontalRule] Copying large files should work just as well, though.
  15. Some people, probably not many, equate using a return statement as a control-flow structure with using a goto statement: a mortal sin these days. (In other words, a return statement should only be used as the last statement in a non-void method.) I say use whatever makes your code the simplest. If that's a return in the middle of a function, fine by me.
  16. Instead of the Mid() function, you can use the String.Chars property to get an individual character. Its quicker and returns a Char value, which you can compare with > and < without using the Asc() method. Private Function FilterFileName(ByVal FileName As String) As String FilterFileName = Empty Dim MyLoop As Integer For MyLoop = 1 To Len(FileName) If FileName.Chars(MyLoop) >= "a"c And FileName.Chars(MyLoop) <= "z"c Or _ FileName.Chars(MyLoop) >= "A"c And FileName.Chars(MyLoop) <= "Z"c Or _ FileName.Chars(MyLoop) >= "0"c And FileName.Chars(MyLoop) <= "9"c Or _ FileName.Chars(MyLoop) = " "c Or _ FileName.Chars(MyLoop) = "-"c Or _ FileName.Chars(MyLoop) = "_"c Then FilterFileName &= FileName.Chars(MyLoop) End If Next End Function You could make it even simpler, too, by using the functions of the Char type. [Vb] Private Function FilterFileName(ByVal FileName As String) As String FilterFileName = Empty Dim MyLoop As Integer For MyLoop = 1 To Len(FileName) Dim C As Char = FileName.Chars(MyLoop) If Char.IsLetterOrDigit© Or _ C = " "c Or _ C = "-"c Or _ C = "_"c Then FilterFileName &= FileName.Chars(MyLoop) End If Next End Function[/code] The System.IO.Path class has some functions that might make things simpler for you, too.
  17. I think something along the lines of the following would be your best bet. Dim h As base = base.Create(1, "ABC", x) Public Class base Public Sub New(ByVal x As Long, ByVal y As String) End Sub Public Shared Function Create(Byval x As Long, ByVal y As String, ByVal z As Long) If x < 0 Then Return New inheritor1(x, y) If x > 0 Then Return New inheritor2(x, y) Return New base(x, y) End Class Public Class inheritor1 Inherits base Public Sub New(ByVal x As Long, ByVal y As String) MyBase.New(x, y) End Sub End Class Public Class inheritor2 Inherits base Public Sub New(ByVal x As Long, ByVal y As String) MyBase.New(x, y) End Sub End Class If you are only going to do this once then I hardly see a problem with the if-elseif chain you used in your example. Otherwise, a shared method like this or a factory pattern may be best. The fact is that your constructors are really just different constructors that just happen to have the same parameters. Its like inheriting a class and shadowing a method with another that has an identical signature. They have no functional relationship. I don't know how else you could simplify the situation. I think ideally it would be nice if there were some way to inherit constructors and place restrictions on a deriving class' constructors to give them polymorphic behavior, but that could get messy fast, which is probably why most languages deal with constructors the way they do. On a side note, I hope you don't take that extreme principal to heart. At some point abstraction becomes counter-productive and repetition is unavoidable.
  18. It doesn't look like it should be too difficult to swap that code into a subclassed control or a separate control dragging class. You could even use the same (but slightly-modified) form-level event handlers to handle multiple controls. You might want to consider a less controls-based solution, depending on how concerned you are about how polished the final result will be. As far as the more specific logic (controls "talking" to one another), thats more of a game logic issue than a UI issue.
  19. I think the issue here is that in one case you are trying to access the enum through a variable (cGPIB), and in the other case you are accessing the enum through the type (comGPIB). The enum is not a member of the class. It is a nested type.
  20. Private Declare Function ChangeDisplaySettings Lib "user32" Alias "ChangeDisplaySettingsA" (ByRef DEVMODE As DEVMODE, ByVal flags As Long) As Integer should be Private Declare Function ChangeDisplaySettings Lib "user32" Alias "ChangeDisplaySettingsA" (ByRef DEVMODE As DEVMODE, ByVal flags As [b][i]Integer[/i][/b]) As Integer
  21. I'm just stabbing in the dark here, but it looks like (ByVal FunctionPointer As Long) would be better off as (ByVal FunctionPointer As IntPtr). A long is 64-bits and a pointer is 32-bits or 64-bits (probably 32), depending on the environment. That could be related to unbalanced or other stack issues (I don't know who cleans the stack in an stdcall). This is a common issue when porting VB6 code that uses unmanaged DLLs since VB6 didn't have a pointer type and a VB6 long is 32-bits. This means that VB6 code had to use a long. In DotNet IntPtr is generally a better representation for a pointer.
  22. snarfblam

    con fus ed

    I don't believe so.
  23. Its hard to read your code without comments, but it looks like you are doing an aweful lot of redimming, which is hell on the garbage collector and CPU (hence your problem). Depending on the number of keys you might expect to have, a LinkedList<T> (like mskeel said) or List<T> class would be a better way to go. Anytime you are unsure of how big of an array you will need or you will need to keep adding items, using a normal array is a bad idea for exactly this reason.
  24. Are you calling BeginUpdate and EndUpdate when updating the Items collection? Not doing so has caused me some very curious problems in the past.
  25. Re: Possibly poor practice, but not significantly I'm not specifically for or against it, but I do find myself doing it once and a while when it seems to make sense. Since I usually code in C# the casing is different and technically there is no ambiguity.
×
×
  • Create New...