Generate Class.vb File Programmatically-VBForums
Results 1 to 20 of 20

Thread: Generate Class.vb File Programmatically

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Feb 2013
    Posts
    26

    Generate Class.vb File Programmatically

    Hello,

    I want to create a class builder which will get the tables from the specified database and build my [className].vb file - at the push of a button!

    For example:
    Code:
            Dim strBuilder As New StringBuilder
    
            strBuilder.Append("Public class clsExample" & vbCrLf)
    
            'Create variables
            strBuilder.Append("Private _ID As String")
            strBuilder.Append(vbCrLf)
    
            'Create properties
            strBuilder.Append("Public Property _ID() As Integer" & vbCrLf)
            strBuilder.Append("Get" & vbCrLf)
            strBuilder.Append("return _ID" & vbCrLf)
            strBuilder.Append("end Get" & vbCrLf)
            strBuilder.Append("Set(ByVal Value As Integer)" & vbCrLf)
            strBuilder.Append("_ID = Value" & vbCrLf)
            strBuilder.Append("End Set" & vbCrLf)
            strBuilder.Append("End Property " & vbCrLf)
            strBuilder.Append(vbCrLf)
            strBuilder.Append(vbCrLf & "End Class")
    
            Console.Write(strBuilder.ToString())
    To get this result in the clsExample.vb file that was created using the previous code
    Code:
    Public Class clsExample
            Private _ID As String
            Public Property _ID() As Integer
                Get
                    Return _ID
                End Get
                Set(ByVal Value As Integer)
                    _ID = Value
                End Set
            End Property
    
    
        End Class
    I'm not sure how to go about telling the program to create the [className].vb file and include my strBuilder as code in the file. Hope this makes sense...
    Last edited by Alex_AMF; Mar 2nd, 2013 at 04:45 PM. Reason: Typos

  2. #2
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,242

    Re: Generate Class.vb File Programmatically

    Hope this makes sense...
    Well, now you mention it .....

    What is the ultimate purpose here? I can't, for the moment, think of any use for such a beast.
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Feb 2013
    Posts
    26

    Re: Generate Class.vb File Programmatically

    Well, every time I create new projects that will use a Database, i must create the basic (and redundant) code that will contain it's properties, methods and functions.

    For example, I would create a table named "Employees" in my database. Once all the table columns are entered with their types, I would go into my ClassGenerator program to (at the click of a button):
    Create a folder named "Classes" if none exist
    Create a class named clsEmployees.vb, and store it in that classes folder
    Append all the code that is normally entered by hand for the properties, methods and functions.


    The ultimate purpose is to save time. If I have 10 tables to create, that means 10 class files in VB to communicate with the database and build my objects so I can use them in the given program. In the long run, it's always the same information but it's time consuming. I figured if my button click event would do all that for me - I'd be winning.
    Last edited by Alex_AMF; Mar 2nd, 2013 at 05:03 PM.

  4. #4
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,242

    Re: Generate Class.vb File Programmatically

    If I have 10 tables to create, that means 10 class files in VB
    Since when? The whole purpose of a class is to create a generic code which may be passed values to distinguish one instance from another. If you're creating a new class for every datatable specific only to that table then you're not merely producing redundant code, you're completely missing the point! In any case ten tables require just one dataset, as do twenty. thirty, forty .... or every table you've ever created!

    Even if you succeeded in this scheme, how would you then include the classes in the project, allowing them to be executed?
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  5. #5

    Thread Starter
    Junior Member
    Join Date
    Feb 2013
    Posts
    26

    Re: Generate Class.vb File Programmatically

    Yeah that's what I was wondering... How would I add that into the project? We use classes to create objects, and we split them up so that it is easier to deal with information being loaded / saved or modified - that's why we have so many clsFiles.vb in our project folder called "Classes".

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Feb 2013
    Posts
    26

    Re: Generate Class.vb File Programmatically

    Code:
    IO.File.WriteAllText(path, strBuilder.ToString())
    Creates the file and appends the text to that file. Works nice, now I just can't see it appear in the project solution explorer. I need to do "Include in project" manually... Gotta figure out how to do that programmatically and everything will work great!
    Last edited by Alex_AMF; Mar 2nd, 2013 at 05:34 PM.

  7. #7
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    31,115

    Re: Generate Class.vb File Programmatically

    What you are doing is starting down the path of creating a code generator. There are a few of them on the market, and I have a bit of experience working with various forms. Frankly, I don't like the idea. Taking it to it's logical conclusion, you end up with the Entity Framework that MS put out where you can build all your objects off of your database nice and easy. You are doing a stripped down version of that, which will have lesser functionality....which is probably a good thing, but ultimately, I've never seen a design like this that looked good. You end up with a maintenance headache, and for what? What do you gain from having a class for each table? Are you going to go on and write the code so that your project changes when you change the DB, or are you going to make all those changes by hand? If each one of these classes wraps a row of data, will you have a class that wraps the whole datatable and includes a List(of Row)? If you do that, how is that different from a datatable, and what greater benefit does it convey?

    Essentially, I think you are doing a whole lot of work to recreate a datatable, or perhaps a strongly typed datatable. I've seen people try it before, but I've never seen any good justification for it.
    My usual boring signature: Nothing

  8. #8

    Thread Starter
    Junior Member
    Join Date
    Feb 2013
    Posts
    26

    Re: Generate Class.vb File Programmatically

    Yeah it will be a very small code generator that will just help me / the company create it's classes faster. The reason I keep this method is because 90% of the programs are designed like that. My boss wanted to keep that method so I just went with the flow and never really explored any alternatives. I have a bout 5 months of experience in VB.Net (used to be more oriented towards web programming). Therefore I do not really know the best concept of information setting/gathering from the database. Managing 10 tables with 1 datatable sounds crazy to me for now, I'll need to explore that.

  9. #9
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    31,115

    Re: Generate Class.vb File Programmatically

    You wouldn't put 10 tables in a datatable, you would put one table in a datatable. You could have 10 datatables in a dataset, though.

    You might look into the Entity Framework, as it does what you are doing and far more. However, if you want to add the files automatically, it has to do with something like the sln or proj file or the manifest, or something like that. I don't remember exactly, but if you look at those files, you'll find one that is a text file where you will see the other files you have added.
    My usual boring signature: Nothing

  10. #10
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,505

    Re: Generate Class.vb File Programmatically

    I wrote an application to convert tables from SQL Server 2005 to classes for use in VB.Net programs. Although I agree with SH in that you should use the Entity Framework instead, which would surely be far superior, I'll be willing to provide my tool as its far simpler to learn and apply than the Entity Framework. Here is an example of a class generated by my tool:-
    vbnet Code:
    1. '
    2. Imports System.Data
    3. Imports System.Data.SqlClient
    4. Imports System.Reflection
    5. Imports System.Text
    6. Imports System.ComponentModel
    7. Imports System.Collections.ObjectModel
    8. Public Class STItemsRow
    9.     Inherits STDataRowBase
    10.  
    11.     Private Shared gshr_lstDbFields As IList(Of DatabaseField)
    12.     Private _ItemID As Integer
    13.     Private _ItemCode As String
    14.     Private _Description As String
    15.     Private _Quantity As Integer
    16.     Private _CostPrice As Decimal
    17.     Private _SellPrice As Decimal
    18.     Private _Taxable As Boolean
    19.  
    20. Protected Overrides Function GetDatabaseFields() As List(Of DatabaseField)
    21.     If gshr_lstDbFields IsNot Nothing Then Return gshr_lstDbFields
    22.     Dim lst As New List(Of DatabaseField)
    23.     lst.Add(New DatabaseField("ItemID", True, True, False, SqlDbType.Int))
    24.     lst.Add(New DatabaseField("ItemCode", False, False, False, SqlDbType.VarChar))
    25.     lst.Add(New DatabaseField("Description", False, False, False, SqlDbType.VarChar))
    26.     lst.Add(New DatabaseField("Quantity", False, False, False, SqlDbType.Int))
    27.     lst.Add(New DatabaseField("CostPrice", False, False, False, SqlDbType.Decimal))
    28.     lst.Add(New DatabaseField("SellPrice", False, False, False, SqlDbType.Decimal))
    29.     lst.Add(New DatabaseField("Taxable", False, False, False, SqlDbType.Bit))
    30.     gshr_lstDbFields = lst
    31.     Return lst
    32. End Function
    33.     Public Property ItemID() As Integer
    34.         Get
    35.             Return _ItemID
    36.         End Get
    37.         Set(ByVal value As Integer)
    38.             OnPropertyChanging(New PropertyChangingEventArgs("ItemID"))
    39.             _ItemID = value
    40.             OnPropertyChanged(New PropertyChangedEventArgs("ItemID"))
    41.         End Set
    42.     End Property
    43.     Public Property ItemCode() As String
    44.         Get
    45.             Return _ItemCode
    46.         End Get
    47.         Set(ByVal value As String)
    48.             OnPropertyChanging(New PropertyChangingEventArgs("ItemCode"))
    49.             _ItemCode = value
    50.             OnPropertyChanged(New PropertyChangedEventArgs("ItemCode"))
    51.         End Set
    52.     End Property
    53.     Public Property Description() As String
    54.         Get
    55.             Return _Description
    56.         End Get
    57.         Set(ByVal value As String)
    58.             OnPropertyChanging(New PropertyChangingEventArgs("Description"))
    59.             _Description = value
    60.             OnPropertyChanged(New PropertyChangedEventArgs("Description"))
    61.         End Set
    62.     End Property
    63.     Public Property Quantity() As Integer
    64.         Get
    65.             Return _Quantity
    66.         End Get
    67.         Set(ByVal value As Integer)
    68.             OnPropertyChanging(New PropertyChangingEventArgs("Quantity"))
    69.             _Quantity = value
    70.             OnPropertyChanged(New PropertyChangedEventArgs("Quantity"))
    71.         End Set
    72.     End Property
    73.     Public Property CostPrice() As Decimal
    74.         Get
    75.             Return _CostPrice
    76.         End Get
    77.         Set(ByVal value As Decimal)
    78.             OnPropertyChanging(New PropertyChangingEventArgs("CostPrice"))
    79.             _CostPrice = value
    80.             OnPropertyChanged(New PropertyChangedEventArgs("CostPrice"))
    81.         End Set
    82.     End Property
    83.     Public Property SellPrice() As Decimal
    84.         Get
    85.             Return _SellPrice
    86.         End Get
    87.         Set(ByVal value As Decimal)
    88.             OnPropertyChanging(New PropertyChangingEventArgs("SellPrice"))
    89.             _SellPrice = value
    90.             OnPropertyChanged(New PropertyChangedEventArgs("SellPrice"))
    91.         End Set
    92.     End Property
    93.     Public Property Taxable() As Boolean
    94.         Get
    95.             Return _Taxable
    96.         End Get
    97.         Set(ByVal value As Boolean)
    98.             OnPropertyChanging(New PropertyChangingEventArgs("Taxable"))
    99.             _Taxable = value
    100.             OnPropertyChanged(New PropertyChangedEventArgs("Taxable"))
    101.         End Set
    102.     End Property
    103. Protected Overrides Function CollectDataFromFields() As IList(Of ClassFieldData)
    104.     Dim r As New List(Of ClassFieldData)
    105.  
    106.     r.Add(New ClassFieldData(MyBase.DatabaseField("ItemID"), Me.ItemID))
    107.     r.Add(New ClassFieldData(MyBase.DatabaseField("ItemCode"), Me.ItemCode, True, True))
    108.     r.Add(New ClassFieldData(MyBase.DatabaseField("Description"), Me.Description, True, True))
    109.     r.Add(New ClassFieldData(MyBase.DatabaseField("Quantity"), Me.Quantity))
    110.     r.Add(New ClassFieldData(MyBase.DatabaseField("CostPrice"), Me.CostPrice))
    111.     r.Add(New ClassFieldData(MyBase.DatabaseField("SellPrice"), Me.SellPrice))
    112.     r.Add(New ClassFieldData(MyBase.DatabaseField("Taxable"), Me.Taxable))
    113.     Return r
    114. End Function
    115. Public Overrides Sub FetchIntoFields(ByVal row As System.Data.DataRow)
    116.     If TryGetColumnData(VBDataTypes.VBInteger, row, "ItemID", Me.ItemID) = False Then ThrowColumnNotExists("ItemID")
    117.     If TryGetColumnData(VBDataTypes.VBString, row, "ItemCode", Me.ItemCode) = False Then ThrowColumnNotExists("ItemCode")
    118.     If TryGetColumnData(VBDataTypes.VBString, row, "Description", Me.Description) = False Then ThrowColumnNotExists("Description")
    119.     If TryGetColumnData(VBDataTypes.VBInteger, row, "Quantity", Me.Quantity) = False Then ThrowColumnNotExists("Quantity")
    120.     If TryGetColumnData(VBDataTypes.VBDecimal, row, "CostPrice", Me.CostPrice) = False Then ThrowColumnNotExists("CostPrice")
    121.     If TryGetColumnData(VBDataTypes.VBDecimal, row, "SellPrice", Me.SellPrice) = False Then ThrowColumnNotExists("SellPrice")
    122.     If TryGetColumnData(VBDataTypes.VBBool, row, "Taxable", Me.Taxable) = False Then ThrowColumnNotExists("Taxable")
    123. End Sub
    124. Protected Overrides Sub SetIdentityFieldValue(ByVal IdentityValue As Long)
    125.     Me.ItemID = IdentityValue
    126. End Sub
    127. End Class
    128. Public Class STItemsRowCollection
    129.     Inherits STDataRowCollection(Of STItemsRow)
    130.  
    131.     Public Sub New()
    132.         SetTable("Items")
    133.     End Sub
    134.     Public Enum Fields
    135.         ItemID
    136.         ItemCode
    137.         Description
    138.         Quantity
    139.         CostPrice
    140.         SellPrice
    141.         Taxable
    142.     End Enum
    143.  
    144.     Public Sub AddWhereClauseCondition(ByVal field As Fields, ByVal SqlOperator As enumSqlOperators, ByVal value As Object)
    145.         If field = Fields.ItemID Then InternalAddWhereClauseCondition(New WhereClauseData("ItemID", value, SqlOperator))
    146.         If field = Fields.ItemCode Then InternalAddWhereClauseCondition(New WhereClauseData("ItemCode", value, SqlOperator))
    147.         If field = Fields.Description Then InternalAddWhereClauseCondition(New WhereClauseData("Description", value, SqlOperator))
    148.         If field = Fields.Quantity Then InternalAddWhereClauseCondition(New WhereClauseData("Quantity", value, SqlOperator))
    149.         If field = Fields.CostPrice Then InternalAddWhereClauseCondition(New WhereClauseData("CostPrice", value, SqlOperator))
    150.         If field = Fields.SellPrice Then InternalAddWhereClauseCondition(New WhereClauseData("SellPrice", value, SqlOperator))
    151.         If field = Fields.Taxable Then InternalAddWhereClauseCondition(New WhereClauseData("Taxable", value, SqlOperator))
    152.     End Sub
    153. End Class
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  11. #11
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,322

    Re: Generate Class.vb File Programmatically

    I agree with Shaggy in regards to Entity Framework or DataContext class which does an excellent job and creating strongly type classes for data. Once the classes are generated you can add functions, procedures and properties and events of your own. Your code is placed into a Partial class and is not distrubed when generating new code via the data wizards.

    http://en.wikipedia.org/wiki/Entity%...tionship_model
    http://msdn.microsoft.com/en-us/library/fxsa23t6.aspx
    http://msdn.microsoft.com/en-us/libr...tacontext.aspx

  12. #12
    Frenzied Member CoachBarker's Avatar
    Join Date
    Aug 2007
    Location
    Central NY State
    Posts
    1,118

    Re: Generate Class.vb File Programmatically

    I created a small program a couple years ago that allows you to select a database, create an entity class for either all or some selected tables. (Access database since that is what I use for small apps I write with certain naming conventions). It also creates a data access class which includes add, update, delete and a basic select statement functions. It creates a module for database connection and closing the database. It creates folders on my C drive in a folder named after the database I am using, a folder for each item I am creating(Database, EntityClass, DAClass, Modules)For me it is simpler to run the app and then import the folders or just the code to any new projects I am creating. A lot less code I have to write and covers all the basic requirements for my projects.
    Thanks
    CoachBarker

    Code Bank Contribution
    Login/Manage Users/Navigate Records
    VB.Net | C#

    Helpful Links: VB.net Tutorial | C Sharp Tutorial | SQL Basics

  13. #13

    Thread Starter
    Junior Member
    Join Date
    Feb 2013
    Posts
    26

    Re: Generate Class.vb File Programmatically

    I presented the program I developed over the weekend to my boss this morning. It works flawlessly and will enable us to save an insane amount of time. It fetches the database specified, allows you to choose which tables to transform into vb code and stores it into a "Classes" folder specified at your desired location. Thanks for everyone who helped

  14. #14
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,505

    Re: Generate Class.vb File Programmatically

    Quote Originally Posted by CoachBarker View Post
    I created a small program a couple years ago that allows you to select a database, create an entity class for either all or some selected tables. (Access database since that is what I use for small apps I write with certain naming conventions). It also creates a data access class which includes add, update, delete and a basic select statement functions. It creates a module for database connection and closing the database. It creates folders on my C drive in a folder named after the database I am using, a folder for each item I am creating(Database, EntityClass, DAClass, Modules)For me it is simpler to run the app and then import the folders or just the code to any new projects I am creating. A lot less code I have to write and covers all the basic requirements for my projects.
    Quote Originally Posted by Alex_AMF View Post
    I presented the program I developed over the weekend to my boss this morning. It works flawlessly and will enable us to save an insane amount of time. It fetches the database specified, allows you to choose which tables to transform into vb code and stores it into a "Classes" folder specified at your desired location. Thanks for everyone who helped
    Wow...I though I was the only one who made such a tool lol....Would be nice to compare our approaches if time could have permitted that.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  15. #15
    Frenzied Member CoachBarker's Avatar
    Join Date
    Aug 2007
    Location
    Central NY State
    Posts
    1,118

    Re: Generate Class.vb File Programmatically

    After I clean mine up a little bit I would be willing to post it in the code bank forum if anyone is interested.
    Thanks
    CoachBarker

    Code Bank Contribution
    Login/Manage Users/Navigate Records
    VB.Net | C#

    Helpful Links: VB.net Tutorial | C Sharp Tutorial | SQL Basics

  16. #16
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,505

    Re: Generate Class.vb File Programmatically

    I'm curious does yours use CodeDOM ? I wanted to use CodeDom for mine but GOD!!!....It takes a million lines of CodeDom to generate a few lines of code. I opted for my own ad-hoc code generation scheme.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  17. #17
    Frenzied Member CoachBarker's Avatar
    Join Date
    Aug 2007
    Location
    Central NY State
    Posts
    1,118

    Re: Generate Class.vb File Programmatically

    no nothing complex straight vb.net in VS 2005 if you mean me

    Just ran across this again. Mine uses StreamReader and StreamWriter to do all the work.
    Last edited by CoachBarker; Feb 5th, 2014 at 03:53 PM. Reason: additional information
    Thanks
    CoachBarker

    Code Bank Contribution
    Login/Manage Users/Navigate Records
    VB.Net | C#

    Helpful Links: VB.net Tutorial | C Sharp Tutorial | SQL Basics

  18. #18
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,505

    Re: Generate Class.vb File Programmatically

    Lol CodeDom is VB.Net....its made up of a few namespaces in the Framework. It allows you to generate source code in either VB.Net or C#.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  19. #19
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: Generate Class.vb File Programmatically

    If you're looking at Entity Framework, I'd urge you to explore all the ORMs available in .NET, not just whatever Microsoft provides. There are a number of very mature ORMs (Object-Relational Mapper), notably NHibernate, and a few "micro-ORMs" such as Massive that come with much less power but much less overhead and faff as well.

  20. #20
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: Generate Class.vb File Programmatically

    Quote Originally Posted by Shaggy Hiker View Post
    What do you gain from having a class for each table?
    Well, for one thing, you get a place to put behaviour related to the entity that is being modelled. Code Generators should create partial classes such that they dump all their code into one file, and you write all the "programmed" bits in another file. That way the generator can re-generate the generated code without affecting or needing to deal with your code. This is exactly the way that the WinForms Designer works - do you refuse to use that as well? (Okay, to be fair, I don't like the Designer and would avoid it if I could, which somewhat detracts from my argument here)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width

Survey posted by VBForums.