Jump to content
Xtreme .Net Talk

divil

*Gurus*
  • Posts

    3026
  • Joined

  • Last visited

Everything posted by divil

  1. The JIT compiler may well do this, as may the VB.NET and C# compilers, I don't know. Why not compile some equivalent code in both, and check the IL produced? [edit]I am told that VB.NET does create a temporary variable for use in a With block[/edit]
  2. Why are you using a code module? Bear in mind that any answer you give will result in "you don't need to use a code module for this". Try it in a static member of a class, and then if it still doesn't work, give us code, error, line number etc.
  3. In .NET: System.Diagnostics.Process.Start("myexe.exe", "test") In VB6: MsgBox Command$ Will reveal "test".
  4. If I remember correctly, this is all done via the IExtenderProvider interface. If you make something which implements this, you can put extra properties on objects in the same container. It's how the designers add (Name) fields etc to components on the design surface. http://ms-help://MS.VSCC/MS.MSDNQTR.2002APR.1033/cpref/html/frlrfSystemComponentModelIExtenderProviderClassTopic.htm [edit]Damn I'm good[/edit]
  5. If you're accessing lots of members of one object, especially repeatedly, then having it in a With... End With clause can make it cache the memory address of the object, rather than having to treverse down the dot-seperated chain of objects on every access.
  6. "Thresher is a .Net IRC client library designed to serve as the basis for IRC bots and GUI clients. It is written in C# but can be used by any .Net supported language." http://sourceforge.net/projects/thresher/
  7. Add a tooltop component to your form, from your toolbox. Every control on the form will then gain a Tooltip property.
  8. Introduction Making your application plugin-aware is an excellent way of ensuring easy upgradability should you want to change part, but not all of it. While not every application is suitable, a good deal are. This tutorial is intended to follow up on one I did on how to write plugin-based apps in VB6, using COM. Doing this in .NET is actually slightly easier than in COM, in my opinion, and far more powerful. For instance, getting your COM plugins to show an interface within a dialog shown by the host application was a bit of a nightmare, and required calls to SetParent and inventive use of window styles to get working properly. This is trivial in .NET because of the Windows Forms architecture. The process of opening and inspecting DLLs in .NET is much the same. Plugin Architecture The best way to implement plugins in your application is with Interfaces. It is beyond the scope of this tutorial to explain interfaces, but they are in essence a contract. Any class implementing an interface must implement every member on the interface, so any application that knows about the interface knows exactly what to expect. You start off by building a class library with the interface(s) in. Usually you would use at least two. The minimum you could have is one, which every plugin class would implement. However, in practice you generally need another interface, which the host implements so the plugins have some way of communicating back to the host application. When the interface class library has been built, you write the host application which references this library, and can inspect any number of DLLs to see if they contain classes that implement these interfaces. At this point you can develop the plugins themselves, again referencing the class library to implement those interfaces. Writing the Interfaces First we create a new project of type Class Library, and define the two interfaces. For the purposes of this tutorial they will be very simple. Each plugin will offer a property with the name of the plugin, and a function which accepts two integers and returns a double. The host interface will expose a method so that the plugin can cause the host to show a message box. When you create a project of type Class Library, there will be one class there by default. We want to clear this and define an interface rather than a class: Public Interface IPlugin Sub Initialize(ByVal Host As IHost) ReadOnly Property Name() As String Function Calculate(ByVal int1 As Integer, ByVal int2 As Integer) As Double End Interface Public Interface IHost Sub ShowFeedback(ByVal strFeedback As String) End Interface Lastly we set the build output directory to a common directory, where we'll also put the host application and the plugins. Writing the first plugin Since we'll need at least one to test the host application with, now we can write a simple plugin. Again, we create a new project of type Class Library, set the build output directory, and make sure we reference the interface class library we just created. Next, we modify the class provided thus: Public Class Class1 Implements PluginSample.Interfaces.IPlugin Private objHost As PluginSample.Interfaces.IHost Public Sub Initialize(ByVal Host As PluginSample.Interfaces.IHost) Implements PluginSample.Interfaces.IPlugin.Initialize objHost = Host End Sub Public ReadOnly Property Name() As String Implements PluginSample.Interfaces.IPlugin.Name Get Return "Example Plugin 1 - Adds two numbers" End Get End Property Public Function Calculate(ByVal int1 As Integer, ByVal int2 As Integer) As Double _ Implements PluginSample.Interfaces.IPlugin.Calculate Return int1 + int2 End Function End Class We've just created a simple plugin, which adds the two numbers provided together. Although we are accepting and storing a reference to the host interface, we don't actually use it. We'll do that in the next plugin we write. Writing the Host Application We create a new project, of type Windows Application. The first thing to do is reference the class library we just created, and set the build output to the same directory. The main content of this article is the process of examining DLLs to see if they contain plugins, storing the information about what plugins are available, and instantiating and using them. To do this, I will provide a class, PluginServices.vb, which will encapsulate all these things. To get our list of plugins, we use the function FindPlugins which accepts a string containing the directory to search in, and a string with the full name of the interface we're looking for classes that implement. This function enumerates over all files with the extension .dll in the directory supplied, loads them using Assembly.LoadFrom() and passes execution to another function to examine the assembly. Public Shared Function FindPlugins(ByVal strPath As String, ByVal strInterface As String) As AvailablePlugin() Dim Plugins As ArrayList = New ArrayList() Dim strDLLs() As String, intIndex As Integer Dim objDLL As [Assembly] 'Go through all DLLs in the directory, attempting to load them strDLLs = Directory.GetFileSystemEntries(strPath, "*.dll") For intIndex = 0 To strDLLs.Length - 1 Try objDLL = [Assembly].LoadFrom(strDLLs(intIndex)) ExamineAssembly(objDLL, strInterface, Plugins) Catch e As Exception 'Error loading DLL, we don't need to do anything special End Try Next 'Return all plugins found Dim Results(Plugins.Count - 1) As AvailablePlugin If Plugins.Count <> 0 Then Plugins.CopyTo(Results) Return Results Else Return Nothing End If End Function Once all files have been examined, the function returns an array of type AvailablePlugin if some were found, or Nothing if none were found. As you can see, this function calls ExamineAssembly to inspect a loaded assembly. The ExamineAssembly enumerates all types exported by the loaded assembly, and uses the GetInterface() method of each type to see if it implements our interface. Conveniently, this method takes a string containing the fully qualified name of the interface. In this case, it's "PluginSample.Interfaces.IPlugin" we're looking for. If a type is found that implements the interface, an entry is added to the ArrayList with the full path of the DLL and the full name of the class. Private Shared Sub ExamineAssembly(ByVal objDLL As [Assembly], ByVal strInterface As String, ByVal Plugins As ArrayList) Dim objType As Type Dim objInterface As Type Dim Plugin As AvailablePlugin 'Loop through each type in the DLL For Each objType In objDLL.GetTypes 'Only look at public types If objType.IsPublic = True Then 'Ignore abstract classes If Not ((objType.Attributes And TypeAttributes.Abstract) = TypeAttributes.Abstract) Then 'See if this type implements our interface objInterface = objType.GetInterface(strInterface, True) If Not (objInterface Is Nothing) Then 'It does Plugin = New AvailablePlugin() Plugin.AssemblyPath = objDLL.Location Plugin.ClassName = objType.FullName Plugins.Add(Plugin) End If End If End If Next End Sub Lastly, we write the function that will be used to create an instance of a plugin where needed. It accepts an AvailablePlugin structure and returns an Object, to be casted to the appropriate type by the calling procedure. Public Shared Function CreateInstance(ByVal Plugin As AvailablePlugin) As Object Dim objDLL As [Assembly] Dim objPlugin As Object Try 'Load dll objDLL = [Assembly].LoadFrom(Plugin.AssemblyPath) 'Create and return class instance objPlugin = objDLL.CreateInstance(Plugin.ClassName) Catch e As Exception Return Nothing End Try Return objPlugin End Function That's about it for the PluginServices.vb file. The rest of the application is pretty simple. In the Sub Main, we call the FindPlugins method and populate a list on the form. The user can select a plugin from this list, and has the opportunity to enter two numbers and run the plugin to see what it returns. One more thing is needed however, and that is to create the class in the host application which implements the IHost interface, and provides the plugins with a way of calling methods in the host application. For the purposes of this sample, the method will simply display a message box. I won't go in to everything else in the host application, hopefully the code will explain itself. It's worth noting, however, that while in this sample we create an instance of a plugin each time we want to perform a calculation, usually the lifetime of a plugin object would be much longer. One more plugin We will just write one more plugin, this time to multiply the two numbers. This one will also use the host interface to show a message box during calculation. The code is in the "Plugin 2" folder. That's about it. I've attached all the code that goes with this tutorial, feel free to use the PluginServices.vb file in your own applications. It shouldn't require any modification. pluginsample.zip
  9. http://www.xtremedotnettalk.com/showthread.php?s=&threadid=49315 Read this thread, that I posted especially to avoid confusion about this matter.
  10. You haven't made your variable to save the last position found. This'll need to be declared outside the scope of that method. Private intLastPos As Integer = 0 Sub findstring() Me.TopMost = True Dim srchstart As Integer If chkbox.Checked = False Then srchstart = texted.txtbox.Text.ToLower.IndexOf(findword.Text.ToLower, intLastPos +1) Else srchstart = texted.txtbox.Text.IndexOf(findword.Text, intLastPos +1) End If If srchstart < 0 Then MsgBox("No Match Found", MsgBoxStyle.Information, "TextEd Find") Exit Sub End If texted.txtbox.Select(srchstart, findword.Text.Length) texted.txtbox.ScrollToCaret() intLastPos = srchstart End Sub You'll probably want another sub to reset it back to the beginning I suppose, by doing intLastPos = 0
  11. You can't actually do this with the built-in tabstrip, you can get it themed but the background of the pages won't be transparent like it should. Someone did, however, make a replacement control which works: http://www.codeproject.com/cs/miscctrl/themedtabpage.asp
  12. Post all the code you have here, including where you save the last position found, and I'll take a look.
  13. Thinker: I've done a great deal of different projects with vb.net and never needed to turn Option Strict off. That's not to say I haven't discovered the need to yet :) Robby: DirectCast(DirectCast(sender, RadioButton).Tag, String)
  14. Control Panel -> Administrative Tools Don't run .net assemblies from network shares without changing these security settings, most things just won't work.
  15. If you just need a strongly-typed collection, you can inherit from CollectionBase.
  16. Make a multiplayer chess game with a map (board) editor, save and load game support, with a database that keeps a record of games played, statistics etc :)
  17. I don't think you'd get that error because it wasn't thread safe. You could try adjusting your .net security settings under control panel. Is it located on a network share by any chance? They have lower security permissions by default.
  18. The best answer is, don't use FileOpen etc. They are pretty poor methods supplied by the VisualBasic runtime of accessing files, and there are much better methods present under the System.IO namespace. I'm not sure how you'd solve your problem if you remained using the VB methods, possibly just read in a Short (which there is an overload for) and put it in the structure. And yeah, you should always have Option Strict on.
  19. One of the IndexOf overloads accepts a Start parameter. You'll have to save in a variable the last result found, and next time they click it, specify this (+1) as the start position to find.
  20. About two and a half years. I've seen jobs posted which ask for 2 years professional C# experience.
  21. Not really. Structured exception handling is built in to the framework, there really isn't an alternative if you want to trap errors.
  22. Not at all. A String is an Object with more methods, you can cast from one to the other. It's the same object, just different ways of looking at it. But you cannot just cast an integer as, say, a double. There's no way of looking at an integer which makes it look like a double. You have to convert the value of it. I avoid using CType in VB because it's designed to do both if need be, which is quite nice in a way but if you know what you want to do, why not do it explicitly and same those extra CPU cycles? To cast objects you have the DirectCast keyword, which (for casting objects) is faster than CType. To convert between value types you have the Convert types, which will also be faster than using CType. Comes down to personal preference I suppose, but these are just my two pennies worth. I know the difference between casting and converting.
  23. Instrrev should work, although it's probably better to use the IndexOf and LastIndexOf methods of the String class. They're likely to have better documentation and samples for. If you still can't get it to work, post the code you're using to search backwards and I'll have another look.
  24. There's no such thing as casting value types! I don't know how much you know about casting, but you cast a class to a subclass or superclass of it. Casting and converting are two different things. Casting operators are part of a language, converting (in this case) is supplied by the framework via the Convert class (and others).
  25. divil

    decimal seperator

    I'd suggest using Double.Parse rather than CDbl. I think the function is aware of the current locale and this should be handled automatically for you.
×
×
  • Create New...