Click here to Skip to main content
Click here to Skip to main content

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

, 7 Dec 2004 GPL3
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

Share

About the Author

Bruno Challier
George Sand Hospital, Bourges
France France
Electronic health record, health classifications (diseases, procedures), database, diagnosis related groups.

Comments and Discussions

 
Questionif i want import to list view ?? PinsussAnonymous9-Dec-04 6:11 
AnswerRe: if i want import to list view ?? PinmemberBruno Challier9-Dec-04 20:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.141015.1 | Last Updated 8 Dec 2004
Article Copyright 2004 by Bruno Challier
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid