thready
asked on
CListCtrl Visual C++ 6.0 - programmatically change selected rows OnItemChanged
Hi Experts,
I'm using an MFC CListCtrl in Visual C++ 6.0 and when a selection changed, I am selecting the chunks of 3 lines around it. - i.e., if I am selecting line number 4, I also want to select line 3 and line 5.
I momentarily see the lines getting selected but they are being deselected immediately after....
I'm using an MFC CListCtrl in Visual C++ 6.0 and when a selection changed, I am selecting the chunks of 3 lines around it. - i.e., if I am selecting line number 4, I also want to select line 3 and line 5.
I momentarily see the lines getting selected but they are being deselected immediately after....
Are you sure that LVS_SINGLESEL is *not* set?
ASKER
positive.. actually, my code works when I press the down arrow... When I click, if I keep the left mouse button down, the selection stays... When I release, the selection disappears...
Here's the code:
void CMyView::OnItemchangedData (NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if ( !(pNMListView->uNewState & LVIS_SELECTED) )
return;
int nIndex = CStringHelper::ListCtrlGet SelItemInd ex(m_Data) ;
if(nIndex != -1)
SelectedIndex(nIndex);
*pResult = 0;
}
// depending on nIndex, 3 lines will get selected...
void CMyView::SelectedIndex(int nIndex)
{
// first deselect everything:
// CStringHelper::ListCtrlDes electAll(m _Data);
int nFirstIndex = nIndex / 3;
nFirstIndex *= 3; // this does have an effect - since nFirstIndex is an INT, it takes the result without remainder....
for(int i = 0; i < 3; i++)
CStringHelper::ListCtrlHig hlightAndE nsureVisib le(m_Data, nFirstIndex + i);
}
static int ListCtrlGetSelItemIndex(CL istCtrl & List)
{
int nIndex = -1;
if(List && ::IsWindow(List.m_hWnd) && List.GetSelectedCount() > 0 )
{
POSITION pos= List.GetFirstSelectedItemP osition();
if (pos != NULL)
nIndex = List.GetNextSelectedItem(p os);
}
return nIndex;
}
static void ListCtrlDeselectAll(CListC trl & List)
{
for(int i = 0; i < List.GetItemCount(); i++)
List.SetItemState(i, 0, 0);
}
static void ListCtrlHighlightAndEnsure Visible(CL istCtrl & List, int nIndex)
{
List.SetItemState(nIndex, LVIS_SELECTED, LVIS_SELECTED | LVIS_FOCUSED);
List.EnsureVisible(nIndex, FALSE);
}
Here's the code:
void CMyView::OnItemchangedData
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if ( !(pNMListView->uNewState & LVIS_SELECTED) )
return;
int nIndex = CStringHelper::ListCtrlGet
if(nIndex != -1)
SelectedIndex(nIndex);
*pResult = 0;
}
// depending on nIndex, 3 lines will get selected...
void CMyView::SelectedIndex(int
{
// first deselect everything:
// CStringHelper::ListCtrlDes
int nFirstIndex = nIndex / 3;
nFirstIndex *= 3; // this does have an effect - since nFirstIndex is an INT, it takes the result without remainder....
for(int i = 0; i < 3; i++)
CStringHelper::ListCtrlHig
}
static int ListCtrlGetSelItemIndex(CL
{
int nIndex = -1;
if(List && ::IsWindow(List.m_hWnd) && List.GetSelectedCount() > 0 )
{
POSITION pos= List.GetFirstSelectedItemP
if (pos != NULL)
nIndex = List.GetNextSelectedItem(p
}
return nIndex;
}
static void ListCtrlDeselectAll(CListC
{
for(int i = 0; i < List.GetItemCount(); i++)
List.SetItemState(i, 0, 0);
}
static void ListCtrlHighlightAndEnsure
{
List.SetItemState(nIndex, LVIS_SELECTED, LVIS_SELECTED | LVIS_FOCUSED);
List.EnsureVisible(nIndex,
}
OK, just wanted to be sure ;o)
What happens if you use
static void ListCtrlHighlightAndEnsure Visible(CL istCtrl & List, int nIndex)
{
List.SetItemState(nIndex, LVIS_SELECTED, LVIS_SELECTED);
List.EnsureVisible(nIndex, FALSE);
}
instead?
What happens if you use
static void ListCtrlHighlightAndEnsure
{
List.SetItemState(nIndex, LVIS_SELECTED, LVIS_SELECTED);
List.EnsureVisible(nIndex,
}
instead?
ASKER
Thanks for your response - same thing happens - I get 3 lines highlighted and then as soon as I release the mouse button, the actual line I clicked on is highlighted... There has to be a quick fix for this... I have a feeling it's a function like "OnMouseUp" getting called which selects the last clicked item... If I override that function and do nothing, my selection should stay... I'm thinking this because of it working when I use the down arrow.... It even worked ONCE out of about 100 clicks (the 3 line selection stayed)!! Timing of some asynchronous function call.....
Mike
Mike
ASKER
ok I realized what made it work when I clicked on it that one time.... I can do it every time now... Basically, whichever row I click on, say row 5, if I drag away from row 5 without releasing and let go on row 4, I get my 3 line selection. For some reason, letting go on the same index causes the selection to change to only the clicked row..... The answer is near....... Hmmmmmmm..............
Hm, sorry, drawing a blank at the moment...
ASKER
Another hint: if I right-click, it works (even on release of the button). Left-click causes the 3 lines to get selected and releasing selects the item I'm over unless I've dragged off the one that the left mouse down was originally on... i.e., if I left click on 4, I get lines 3, 4 and 5 highlighted, and if I release on 4, only 4 is highlighted. But if I release on 5 instead, 3, 4 and 5 stay highlighted. Right clicking on 4 works perfectly in either case.....
What does left clicking call that right clicking does not? That is how I should rephrase this question. For one, it calls new selection code. Which code?? =) Little bugger.
What does left clicking call that right clicking does not? That is how I should rephrase this question. For one, it calls new selection code. Which code?? =) Little bugger.
Why not select the rows based on a mouse event (mouse down and/or up) in the view.
>>>> int nFirstIndex = nIndex / 3;
>>>> nFirstIndex *= 3;
That turns any index to the next lower multiple of 3, e. g. line 4 and line 5 got the same nFirstIndex. That is hardly what you intend to do?
Regards, Alex
>>>> nFirstIndex *= 3;
That turns any index to the next lower multiple of 3, e. g. line 4 and line 5 got the same nFirstIndex. That is hardly what you intend to do?
Regards, Alex
ASKER
Hey Alex, yes, that's what I'm looking for.... The app I'm writing requires it for display purposes (each line is really like 3 lines)...
Andy - I think that's a good idea - I was getting a problem with setting a selection in OnItemchangedData since it was causing infinite recursion and I couldn't figure out how to stop it.... I'll try it! Let you know at the end of the day... Very little internet access later.... Thanks!
Andy - I think that's a good idea - I was getting a problem with setting a selection in OnItemchangedData since it was causing infinite recursion and I couldn't figure out how to stop it.... I'll try it! Let you know at the end of the day... Very little internet access later.... Thanks!
<I was getting a problem with setting a selection in OnItemchangedData since it was causing infinite recursion>
I had that as a worry about the way you were attempting it.. Let the view do the default behaviour for the mouse event then run you code to select the three lines.
I had that as a worry about the way you were attempting it.. Let the view do the default behaviour for the mouse event then run you code to select the three lines.
ASKER
Do I need to GetView off my CListCtrl? I'm not sure how to do this.... Is there a way to set a new view for my CListCtrl that handles the mouse clicks? Hmm....
Your earlier comments had the class CMyView - handle the mouse click there.
ASKER
That's the view in an MDI app - How do I know what index was clicked on... Do I have to do gymnastics in figuring out the client click position and where the scrollbar in my list is set?
Is it a CListView based view?
If you let the base class handle the mouse event then that will perform the default behaviour and select the line you clicked on. Then just interrogate the list control to find out what line is selected and perform your routine to select the three lines.
If you let the base class handle the mouse event then that will perform the default behaviour and select the line you clicked on. Then just interrogate the list control to find out what line is selected and perform your routine to select the three lines.
SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
ASKER
Thanks Alex for your infinite recursion blocker!
Andy - my list is a CLIstCtrl - not a CListView... Actually, it's a class that extends CListCtrl (CEditableListCtrl - my own)....
Andy - my list is a CLIstCtrl - not a CListView... Actually, it's a class that extends CListCtrl (CEditableListCtrl - my own)....
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.