Jump to content

Select LV item by LV item ID


Recommended Posts

Hi -

How to select a LV item by using a LV item control ID (-- meaning NOT a LV item index! --). This - obvious - won't work (logic only):

$iID = GUICtrlCreateListViewItem("test1|test2", $iLV)

_GUICtrlListView_EnsureVisible($iLV, $iID)
_GUICtrlListView_SetItemSelected($iLV, $iID)
_GUICtrlListView_SetItemFocused($iLV, $iID)

Can a LV item index be retrieved by its item ID?

I have a sortable LV (50+ columns, 150+ rows) and like to select LV items (after search for a specific item). Using _GUICtrlListView_FindInText() takes too much time. But I have LV item IDs already.

Edited by supersonic
Link to comment
Share on other sites

The item-ID will stored as item param. You can ask for this by using the item index.

ListView_Get_Item_Param()

Func ListView_Get_Item_Param()
    Local $hGUI, $hListView

    $hGUI = GUICreate("ListView Get Item Param", 400, 300)
    $hListView = GUICtrlCreateListView("Column 1|Column 2", 2, 2, 394, 268)
    GUISetState(@SW_SHOW)


    ; Add items
    Local $ID1, $ID2, $ID3
    $ID1 = GUICtrlCreateListViewItem('Item-1|Item-1.1', $hListview)
    $ID2 = GUICtrlCreateListViewItem('Item-2|Item-2.1', $hListview)
    $ID3 = GUICtrlCreateListViewItem('Item-3|Item-3.1', $hListview)
    ConsoleWrite('ID Item-1: ' & $ID1 & @CRLF)
    ConsoleWrite('ID Item-2: ' & $ID2 & @CRLF)
    ConsoleWrite('ID Item-3: ' & $ID3 & @CRLF)

    ; Get ID from item parameter by item index
    ConsoleWrite('Item-param-1: ' & _GUICtrlListView_GetItemParam($hListView, 0) & @CRLF)
    ConsoleWrite('Item-param-2: ' & _GUICtrlListView_GetItemParam($hListView, 1) & @CRLF)
    ConsoleWrite('Item-param-3: ' & _GUICtrlListView_GetItemParam($hListView, 2) & @CRLF)

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
EndFunc

But please note that the ID will only be saved as param if the listview item is created with the function GUICtrlCreateListViewItem!

Edited by BugFix

Best Regards BugFix  

Link to comment
Share on other sites

@BugFix - Thank you. Regarding to your example (as is): If $ID3 = 6 Then _GUICtrlListView_SetItemSelected($hListview, $ID3) won't work. There is no LV index with a value of 6. I need something like _GUICtrlListView_GetItemIndexByItemID($hListview, $ID3). Using _GUICtrlListView_SetItemParam/_GUICtrlListView_GetItemParam won't help because after LV is sorted (whatever column/direction) there's no 1 to 1 relationship any longer...

Any help still appreciated :)

Link to comment
Share on other sites

OK, there exists since many, many years the bug, that the SimpleSort function NOT sorts the item param too. But with sort callback it works:

Global $hListView

ListView_Get_Item_Param()

Func ListView_Get_Item_Param()
    Local $hGUI

    $hGUI = GUICreate("ListView Get Item Param", 400, 300)
    $hListView = GUICtrlCreateListView("Column 1|Column 2", 2, 2, 394, 268, $LVS_SORTASCENDING)
    GUISetState(@SW_SHOW)

    _GUICtrlListView_RegisterSortCallBack($hListView)
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

    ; Add items
    Local $ID1, $ID2, $ID3
    $ID1 = GUICtrlCreateListViewItem('B|B.1', $hListview)
    $ID2 = GUICtrlCreateListViewItem('C|C.1', $hListview)
    $ID3 = GUICtrlCreateListViewItem('A|A.1', $hListview)
    ConsoleWrite('ID Item-A: ' & $ID3 & @CRLF)
    ConsoleWrite('ID Item-B: ' & $ID1 & @CRLF)
    ConsoleWrite('ID Item-C: ' & $ID2 & @CRLF)

    ; Get ID from item parameter by item index
;~  ConsoleWrite('Item-param-Index 0 [' & _GUICtrlListView_GetItemText($hListView, 0) & ']: ' & _GUICtrlListView_GetItemParam($hListView, 0) & @CRLF)
;~  ConsoleWrite('Item-param-Index 1 [' & _GUICtrlListView_GetItemText($hListView, 1) & ']: ' & _GUICtrlListView_GetItemParam($hListView, 1) & @CRLF)
;~  ConsoleWrite('Item-param-Index 2 [' & _GUICtrlListView_GetItemText($hListView, 2) & ']: ' & _GUICtrlListView_GetItemParam($hListView, 2) & @CRLF)

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    _GUICtrlListView_UnRegisterSortCallBack($hListView)
    GUIDelete()
EndFunc

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndListView
            Switch $iCode
                Case $LVN_COLUMNCLICK ; A column was clicked
                    _GUICtrlListView_SortItems($hWndListView, 0)
                Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
                    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                    Local $iIndex = DllStructGetData($tInfo, "Index")
                    ConsoleWrite('Clicked Index: ' & $iIndex & ' [' & _GUICtrlListView_GetItemText($hWndListView, $iIndex) & '], ID: ' & _GUICtrlListView_GetItemParam($hWndListView, $iIndex) & @CRLF)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

 

Or you use my modified version for simple sort, it sorts the param too.

Func __GUICtrlListView_SimpleSort($hWnd, ByRef $vDescending, $iCol) ; modified to sort also IParam
    Local $x, $Y, $Z, $b_desc, $columns, $items, $v_item, $temp_item, $iFocused = -1
    Local $SeparatorChar = Opt('GUIDataSeparatorChar')
    If _GUICtrlListView_GetItemCount($hWnd) Then
        If (IsArray($vDescending)) Then
            $b_desc = $vDescending[$iCol]
        Else
            $b_desc = $vDescending
        EndIf
        $columns = _GUICtrlListView_GetColumnCount($hWnd)
        $items = _GUICtrlListView_GetItemCount($hWnd)
        For $x = 1 To $columns
            $temp_item = $temp_item & " " & $SeparatorChar
        Next
        $temp_item = StringTrimRight($temp_item, 1)
        Local $a_lv[$items][$columns + 2], $i_selected ; add column for IParam  ### MODIFIED ###

        $i_selected = StringSplit(_GUICtrlListView_GetSelectedIndices($hWnd), $SeparatorChar)
        For $x = 0 To UBound($a_lv) - 1 Step 1
            If $iFocused = -1 Then
                If _GUICtrlListView_GetItemFocused($hWnd, $x) Then $iFocused = $x
            EndIf
            _GUICtrlListView_SetItemSelected($hWnd, $x, False)
            For $Y = 0 To UBound($a_lv, 2) - 3 Step 1  ;  ### MODIFIED ###
                $v_item = StringStripWS(_GUICtrlListView_GetItemText($hWnd, $x, $Y), 2)
                If (StringIsFloat($v_item) Or StringIsInt($v_item)) Then
                    $a_lv[$x][$Y] = Number($v_item)
                Else
                    $a_lv[$x][$Y] = $v_item
                EndIf
            Next
            $a_lv[$x][$Y] = $x
            $a_lv[$x][$Y+1] = _GUICtrlListView_GetItemParam($hWnd, $x)  ;  ### NEW ###
        Next
        _ArraySort($a_lv, $b_desc, 0, 0, $iCol)
        For $x = 0 To UBound($a_lv) - 1 Step 1
            For $Y = 0 To UBound($a_lv, 2) - 3 Step 1  ;  ### MODIFIED ###
                _GUICtrlListView_SetItemText($hWnd, $x, $a_lv[$x][$Y], $Y)
            Next
            _GUICtrlListView_SetItemParam($hWnd, $x, $a_lv[$x][$Y+1])  ;  ### NEW ###
            For $Z = 1 To $i_selected[0]
                If $a_lv[$x][UBound($a_lv, 2) - 2] = $i_selected[$Z] Then  ;  ### MODIFIED ###
                    If $a_lv[$x][UBound($a_lv, 2) - 2] = $iFocused Then  ;  ### MODIFIED ###
                        _GUICtrlListView_SetItemSelected($hWnd, $x, True, True)
                    Else
                        _GUICtrlListView_SetItemSelected($hWnd, $x, True)
                    EndIf
                    ExitLoop
                EndIf
            Next
        Next
        If (IsArray($vDescending)) Then
            $vDescending[$iCol] = Not $b_desc
        Else
            $vDescending = Not $b_desc
        EndIf
    EndIf
EndFunc   ;==>__GUICtrlListView_SimpleSort

 

EDIT:

Here is an full working example, that exactly does, what you want:

Global $hListView

ListView_Get_Item_Param()

Func ListView_Get_Item_Param()
    Local $hGUI

    $hGUI = GUICreate("ListView Get Item Param", 400, 300)
    GUICtrlCreateLabel('Sort by column click', 10, 50)
    GUICtrlCreateLabel('List of Ctrl-ID', 10, 13, 75)
    Local $combo = GUICtrlCreateCombo('', 85, 10, 60)
    Local $select = GUICtrlCreateButton('Select ID in listview', 165, 10, 120, 22)
    $hListView = GUICtrlCreateListView("Column 1|Column 2", 2, 72, 394, 218, $LVS_SORTASCENDING, $LVS_EX_FULLROWSELECT)
    Local $sCombo = StringFormat('%s|%s|%s', $hListview +1, $hListview +2, $hListview +3)
    GUICtrlSetData($combo, $sCombo)
    GUISetState(@SW_SHOW)

    _GUICtrlListView_RegisterSortCallBack($hListView)
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

    ; Add items
    Local $aID[3]
    $aID[0] = GUICtrlCreateListViewItem('B|B.1  [ID '& $hListview + 1 &']', $hListview)
    $aID[1] = GUICtrlCreateListViewItem('C|C.1  [ID '& $hListview + 2 &']', $hListview)
    $aID[2] = GUICtrlCreateListViewItem('A|A.1  [ID '& $hListview + 3 &']', $hListview)

    While 1
        Switch GUIGetMsg()
            Case $select
                _GuiCtrlListview_SelectByID($hListView, GUICtrlRead($combo))
                ControlFocus($hGui, '', $hListView)
            Case $GUI_EVENT_CLOSE
                _GUICtrlListView_UnRegisterSortCallBack($hListView)
                GUIDelete()
                Exit
        EndSwitch
    WEnd
EndFunc

Func _GuiCtrlListview_SelectByID($hWnd, $ID)
    ; unselect all item
    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) -1
        _GUICtrlListView_SetItemSelected($hWnd, $i, False)
    Next
    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) -1
        If _GUICtrlListView_GetItemParam($hWnd, $i) = $ID Then
            _GUICtrlListView_SetItemSelected($hWnd, $i, True)
            ExitLoop
        EndIf
    Next
EndFunc


Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndListView
            Switch $iCode
                Case $LVN_COLUMNCLICK ; A column was clicked
                    _GUICtrlListView_SortItems($hWndListView, 0)
                Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
                    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                    Local $iIndex = DllStructGetData($tInfo, "Index")
                    ConsoleWrite('Clicked Index: ' & $iIndex & ' [' & _GUICtrlListView_GetItemText($hWndListView, $iIndex) & '], ID: ' & _GUICtrlListView_GetItemParam($hWndListView, $iIndex) & @CRLF)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

 

Edited by BugFix

Best Regards BugFix  

Link to comment
Share on other sites

@BugFix: Many thanks for your examples! I ended up using a modified version of _GuiCtrlListview_SelectByID provided in your last example. And it is fast enough - even if handling a larger LV (60+ columns, 1000+ rows).

Initially I hoped there is a structure (or whatever magical function I missed until now) which can be feeded by a LV item ID to return the current/real position (= index) of a LV item. Looping through a LV is OK (~ somehow practical)...

Thanks again!
 

Edited by supersonic
Link to comment
Share on other sites

1 hour ago, supersonic said:

@BugFix: Your modified _GUICtrlListView_SimpleSort is useful too. I'm not sure if this is a bug but a worthwhile enhancement. Did you opened a feature request? Is this issue already discussed in this forum?

My feature request was rejected without giving reasons.

Best Regards BugFix  

Link to comment
Share on other sites

On 2/1/2019 at 4:29 AM, BugFix said:

was rejected without giving reasons.

There was a reason, you never explained what your code modification was doing, or how it improved the function. It was also 8 years ago during which time you were free to add to the bug fix report with more information which you never did.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

18 hours ago, BrewManNH said:

with more information which you never did.

Really?! What more information you need as: _GUICtrlListView_SimpleSort doesn't sort ItemParam

Quote

you never explained what your code modification was doing, or how it improved the function.

Sometimes, it helps to read the feature request. There I wrote: "I've changed this function, so that it also sort ItemParam."

Best Regards BugFix  

Link to comment
Share on other sites

  • Moderators

BugFix,

Your modified code posted above is not based on the current version of the SimpleSort function - which looks to me as if it should correctly reset the ItemParam value when rewriting the ListView contents. However, testing shows that although the function appears to correctly set the ItemParam value within the function, it most definitely does not return the same value when asked in the main script!

Could you please take a look at the example script below (which actually uses the slightly changed SVN version of the function) and see if you can spot where the problem lies - I have been playing with the code for a while and it has me beaten:

#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

Global $aSortSense[] = [0]
Global $cItem_3

$hGUI = GUICreate("Test", 500, 500)

$cLV = GUICtrlCreateListView("Sortable Value|Initial CID|Init Param|Post Sort", 10, 10, 400, 300)

$cButton = GUICtrlCreateButton("Sort", 10, 450, 80, 30)

$cStart = GUICtrlCreateDummy()

For $i = 0 To 9
    $cLVI_CID = GUICtrlCreateListViewItem(Random(1, 9, 1) & "|", $cLV)
    $iParam = _GUICtrlListView_GetItemParam($cLV, $i)
    GUICtrlSetData($cLVI_CID, "|" & $cLVI_CID & "|" & $iParam)
    If $i = 3 Then
        $cItem_3 = $cLVI_CID
    EndIf
Next

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $cButton
            ConsoleWrite("Before: " & GUICtrlRead($cItem_3) & @CRLF)
            _GUICtrlListView_SimpleSort_SVN($cLV, $aSortSense, 0)
            For $i = 0 To 9
                $iParam = _GUICtrlListView_GetItemParam($cLV, $i)
                GUICtrlSetData($cStart + 1 + $i, "|||" & $iParam)
            Next
            ConsoleWrite("After : " & GUICtrlRead($cItem_3) & @CRLF)
    EndSwitch

WEnd

Func _GUICtrlListView_SimpleSort_SVN($hWnd, ByRef $vSortSense, $iCol, $bToggleSense = True)
    Local $iItemCount = _GUICtrlListView_GetItemCount($hWnd)
    If $iItemCount Then
        Local $iDescending = 0
        If UBound($vSortSense) Then
            $iDescending = $vSortSense[$iCol]
        Else
            $iDescending = $vSortSense
        EndIf
        Local $vSeparatorChar = Opt('GUIDataSeparatorChar')
        Local $iColumnCount = _GUICtrlListView_GetColumnCount($hWnd)
        Local Enum $iIndexValue = $iColumnCount, $iItemParam ; Additional columns for the index value and ItemParam
        Local $aListViewItems[$iItemCount][$iColumnCount + 2]

        Local $sSelectedItems = _GUICtrlListView_GetSelectedIndices($hWnd)
        Local $aSelectedItems[1] = [0] ; No selection
        If Not $sSelectedItems = "" Then $aSelectedItems = StringSplit($sSelectedItems, $vSeparatorChar)

        Local $aCheckedItems = __GUICtrlListView_GetCheckedIndices($hWnd)
        Local $sItemText, $iFocused = -1
        For $i = 0 To $iItemCount - 1 ; Rows
            If $iFocused = -1 Then
                If _GUICtrlListView_GetItemFocused($hWnd, $i) Then $iFocused = $i
            EndIf
            _GUICtrlListView_SetItemSelected($hWnd, $i, False)
            _GUICtrlListView_SetItemChecked($hWnd, $i, False)
            For $j = 0 To $iColumnCount - 1 ; Columns
                $sItemText = StringStripWS(_GUICtrlListView_GetItemText($hWnd, $i, $j), $STR_STRIPTRAILING)
                If (StringIsFloat($sItemText) Or StringIsInt($sItemText)) Then
                    $aListViewItems[$i][$j] = Number($sItemText)
                Else
                    $aListViewItems[$i][$j] = $sItemText
                EndIf
            Next
            $aListViewItems[$i][$iIndexValue] = $i ; Index value
            $aListViewItems[$i][$iItemParam] = _GUICtrlListView_GetItemParam($hWnd, $i) ; ItemParam
        Next

        ; Sort the ListView array
        _ArraySort($aListViewItems, $iDescending, 0, 0, $iCol)

        For $i = 0 To $iItemCount - 1 ; Rows
            For $j = 0 To $iColumnCount - 1 ; Columns
                _GUICtrlListView_SetItemText($hWnd, $i, $aListViewItems[$i][$j], $j)
            Next

            _GUICtrlListView_SetItemParam($hWnd, $i, $aListViewItems[$i][$iItemParam]) ; ItemParam

            For $j = 1 To $aSelectedItems[0]
                If $aListViewItems[$i][$iIndexValue] = $aSelectedItems[$j] Then
                    If $aListViewItems[$i][$iIndexValue] = $iFocused Then
                        _GUICtrlListView_SetItemSelected($hWnd, $i, True, True)
                    Else
                        _GUICtrlListView_SetItemSelected($hWnd, $i, True)
                    EndIf
                    ExitLoop
                EndIf
            Next
            For $j = 1 To $aCheckedItems[0]
                If $aListViewItems[$i][$iIndexValue] = $aCheckedItems[$j] Then
                    _GUICtrlListView_SetItemChecked($hWnd, $i, True)
                    ExitLoop
                EndIf
            Next
        Next
        If $bToggleSense Then ; Automatic sort sense toggle
            If UBound($vSortSense) Then
                $vSortSense[$iCol] = Not $iDescending
            Else
                $vSortSense = Not $iDescending
            EndIf
        EndIf
    EndIf
EndFunc   ;==>_GUICtrlListView_SimpleSort_SVN

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

@Melba23

Oh, you're right. 

I've overseen, that the issue was already fixed 2.5 years after rejecting my request. But after that time I did not really reckon with a renewed interest in the problem and did not pursue the story any further. I hope you can forgive my impatience.

Best Regards BugFix  

Link to comment
Share on other sites

  • Moderators

BugFix,

No problem.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...