Results 1 to 21 of 21

Thread: [RESOLVED] Looking for a checkbox shortcut

  1. #1
    Junior Member Prognosticator's Avatar
    Join Date
    Jun 10
    Location
    Pittsburgh, PA
    Posts
    18

    Resolved [RESOLVED] Looking for a checkbox shortcut

    So I'm building a semi-complex math program with my own specialized functions for performing operations on a number or a group of numbers. The user interface is designed so that the user can choose which functions will take place. (Order is non specific - meaning each function performs correctly regardless of any other functions behavior/they are all mutually exclusive). I know basically how to code the program, but I'd call it the hard way. I can perform multiple if then statements that execute each function if the check box is selected. That's fine but with functions ranging in the hundreds, that's a lot of code just to see if the checkboxes are selected. In this case I don't think a select case statement would work because it to would be long winded depending on the number of possibilities. Unfortunately I don't see a for... each or for next loop working since each check box relates to a different function. So the question essentially is, is there a short cut to this tedium? Is there a code snippet or an idea for a methodology that would allow me to iterate or run through the checkboxes, finding which are selected and executing each assigned function as the user dictates? Or is the most concise method simply if, then, if then, if then, ad infinitum?

    VB 2010 Express edition if it matters.

    'Side note, I don't want the functions to perform upon the checkbox being clicked. The checkboxes will have no click event. While this may be a possibility (for simplification), I want to be able to assign default selections and have the user only manipulate the numbers to perform functions on and only select or deselect functions as deemed necessary or desired.

  2. #2
    .NUT jmcilhinney's Avatar
    Join Date
    May 05
    Location
    Sydney, Australia
    Posts
    80,768

    Re: Looking for a checkbox shortcut

    Let's say that these are the method you want executed for CheckBox1 and CheckBox2:
    vb.net Code:
    1. Private Sub DoSomething()
    2.     '...
    3. End Sub
    4.  
    5. Private Sub DoSomethingElse()
    6.     '...
    7. End Sub
    You can create two arrays: one for the CheckBoxes and one for delegates that refer to those methods:
    vb.net Code:
    1. Private checkBoxes As CheckBox()
    2. Private actions As Action() = {New Action(AddressOf DoSomething), New Action(AddressOf DoSomethingElse)}
    You would then need to create the array of CheckBoxes in the form's Load event handler:[highlight=vb.net]checkBoxes = {CheckBox1, CheckBox2}[/jighlight]You can then execute all the method that correspond to the check boxes like so:
    vb.net Code:
    1. For index = 0 To checkBoxes.GetUpperBound(0)
    2.     If checkBoxes(index).Checked Then
    3.         actions(index).Invoke()
    4.     End If
    5. Next
    If you didn't ant to create the array of CheckBoxes explicitly then you could do something like this:
    vb.net Code:
    1. checkBoxes = Controls.OfType(Of CheckBox)().ToArray()

  3. #3
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 12
    Posts
    5,471

    Re: Looking for a checkbox shortcut

    Hundreds of check boxes? Why does everybody always choose the hard way to do this kind of multiple selection? If you place all the equations in a multi-selection list box you have access through ListBox1.SelectedIndices(n) to exactly what you want without the need to run any kind of loop. You can then use a Select Case very simply

    Code:
    For n = 0 to ListBox1.SelectedItems.Count-1
    
    Select Case ListBox1.SelectedIndices(n)
    
    Case 0
    
    'first equation
    
    'etc.
    
    Next

  4. #4
    Junior Member Prognosticator's Avatar
    Join Date
    Jun 10
    Location
    Pittsburgh, PA
    Posts
    18

    Re: Looking for a checkbox shortcut

    Quote Originally Posted by dunfiddlin View Post
    Hundreds of check boxes? Why does everybody always choose the hard way to do this kind of multiple selection? If you place all the equations in a multi-selection list box you have access through ListBox1.SelectedIndices(n) to exactly what you want without the need to run any kind of loop. You can then use a Select Case very simply

    Code:
    For n = 0 to ListBox1.SelectedItems.Count-1
    
    Select Case ListBox1.SelectedIndices(n)
    
    Case 0
    
    'first equation
    
    'etc.
    
    Next
    Interesting. Hadn't thought of using a listbox for the equations. Although technically it's not quite how I want the user interface to look. The main reason being that the target user isn't going to be familiar with the math functions. So I would prefer to keep the "math" behind the scenes. The check box method is used so that I can tell the user what the output should be (sort of) without them needing to understand any math. In other words, they have data they want to work with, and they have an idea of the type of answer they are looking for, but won't know how to get there. This is why a selection is important. Also in a listbox I don't even know how to make multiple selections, so my users might not also. I'm assuming you hold down the control or shift key. With checkboxes the selection method is very simple and straightforward. But I do appreciate the feedback because if I ever need to make a different type of list of choices now I know the shortcut for that. Thank you.

  5. #5
    Junior Member Prognosticator's Avatar
    Join Date
    Jun 10
    Location
    Pittsburgh, PA
    Posts
    18

    Re: Looking for a checkbox shortcut

    This is exactly what I was looking for. I didn't know you could create an action list array. (Nor would I have known how to perform the functions even if I could have filled the area. I will try this method and see if I can get it to work. A couple of quick questions. In your sample code you didn't designate an array size, I will need to do that correct? For instance

    Private checkboxes as CheckBox(20)
    Private actions as Action(20) = {...}

    Or are these arrays that are dynamic? (Meaning they can change their size?)
    Or do I first declare an array of type CheckBox(intSizeOfArray) then use the assignment checkboxes as CheckBox()?
    -Actually I think I answered my own question, because your declaring the array explicitly by: checkboxes = {item1, item2, ...} the upper bound will be the number of items you input. ?
    Last question. The "Invoke()" keyword can be used for any action correct? Calling a function, a sub, loading a window, repainting the screen?

    Thanks for the info, I'm going to mark this as resolved.

  6. #6
    Junior Member Prognosticator's Avatar
    Join Date
    Jun 10
    Location
    Pittsburgh, PA
    Posts
    18

    Re: Looking for a checkbox shortcut

    ~Accidentally hit quick reply twice, same message, deleted content from second one.~~
    Last edited by Prognosticator; Aug 5th, 2012 at 01:11 PM. Reason: Double post by accident

  7. #7
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 12
    Posts
    5,471

    Re: Looking for a checkbox shortcut

    Well what you actually list is somewhat irrelevant as you use the index to direct the code and not the content. In multisimple selection mode you just click on the items and they're selected until such time as you click on them again, exactly the same as checkboxes. No special keys involved.

  8. #8
    Junior Member Prognosticator's Avatar
    Join Date
    Jun 10
    Location
    Pittsburgh, PA
    Posts
    18

    Re: Looking for a checkbox shortcut

    Quote Originally Posted by dunfiddlin View Post
    Well what you actually list is somewhat irrelevant as you use the index to direct the code and not the content. In multisimple selection mode you just click on the items and they're selected until such time as you click on them again, exactly the same as checkboxes. No special keys involved.
    That's a great point. I kinda realized it after I reread my response. I was assuming you meant to write the functions in the listbox but of course just like the checkbox the text doesn't have to be a pure reflection of the behind the scenes operation. My list box skills still needs some work. As a matter of fact I have a question regarding listboxes that is throwing me right now. It has to do with the difference between setting a list box's collection at or before run time. I've written a program or two that filled a listbox at runtime, but I've never coded a listbox that had a data set that was known in advance. A static data set. The conundrum I'm faced with is I'm not sure how the list box will react during run time if I want to modify what is displayed from the static data set. In particular if I remove an item but want to add it back later. I'm assuming the Remove() or RemoveAt() methods will enable me to remove an item from the collection at run time. However what if I want to reset the listbox to the default values that I've input during the design phase? Is the collection I create at design time held somewhere for retrieval during run-time execution? Or is it better if I hard code the collection in the program and then data bind it to the listbox or simply write code to fill it as a sub procedure? I'm worried about hard coding that many items. (Also a side note... I know I said hundreds of checkboxes, that was an exaggeration. It's more like 25 right now. I just wanted to know how to do it if I keep adding items. If I can understand listboxes better, I will play around with them and see which format I like best for concise programming and ease of use for the user. - I didn't know there was a multi-select option for listboxes til you pointed it out. thank you.)

  9. #9
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 12
    Posts
    5,471

    Re: [RESOLVED] Looking for a checkbox shortcut

    The ListBox item collection is always dynamic so if you remove an item there is no recourse to the original set. However, you can very easily create your own reference by using a non-visible listbox containing all possible entries as a static source. You can then use this list as an absolute reference matching entries to the dynamic visible collection using ...

    idx = ListBoxSource.Items.IndexOf(ListBoxVisible.Items(n))

  10. #10
    .NUT jmcilhinney's Avatar
    Join Date
    May 05
    Location
    Sydney, Australia
    Posts
    80,768

    Re: [RESOLVED] Looking for a checkbox shortcut

    Quote Originally Posted by dunfiddlin View Post
    The ListBox item collection is always dynamic so if you remove an item there is no recourse to the original set. However, you can very easily create your own reference by using a non-visible listbox containing all possible entries as a static source. You can then use this list as an absolute reference matching entries to the dynamic visible collection using ...

    idx = ListBoxSource.Items.IndexOf(ListBoxVisible.Items(n))
    Why use a ListBox control that you're not going to show the user when you could just use a generic List or an array?

  11. #11
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 12
    Posts
    5,471

    Re: [RESOLVED] Looking for a checkbox shortcut

    Because you can fill the listbox at design time bypassing the need for a datafile for initialisation.

  12. #12
    .NUT jmcilhinney's Avatar
    Join Date
    May 05
    Location
    Sydney, Australia
    Posts
    80,768

    Re: [RESOLVED] Looking for a checkbox shortcut

    Quote Originally Posted by dunfiddlin View Post
    Because you can fill the listbox at design time bypassing the need for a datafile for initialisation.
    That doesn't really make sense. You can populate a List or array in code with no need for an external file.

  13. #13
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 12
    Posts
    5,471

    Re: [RESOLVED] Looking for a checkbox shortcut

    Hardly the easiest way to do it though, is it? Nor the best way to keep code readable. Given the experience level of the poster and the task that's being undertaken it's a perfectly simple, consistent way of doing things with an easily understood logic so why complicate matters?

    In any case this is not a task for which an array would be a good choice. A generic list would be a better choice if there were items in the hundreds and search patterns a plenty but for 25 items and a single search criterion any difference in efficiency is going to be marginal and hardly worth taking on board a second lump of syntax when you're still coming to terms with listboxes. It may not pass any programming exams but it works. As I've said before that's what matters to those of us who don't do this for a living and only have ourselves to impress.

  14. #14
    .NUT jmcilhinney's Avatar
    Join Date
    May 05
    Location
    Sydney, Australia
    Posts
    80,768

    Re: [RESOLVED] Looking for a checkbox shortcut

    Quote Originally Posted by dunfiddlin View Post
    Hardly the easiest way to do it though, is it? Nor the best way to keep code readable. Given the experience level of the poster and the task that's being undertaken it's a perfectly simple, consistent way of doing things with an easily understood logic so why complicate matters?

    In any case this is not a task for which an array would be a good choice. A generic list would be a better choice if there were items in the hundreds and search patterns a plenty but for 25 items and a single search criterion any difference in efficiency is going to be marginal and hardly worth taking on board a second lump of syntax when you're still coming to terms with listboxes. It may not pass any programming exams but it works. As I've said before that's what matters to those of us who don't do this for a living and only have ourselves to impress.
    It's a hack.

  15. #15
    Junior Member Prognosticator's Avatar
    Join Date
    Jun 10
    Location
    Pittsburgh, PA
    Posts
    18

    Re: [RESOLVED] Looking for a checkbox shortcut

    Hey guys I appreciate the feedback all around. I would like to say really quick though, my experience level may seem minimal but I have taken programming classes (working on my associates degree now as a software developer). I program in java, html, css, vb2010, vb2008 and I'm starting C in the fall, then data structures in C++ in the spring. I know some of the questions I ask may seem pretty simple, but the classes I took were pretty elementary and more of an introduction. That's why I'm plugging away at my own projects. I'm focusing a lot on VB mainly because I love intellisense and the IDE for VS2010. That and I've been programming since the 90's with qbasic, but I haven't programmed in a while. At any rate, I say all that because ultimately I like all types of answers because I like to know options and I like to dive into the inner workings of the objects I hope to use as a professional programmer one day. That being said, I do tend to prefer programming in ways that I'm most apt to repeat in a business setting. I agree that sometimes we just want things to work and I love knowing those shortcuts! But generally I'll program things the way it will work best and most efficiently. Dunfiddlin - you were right about one thing, I did not want to access a file or data source. In this case I did create an array to fill the listbox at run time. I made the array private and its the first declaration in my form so its easy to read, easy to edit and correct programming etiquette. While the invisible listbox is an interesting approach (which I actually thought about doing), it's not exactly what a future boss would want to see . At any rate, thanx Dunfiddlin and jmcilhinney for your feedback!

  16. #16
    Junior Member Prognosticator's Avatar
    Join Date
    Jun 10
    Location
    Pittsburgh, PA
    Posts
    18

    Re: Looking for a checkbox shortcut

    Quote Originally Posted by jmcilhinney View Post
    Let's say that these are the method you want executed for CheckBox1 and CheckBox2:
    vb.net Code:
    1. Private Sub DoSomething()
    2.     '...
    3. End Sub
    4.  
    5. Private Sub DoSomethingElse()
    6.     '...
    7. End Sub
    You can create two arrays: one for the CheckBoxes and one for delegates that refer to those methods:
    vb.net Code:
    1. Private checkBoxes As CheckBox()
    2. Private actions As Action() = {New Action(AddressOf DoSomething), New Action(AddressOf DoSomethingElse)}
    You would then need to create the array of CheckBoxes in the form's Load event handler:[highlight=vb.net]checkBoxes = {CheckBox1, CheckBox2}[/jighlight]You can then execute all the method that correspond to the check boxes like so:
    vb.net Code:
    1. For index = 0 To checkBoxes.GetUpperBound(0)
    2.     If checkBoxes(index).Checked Then
    3.         actions(index).Invoke()
    4.     End If
    5. Next
    If you didn't ant to create the array of CheckBoxes explicitly then you could do something like this:
    vb.net Code:
    1. checkBoxes = Controls.OfType(Of CheckBox)().ToArray()

    I'm implementing this method and I came across a problem. I'm actually trying to perform Functions (that return values) and not sub procedures. When I coded it as you have listed (above) the IDE is telling me that they don't have "compatible signatures". I'm assuming it's because one is a function and Action defines a sub procedure. I looked through intellisense and found an option for Func(Of T, TResult). I'm not sure if I can actually use this method though. I did program most of the functions to return a single data type. (A structure I defined) Or of another data type (an array of structures, the same structure I defined). However I'm worried that in doing the iteration through the Action array may not be versatile enough for the two different data types. One option is to ensure all data types are the same. Since the array of structures is necessary it is possible to convert all functions to produce the array of structures data type and then I can simply manipulate that data, if I can figure out how to create an "Action" array of "Functions". The other option I'm actually leaning towards (although it seems like redundant code to me which I'm not keen on) is to create sub procedures that call the functions. In this way each sub procedure can deal specifically with the function and its particular data type and handle the output accordingly. However when thinking about this it would seem I'm going to create a sub procedure that closely mirrors the function. In which case - why have the function? Aside from using the functions in other programs I may code, it would seem a sub procedure that performs the operations and displays the output is just as easy in this case. So I guess I'm hoping there is a way to call the functions through iteration of an array that also allows me some method of handling multiple data types. Of course I can just arrange the array in such a way that it is sorted into data types, iterate through the first series of data types, then the second using a conditional statement. Not the neatest coding or easiest to read. I could also code multiple arrays. One for the actions associated with functions calls of a specific data type (thus handling it the same way) then another array for the other data type with different methods of handling the data. Any thoughts?

    NOTE: The functions all accept 1 argument (a string) and then return one of two values. Either it returns a structure of strings or it returns an array of (structures of strings).
    Last edited by Prognosticator; Aug 14th, 2012 at 04:40 AM. Reason: Note added.

  17. #17
    .NUT jmcilhinney's Avatar
    Join Date
    May 05
    Location
    Sydney, Australia
    Posts
    80,768

    Re: [RESOLVED] Looking for a checkbox shortcut

    Action is a delegate that represents a Sub, i.e. a method that doesn't return a value, while Func is a delegate that represents a function, i.e. a method that does return a value. They are both overloaded and accept from zero to 16 parameters.

    An array requires that you specify its type, which then restricts each element to be that type. In my example, the array was type Action, so each element had to be an Action delegate that referred to a method with no parameters that doesn't return a value. If all your functions had the same return type then you could declare the array with the appropriate Func type, but that's not an option in this case. As is always the case when declaring something as a particular type, if it needs to refer to objects of multiple types then you need to declare it as a common type. The most specific type that is common to all delegates is Delegate. I don't know what you mean by "structure of strings" but here's an example of how you might approach this:
    vb.net Code:
    1. Private checkBoxes As CheckBox()
    2. Private methods As [Delegate]() = {New Func(Of String, String)(AddressOf GetSomething),
    3.                                    New Func(Of String, String())(AddressOf GetSomethingElse)}
    4.  
    5. Private Function GetSomething(str As String) As String
    6.     '...
    7. End Function
    8.  
    9. Private Function GetSomethingElse(str As String) As String()
    10.     '...
    11. End Function
    vb.net Code:
    1. For Each method As [Delegate] In methods
    2.     Dim result = method.DynamicInvoke(TextBox1.Text)
    3.  
    4.     If TypeOf result Is String Then
    5.         MessageBox.Show(CStr(result))
    6.     ElseIf TypeOf result Is String() Then
    7.         For Each value As String In DirectCast(result, String())
    8.             MessageBox.Show(value)
    9.         Next
    10.     End If
    11. Next

  18. #18
    Frenzied Member Evil_Giraffe's Avatar
    Join Date
    Aug 02
    Location
    Suffolk, UK
    Posts
    1,877

    Re: [RESOLVED] Looking for a checkbox shortcut

    Quote Originally Posted by dunfiddlin View Post
    Hardly the easiest way to do it though, is it?
    Umm... yes it is?
    Quote Originally Posted by dunfiddlin View Post
    Nor the best way to keep code readable.
    Again, I think I'm going to have to disagree with you, there.
    Quote Originally Posted by dunfiddlin View Post
    It may not pass any programming exams but it works. As I've said before that's what matters to those of us who don't do this for a living and only have ourselves to impress.
    Do you really think "those of us who do this for a living" are more worried that our code would "pass programming exams" than that our code is a) demonstrably correct and b) easy to work with? There are reasons why professional programmers have developed certain practices and it isn't to confuse hobbyist programmers - it's because these are better ways of developing software.

  19. #19
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 12
    Posts
    5,471

    Re: [RESOLVED] Looking for a checkbox shortcut

    There are reasons why professional programmers have developed certain practices and it isn't to confuse hobbyist programmers - it's because these are better ways of developing software.
    As evidenced presumably by the constant patching necessary for just about every commercial release, the scrapping of just about every major Government software project in the last 20 years, and the never ending stream of contributions to forums such as Code Project's Weird & Wonderful section (to say nothing of the nightmare to use that the forum has become since the wonderful new programming was adopted!)? It may well be that you and the other professionals around here are in fact both inerrant and immune to the pride which comes before a fall but even so it would be wise not to believe too much in your own publicity. Sometimes different is just different and none the worse for that!
    Last edited by dunfiddlin; Aug 14th, 2012 at 09:01 AM.

  20. #20
    Fanatic Member ThomasJohnsen's Avatar
    Join Date
    Jul 10
    Location
    Denmark
    Posts
    521

    Re: [RESOLVED] Looking for a checkbox shortcut

    Quote Originally Posted by dunfiddlin View Post
    As evidenced presumably by the constant patching necessary for just about every commercial release, the scrapping of just about every major Government software project in the last 20 years, and the never ending stream of contributions to forums such as Code Project's Weird & Wonderful section? It may well be that you and the other professionals around here are in fact both inerrant and immune to the pride which comes before a fall but even so it would be wise not to believe too much in your own publicity. Sometimes different is just different and none the worse for that!
    I don't code for a living - and yet I completely agree with McIlhinney and EG. Using invisible controls is bad coding practise. It's difficult to read and understand for others (and yourself if you haven't seen the code in a while), it clutters up the design window (ie. WYSINWYG) and it's not efficient. You can most likely create and add a resource in the same time it takes to populate an invisible control anyways.
    In truth, a mature man who uses hair-oil, unless medicinally , that man has probably got a quoggy spot in him somewhere. As a general rule, he can't amount to much in his totality. (Melville: Moby Dick)

  21. #21
    Junior Member Prognosticator's Avatar
    Join Date
    Jun 10
    Location
    Pittsburgh, PA
    Posts
    18

    Re: [RESOLVED] Looking for a checkbox shortcut

    Quote Originally Posted by jmcilhinney View Post
    Action is a delegate that represents a Sub, i.e. a method that doesn't return a value, while Func is a delegate that represents a function, i.e. a method that does return a value. They are both overloaded and accept from zero to 16 parameters.

    An array requires that you specify its type, which then restricts each element to be that type. In my example, the array was type Action, so each element had to be an Action delegate that referred to a method with no parameters that doesn't return a value. If all your functions had the same return type then you could declare the array with the appropriate Func type, but that's not an option in this case. As is always the case when declaring something as a particular type, if it needs to refer to objects of multiple types then you need to declare it as a common type. The most specific type that is common to all delegates is Delegate. I don't know what you mean by "structure of strings" but here's an example of how you might approach this:
    vb.net Code:
    1. Private checkBoxes As CheckBox()
    2. Private methods As [Delegate]() = {New Func(Of String, String)(AddressOf GetSomething),
    3.                                    New Func(Of String, String())(AddressOf GetSomethingElse)}
    4.  
    5. Private Function GetSomething(str As String) As String
    6.     '...
    7. End Function
    8.  
    9. Private Function GetSomethingElse(str As String) As String()
    10.     '...
    11. End Function
    vb.net Code:
    1. For Each method As [Delegate] In methods
    2.     Dim result = method.DynamicInvoke(TextBox1.Text)
    3.  
    4.     If TypeOf result Is String Then
    5.         MessageBox.Show(CStr(result))
    6.     ElseIf TypeOf result Is String() Then
    7.         For Each value As String In DirectCast(result, String())
    8.             MessageBox.Show(value)
    9.         Next
    10.     End If
    11. Next
    Thank you. I actually modified the code but got it to work. It was a matter of understanding how it dealt with the data type. When I used the [Delegate] data type it actually didn't quite work. However by specifying the function type as the data type it worked just fine. I had to code four separate arrays. 1 for the first type of function return type and 1 for its associated checkboxes. Then a second for the second data return type and its associated checkboxes. Essentially to better explain the dilemma, I built a structure say:
    vb.net Code:
    1. Public Structure MyStructure
    2.     strFirstPartOfString = "x"
    3.     strSecondPartOfString = "y"
    4.     strThirdPartOfString = "z"
    5. end structure
    Then I created a function to use that structure. I also created functions that returned an array filled with variable of that structure:
    vb.net Code:
    1. Public Function MyFunction(ByVal As String) as MyStructure()
    2.   'Fill array with variable of type "MyStructure"
    3.  Return myStructureArray
    4. End Function
    So to code the actual "action list" array, using delegate didn't work. However this did:
    vb.net Code:
    1. Private arrayMyArrayOfFunctions As Func(Of String, MyStructure) = {Func(Of String, MyStructure)(AddressOf MyFunction),  ....}
    and also
    vb.net Code:
    1. Private arrayMyArrayOfFunctions2 As Func(Of String, MyStructure()) = {Func(Of String, MyStructure())(Address of MyFunction), ...}

    Now all I have to do is get the manipulations to work. Thanks so much for your continued help in this matter. Hopefully delving into data types and structures in the spring will help me better understand how to deal with "homemade" data types a little better I really appreciate the feedback, I'm learning a lot. Is there a good resource for learning more complex coding like this? Have any good book suggestions?

    Note: It may appear as if my two function arrays are referencing the same function that returns a type of array, but I actually have two different functions, one returns a variable of type MyStructure, one returns a variable of type MyStructure(). Sorry if my examples are a little misleading in that regard or confusing.
    Last edited by Prognosticator; Aug 14th, 2012 at 03:03 PM. Reason: Note Added, typos corrected

Posting Permissions

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