CListCtrl LVN_ITEMCHANGING
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 18

Thread: CListCtrl LVN_ITEMCHANGING

  1. #1
    Join Date
    Dec 2001
    Location
    Bremen, Germany
    Posts
    314

    CListCtrl LVN_ITEMCHANGING

    hi @all

    I want to handle the LVN_ITEMCHANGING notification for one of my CListCtrl (Report Style) to prevent change of item focus. According to MSDN, returning *pResult = TRUE from the LVN_ITEMCHANGING notification handler should prevent the change.

    Problem: When I try to change the item focus by mouse and display a (Afx)MessageBox(...) within the LVN_ITEMCHANGING handler function, the message is received a 2nd time as soon as the mouse is moved.
    This does not occur when either (a) I change the focus item with the cursor-keys on the keyboard or (b) I don't display a message box.

    You can breakpoint in the notification handler and see, that the pNMListView data is excatly the same for the doubled message.

    This is the relevant code:
    Code:
    void CListCtrl_LVN_ITEMCHANGINGDlg::OnItemChangingList1(NMHDR* pNMHDR, LRESULT* pResult) 
    {
    	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
    
    	// check for change of LVIS_FOCUSED state
    	if ( (pNMListView->uChanged == LVIF_STATE) && (pNMListView->uOldState == LVIS_FOCUSED) )
    	{
    		// display message box
    		AfxMessageBox("Item change not allowed.");
    
    		// disallow itemchange
    		*pResult = TRUE;
    	}
    	else
    	{
    		// allow itemchange
    		*pResult = FALSE;
    	}
    }
    
    
    
    
    void CListCtrl_LVN_ITEMCHANGINGDlg::OnItemChangingList2(NMHDR* pNMHDR, LRESULT* pResult) 
    {
    	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
    	
    	// check for change of LVIS_FOCUSED state
    	if ( (pNMListView->uChanged == LVIF_STATE) && (pNMListView->uOldState == LVIS_FOCUSED) )
    	{
    		// play sound
    		MessageBeep(MB_ICONEXCLAMATION);
    
    		// disallow itemchange
    		*pResult = TRUE;
    	}
    	else
    	{
    		// allow itemchange
    		*pResult = FALSE;
    	}
    }
    I've also built a small demo project (dialog based) you may want to download and have a look into.

    Any suggestions are greatly appreciated! Thank you!

    Oliver.

  2. #2
    Join Date
    Dec 2001
    Location
    Bremen, Germany
    Posts
    314
    Sorry, forgot to add demo project after preview...
    Attached Files Attached Files

  3. #3
    Join Date
    Feb 2002
    Posts
    5,758
    I suspect that windows sends the main thread a an item update message each time the list control gains focus, which is after the messages box closes. One possible solution is a boolean variable. Implement it inside of the function you posted and return TRUE immediately.

    Kuphryn

  4. #4
    Join Date
    Dec 2001
    Location
    Bremen, Germany
    Posts
    314
    Hi Kuphryn

    Thanks for your suggestion - but this would be too easy

    If it were just because the control re-gains the focus, it should happen also when changing the items via keyboard.

    But this doubled message only occurs when changing the item with the mouse. Just download the demo project (exe is inside) and see for yourself.

    Btw. I've tested the code on Win98se, Win2000, WinXP Pro with all the same results.

    By now I use a workaround by posting an application message and display the MessageBox in the application message handler, but there are other issues (with SetFocus()) that also only apply to mouse actions...

    Someone's got another idea? Thx!

    Oliver.

  5. #5
    Join Date
    May 1999
    Location
    Southern California
    Posts
    12,266
    I think Kuphryn is right.
    "Signature":
    My web site is Simple Samples.
    C# Corner Editor

  6. #6
    Join Date
    Dec 2001
    Location
    Bremen, Germany
    Posts
    314
    But why doesn't windows send this notification if you change the item by keyboard?

    If Kuphryn is right, keyboard actions must have the same effect, so there would be a bug in handling the keyboard input.
    If Kuphryn is wrong, it seems to be a bug with the mouse input handler.

    Anyway, I can't simply ignore the second (doubled) message, because it's only posted on mouse item changes. If I generally ignore it, my app would be buggy when using the keyboard.

    So how can I determine whether the message is generated due to a mouse vs. keyboard action?

    Oliver.

  7. #7
    Join Date
    Dec 2001
    Location
    Bremen, Germany
    Posts
    314
    Btw. Why do I get the doubled message at the time I move the mouse, not at the time the control regains focus?!

    Oliver.

  8. #8
    Join Date
    May 1999
    Location
    Southern California
    Posts
    12,266
    The problem probably is the AfxMessageBox function.
    "Signature":
    My web site is Simple Samples.
    C# Corner Editor

  9. #9
    Join Date
    Dec 2001
    Location
    Bremen, Germany
    Posts
    314
    Tried it... same thing happens when displaying a dialog instead.

    And as I mentioned before, some other strange things go on when using the mouse to change the focus item.

    The background: I'm validating an input dialog (displayed as child) and only allow an item change if all input is correct. So I (a) want to inform the user by a message box of a false entry and (b) want to set the focus to the CEdit box containing the wrong value and select whole content.

    What should I say: It does not work when using the mouse, but it does when using the keyboard. When using the mouse to change item focus, the focus is returned to the CListCtrl (even I see a blue flash of selected text in the CEdit box).

    For displaying a message box and avoiding the doubled message, I post an app message with a pointer to a string member. The message is received after the LVN_ITEMCHANGING message is fully processed and the message handler displays the apropriate message box.

    Now I tried to put the pEdit->SetFocus() and pEdit->SetSel(0,-1) code after display of the message box (in the handler of the application message), but this won't work either: The focus is still returned to the CListCtrl.

    I also tried to: Capture the mouse and release the capture, pump the windows messages for the CListCtrl prior to pEdit->SetFocus(); pEdit->SetSel(0,-1) without any success!

    Is it such a strange idea to use LVN_ITEMCHANGING in this way?

    I'll keep on searching for a solution since - what can I say - I can't explain it to my customers and if I could, it's not their business anyway.

    Maybe anyone can help me shed some light on this issue... Thanks you all in advance!

    Oliver.

  10. #10
    Join Date
    May 1999
    Location
    Southern California
    Posts
    12,266
    Did you try doing without the message box? That is the only way to know that it is the message box.
    "Signature":
    My web site is Simple Samples.
    C# Corner Editor

  11. #11
    Join Date
    Dec 2001
    Location
    Bremen, Germany
    Posts
    314
    Yes, as in my sample project I've posted, I've also tried to play a sound (MessageBeep(...) or Beep(...)) and breakpoint at the notification handler to inspect the (doubled) messages.
    As I said, it also happens when using a CDialog.

    Funny thing, just played around a little bit. When I use only pEdit->SetFocus(); pEdit->SetSel(0,-1); without a MsgBox, some more strange things happen:
    The focus is set to the edit control, but when I release the mouse button without moving the mouse, the focus is set back to the CListCtrl. When I do move the mouse before releasing the mouse button, the focus stays on the CEdit control...

    Things go more and more strange. It's late (midnight in germany), but I try out some more things tomorrow...

    Thank you

    Oliver.

  12. #12
    Join Date
    Oct 2012
    Posts
    9

    Re: CListCtrl LVN_ITEMCHANGING

    I am trying to do the same thing, 9 years after you. Anyways, I noticed that the second message box appears after I have moved my mouse. The only way to get that to happen is to hit Enter on your keyboard when the message box appears. When I then move my mouse over a different item than it is already on, I get the second message box.

    Oliver, did you ever resolve this?

  13. #13
    Join Date
    Oct 2012
    Posts
    9

    Re: CListCtrl LVN_ITEMCHANGING

    Small correction: I noticed the second message box everytime that I use my mouse to click on a different item. I only noticed that it happens when I move my mouse over another item, if I use Enter to clear the message box.

  14. #14
    Join Date
    Oct 2012
    Posts
    9

    Re: CListCtrl LVN_ITEMCHANGING

    I found what appears to be you asking the same question again in 2005. There it appears that you figured it out. I used your possible solution and built on it because it was losing the selection. See my example.

    void CCommentsTabDlg::OnItemchangingCmntsCommentList(NMHDR* pNMHDR, LRESULT* pResult)
    {
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

    if ( pNMListView->uChanged == LVIF_STATE &&
    ( pNMListView->uOldState == LVIS_FOCUSED ||
    pNMListView->uOldState == LVIS_SELECTED ) &&
    ( m_nMode == MODE_ADD || m_nMode == MODE_UPDATE ) ) {
    // Only show message once to prevent the message when focus and selection change.
    if ( pNMListView->uOldState == LVIS_FOCUSED ) {
    if ( m_nMode == MODE_ADD ) {
    m_sUpdateAddMessage = "You cannot select another comment while adding.\n\nYou must finish adding first.";
    }
    else if ( m_nMode == MODE_UPDATE ) {
    m_sUpdateAddMessage = "You cannot select another comment while updating.\n\nYou must finish updating first.";
    }
    PostMessage(WM_UPDATE_ADD_MESSAGE);
    }

    // Do not allow ItemChange
    *pResult = -1;
    }
    else {
    *pResult = 0;
    }
    }

    2005 Thread: http://forums.codeguru.com/archive/i...t-344941.html?

  15. #15
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,770

    Re: CListCtrl LVN_ITEMCHANGING

    LVN_ITEMCHANGING cannot be used to prevent actual change of focus.

    This message is merely posted so you can prevent the status change from being applied to the item. (i.e. the small focus rectangle around an item.

    If what you seek to do is actual focus change prevention, then you have a much much more complex task ahead of you and even one that will violate many core principles in Windows. Your users may not end up being very happy depending on how strict you apply such rules.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center