CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Jan 2008
    Location
    India
    Posts
    408

    ListControl Password Field

    Hello, I am using CListCtrl in report view. I need to display the text in a column as a series of astrerisks (for password field). Is this possible to achieve? How can I do that? Thanks.
    Rate the posts which you find useful

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,398

    Re: ListControl Password Field

    Code:
    int iItem = ...;
    iint iSubItem = ...;
    c_ListCtrl.SetItemText(iIte, iSubItem, _T("******"));
    Victor Nijegorodov

  3. #3
    Join Date
    Jan 2008
    Location
    India
    Posts
    408

    Re: ListControl Password Field

    Quote Originally Posted by VictorN View Post
    Code:
    int iItem = ...;
    iint iSubItem = ...;
    c_ListCtrl.SetItemText(iIte, iSubItem, _T("******"));
    Thanks Victor. I'm afraid I cannot go for this solution. Because, I have to populate the list control. The user would change the data and I have to read the text back from the list control. I cannot achieve that from this method, right?
    Rate the posts which you find useful

  4. #4
    Join Date
    Sep 2004
    Location
    Holland (land of the dope)
    Posts
    4,123

    Re: ListControl Password Field

    The user would change the data and I have to read the text back from the list control. I cannot achieve that from this method, right?
    You could store the actual password inside each node with SetItemData.

  5. #5
    Join Date
    Jan 2008
    Location
    India
    Posts
    408

    Re: ListControl Password Field

    Quote Originally Posted by Skizmo View Post
    You could store the actual password inside each node with SetItemData.
    Yes. I have been doing this actually. But I'm facing a problem now. The data is actually string (passwords with leading zeroes). Can I convert this CString object to DWORD (argument for SetItemData) and retrieve it back without loss of the leading zeroes?
    Rate the posts which you find useful

  6. #6
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,398

    Re: ListControl Password Field

    You could either save real passwords in an additional list/array/... (CStringList, CStrinfArray, ...)
    or you could use list control item data like:
    Code:
    int iItem = ...;
    iint iSubItem = ...;
    ...
    CString strPass = ....;// get password;
    c_ListCtrl.SetItemText(iIte, iSubItem, _T("******"));  // set masked text
    //  save password
    CString * pstrPass = new CString(strPass);
    // save pointer as item data
    c_ListCtrl.SetItemData(iItem, (DWORD)pstrPass);
    Victor Nijegorodov

  7. #7
    Join Date
    Jan 2008
    Location
    India
    Posts
    408

    Re: ListControl Password Field

    OK. Let me try! Thanks!
    Rate the posts which you find useful

  8. #8
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,398

    Re: ListControl Password Field

    ajbharani!
    If you will use SetItemData then don't forget to delete each dynamically created CString with password before deleting corresponding list control item.
    Victor Nijegorodov

  9. #9
    Join Date
    Jan 2008
    Location
    India
    Posts
    408

    Re: ListControl Password Field

    Ya.. ok
    Rate the posts which you find useful

  10. #10
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: ListControl Password Field

    Another option is the use a 'virtual' list view control.

    With this approach, the list view control is 'bound' to a list of it's data.

    This differs from a normal list view control, where data is copied into the control.

    See the LVSelState.zip file in this reply for a code samples: http://www.codeguru.com/forum/showthread.php?t=441094

    Now you may ask what benefit does this approach offer your particular problem of displaying password ****, but still retain the underlying data?

    Well, in a virtual listview, when an lvitem needs to display data, it asks the underlying data item for the data. It does this through the LVN_GETDISPINFO notification message. The virtual list view (when in report style) sends this message for each item and each column within the item. If you use the SetItemDataPtr when you add an item to the virtual list view, it becomes a simple matter to retrieve that data item attached to the item:

    Code:
    void CLVSelStateDlg::OnLvnGetdispinfoList(NMHDR *pNMHDR, LRESULT *pResult)
    {
        NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
    
        // Get the list control item
        LVITEM* pItem = &(pDispInfo)->item;
    
        // Retrieve the CLVItemData object associated with this item
        CLVItemData* pLVItemData = reinterpret_cast<CLVItemData*>(pItem->lParam);
    
        if( NULL != pLVItemData )
        {
            // Let the item method fill out the display data 
            pLVItemData->GetListViewItemInfo( pItem );
        }
    
        *pResult = 0;
    }
    In the code above, the CLVItemData object is a class that holds the data that represents each lv item. We simple retrieve the CLVItemData* that was attached to the item when we populated the control (via SetItemDataPtr).

    Once we have the pointer to the data, we call a method that actually sets the visible list view item/column data. This is where things get interesting because for the password hiding, the underlying data can be the true password, but it is a simple matter to return "****" for display purposed when the appropriate column is requested.

    For example, let me use the sample code but modify it for a password.
    Say Column0 is the name, Column1 is the masked pw, and Column2 is the real password.

    Code:
    void GetListViewItemInfo( LPLVITEM pItem )
    {
      if ((pItem->mask & LVIF_TEXT) == LVIF_TEXT) 
      {
        switch( pItem->iSubItem )
        {
        case LVID_COLUMN_ZERO:
          StringCchCopy( pItem->pszText, MAX_LVITEMLEN, m_sName );
          break;
        case LVID_COLUMN_ONE:
          StringCchCopy( pItem->pszText, MAX_LVITEMLEN, _T("********") );
          break;
        case LVID_COLUMN_TWO: 
          StringCchCopy( pItem->pszText, MAX_LVITEMLEN, m_sPassword );
          break;
        default:
          ASSERT( 0 );
          TRACE( _T("Invalid Column Index in CLVItemData::GetListViewString() - %d\n"), pItem->iSubItem );
        }
      }
    }
    So that's how easy it is.

    Note: StringCchCopy is an older method that performs a safe string copy. It's found in strsafe.h. You can just replace it with a std lib safe string equivalent.

    For completeness, here's a modified version of the code that walks through a std::vector and 'adds' each vector item to the virtual list view.

    Code:
    // Cycle through the list and add each item into the list control
    for(CLVItemDataList::iterator it = m_LVItemDataList.begin();
                    it < m_LVItemDataList.end();
                    it++)
    {
        CLVItemData* pLVItemData = (*it);
        lvitem.iItem        = iItem;
        lvitem.iSubItem     = 0;
        lvitem.lParam		= reinterpret_cast<LPARAM>(pLVItemData);
    
        // Tell the list control to become 'Virtual' and request display
        // data from the lvitem.lParam.
        // See CLVSelStateDlg::OnLvnGetdispinfoList for where this happens
        lvitem.iImage       = I_IMAGECALLBACK;
        lvitem.pszText		= LPSTR_TEXTCALLBACK;
        lvitem.cchTextMax	= MAX_LVITEMLEN;
    
        // Insert the item
        ctlList.InsertItem(&lvitem);
    
        // Set the text for each column (all virtual callbacks)
        ctlList.SetItemText(iItem, 0, LPSTR_TEXTCALLBACK);
        ctlList.SetItemText(iItem, 1, LPSTR_TEXTCALLBACK);
        ctlList.SetItemText(iItem, 2, LPSTR_TEXTCALLBACK);
    
        iItem++;
    }

Posting Permissions

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





Click Here to Expand Forum to Full Width

Featured