CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Nov 2012
    Posts
    21

    List Control Column data

    Im trying to populate a list control with the filename and maybe some other thing when i push the OK button

    here is my code
    Code:
    void CThisDlg::OnOK() 
    {
    
     int iItem = 0, iActualItem = 0;
    
    		HANDLE hFind;
    WIN32_FIND_DATA data2;
    
    int iNum = 0;
    hFind = FindFirstFile("*.*", &data2);
    
    if (hFind != INVALID_HANDLE_VALUE) {
    	while (FindNextFile(hFind, &data2)){
    if ( data2.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE )
    {
              
        testing *node = new testing();
    
    node->strFileName = data2.cFileName;  
    
    
        LV_ITEM lvi;
        lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; 
        lvi.iItem = iNum; 
        lvi.iSubItem = 0; 
    	lvi.iImage = I_IMAGECALLBACK;
        lvi.pszText = LPSTR_TEXTCALLBACK; 
        lvi.lParam = reinterpret_cast<LPARAM>(node);
    	lvi.cchTextMax	= MAX_LVITEMLEN;
        m_list.InsertItem(&lvi);
        m_list.SetItemText(iItem, 0, LPSTR_TEXTCALLBACK);
    
    
    	iNum++;
    }
    
    	}
    }
     
    }
    When i push ok, no files get loaded. I also attached a image
    Attached Images Attached Images  

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

    Re: List Control Column data

    Rather than attach an image you should have better debugged your code to see what, where and why goes wrong or at least unexpected!
    Second note: despite you put your code between the Code tags it is not so easy to read/understand. It is just because of inproper code indentations!

    Besides, I don't see any need to use
    Code:
      testing *node = new testing();
    here.
    Why not lust create it on the stack?
    Code:
    testing node;
    node.strFileName = data2.cFileName;
    Victor Nijegorodov

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

    Re: List Control Column data

    Quote Originally Posted by terryeverlast View Post
    Im trying to populate a list control with the filename and maybe some other thing when i push the OK button

    here is my code
    Code:
        ...
        LV_ITEM lvi;
        lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; 
        lvi.iItem = iNum; 
        lvi.iSubItem = 0; 
    	lvi.iImage = I_IMAGECALLBACK;
        lvi.pszText = LPSTR_TEXTCALLBACK;
    You are using LPSTR_TEXTCALLBACK flag... But do you handle the LVN_GETDISPINFO notification? And if you do then how?
    Victor Nijegorodov

  4. #4
    Join Date
    Nov 2012
    Posts
    21

    Re: List Control Column data

    Ok i see. I need to also handle LVN_GETDISPINFO in the message maps with ON_NOTIFY and form the columns in a switch statment

  5. #5
    Join Date
    Nov 2012
    Posts
    21

    Re: List Control Column data

    0k i handled the LVN_GETDISPINFO with this code

    Code:
    void CThisDlg::OnGetdispinfoList1(NMHDR* pNMHDR, LRESULT* pResult) 
    {
    	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
     if(pDispInfo->item.mask & LVIF_TEXT) 
    	{
    		testing* node =(testing*) pDispInfo->item.lParam;
    
            switch(pDispInfo->item.iSubItem) 
    		{
            case 0: // File name
                ::lstrcpy(pDispInfo->item.pszText, node->strFileName);
                break;
    
        
            }
        }
    
       
    
    	
    	*pResult = 0;
    }

    the whole program freezes up and gives me debug..so i debuged and got this line

    lstrcpy(pDispInfo->item.pszText, node->strFileName); <---the error

  6. #6
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: List Control Column data

    pDispInfo->item.pszText needs to be a pointer to the text. You don't copy the text itself - you just set pszText to point to the start of the text to be stored. I don't know the structure of testing but try pDispInfo->item.pszText = node->strFileName;

  7. #7
    Join Date
    Nov 2012
    Posts
    21

    Re: List Control Column data

    Still got a problem..now is is this line of code

    Code:
    lvi.lParam = (LPARAM)node;
    which gives me the error
    error C2440: 'type cast' : cannot convert from 'struct testing' to 'long'
    No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called


    oh yea..i created my structure like here
    Code:
    struct testing
    {
    	char* strFileName; 
    
    };

  8. #8
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: List Control Column data

    As node is now an auto structure on the stack its address can't be used as an element of lvi as the address will be invalid when OnGetdispinfoList1 is called. A quick and dirty workaround for this is to make node static and then pass its addess to lvi

    Code:
    static testing node;
    ...
    lvi.lParam = (LPARAM)&node;
    Note by making it static there are threading issues if multiple threads are used.

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

    Re: List Control Column data

    Perhaps, it was my bad: I missed the line where you assign
    Code:
    lvi.lParam = reinterpret_cast<LPARAM>(node);
    I such a case you have to use what you did:
    Code:
     testing *node = new testing();
    So, I am sorry!
    Victor Nijegorodov

  10. #10
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: List Control Column data

    If you allocate memory for node on the heap by using new, then you will need to deallocate that memory once you are finished with it using delete otherwise you will have a memory leak.

  11. #11
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: List Control Column data

    Looking back at your original code, you're got another problem.

    Code:
    struct testing
    {
    	char* strFileName; 
    
    };
    ...
    testing *node = new testing();
    node->strFileName = data2.cFileName;
    Node is defined as a pointer to testing with memory allocated for that structure - which just contains a pointer to a char. So the node->strFileName = data2.cFileName will set this char pointer to the addess of the cFileName entry in data2. However, data2 is overwritten every time you go through the loop to get the next file name!

    So you also need to allocate memory for the string held within node and then copy the contents of cFileName to that memory. Something like

    Code:
    testing *node = new testing();
    node->strFileName = new char[lstrlen(data2.cFileName) + 1];
    lstrcpy(node->strFileName, data2.cFileName);

    Note that when finished with the file names then the memory pointed to by strFileName need to be deleted first then the memory pointed to by node is then deleted - otherwise you have a memory leak!

  12. #12
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: List Control Column data

    Why are you using LPSTR_TEXTCALLBACK? If all you are trying to do is to populate a list box with file names then this can be done directly without using callback.

    Code:
    void CThisDlg::OnOK() 
    {
    int iNum = 0;
    
    HANDLE hFind;
    
    WIN32_FIND_DATA data2;
    
    LV_ITEM lvi;
    
        lvi.mask = LVIF_TEXT; 
        hFind = FindFirstFile("*.*", &data2);
        while (hFind != INVALID_HANDLE_VALUE) {
             if (data2.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) {
                  lvi.iItem = iNum++; 
                  lvi.iSubItem = 0; 
                  lvi.pszText = new char[lstrlen(data2.cFileName) + 1];
                  lstrcpy(lvi.pszText, data2.cFileName);
                  m_list.InsertItem(&lvi);
             }
             hfind = FindNextFile(hfind, &data2);
         }
    }

  13. #13
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: List Control Column data

    Whoops, sorry - I've had a long day and brain is frazzled! Doing it this way you don't need to allocate memory as that would cause a memory leak! You just need lvi.pszText = data2.cFileName. My FindNextFile line somehow got corrupted when copied. The code should be

    Code:
    void CThisDlg::OnOK() 
    {
    int iNum = 0;
    
    HANDLE hFind;
    
    WIN32_FIND_DATA data2;
    
    LV_ITEM lvi;
    
        lvi.mask = LVIF_TEXT; 
        lvi.iSubItem = 0;
    
        hFind = FindFirstFile("*.*", &data2);
        while (hFind != INVALID_HANDLE_VALUE) {
             if (data2.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) {
                  lvi.iItem = iNum++; 
                  lvi.pszText = data2.cFileName;
                  m_list.InsertItem(&lvi);
             }
             if (!FindNextFile(hFind, &data2)) hFind = INVALID_HANDLE_VALUE;
         }
    }

  14. #14
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: List Control Column data

    In your find file code you are also not closing the find handle when finished. This will cause a resource leak. Once all the file names have been obtained then the handle should be closed as in

    Code:
    void CThisDlg::OnOK() 
    {
    int     iNum = 0;
    
    HANDLE	hFind;
    
    LV_ITEM	lvi;
    
    WIN32_FIND_DATA data2;
    
    BOOL    cont = ((hFind = FindFirstFile("*.*", &data2)) != INVALID_HANDLE_VALUE);
    
        lvi.mask = LVIF_TEXT; 
        lvi.iSubItem = 0; 
    
        while (cont) {
             if (data2.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) {
                  lvi.iItem = iNum++; 
                  lvi.pszText = data2.cFileName;
                  m_list.InsertItem(&lvi);
             }
             cont = FindNextFile(hFind, &data2);
         }
    
         if (hFind != INVALID_HANDLE_VALUE) FindClose(hFind);
    }

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