MsgRouting AwtScrollbar::HandleEvent(MSG *msg, BOOL synthetic) { // SCROLLBAR control doesn't cause activation on mouse/key events, // so we can safely (for synthetic focus) pass them to the system proc. if (IsFocusingMouseMessage(msg)) { // Left button press was already routed to default window // procedure in the WmMouseDown above. Propagating synthetic // press seems like a bad idea as internal message loop // doesn't know how to unwrap synthetic release. delete msg; return mrConsume; } return AwtComponent::HandleEvent(msg, synthetic); }
MsgRouting AwtCheckbox::HandleEvent(MSG *msg, BOOL synthetic) { if (IsFocusingMouseMessage(msg)) { SendMessage(BM_SETSTATE, (WPARAM)(msg->message == WM_LBUTTONDOWN ? TRUE : FALSE)); delete msg; return mrConsume; } if (IsFocusingKeyMessage(msg)) { SendMessage(BM_SETSTATE, (WPARAM)(msg->message == WM_KEYDOWN ? TRUE : FALSE)); if (msg->message == WM_KEYDOWN) { m_fLButtonDowned = TRUE; } else if (m_fLButtonDowned == TRUE) { WmNotify(BN_CLICKED); m_fLButtonDowned = TRUE; } delete msg; return mrConsume; } return AwtComponent::HandleEvent(msg, synthetic); }
MsgRouting AwtList::HandleEvent(MSG *msg, BOOL synthetic) { if (IsFocusingMouseMessage(msg)) { LONG item = static_cast<LONG>(SendListMessage(LB_ITEMFROMPOINT, 0, msg->lParam)); if (item != LB_ERR) { if (isMultiSelect) { if (IsItemSelected(item)) { Deselect(item); } else { Select(item); } } else { Select(item); } } delete msg; return mrConsume; } if (msg->message == WM_KEYDOWN && msg->wParam == VK_RETURN) { WmNotify(LBN_DBLCLK); } return AwtComponent::HandleEvent(msg, synthetic); }
MsgRouting AwtTextField::HandleEvent(MSG *msg, BOOL synthetic) { MsgRouting returnVal; /* * RichEdit 1.0 control starts internal message loop if the * left mouse button is pressed while the cursor is not over * the current selection or the current selection is empty. * Because of this we don't receive WM_MOUSEMOVE messages * while the left mouse button is pressed. To work around * this behavior we process the relevant mouse messages * by ourselves. * By consuming WM_MOUSEMOVE messages we also don't give * the RichEdit control a chance to recognize a drag gesture * and initiate its own drag-n-drop operation. * * The workaround also allows us to implement synthetic focus mechanism. */ if (IsFocusingMouseMessage(msg)) { LONG lCurPos = EditGetCharFromPos(msg->pt); /* * NOTE: Plain EDIT control always clears selection on mouse * button press. We are clearing the current selection only if * the mouse pointer is not over the selected region. * In this case we sacrifice backward compatibility * to allow dnd of the current selection. */ if (msg->message == WM_LBUTTONDBLCLK) { jchar echo = SendMessage(EM_GETPASSWORDCHAR); if(echo == 0){ SetStartSelectionPos(static_cast<LONG>(SendMessage( EM_FINDWORDBREAK, WB_MOVEWORDLEFT, lCurPos))); SetEndSelectionPos(static_cast<LONG>(SendMessage( EM_FINDWORDBREAK, WB_MOVEWORDRIGHT, lCurPos))); }else{ SetStartSelectionPos(0); SetEndSelectionPos(GetTextLength()); } } else { SetStartSelectionPos(lCurPos); SetEndSelectionPos(lCurPos); } CHARRANGE cr; cr.cpMin = GetStartSelectionPos(); cr.cpMax = GetEndSelectionPos(); EditSetSel(cr); delete msg; return mrConsume; } else if (msg->message == WM_LBUTTONUP) { /* * If the left mouse button is pressed on the selected region * we don't clear the current selection. We clear it on button * release instead. This is to allow dnd of the current selection. */ if (GetStartSelectionPos() == -1 && GetEndSelectionPos() == -1) { CHARRANGE cr; LONG lCurPos = EditGetCharFromPos(msg->pt); cr.cpMin = lCurPos; cr.cpMax = lCurPos; EditSetSel(cr); } /* * Cleanup the state variables when left mouse button is released. * These state variables are designed to reflect the selection state * while the left mouse button is pressed and be set to -1 otherwise. */ SetStartSelectionPos(-1); SetEndSelectionPos(-1); SetLastSelectionPos(-1); delete msg; return mrConsume; } else if (msg->message == WM_MOUSEMOVE && (msg->wParam & MK_LBUTTON)) { /* * We consume WM_MOUSEMOVE while the left mouse button is pressed, * so we have to simulate autoscrolling when mouse is moved outside * of the client area. */ POINT p; RECT r; BOOL bScrollLeft = FALSE; BOOL bScrollRight = FALSE; BOOL bScrollUp = FALSE; BOOL bScrollDown = FALSE; p.x = msg->pt.x; p.y = msg->pt.y; VERIFY(::GetClientRect(GetHWnd(), &r)); if (p.x < 0) { bScrollLeft = TRUE; p.x = 0; } else if (p.x > r.right) { bScrollRight = TRUE; p.x = r.right - 1; } LONG lCurPos = EditGetCharFromPos(p); if (GetStartSelectionPos() != -1 && GetEndSelectionPos() != -1 && lCurPos != GetLastSelectionPos()) { CHARRANGE cr; SetLastSelectionPos(lCurPos); cr.cpMin = GetStartSelectionPos(); cr.cpMax = GetLastSelectionPos(); EditSetSel(cr); } if (bScrollLeft == TRUE || bScrollRight == TRUE) { SCROLLINFO si; memset(&si, 0, sizeof(si)); si.cbSize = sizeof(si); si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; VERIFY(::GetScrollInfo(GetHWnd(), SB_HORZ, &si)); if (bScrollLeft == TRUE) { si.nPos = si.nPos - si.nPage / 2; si.nPos = max(si.nMin, si.nPos); } else if (bScrollRight == TRUE) { si.nPos = si.nPos + si.nPage / 2; si.nPos = min(si.nPos, si.nMax); } /* * Okay to use 16-bit position since RichEdit control adjusts * its scrollbars so that their range is always 16-bit. */ DASSERT(abs(si.nPos) < 0x8000); SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, LOWORD(si.nPos))); } delete msg; return mrConsume; } /* * Store the 'synthetic' parameter so that the WM_PASTE security check * happens only for synthetic events. */ m_synthetic = synthetic; returnVal = AwtComponent::HandleEvent(msg, synthetic); m_synthetic = FALSE; return returnVal; }