Thread: questions regarding listview items

  1. #1
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211

    questions regarding listview items

    hello all,
    I just have some questions about listview items.

    /***********NEVERMIND THIS QUESTION******************************
    in my application, for the listview, for WM_NOTIFY, I am handling the NM_RCLICK message, and that is all. I assume that when a user right clicks on a listview control item that it will automatically set focus (selection, whatever you wanna call it) on that item? or would I have to manually set the focus (note that I am not using DefWindowProc() since it is a dialog)?
    ****TESTED BY ADDING AN ITEM, AND IT DOES SET FOCUS AUTOMATICALLY****/

    secondly, how would I find out if an item is in focus? my intent is to dynamically create a popup floating menu on NM_RCLICK in the listview. but as I call AppendMenu(), I would like to know whether or not a listview item is being right clicked (to properly set the menu item flags, for example set a menu item to MF_GRAYED if NM_RCLICK is on a listview item).

    could anyone please help me with these questions?


    thank you in advance!
    Last edited by Bleech; 08-25-2006 at 03:49 PM.

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    ListView_GetSelectionMark seems to do the trick. You could also use ListView_HitTest.
    Code:
        case WM_NOTIFY:
        {
    	LPNMHDR hdr = (LPNMHDR) lParam;
    
    	if (hdr->hwndFrom == hListView &&
                hdr->code     == NM_RCLICK)
    	{
               char buf[200];
               int iIndex = ListView_GetSelectionMark(hListView);
               wsprintf(buf, "%d", iIndex);
               MessageBox(NULL, buf, NULL, 0);
    	}
            break;
        }

  3. #3
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    thanks anonytmouse, ListView_GetSelectionMark is exactly what I am looking for.

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

  4. #4
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    very sorry for the double post, but I have another situation related to this, and really don't want to start a new thread.

    I got it working, but am now stumped with another very tedious problem. it is not working how I would like it to. here is how I am handling WM_NOTIFY:

    Code:
    case WM_NOTIFY:
    		lpnmhdr = (LPNMHDR)lParam;
    		hMenu = CreatePopupMenu();
    		if(lpnmhdr->hwndFrom == hwndList) {
    			if(lpnmhdr->code == NM_RCLICK) {
    				iSelect = ListView_GetSelectionMark(hwndList);
    				if(iSelect != -1) {
    					AppendMenu(hMenu, MF_GRAYED | MF_STRING, IDM_ADD, "Add");
    					AppendMenu(hMenu, MF_STRING, IDM_REMOVE, "Remove");
    					GetCursorPos(&pt);
    					TrackPopupMenu(hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hwndDlg, 0);
    				}
    				else {
    					AppendMenu(hMenu, MF_STRING, IDM_ADD, "Add");
    					AppendMenu(hMenu, MF_GRAYED | MF_STRING, IDM_REMOVE, "Remove");
    					GetCursorPos(&pt);
    					TrackPopupMenu(hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hwndDlg, 0);
    				}
    			}
    		}
                      DestroyMenu(hMenu);
    
    		break;
    take a close look at the calls to AppendMenu. as you can see, here is how I am trying to make the menu look:

    IF we have right clicked on a listview item = IDM_ADD is set MF_GRAYED (disabled)
    ELSE we have not right clicked on a listview item = IDM_REMOVE is set MF_GRAYED

    this makes sense, since if an item is selected (right clicked in this case), we should only want to be able to remove it from the list. and if we are right clicking open space, we don't want to remove it (that wouldn't make sense), but we want to be able to add an item instead.

    so here is my problem. if I click open space it works fine, IDM_REMOVE is MF_GRAYED. but as soon as I click an item, the if(iSelect != -1) conditional no longer applies, IDM_ADD stays disabled, even if I click off the item. so you don't have to delve into msdn, I will tell you now that that conditional is testing if a listview item has been right clicked (ListView_GetSelectionMark returns -1 if no item is selected).

    I have tried enabling the items like this:

    Code:
    if(iSelect != -1) {
    					AppendMenu(hMenu, MF_GRAYED | MF_STRING, IDM_ADD, "Add");
    					AppendMenu(hMenu, MF_ENABLED | MF_STRING, IDM_REMOVE, "Remove");
    					GetCursorPos(&pt);
    					TrackPopupMenu(hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hwndDlg, 0);
    					break;
    				}
    				else {
    					AppendMenu(hMenu, MF_ENABLED | MF_STRING, IDM_ADD, "Add");
    					AppendMenu(hMenu, MF_GRAYED | MF_STRING, IDM_REMOVE, "Remove");
    					GetCursorPos(&pt);
    					TrackPopupMenu(hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hwndDlg, 0);
    					break;
    				}
    but it makes no difference (as expected ).

    I am left puzzled here. I don't know what could possibly fix this problem, if anything. I have absolutely no clue why it doesn't work like it should . each right click is a WM_NOTIFY message, Windows should call my dialog callback with the NM_RCLICK message every time I right click, and the conditional testing if it is on an item should be evaluated each time.

    would anyone please be able to shed some light here? if not, I will give up on this whole menu thing and stick to buttons (at least I can send messages to buttons), but that would be a last resort.

    any help at all would be greatly appreciated, sorry for all the recent questions, this is my first serious GUI'd project with the Win32 API. thank you in advance.

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

  5. #5
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    The first thing to do is check the value of iSelect:
    Code:
    case WM_NOTIFY:
    		lpnmhdr = (LPNMHDR)lParam;
    		hMenu = CreatePopupMenu();
    		if(lpnmhdr->hwndFrom == hwndList) {
    			if(lpnmhdr->code == NM_RCLICK) {
    				iSelect = ListView_GetSelectionMark(hwndList);
    
    				{ char buf[200];
    				wsprintf(buf, "%d", iSelect);
    				MessageBox(NULL, buf, NULL, 0); }
    
    				if(iSelect != -1) {
    					AppendMenu(hMenu, MF_GRAYED | MF_STRING, IDM_ADD, "Add");
    					AppendMenu(hMenu, MF_STRING, IDM_REMOVE, "Remove");
    					GetCursorPos(&pt);
    					TrackPopupMenu(hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hwndDlg, 0);
    				}
    				else {
    					AppendMenu(hMenu, MF_STRING, IDM_ADD, "Add");
    					AppendMenu(hMenu, MF_GRAYED | MF_STRING, IDM_REMOVE, "Remove");
    					GetCursorPos(&pt);
    					TrackPopupMenu(hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hwndDlg, 0);
    				}
    			}
    		}
                      DestroyMenu(hMenu);
    
    		break;
    I suspect it will not be -1. If the message box does not show up at all, it means that NM_RCLICK is not being received. Is iSelect declared as an int, as opposed to an unsinged int, etc?

    This is pretty impressive code for your first major GUI project, so don't lose heart yet.

  6. #6
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    iSelect is declared as an int, signed by default.

    here is how adding that works:

    1. I right click open listview space, I get -1.
    2. I right click an item, I get 0.
    3. I right click open listview space, I get 0.

    - without printing iSelect

    1. I right click open listview space, the popup menu appears, Remove is disabled, Add is enabled.

    2. I right click an item, the popup menu appears, Add is disabled, Remove is enabled.

    3. I right click open listview space, Add is disabled, Remove is enabled.

    3 is obviously the problem, but I just can't figure it out.

    ListView_GetSelectionMark
    Syntax

    INT ListView_GetSelectionMark(
    HWND hwndLV
    );

    Parameters

    hwndLV
    - Handle to a list-view control.

    Return Value

    Returns the zero-based selection mark, or -1 if there is no selection mark.

    Remarks

    The selection mark is the item index from which a multiple selection starts.

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

  7. #7
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Yes, it turns out the selection mark stays on the last clicked on item. I don't know how I missed this when I tested my original code. I'm sorry for leading you in the wrong direction and wasting your time. The good news is that ListView_HitTest does seem to work.
    Code:
    case WM_NOTIFY:
    		lpnmhdr = (LPNMHDR)lParam;
    
    		if(lpnmhdr->hwndFrom == hwndList) {
    			if(lpnmhdr->code == NM_RCLICK) {
    
    				LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE) lParam;
    				LVHITTESTINFO    hti      = { 0 };
    
    				hMenu = CreatePopupMenu();
    
    				hti.pt = lpnmitem->ptAction;
    				ListView_HitTest(hListView, &hti);
    
    				if(hti.flags & LVHT_ONITEM) {
    					AppendMenu(hMenu, MF_GRAYED | MF_STRING, IDM_ADD, "Add");
    					AppendMenu(hMenu, MF_STRING, IDM_REMOVE, "Remove");
    					GetCursorPos(&pt);
    					TrackPopupMenu(hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hwndDlg, 0);
    				}
    				else {
    					AppendMenu(hMenu, MF_STRING, IDM_ADD, "Add");
    					AppendMenu(hMenu, MF_GRAYED | MF_STRING, IDM_REMOVE, "Remove");
    					GetCursorPos(&pt);
    					TrackPopupMenu(hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hwndDlg, 0);
    				}
    
    				DestroyMenu(hMenu);
    			}
    		}
    
    		break;

  8. #8
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    using ListView_HitTest, it works perfectly.

    thank you very much for your help.

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. HELP!!!!emergency Problem~expert please help
    By unknowppl in forum C++ Programming
    Replies: 9
    Last Post: 08-21-2008, 06:41 PM
  2. HELP!!!!emergency ~expert please help
    By unknowppl in forum C Programming
    Replies: 1
    Last Post: 08-19-2008, 07:35 AM
  3. ListView controls - Adding items .. What the beep?
    By IceDane in forum Windows Programming
    Replies: 7
    Last Post: 04-08-2008, 12:07 PM
  4. A few questions on ListView Control...
    By Devil Panther in forum Windows Programming
    Replies: 0
    Last Post: 09-05-2003, 02:33 PM
  5. Selected Items in a ListView
    By Lowas in forum Windows Programming
    Replies: 12
    Last Post: 09-01-2001, 07:17 PM