mouseDown = false;
LRESULT sendMouseDownEvent (int type, int button, int msg, int wParam, int lParam) {	/*	* Feature in Windows.  Inside WM_LBUTTONDOWN and WM_RBUTTONDOWN,	* the widget starts a modal loop to determine if the user wants	* to begin a drag/drop operation or marque select.  Unfortunately,	* this modal loop eats the corresponding mouse up.  The fix is to	* detect the cases when the modal loop has eaten the mouse up and	* issue a fake mouse up.	*	* By observation, when the mouse is clicked anywhere but the check	* box, the widget eats the mouse up.  When the mouse is dragged,	* the widget does not eat the mouse up.	*/	LVHITTESTINFO pinfo = new LVHITTESTINFO ();	pinfo.x = (short) (lParam & 0xFFFF);	pinfo.y = (short) (lParam >> 16);	OS.SendMessage (handle, OS.LVM_HITTEST, 0, pinfo);	sendMouseEvent (type, button, handle, msg, wParam, lParam);	/*	* Force the table to have focus so that when the user	* reselects the focus item, the LVIS_FOCUSED state bits	* for the item will be set.  These bits are used when	* the table is multi-select to issue the selection	* event.  If the user did not click on an item, then	* set focus to the table so that it will come to the	* front and take focus in the work around below.	*/	OS.SetFocus (handle);			/*	* Feature in Windows.  When the user selects outside of	* a table item, Windows deselects all the items, even	* when the table is multi-select.  While not strictly	* wrong, this is unexpected.  The fix is to detect the	* case and avoid calling the window proc.	*/	if (pinfo.iItem == -1) {		if (OS.GetCapture () != handle) OS.SetCapture (handle);		return LRESULT.ZERO;	}		/*	* Feature in Windows.  When a table item is reselected	* in a single-select table, Windows does not issue a	* WM_NOTIFY because the item state has not changed.	* This is strictly correct but is inconsistent with the	* list widget and other widgets in Windows.  The fix is	* to detect the case when an item is reselected and issue	* the notification.	* 	* NOTE: This code runs for multi-select as well, ignoring	* the selection that is issed from WM_NOTIFY.	*/	boolean wasSelected = false;	int count = OS.SendMessage (handle, OS.LVM_GETSELECTEDCOUNT, 0, 0);	if (count == 1 && pinfo.iItem != -1) {		LVITEM lvItem = new LVITEM ();		lvItem.mask = OS.LVIF_STATE;		lvItem.stateMask = OS.LVIS_SELECTED;		lvItem.iItem = pinfo.iItem;		OS.SendMessage (handle, OS.LVM_GETITEM, 0, lvItem);		wasSelected = (lvItem.state & OS.LVIS_SELECTED) != 0;		if (wasSelected) ignoreSelect = true;	}	dragStarted = false;	int code = callWindowProc (handle, msg, wParam, lParam);	if (wasSelected) {		ignoreSelect = false;		Event event = new Event ();		event.item = _getItem (pinfo.iItem);		postEvent (SWT.Selection, event);	}	if (dragStarted) {		if (OS.GetCapture () != handle) OS.SetCapture (handle);	} else {		int flags = OS.LVHT_ONITEMLABEL | OS.LVHT_ONITEMICON;		boolean fakeMouseUp = (pinfo.flags & flags) != 0;		if (!fakeMouseUp && (style & SWT.MULTI) != 0) {			fakeMouseUp = (pinfo.flags & OS.LVHT_ONITEMSTATEICON) == 0;		}		if (fakeMouseUp) {			mouseDown = false;			sendMouseEvent (SWT.MouseUp, button, handle, msg, wParam, lParam);		}	}	dragStarted = false;	return new LRESULT (code);}