Click here to Skip to main content
15,888,351 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
QuestionRe: How to handle Column Click in a multi column list box Pin
Richard MacCutchan17-Sep-11 3:03
mveRichard MacCutchan17-Sep-11 3:03 
AnswerRe: How to handle Column Click in a multi column list box Pin
Amrit Agr18-Sep-11 19:25
Amrit Agr18-Sep-11 19:25 
GeneralRe: How to handle Column Click in a multi column list box Pin
Richard MacCutchan18-Sep-11 23:04
mveRichard MacCutchan18-Sep-11 23:04 
GeneralRe: How to handle Column Click in a multi column list box Pin
David Crow19-Sep-11 3:26
David Crow19-Sep-11 3:26 
GeneralRe: How to handle Column Click in a multi column list box Pin
Richard MacCutchan19-Sep-11 4:00
mveRichard MacCutchan19-Sep-11 4:00 
GeneralRe: How to handle Column Click in a multi column list box Pin
David Crow19-Sep-11 4:40
David Crow19-Sep-11 4:40 
JokeRe: How to handle Column Click in a multi column list box Pin
Richard MacCutchan19-Sep-11 5:04
mveRichard MacCutchan19-Sep-11 5:04 
AnswerRe: How to handle Column Click in a multi column list box - caution long post Pin
enhzflep19-Sep-11 15:41
enhzflep19-Sep-11 15:41 
As others have mentioned, ListBox controls don't allow for multiple columns of data for each item. A ListBox is scrollable in one direction or the other, while a ListView is scrollable in both directions.
Windows explorer uses a ListView - right-click inside the client area of the window and you can change the view to Details - this gives a heading control and several columns per file - size, date, name etc, etc.


In any case, no - sorting won't work automatically when you click on the column header.
You'll get a notification of LVN_COLUMNCLICK via the WM_NOTIFY message. It's then up to you to determine which column was clicked on and whether you want to sort in ascending or descending order.
Having done so, you would then call ListView_SortItems with a pointer to the appropriate sorting function, the HWND of the control and an application-defined lParam value.

There are a couple of ways to go about it - typical uses the lParam value may be to flag whether the sorting is in ascending or descending order. You could also get clever, and use negative values for sorting in one direction and positive numbers for sorting in the other direction. Abs(lParam) could be used to hold the column index that you wish to perform the sort on.

Another approach may be to have one sorting function per column, calling ListView_SortItems using the appropriate function each time.

Ensuring that you give each ListView item a lParam value when adding them, gives you an identifier that can be used to extract the text from any column, which is then used for sorting.

Perhaps you'd like to look over the following code:

#include <pre><windows.h>
#include <stdio.h>
#include <commctrl.h>

#define IDC_ListView1  10001

enum gender {male=0, female};
typedef struct person_t
{
    char *firstName;
    char *lastName;
    int   age;
    gender sex;
};

person_t peopleList[] =
{
    {"Micky", "Mouse", 61, male},
    {"Donald", "Duck", 59, male},
    {"Betty", "Boo", 34, female},
    {"Olive", "Oil", 32, female},
    {"Clark", "Kent", 29, male}
};

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "CodeBlocksWindowsApp";


BOOL insertListViewColumn(HWND listHwnd, char *columnText, int colIndex)
{
    CHAR szText[256];     // Temporary buffer.
    LVCOLUMN lvc;
    int iCol;

    // Initialize the LVCOLUMN structure.
    // The mask specifies that the format, width, text,
    // and subitem members of the structure are valid.
    lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;

    iCol = colIndex;

    lvc.iSubItem = iCol;
    lvc.pszText = columnText;
    lvc.cx = 70;               // Width of column in pixels.

    lvc.fmt = LVCFMT_LEFT;  // Left-aligned column.

    // Insert the columns into the list view.
    if (ListView_InsertColumn(listHwnd, iCol, &lvc) == -1)
        return FALSE;

    return TRUE;
}

void addListViewItem(HWND hWndListView, char  *pszText, int iItem, int iSubItem, int iImage=-1)
{
    LVITEM lvItem;

    ZeroMemory(&lvItem, sizeof(LVITEM));
    lvItem.mask	      = LVIF_TEXT;
    lvItem.iItem      = iItem;
    lvItem.iSubItem   = iSubItem;
    lvItem.pszText    = pszText;
    lvItem.cchTextMax = strlen(pszText);

    if (iImage != -1)
    {
        lvItem.mask	 |= LVIF_IMAGE;
        lvItem.iImage = iImage;
    }

    if (iSubItem == 0)
    {
        if (ListView_InsertItem(hWndListView, &lvItem) == -1)
            //throw (CWinException(_T("CListCtrl::AddItem ... LVM_INSERTITEM failed ")));
            return;
    }
    else
    {
        if (ListView_SetItem(hWndListView, &lvItem) == -1)
            //throw (CWinException(_T("CListCtrl::AddItem ... LVM_SETITEM failed ")));
            return;
    }
}

BOOL InsertPersonIntoListView(HWND hWndListView, person_t person)
{
    static int curItemIndex = 0;
    char szBuffer[256];

    addListViewItem(hWndListView, person.firstName, curItemIndex, 0, -1);
    addListViewItem(hWndListView, person.lastName, curItemIndex, 1, -1);

    sprintf(szBuffer,"%d", person.age);
    addListViewItem(hWndListView, szBuffer, curItemIndex, 2, -1);

    sprintf(szBuffer,"%s", person.sex==male?"male":"female");
    addListViewItem(hWndListView, szBuffer, curItemIndex, 3, -1);

    curItemIndex++;
}

int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszArgument, int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hInst;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx(0, szClassName, "ListView Sorting demo", WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT, 426, 154,
                          HWND_DESKTOP, NULL, hInst, NULL);

    HWND btnWnd, listViewWnd;

    InitCommonControls();
    listViewWnd = CreateWindow(WC_LISTVIEW, "", WS_CHILD|WS_VISIBLE|LVS_REPORT, 5,5, 400,100, hwnd, (HMENU)IDC_ListView1, hInst, 0);

    insertListViewColumn(listViewWnd, "First Name", 0);
    insertListViewColumn(listViewWnd, "Last Name", 1);
    insertListViewColumn(listViewWnd, "Age", 2);
    insertListViewColumn(listViewWnd, "Sex", 3);

    for (int i=0; i<sizeof(peopleList)/sizeof(peopleList[0]); i++)
        InsertPersonIntoListView(listViewWnd, peopleList[i]);

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int idControl;
    char szText[256];
    NM_LISTVIEW *pnmv;
    switch (message)                  /* handle the messages */
    {
    case WM_DESTROY:
        PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
        break;


    case WM_NOTIFY:
        idControl = (int)wParam;
        if (idControl == IDC_ListView1)
        {
            pnmv = (NM_LISTVIEW*) lParam;

            if (pnmv->hdr.code == LVN_COLUMNCLICK)
            {
                sprintf(szText, "Column %d clicked", pnmv->iSubItem);
                MessageBox(hwnd, szText, "ListView WM_NOTIFY message", MB_OK);
            }
//                    printf("ListView WM_NOTIFY message - column %d clicked\n", pnmv->iSubItem);
        }
        break;

    default:                      /* for messages that we don't deal with */
        return DefWindowProc (hwnd, message, wParam, lParam);
    }
    return 0;
}

QuestionShellExecuteEx for windows7 Pin
MKC00216-Sep-11 22:47
MKC00216-Sep-11 22:47 
AnswerRe: ShellExecuteEx for windows7 Pin
Software_Developer17-Sep-11 10:53
Software_Developer17-Sep-11 10:53 
AnswerRe: ShellExecuteEx for windows7 Pin
Philippe Mori17-Sep-11 14:27
Philippe Mori17-Sep-11 14:27 
GeneralRe: ShellExecuteEx for windows7 Pin
MKC00219-Sep-11 7:00
MKC00219-Sep-11 7:00 
QuestionRe: ShellExecuteEx for windows7 Pin
David Crow19-Sep-11 8:07
David Crow19-Sep-11 8:07 
AnswerRe: ShellExecuteEx for windows7 Pin
MKC00220-Sep-11 6:58
MKC00220-Sep-11 6:58 
QuestionRe: ShellExecuteEx for windows7 Pin
David Crow20-Sep-11 9:15
David Crow20-Sep-11 9:15 
AnswerRe: ShellExecuteEx for windows7 Pin
MKC00221-Sep-11 4:12
MKC00221-Sep-11 4:12 
AnswerRe: ShellExecuteEx for windows7 Pin
MKC00223-Sep-11 0:50
MKC00223-Sep-11 0:50 
AnswerRe: ShellExecuteEx for windows7 Pin
MKC00225-Sep-11 2:37
MKC00225-Sep-11 2:37 
QuestionPointer Casting warning Pin
Software200715-Sep-11 8:57
Software200715-Sep-11 8:57 
QuestionRe: Pointer Casting warning Pin
David Crow15-Sep-11 9:08
David Crow15-Sep-11 9:08 
AnswerRe: Pointer Casting warning Pin
Software200715-Sep-11 9:36
Software200715-Sep-11 9:36 
AnswerRe: Pointer Casting warning Pin
krmed15-Sep-11 10:04
krmed15-Sep-11 10:04 
GeneralRe: Pointer Casting warning Pin
Software200715-Sep-11 10:17
Software200715-Sep-11 10:17 
AnswerRe: Pointer Casting warning Pin
Chuck O'Toole15-Sep-11 10:53
Chuck O'Toole15-Sep-11 10:53 
AnswerRe: Pointer Casting warning Pin
tushar_patil20-Sep-11 20:57
tushar_patil20-Sep-11 20:57 

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

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