Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

How to change a selected item in CListCtrl to not_selected without the click action

Posted on 2001-08-15
10
Medium Priority
?
3,867 Views
Last Modified: 2013-11-20
Hello, Experts:
 I need your help !
 you may think my question is very strange, but I have to solve this because my client stick to this feature.
 my situation is, I have a CListCtrl in my dialog,and list items with checkbox. the feature of the CListCtrl need to satisfy following:
1) when click and select an item, only this item must be checked and selected.
2) when check on the checkbox of an item, this item must be checked and selected, other selected item must be turn to unselected state.
3) when uncheck on the checkbox of an item, this item must be unchecked and unselected.

I finished 1), but I have problem to do 2) &3),  I tried use OnItemChangedListCtrl to check the status and then try to make the item selected/unselected. but I failed.
Can somebody kindly tell me the possible solution? please tell me if I had use the event-handle and also how to make a selected item to unselected state.
Thank you very much !

-- pigangel with big headache
0
Comment
Question by:pigangel
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
10 Comments
 
LVL 12

Expert Comment

by:migel
ID: 6389470
Hi!
You have to derive your clas fom CListCtrl and handle WM_LBUTTONDOWN message or reflected NM_CLICK message (IMHO 1 way is preffered)
In this hadler you must determine where click occured (using CListCtrl::HitTest member) and implement checking unchecking.
Since only one item must be checked you can store in the class checked itemId and use in the future.
in the pseudocode alg to keep only one item checked:
WM_LBUTTONDOWN
{
nClickedItem  = .... ;
if (HitTest() == LVHT_ONITEMSTATEICON)
  {
 
  if (m_CheckedId == -1)
     {
     CheckItem(nClickedItem = m_CheckedId);
     }
  else
     {
     UncheckItem(CheckedId);
     if (m_CheckedId != nClickedItem)
       {
     CheckItem(nClickedItem = m_CheckedId);
       }
    else
       m_CheckedId = -1;
     }
  }
}
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6391393
Can you use the MFC class CCheckListbox?  

It provides both a "Selection changed" and a "check changed" notifications.  It should be easy to implement your requirement if you know whenever either of these events occur.

-- Dan
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6391502
To change the selected item in a CListCtrl, you need to use:

SetItme.  FOr instance,

BOOL fRet= m_ctlList.SetItem( 1, 0, LVIF_STATE, 0, 0, LVIS_SELECTED, LVIS_SELECTED, 0 );

This handler displays all the info you need to know.  Be aware that before an item gets selected, another item gets unselected.  

void CMyDlg::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult)
{
     NMLISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
    if ( pNMListView->uChanged & LVIF_STATE ) {
        // MessageBox("State change");
        int nItem= pNMListView->iItem;
        int nNewState= pNMListView->uNewState;
        int nOldState= pNMListView->uOldState;
        CString sSel= "NOT Selected";
        if ( nNewState & LVIS_SELECTED ) {
            sSel= "Selected";
        }
        CString sChecked= "NOT Checked";
        if ( m_ctlList.GetCheck(nItem) ) {
            sChecked= "Checked";
        }
        CString sMsg;
        sMsg.Format("item %d is %s/%s  (State=%04x)", nItem, (LPCSTR)sChecked, (LPCSTR)sSel, nNewState );

        MessageBox(sMsg);
    }    
     *pResult = 0;
}


THis handler will be called even when you change the selection or check programatically (it does not depend on the user clicking anything)

-- Dan
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:pigangel
ID: 6396476
Hi,migel & Dan:
  thanks to both of you! from Dan's example, I got to know deeply about the actions of click and check(box). and I tried migel's proposal to use OnClickListCtrl() and implemented like following :

Mydlg::OnCliclListCtrl(...)
{

     int           nSel;

     NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

     nSel = pNMListView->iItem;
     
     if(nSel != -1) {
         
          for(int i=0;i < m_lstMachineType.GetItemCount(); i++ ) {
               if (i != nSel ) {
                    m_lstMachineType.SetCheck(i,FALSE);
                    // **** set the item to unselected state.
                    //m_lstMachineType.SetItem( i, 0, LVIF_STATE, 0, 0, 0, 0, 0 );
                    //m_lstMachineType.SetItemState(i,LVIS_SELECTED,0);

               }
          }

          m_lstMachineType.SetCheck(nSel,TRUE);
          m_lstMachineType.SetItemState(nSel,LVIS_SELECTED,LVIS_SELECTED);
     }else{

          for(int i=0;i < m_lstMachineType.GetItemCount(); i++ ) {
                    m_lstMachineType.SetCheck(i,FALSE);
          }
     }


     *pResult = 0;


}


I almost get the features done, but that I tried SetItemState method,  but I could set the item to unselected state (please see my comment *** in the code part), can you please kindly how to do it ? thank you very much!


-- pigangel
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6398203
If your testing code implements my hander as well as you OnClick, then you are experiencing a conflict because of that.
-=-==-=--=-==--=-==-=-=-
As I said:
To change the selected item in a CListCtrl, you need to use SetItem.  For instance,

BOOL fRet= m_ctlList.SetItem( 1, 0, LVIF_STATE, 0, 0, LVIS_SELECTED, LVIS_SELECTED, 0 );

So, to unselect an item, use:

BOOL fRet= m_ctlList.SetItem( 1, 0, LVIF_STATE, 0, 0, 0, LVIS_SELECTED, 0 );

That is, set statemask to LVIS_SELECTED and state to 0.

Note that because you are doing this in an OnClick handler, the actions you perform may be undone by the system as soon as you are finished.  I've seen some strange results because of the way MS implemented the 'check' feature of this control.  If you watch the default action closely, the control first changes the selection, then sets the check, then puts the old selection back.

If you insist on handling this in your OnClick handler, I recommend posting a message to yourself, say UM_MySetAllItemStates.  In your handler for that, you could go through the entire list checking/unchecking selecting/unselectiong as needed.

-- Dan
0
 

Author Comment

by:pigangel
ID: 6403072
I used SetItem to change the selected item, it was  successful to change the item state. I am very happy though
there are still strange results like Dan mentioned, at least I am very close to the features.
thank you very much! I will try your proposal to see how I can solve the strange result.

-- pigangel
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6420473
Hi pigangel,

Do you have any additional questions?  Do any comments need clarification?

-- Dan
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6420477
hi pigangel,

Do you have any additional questions?  Do any comments need clarification?

-- Dan
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 600 total points
ID: 6443892
hi pigangel,

Do you have any additional questions?  Do any comments need clarification?

-- Dan
0
 

Author Comment

by:pigangel
ID: 6444024
Hi,Dan:
  sorry to be late to accept your answer, I have been busy with field test. thank you very mcuh! your answer is the exact one for my question!
 
  Thanks to migel too, I will try the suggestion to see how it satisfy the whole 3 features.

-- pigangel
0

Featured Post

Ask an Anonymous Question!

Don't feel intimidated by what you don't know. Ask your question anonymously. It's easy! Learn more and upgrade.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Suggested Courses

597 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question