Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

C function to export text from a ListView into a text file with separators

0.00/5 (No votes)
8 Dec 2004 1  
Win32 API using C - no MFC.

Sample Image - fexportlistview.png

Introduction

You can find plenty of C++ and/or MFC code to deal with your ListView controls, but maybe not enough pure C and API (SDK) code. This code snippet consists of only one C function (fExportListView) that outputs the text content of a ListView control into a newly created text file (with fields separated). The output text file can be imported into a spreadsheet software such as MS Excel, or into a database. Any reader interested in thorough explanations (only SDK, no MFC) can read the excellent article by Bengi (titled 'Using ListView control under Win32 API').

This is a first attempt at proposing C and API code - maybe completely useless? However, if you are interested in simple 'insert ListView item' or 'insert ListView column' functions, just let me know and I will upload those too, if they are needed.

Background

You should be familiar with C language and C program compiling, including Win32 API. Whether you use MFC or not, you should know about API. Therefore, reading Charles Petzold's book "Programming Windows" (published by Microsoft Press) is quite mandatory. By the way, thank you so much for your explanations and inspiring examples, Mr. Petzold.

Using the code

I assume you have declared, created, (re)sized and filled (with text) a ListView control (i.e., a window of class WC_LISTVIEW, with style, e.g., WS_BORDER | WS_CHILD | WS_VISIBLE | LVS_REPORT). See reference on CreateWindowEx in MSDN, and/or include the ListView in your Visual Studio project.

Bear in mind that in a ListView, you deal with columns, items and subitems. One of the columns contains only items (usually, the leftmost column), all the other columns contain only subitems. So, for a given 'line' in your ListView, the LVM_GETITEMTEXT message will copy text from:

  1. an item when the iSubItem member of the LVITEM struct equals zero, or
  2. from a subitem when iSubItem is greater than zero.

See the code below and try it out.

The function is really simple, and comes with embedded comments explaining what it does step by step. However, here are some elements:

Declaration of the function:

int fExportListView(HWND hwndListView, FILE *filehandle, unsigned char *sFileName, 
               char cSep, long lLines, long lCols);

The parameters to the function:

  • hwndListView is the handle for your ListView child window
  • filehandle is the pointer to your FILE structure
  • sFileName is the pointer to the 'string' that is your filename
  • cSep is the character you want as a separator between fields
  • lLines and lCols are the numbers of lines and columns (respectively) in the ListView

You might also need these includes:

#include <windows.h>

#include <stdio.h>

#include <commctrl.h>

(etc...)

C language background: functions such as sprintf(), fprintf(), memset(), fopen(), fclose(), pointers and arrays.

API background: functions such as SendMessage(), MessageBox() and a struct called LVITEM.

Call this function, e.g., like this:

  • fExportListView(hwndLV, f, "fExportListView_tab.txt", 9, 10, 5);
  • fExportListView(hwndLV, f, "fExportListView_pipe.txt", '|', 20, 8);

with parameters of the same types as those described above - and properly declared someplace.

Return values of the function: 0 if problem or error occurs, 1 if OK.

Here is the code itself:

int fExportListView(HWND hwndListView, FILE *filehandle, 
    unsigned char *sFileName, char cSep, long lLines, long lCols)
{
    
    /*********************
    * Local declarations *
    *********************/
    
    // LVITEM struct (see MSDN for content) :
    LVITEM lvi;
    // Max length of string into pszText member of LVITEM struct :
    long lMAX = 5000;
    // String buffer for pszText member of LVITEM struct :
    unsigned char LVtext[lMAX];
    // To appear in the caption of the MessageBox :
    static unsigned char *sYourApplicationsName = 
                    "You fill that in with your app name :)";
    // Error string you can use to 'MessageBox' and/or to 'fprintf'
    // into a logfile - a reasonable thing to do :)
    unsigned char sErrorString[lMAX];
    // Long integers for various tasks :
    long i, j;
    
    
    /*************************
    * Minimum error checking *
    *************************/
    
    // Checking ListView handle :
    if (hwndListView == NULL)
    {
        sprintf(sErrorString, "Handle of ListView NULL (fExportListView)");
        // Your good old Windows message box :
        MessageBox(NULL, (LPSTR) sErrorString, 
                  (LPSTR) sYourApplicationsName, 
                  MB_OK | MB_ICONEXCLAMATION);
        return(0);
    }
    
    // Checking number of lines against parameter value :
    i = SendMessage((HWND) hwndListView, (UINT) LVM_GETITEMCOUNT, 
                                         (WPARAM) 0, (LPARAM) 0);
    if (lLines != i)
    {
        sprintf(sErrorString, "%ld lines in ListView != %ld as" 
                " parameter (fExportListView)", i, lLines);
        MessageBox(NULL, (LPSTR) sErrorString, 
                  (LPSTR) sYourApplicationsName, 
                  MB_OK | MB_ICONEXCLAMATION);
        return(0);
    }
    
    // Checking whether ListView empty :
    if (i == 0)
    {
        sprintf(sErrorString, "ListView empty (fExportListView)");
        MessageBox(NULL, (LPSTR) sErrorString, 
                         (LPSTR) sYourApplicationsName, 
                         MB_OK | MB_ICONEXCLAMATION);
        return(0);
    }
    
    // Opening - rather creating - output file in write mode
    // (caution : overwrites a file with the same 'sFileName') :
    filehandle = fopen(sFileName, "w");
    if (filehandle == NULL)
    {
        sprintf(sErrorString, "Error occurred while creating" 
                " file %s (w mode) (fExportListView)", sFileName);
        MessageBox(NULL, (LPSTR) sErrorString, 
                         (LPSTR) sYourApplicationsName, 
                         MB_OK | MB_ICONEXCLAMATION);
        return(0);
    }
    
    
    /*************************************************************
    * Use a LVITEM struct to collect some text from the ListView *
    *************************************************************/
    
    for (i=0; i<lLines; i++)
    {
        memset(&lvi, 0, sizeof(lvi));  // Clean up before action
        // Fill in the members of the LVITEM struct :
        lvi.mask = LVIF_TEXT;
        // Minimum here to take care of the pszText member
        // - see other LVIF_xxx constants in MSDN

        lvi.state = 0;
        lvi.stateMask = 0;
        // lvi.iSubItem : not here, see 'j' loop below
        lvi.cchTextMax = lMAX - 1;
        // Length of string to be copied into pszText member

        lvi.pszText = LVtext;
        // String buffer for pszText member
        
        // Nota bene : starts at zero (item) and ends at 'lCols' (last subitem) :
        for (j=0; j<=lCols; j++)
        {
            // Important member of LVITEM struct you
            // need to fill in (j=0 : item; j>0 : subitem) :
            lvi.iSubItem = j;
            // Retrieve the text in an item or a subitem of line 'i' :
            SendMessage(hwndListView, LVM_GETITEMTEXT, (WPARAM) i, (LPARAM) &lvi);
            if (filehandle != NULL)
            {
                // No separator at the beginning of a line (here, at item level) ...
                if (j == 0) fprintf(filehandle, "%s", LVtext);
                // ... only between two consecutive fields (here, at subitem level) :
                else fprintf(filehandle, "%c%s", cSep, LVtext);
            }
        }
        // End of line, Windows style i.e. carriage return
        // (implicit) plus new line (explicit) :
        if (filehandle != NULL) fprintf(filehandle, "\n");
    }
    
    /*******************************
    * Close the output text file   *
    * and return from the function *
    *******************************/
    if (filehandle != NULL) fclose(filehandle);
    return(1);
}

History

  • December 8, 2004: version 1 of the function.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here