Click here to Skip to main content
15,905,508 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Scenario:
A dialog, has various other controls along with List Box control::

LBS_MULTIPLESEL
ON_LBN_SELCHANGE is used to get the index of the latest selected control.
If the user hold the ControlKey, multiple selection occurs else, it acts like a normal multiple selection list box.

so whenever ON_LBN_SELCHANGE occurs by selecting a new item(non selected item), the old selection is retained if the user holds control key and new item is also selected.

whenever ON_LBN_SELCHANGE occurs by selecting an already selected item, the old selections are retained if the user holds control key and the clicked item is also deselected (or) the old selections are cleared off if the user doesn't hold control key and clicked item is selected.

Problem:
according to working of a MFC Multiple selection listbox, when we select a new item, the old item remains selected, whenever we select on already selected item its deselected. these were happening in the MouseDown events itself.

After these mouse down event, comes the mouse up event which triggers the ON_LBN_SELCHANGE(i am using this because it gives the correct index of the newly clicked or anchored item here), now this is where i am deselecting the already selected item or selecting the new item. So clearly i am doing reverse of what MFC is doing in the Mouse Down event.

So i the user doesn't hold the control key i am doing the reverse action what mouse down event is doing.

Brief:
This is annoying, lets take an example where user click the mouse down and holds for 3 seconds and then clicks mouse up, so if he selects a new item, and holds the mouse down the old item is still selected (MFC) and he thinks both were selected, now when he releases the mouse i am deselecting the old one (done by ON_LBN_SELCHANGE).

Similarly if he clicks on an already selected item, the item is deselcted in mouse down (MFC) and i am selecting it back (ON_LBN_SELCHANGE)

Workaround or my solution:
Capture the mouse down event in the ListBox and handle the situation accordingly.
BOOL CLGDlg::PreTranslateMessage(MSG* pMsg)
{
	if (pMsg->message == WM_LBUTTONDOWN)
	{
		CWnd* pWnd = GetFocus();
		if (pWnd->GetDlgCtrlID() == IDC_LNGNAMEBOX)
		{
			if(GetKeyState(VK_CONTROL) < 0)
			{
				//dont do anything since its working fine
			}
			else
			{
			        int SelectedItem;
				SelectedItem = m_LngNameList.GetAnchorIndex();
				m_LngNameList.SetSel(SelectedItem, 0);
			}
		}
	}
}


This is not working for the first time and last time, since the focus is not on the list box the first time i click it or the focus is still in the listbox when i click away from it.

Any suggestions please?
Posted

1 solution

If you want to do this within PreTranslateMessage(), then another way to identify the window that was clicked on is to look at the location of the click and see if it's within the location of the button, since that information is in the MSG* parameter.

//MSG definition
typedef struct tagMSG {     // msg
   HWND hwnd;
   UINT message;
   WPARAM wParam;
   LPARAM lParam;
   DWORD time;
   POINT pt;
} MSG;


Use GetDlgItem() to get a handle to the window of the button, then GetWindowRect() to find its location to compare with the location of the click.
 
Share this answer
 
Comments
amarasat 9-Jun-11 15:53pm    
You were right, i was able to use the pt of PMsg and solve my issue
Albert Holguin 9-Jun-11 16:37pm    
cool :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900