Validating a checked box and then running code

Ask questions about creating Graphical User Interfaces (GUI) in PowerShell and using WinForms controls.
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
This topic is 11 years and 2 weeks old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked
User avatar
BCBSSC
Posts: 6
Last visit: Tue Jun 16, 2015 12:37 pm

Validating a checked box and then running code

Post by BCBSSC »

Hey All,
I'm a fairly new Powershell script developer and I'm trying to figure out how to use check boxes.
I am responsible for the installation of a lot of software at my company and I have a Powershell script that will run through and install it all. This is great for a new workstation setup but sometimes I only need to install some of the software.
I have a checkbox form coded with a partial list of the software but I'm not sure how to proceed once the boxes are checked and the "OK" button is pressed. I've included the form code so you can see where I am so far. Any suggestions on cleaning up the forms code would be appreciated as well. Thanks in advance.


[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

$Form = New-Object System.Windows.Forms.Form
$tlp_MainTable = New-Object System.Windows.Forms.TableLayoutPanel
$gb_ServiceType = New-Object System.Windows.Forms.GroupBox
$cb_AllTools = New-Object System.Windows.Forms.CheckBox
$gb_IndividualTools = New-Object System.Windows.Forms.GroupBox
$lbl_or = New-Object System.Windows.Forms.Label
$cb_PowerArchive = New-Object System.Windows.Forms.CheckBox
$cb_ProcExp = New-Object System.Windows.Forms.CheckBox
$cb_WinSCP = New-Object System.Windows.Forms.CheckBox
$cb_TextPad = New-Object System.Windows.Forms.CheckBox
$cb_BeyondCompare = New-Object System.Windows.Forms.CheckBox
$cb_SoapUI = New-Object System.Windows.Forms.CheckBox
$cb_LDapBrowser = New-Object System.Windows.Forms.CheckBox
$cb_IEDebugTool = New-Object System.Windows.Forms.CheckBox
$cb_SecureCRT = New-Object System.Windows.Forms.CheckBox
$cb_TcpView = New-Object System.Windows.Forms.CheckBox
$cb_CygWin = New-Object System.Windows.Forms.CheckBox
$cb_JRuler = New-Object System.Windows.Forms.CheckBox
$cb_ChainSaw = New-Object System.Windows.Forms.CheckBox
$cb_MQMonitor = New-Object System.Windows.Forms.CheckBox
$cb_CutePDF = New-Object System.Windows.Forms.CheckBox
$cb_JDGUI = New-Object System.Windows.Forms.CheckBox
$cb_SafariQT = New-Object System.Windows.Forms.CheckBox
$gb_Buttons = New-Object System.Windows.Forms.GroupBox
$btn_OK = New-Object System.Windows.Forms.Button
$btn_CANCEL = New-Object System.Windows.Forms.Button
$tlp_MainTable.SuspendLayout()
$gb_ServiceType.SuspendLayout()
$gb_IndividualTools.SuspendLayout()
$Form.SuspendLayout()
#
#tlp_MainTable
$tlp_MainTable.ColumnCount = 1
[void]$tlp_MainTable.ColumnStyles.Add((New-Object System.Windows.Forms.ColumnStyle([System.Windows.Forms.SizeType]::Percent, 100)))
$tlp_MainTable.Controls.Add($gb_IndividualTools, 0, 2)
$tlp_MainTable.Controls.Add($gb_ServiceType, 0, 0)
$tlp_MainTable.Controls.Add($lbl_or, 0, 1)
$tlp_MainTable.Controls.Add($gb_Buttons, 0, 3)
$tlp_MainTable.Dock = [System.Windows.Forms.DockStyle]::Fill
$tlp_MainTable.Location = New-Object System.Drawing.Point(0, 0)
$tlp_MainTable.Name = "tlp_MainTable"
$tlp_MainTable.RowCount = 4
[void]$tlp_MainTable.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Absolute, 45)))
[void]$tlp_MainTable.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Absolute, 20)))
[void]$tlp_MainTable.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Percent, 100)))
[void]$tlp_MainTable.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Absolute, 75)))
$tlp_MainTable.Size = New-Object System.Drawing.Size(760, 530)
$tlp_MainTable.TabIndex = 0
#
#gb_ServiceType
$gb_ServiceType.Controls.Add($cb_AllTools)
$gb_ServiceType.Dock = [System.Windows.Forms.DockStyle]::Fill
$gb_ServiceType.Location = New-Object System.Drawing.Point(3, 3)
$gb_ServiceType.Name = "gb_ServiceType"
$gb_ServiceType.Size = New-Object System.Drawing.Size(554, 69)
$gb_ServiceType.TabIndex = 0
$gb_ServiceType.TabStop = $False
$gb_ServiceType.Text = "Install All Tools"
#
#cb_AllTools
$cb_AllTools.AutoSize = $True
$cb_AllTools.Location = New-Object System.Drawing.Point(6, 19)
$cb_AllTools.Name = "cb_AllTools"
$cb_AllTools.Size = New-Object System.Drawing.Size(110, 17)
$cb_AllTools.TabIndex = 0
$cb_AllTools.Text = "All Tools"
$cb_AllTools.UseVisualStyleBackColor = $True
#
#gb_IndividualTools
$gb_IndividualTools.Controls.Add($cb_SecureCRT)
$gb_IndividualTools.Controls.Add($cb_IEDebugTool)
$gb_IndividualTools.Controls.Add($cb_LDapBrowser)
$gb_IndividualTools.Controls.Add($cb_SoapUI)
$gb_IndividualTools.Controls.Add($cb_BeyondCompare)
$gb_IndividualTools.Controls.Add($cb_TextPad)
$gb_IndividualTools.Controls.Add($cb_WinSCP)
$gb_IndividualTools.Controls.Add($cb_ProcExp)
$gb_IndividualTools.Controls.Add($cb_PowerArchive)
$gb_IndividualTools.Controls.Add($cb_TcpView)
$gb_IndividualTools.Controls.Add($cb_CygWin)
$gb_IndividualTools.Controls.Add($cb_JRuler)
$gb_IndividualTools.Controls.Add($cb_ChainSaw)
$gb_IndividualTools.Controls.Add($cb_MQMonitor)
$gb_IndividualTools.Controls.Add($cb_CutePDF)
$gb_IndividualTools.Controls.Add($cb_JDGUI)
$gb_IndividualTools.Controls.Add($cb_SafariQT)
$gb_IndividualTools.Dock = [System.Windows.Forms.DockStyle]::Fill
$gb_IndividualTools.Location = New-Object System.Drawing.Point(3, 98)
$gb_IndividualTools.Name = "gb_IndividualTools"
$gb_IndividualTools.Size = New-Object System.Drawing.Size(554, 229)
$gb_IndividualTools.TabIndex = 1
$gb_IndividualTools.TabStop = $False
$gb_IndividualTools.Text = "Select Individual Tools To Install"
#
#lbl_or
$lbl_or.Anchor = [System.Windows.Forms.AnchorStyles]::Left
$lbl_or.AutoSize = $True
$lbl_or.Location = New-Object System.Drawing.Point(3, 78)
$lbl_or.Name = "lbl_or"
$lbl_or.Size = New-Object System.Drawing.Size(16, 13)
$lbl_or.TabIndex = 2
$lbl_or.Text = "or"
#
#cb_PowerArchive
$cb_PowerArchive.AutoSize = $True
$cb_PowerArchive.Location = New-Object System.Drawing.Point(6, 19)
$cb_PowerArchive.Name = "cb_PowerArchive"
$cb_PowerArchive.Size = New-Object System.Drawing.Size(125, 17)
$cb_PowerArchive.TabIndex = 0
$cb_PowerArchive.Text = "Power Archiver 2011"
$cb_PowerArchive.UseVisualStyleBackColor = $True
#
#cb_ProcExp
$cb_ProcExp.AutoSize = $True
$cb_ProcExp.Location = New-Object System.Drawing.Point(6, 42)
$cb_ProcExp.Name = "cb_ProcExp"
$cb_ProcExp.Size = New-Object System.Drawing.Size(135, 17)
$cb_ProcExp.TabIndex = 1
$cb_ProcExp.Text = "Process Explorer"
$cb_ProcExp.UseVisualStyleBackColor = $True
#
#cb_WinSCP
$cb_WinSCP.AutoSize = $True
$cb_WinSCP.Location = New-Object System.Drawing.Point(6, 65)
$cb_WinSCP.Name = "cb_WinSCP"
$cb_WinSCP.Size = New-Object System.Drawing.Size(93, 17)
$cb_WinSCP.TabIndex = 2
$cb_WinSCP.Text = "WinSCP"
$cb_WinSCP.UseVisualStyleBackColor = $True
#
#cb_TextPad
$cb_TextPad.AutoSize = $True
$cb_TextPad.Location = New-Object System.Drawing.Point(6, 88)
$cb_TextPad.Name = "cb_TextPad"
$cb_TextPad.Size = New-Object System.Drawing.Size(53, 17)
$cb_TextPad.TabIndex = 3
$cb_TextPad.Text = "TextPad 5"
$cb_TextPad.UseVisualStyleBackColor = $True
#
#cb_BeyondCompare
$cb_BeyondCompare.AutoSize = $True
$cb_BeyondCompare.Location = New-Object System.Drawing.Point(6, 112)
$cb_BeyondCompare.Name = "cb_BeyondCompare"
$cb_BeyondCompare.Size = New-Object System.Drawing.Size(116, 17)
$cb_BeyondCompare.TabIndex = 4
$cb_BeyondCompare.Text = "Beyond Compare 3"
$cb_BeyondCompare.UseVisualStyleBackColor = $True
#
#cb_SoapUI
$cb_SoapUI.AutoSize = $True
$cb_SoapUI.Location = New-Object System.Drawing.Point(6, 135)
$cb_SoapUI.Name = "cb_SoapUI"
$cb_SoapUI.Size = New-Object System.Drawing.Size(89, 17)
$cb_SoapUI.TabIndex = 5
$cb_SoapUI.Text = "SoapUI"
$cb_SoapUI.UseVisualStyleBackColor = $True
#
#cb_LDapBrowser
$cb_LDapBrowser.AutoSize = $True
$cb_LDapBrowser.Location = New-Object System.Drawing.Point(6, 159)
$cb_LDapBrowser.Name = "cb_LDapBrowser"
$cb_LDapBrowser.Size = New-Object System.Drawing.Size(93, 17)
$cb_LDapBrowser.TabIndex = 6
$cb_LDapBrowser.Text = "LDapBrowser"
$cb_LDapBrowser.UseVisualStyleBackColor = $True
#
#cb_IEDebugTool
$cb_IEDebugTool.AutoSize = $True
$cb_IEDebugTool.Location = New-Object System.Drawing.Point(6, 183)
$cb_IEDebugTool.Name = "cb_IEDebugTool"
$cb_IEDebugTool.Size = New-Object System.Drawing.Size(132, 17)
$cb_IEDebugTool.TabIndex = 7
$cb_IEDebugTool.Text = "IEDebugToolBar"
$cb_IEDebugTool.UseVisualStyleBackColor = $True
#
#cb_SecureCRT
$cb_SecureCRT.AutoSize = $True
$cb_SecureCRT.Location = New-Object System.Drawing.Point(6, 207)
$cb_SecureCRT.Name = "cb_SecureCRT"
$cb_SecureCRT.Size = New-Object System.Drawing.Size(109, 17)
$cb_SecureCRT.TabIndex = 8
$cb_SecureCRT.Text = "SecureCRT 6.7.1"
$cb_SecureCRT.UseVisualStyleBackColor = $True
#
#cb_TcpView
$cb_TcpView.AutoSize = $True
$cb_TcpView.Location = New-Object System.Drawing.Point(6, 231)
$cb_TcpView.Name = "cb_TcpView"
$cb_TcpView.Size = New-Object System.Drawing.Size(50, 17)
$cb_TcpView.TabIndex = 9
$cb_TcpView.Text = "TcpView"
$cb_TcpView.UseVisualStyleBackColor = $True
#
#cb_CygWin
$cb_CygWin.AutoSize = $True
$cb_CygWin.Location = New-Object System.Drawing.Point(6, 255)
$cb_CygWin.Name = "cb_CygWin"
$cb_CygWin.Size = New-Object System.Drawing.Size(135, 17)
$cb_CygWin.TabIndex = 10
$cb_CygWin.Text = "CygWin"
$cb_CygWin.UseVisualStyleBackColor = $True
#
#cb_JRuler
$cb_JRuler.AutoSize = $True
$cb_JRuler.Location = New-Object System.Drawing.Point(6, 279)
$cb_JRuler.Name = "cb_JRuler"
$cb_JRuler.Size = New-Object System.Drawing.Size(135, 17)
$cb_JRuler.TabIndex = 11
$cb_JRuler.Text = "JRuler"
$cb_JRuler.UseVisualStyleBackColor = $True
#
#cb_ChainSaw
$cb_ChainSaw.AutoSize = $True
$cb_ChainSaw.Location = New-Object System.Drawing.Point(6, 303)
$cb_ChainSaw.Name = "cb_ChainSaw"
$cb_ChainSaw.Size = New-Object System.Drawing.Size(135, 17)
$cb_ChainSaw.TabIndex = 12
$cb_ChainSaw.Text = "ChainSaw"
$cb_ChainSaw.UseVisualStyleBackColor = $True
#
#cb_MQMonitor
$cb_MQMonitor.AutoSize = $True
$cb_MQMonitor.Location = New-Object System.Drawing.Point(6, 327)
$cb_MQMonitor.Name = "cb_MQMonitor"
$cb_MQMonitor.Size = New-Object System.Drawing.Size(135, 17)
$cb_MQMonitor.TabIndex = 13
$cb_MQMonitor.Text = "MQMonitor"
$cb_MQMonitor.UseVisualStyleBackColor = $True
#
#cb_CutePDF
$cb_CutePDF.AutoSize = $True
$cb_CutePDF.Location = New-Object System.Drawing.Point(6, 351)
$cb_CutePDF.Name = "cb_CutePDF"
$cb_CutePDF.Size = New-Object System.Drawing.Size(135, 17)
$cb_CutePDF.TabIndex = 14
$cb_CutePDF.Text = "CutePDF"
$cb_CutePDF.UseVisualStyleBackColor = $True
#---------------------------------------------------------------#
# End Column One - Begin Column Two #
#---------------------------------------------------------------#
#cb_JD-GUI
$cb_JDGUI.AutoSize = $True
$cb_JDGUI.Location = New-Object System.Drawing.Point(305, 19)
$cb_JDGUI.Name = "cb_JDGUI"
$cb_JDGUI.Size = New-Object System.Drawing.Size(135, 17)
$cb_JDGUI.TabIndex = 15
$cb_JDGUI.Text = "JD-GUI"
$cb_JDGUI.UseVisualStyleBackColor = $True
#
#cb_SafariQT
$cb_SafariQT.AutoSize = $True
$cb_SafariQT.Location = New-Object System.Drawing.Point(305, 42)
$cb_SafariQT.Name = "cb_SafariQT"
$cb_SafariQT.Size = New-Object System.Drawing.Size(135, 17)
$cb_SafariQT.TabIndex = 15
$cb_SafariQT.Text = "Safari-QuickTime"
$cb_SafariQT.UseVisualStyleBackColor = $True
#---------------------------------------------------------------#
# End Column Two - #
#---------------------------------------------------------------#
#
#gb_Buttons
$gb_Buttons.Controls.Add($btn_OK)
$gb_Buttons.Controls.Add($btn_CANCEL)
$gb_Buttons.Dock = [System.Windows.Forms.DockStyle]::Fill
$gb_Buttons.Location = New-Object System.Drawing.Point(3, 98)
$gb_Buttons.Name = "gb_Buttons"
$gb_Buttons.Size = New-Object System.Drawing.Size(554, 69)
$gb_Buttons.TabIndex = 3
$gb_Buttons.TabStop = $False
#
#btn_OK
$btn_OK.Autosize = $True
$btn_OK.Location = New-Object System.Drawing.Size(540, 25)
$btn_OK.Name = "btn_OK"
$btn_OK.Size = New-Object System.Drawing.Size(75,23)
$btn_OK.TabIndex = 0
$btn_OK.Text = "OK"
$btn_OK.Add_Click({$x=$objChkBox.SelectedItem;$Form.Close()})
$btn_OK.UseVisualStyleBackColor = $True
#
#btn_CANCEL
$btn_CANCEL.Autosize = $True
$btn_CANCEL.Location = New-Object System.Drawing.Size(625, 25)
$btn_CANCEL.Name = "btn_CANCEL"
$btn_CANCEL.Size = New-Object System.Drawing.Size(75,23)
$btn_CANCEL.TabIndex = 1
$btn_CANCEL.Text = "CANCEL"
$btn_CANCEL.Add_Click({$x=$objChkBox.SelectedItem;$Form.Close()})
$btn_CANCEL.UseVisualStyleBackColor = $True
#
#Form
$Form.AutoScaleDimensions = New-Object System.Drawing.SizeF(6, 13)
$Form.AutoScaleMode = [System.Windows.Forms.AutoScaleMode]::Font
$Form.AutoSize = $True
$Form.ClientSize = New-Object System.Drawing.Size(760, 530)
$Form.Controls.Add($tlp_MainTable)
$Form.Name = "Form"
$Form.Text = "Developer Desktop Tool Selection"

########################################################
# Event Handler Functions
########################################################
Function cb_ServiceType_CheckedChanged{
param([object]$Sender, [System.EventArgs]$Arguments)

$IndividualTools = $gb_IndividualTools.Controls | ? {$_.GetType().Name -eq "CheckBox"}
$ServiceTypes = $gb_ServiceType.Controls | ? {$_.GetType().Name -eq "CheckBox"}
if ($Sender.Name -eq "cb_AllTools" -and $Sender.Checked){
$IndividualTools | % {$_.Checked = $False; $_.Enabled = $False}
}
else{
$ServiceTypes | % {$_.Enabled = $True}
$IndividualTools | % {$_.Enabled = $True}
}
}
########################################################
# Event Handler Definitions
########################################################
$cb_AllTools.Add_CheckedChanged({cb_ServiceType_CheckedChanged $this $_})
########################################################
# Final Layout of the form.
########################################################
$tlp_MainTable.ResumeLayout($False)
$tlp_MainTable.PerformLayout()
$gb_ServiceType.ResumeLayout($False)
$gb_ServiceType.PerformLayout()
$gb_IndividualTools.ResumeLayout($False)
$gb_IndividualTools.PerformLayout()
$Form.ResumeLayout($False)

[void]$Form.ShowDialog()
User avatar
davidc
Posts: 5913
Last visit: Mon Jul 08, 2019 8:55 am
Been upvoted: 2 times

Re: Validating a checked box and then running code

Post by davidc »

I recommend reading the Spotlight on the CheckBox control:

http://www.sapien.com/blog/2011/06/29/p ... x-control/

This article may help as well:

http://www.sapien.com/blog/2013/02/12/p ... -controls/

Note: When you use the CheckChanged event you don't have to change the true / false values. The control handles that already.

Just out curiosity are you writing this by hand? Is this a converted C# code?


David
David
SAPIEN Technologies, Inc.
User avatar
BCBSSC
Posts: 6
Last visit: Tue Jun 16, 2015 12:37 pm

Re: Validating a checked box and then running code

Post by BCBSSC »

I pulled a sample of checkbox form code from the internet and then built upon it by hand. It's just the easiest way for me to learn how to write new code. I'm just stuck at what I would have to do once a box is checked in order to execute the code to install the selected software. Steps would be;

1. check appropriate box(es)
2. Click "OK"
3. code would begin the installation of selected software.
User avatar
davidc
Posts: 5913
Last visit: Mon Jul 08, 2019 8:55 am
Been upvoted: 2 times

Re: Validating a checked box and then running code

Post by davidc »

In this case you only need to handle the OK button's click event:
PowerShell Code
Double-click the code block to select all.
$buttonOK_Click={

	if($checkBox1.Checked)
	{
		#perform scripts 1	
	}
	
	if($checkBox2.Checked)
	{
		#perform script 2	
	}
}
FYI SAPIEN offers tools to create GUIs in Powershell and it will save you time.

PrimalFormsCE is free and you can use it to generate your GUI code. It can be found in the downloads section.

SAPIEN does offer a paided product (PowerShell Studio) which makes GUI editing a lot easier and faster. PowerShell Studio also allows you to package your GUI scripts into an exe.
David
SAPIEN Technologies, Inc.
User avatar
BCBSSC
Posts: 6
Last visit: Tue Jun 16, 2015 12:37 pm

Re: Validating a checked box and then running code

Post by BCBSSC »

I appreciate the help on this. I was thinking I'd have to validate the different checkboxes before even beginning to look at the "OK" button.

I've looked at Sapiens software and I'll probably eventually use it. Right now though, actually having to write the code by hand helps me to better understand what is going on as I learn Powershell. Once I have a better graps of it, then I'll switch so a tool to help make it easier and more efficient.
User avatar
davidc
Posts: 5913
Last visit: Mon Jul 08, 2019 8:55 am
Been upvoted: 2 times

Re: Validating a checked box and then running code

Post by davidc »

No problem. There is no obligation; I just wanted to make sure you are aware that you don't always have to do this by hand :).

I'm happy to help.

David
David
SAPIEN Technologies, Inc.
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Validating a checked box and then running code

Post by jvierra »

Here are some suggestions for using checkboxes.

1. Place check boxes in a FlowLayoutPanel. This will automatically maintain the list even if it is changed dynamically.

2. When selecting 'All Tools' just check all existing checkboxes and uncheck when un-checking 'All Tools'

3. Dynamically generate checkboxes from a list or from a file.

4. Use Tag property to store code that installs software or text that is used to option installer.

I am attaching two file that demonstrate in very few lines of code how to do this. On is a PS1 which you can execute and inspect. The other is a PFF file of teh project that generates the PS1. I am uploading this one for David as he may want to take it as a suggestion for a new blog on FlowLayout and auto-generation of options.

The ListView control can also be used to do this very similar thing but is harder to use.

The file is a ZIP and contains both the PS1 and the ZIP file.
Attachments
Demo-CheckBoxFlow.zip
(8.86 KiB) Downloaded 698 times
User avatar
davidc
Posts: 5913
Last visit: Mon Jul 08, 2019 8:55 am
Been upvoted: 2 times

Re: Validating a checked box and then running code

Post by davidc »

Yes FlowLayoutPanel is good for dynamic controls. Another alternative is to use the CheckedListBox control.
PowerShell Code
Double-click the code block to select all.
$buttonLoadOptions_Click={
    for($i=1;$i -lt 20; $i++)
	{
        $checkedlistbox1.Items.Add('Install option ' + $i)
	}
   
	$checkboxCheckUncheckAll.Enabled = $true
}

$checkboxCheckUncheckAll_CheckedChanged={
#0..($checkedlistbox1.Items.Count-1) | %{ $checkedlistbox1.SetItemChecked($_, $this.Checked) }
#or
	for ($x = 0; $x -lt $checkedlistbox1.Items.Count; $x++)
	{
	   $checkedlistbox1.SetItemChecked($x, $this.Checked);
	}
}
David
David
SAPIEN Technologies, Inc.
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Validating a checked box and then running code

Post by jvierra »

Yes - checkedListBox is very good if you want scrollable list. For some things it is better. For the original OP example the FlowPanel may be an easier method but that is up to the end user and the overall project I suppose.


This is why learning all of the main controls is so important. It can save many hours of frustration. The blog posts are very useful for learning the controls.
User avatar
BCBSSC
Posts: 6
Last visit: Tue Jun 16, 2015 12:37 pm

Re: Validating a checked box and then running code

Post by BCBSSC »

Thanks for all the input guys. I definitely took some of the advice to heart and I have it all working now.
This topic is 11 years and 2 weeks old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked