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:
- an item when the
iSubItem
member of the LVITEM
struct
equals zero, or
- 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 include
s:
#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)
{
LVITEM lvi;
long lMAX = 5000;
unsigned char LVtext[lMAX];
static unsigned char *sYourApplicationsName =
"You fill that in with your app name :)";
unsigned char sErrorString[lMAX];
long i, j;
if (hwndListView == NULL)
{
sprintf(sErrorString, "Handle of ListView NULL (fExportListView)");
MessageBox(NULL, (LPSTR) sErrorString,
(LPSTR) sYourApplicationsName,
MB_OK | MB_ICONEXCLAMATION);
return(0);
}
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);
}
if (i == 0)
{
sprintf(sErrorString, "ListView empty (fExportListView)");
MessageBox(NULL, (LPSTR) sErrorString,
(LPSTR) sYourApplicationsName,
MB_OK | MB_ICONEXCLAMATION);
return(0);
}
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);
}
for (i=0; i<lLines; i++)
{
memset(&lvi, 0, sizeof(lvi)); lvi.mask = LVIF_TEXT;
lvi.state = 0;
lvi.stateMask = 0;
lvi.cchTextMax = lMAX - 1;
lvi.pszText = LVtext;
for (j=0; j<=lCols; j++)
{
lvi.iSubItem = j;
SendMessage(hwndListView, LVM_GETITEMTEXT, (WPARAM) i, (LPARAM) &lvi);
if (filehandle != NULL)
{
if (j == 0) fprintf(filehandle, "%s", LVtext);
else fprintf(filehandle, "%c%s", cSep, LVtext);
}
}
if (filehandle != NULL) fprintf(filehandle, "\n");
}
if (filehandle != NULL) fclose(filehandle);
return(1);
}
History
- December 8, 2004: version 1 of the function.