/***************************************************************** * HideCaret (USER32.@) */ BOOL WINAPI HideCaret( HWND hwnd ) { BOOL ret; RECT r; int old_state = 0; int hidden = 0; SERVER_START_REQ( set_caret_info ) { req->flags = SET_CARET_HIDE|SET_CARET_STATE; req->handle = wine_server_user_handle( hwnd ); req->x = 0; req->y = 0; req->hide = 1; req->state = 0; if ((ret = !wine_server_call_err( req ))) { hwnd = wine_server_ptr_handle( reply->full_handle ); r.left = reply->old_rect.left; r.top = reply->old_rect.top; r.right = reply->old_rect.right; r.bottom = reply->old_rect.bottom; old_state = reply->old_state; hidden = reply->old_hide; } } SERVER_END_REQ; if (ret && !hidden) { if (old_state) CARET_DisplayCaret( hwnd, &r ); KillSystemTimer( hwnd, TIMERID ); } return ret; }
BOOL CTCPSocketAsync::LocalSocketConnect(int iErrorCode, BOOL bNoEvent) { try { if (m_ulTimeout) //Kill the timer KillSystemTimer(); //Did we got an error if (!iErrorCode) //Set the connection status SetConnectionStatus(TRUE); //Call father return CAsyncSocket::SocketConnected(iErrorCode, bNoEvent); } ERROR_HANDLER_RETURN("LocalSocketConnect",FALSE) }
BOOL CTCPSocketAsync::SetConnectionTimeout(unsigned long ulMS) { try { //Do we have a timeout ? if (HasSystemTimer()) if (!KillSystemTimer()) { //Report it ReportError("SetConnectionTimeout","Failed to kill previous timer!"); //Exit return FALSE; } //Create the timer m_ulTimeout=ulMS; //Done return TRUE; } ERROR_HANDLER_RETURN("SetConnectionTimeout",FALSE) }
/***************************************************************** * DestroyCaret (USER32.@) */ BOOL WINAPI DestroyCaret(void) { BOOL ret; HWND prev = 0; RECT r; int old_state = 0; int hidden = 0; SERVER_START_REQ( set_caret_window ) { req->handle = 0; req->width = 0; req->height = 0; if ((ret = !wine_server_call_err( req ))) { prev = wine_server_ptr_handle( reply->previous ); r.left = reply->old_rect.left; r.top = reply->old_rect.top; r.right = reply->old_rect.right; r.bottom = reply->old_rect.bottom; old_state = reply->old_state; hidden = reply->old_hide; } } SERVER_END_REQ; if (ret && prev && !hidden) { /* FIXME: won't work if prev belongs to a different process */ KillSystemTimer( prev, TIMERID ); if (old_state) CARET_DisplayCaret( prev, &r ); } if (Caret.hBmp) DeleteObject( Caret.hBmp ); Caret.hBmp = 0; return ret; }
static void CALLBACK TrackMouseEventProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { POINT pos; INT hoverwidth = 0, hoverheight = 0, hittest; TRACE("hwnd %p, msg %04x, id %04lx, time %u\n", hwnd, uMsg, idEvent, dwTime); GetCursorPos(&pos); hwnd = WINPOS_WindowFromPoint(hwnd, pos, &hittest); TRACE("point %s hwnd %p hittest %d\n", wine_dbgstr_point(&pos), hwnd, hittest); SystemParametersInfoW(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0); SystemParametersInfoW(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0); TRACE("tracked pos %s, current pos %s, hover width %d, hover height %d\n", wine_dbgstr_point(&tracking_info.pos), wine_dbgstr_point(&pos), hoverwidth, hoverheight); /* see if this tracking event is looking for TME_LEAVE and that the */ /* mouse has left the window */ if (tracking_info.tme.dwFlags & TME_LEAVE) { check_mouse_leave(hwnd, hittest); } if (tracking_info.tme.hwndTrack != hwnd) { /* mouse is gone, stop tracking mouse hover */ tracking_info.tme.dwFlags &= ~TME_HOVER; } /* see if we are tracking hovering for this hwnd */ if (tracking_info.tme.dwFlags & TME_HOVER) { /* has the cursor moved outside the rectangle centered around pos? */ if ((abs(pos.x - tracking_info.pos.x) > (hoverwidth / 2)) || (abs(pos.y - tracking_info.pos.y) > (hoverheight / 2))) { /* record this new position as the current position */ tracking_info.pos = pos; } else { if (hittest == HTCLIENT) { ScreenToClient(hwnd, &pos); TRACE("client cursor pos %s\n", wine_dbgstr_point(&pos)); PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSEHOVER, get_key_state(), MAKELPARAM( pos.x, pos.y )); } else { if (tracking_info.tme.dwFlags & TME_NONCLIENT) PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSEHOVER, hittest, MAKELPARAM( pos.x, pos.y )); } /* stop tracking mouse hover */ tracking_info.tme.dwFlags &= ~TME_HOVER; } } /* stop the timer if the tracking list is empty */ if (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE))) { KillSystemTimer(tracking_info.tme.hwndTrack, timer); timer = 0; tracking_info.tme.hwndTrack = 0; tracking_info.tme.dwFlags = 0; tracking_info.tme.dwHoverTime = 0; } }
BOOL WINAPI TrackMouseEvent (TRACKMOUSEEVENT *ptme) { HWND hwnd; POINT pos; DWORD hover_time; INT hittest; TRACE("%x, %x, %p, %u\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime); if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) { WARN("wrong TRACKMOUSEEVENT size from app\n"); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } /* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */ if (ptme->dwFlags & TME_QUERY ) { *ptme = tracking_info.tme; /* set cbSize in the case it's not initialized yet */ ptme->cbSize = sizeof(TRACKMOUSEEVENT); return TRUE; /* return here, TME_QUERY is retrieving information */ } if (!IsWindow(ptme->hwndTrack)) { SetLastError(ERROR_INVALID_WINDOW_HANDLE); return FALSE; } hover_time = ptme->dwHoverTime; /* if HOVER_DEFAULT was specified replace this with the systems current value. * TME_LEAVE doesn't need to specify hover time so use default */ if (hover_time == HOVER_DEFAULT || hover_time == 0 || !(ptme->dwHoverTime&TME_HOVER)) SystemParametersInfoW(SPI_GETMOUSEHOVERTIME, 0, &hover_time, 0); GetCursorPos(&pos); hwnd = WINPOS_WindowFromPoint(ptme->hwndTrack, pos, &hittest); TRACE("point %s hwnd %p hittest %d\n", wine_dbgstr_point(&pos), hwnd, hittest); if (ptme->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT)) FIXME("Unknown flag(s) %08x\n", ptme->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT)); if (ptme->dwFlags & TME_CANCEL) { if (tracking_info.tme.hwndTrack == ptme->hwndTrack) { tracking_info.tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL); /* if we aren't tracking on hover or leave remove this entry */ if (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE))) { KillSystemTimer(tracking_info.tme.hwndTrack, timer); timer = 0; tracking_info.tme.hwndTrack = 0; tracking_info.tme.dwFlags = 0; tracking_info.tme.dwHoverTime = 0; } } } else { /* In our implementation it's possible that another window will receive a * WM_MOUSEMOVE and call TrackMouseEvent before TrackMouseEventProc is * called. In such a situation post the WM_MOUSELEAVE now */ if (tracking_info.tme.dwFlags & TME_LEAVE && tracking_info.tme.hwndTrack != NULL) check_mouse_leave(hwnd, hittest); if (timer) { KillSystemTimer(tracking_info.tme.hwndTrack, timer); timer = 0; tracking_info.tme.hwndTrack = 0; tracking_info.tme.dwFlags = 0; tracking_info.tme.dwHoverTime = 0; } if (ptme->hwndTrack == hwnd) { /* Adding new mouse event to the tracking list */ tracking_info.tme = *ptme; tracking_info.tme.dwHoverTime = hover_time; /* Initialize HoverInfo variables even if not hover tracking */ tracking_info.pos = pos; timer = SetSystemTimer(tracking_info.tme.hwndTrack, (UINT_PTR)&tracking_info.tme, hover_time, TrackMouseEventProc); } } return TRUE; }
BOOL CTCPSocketAsync::LocalConnect(unsigned short usSourcePort, IP aDestinationAddress, unsigned short usDestinationPort, BOOL bDisableAsync, BOOL bForceErrorEvent) { try { //Quit if not ok if (!CheckSocketValid()) return FALSE; //Set the async notification if (!bDisableAsync) { int iResult; iResult=InternalWSAAsyncSelect(WM_SOCKET_CONNECT, FD_CONNECT); if (iResult) { //Get the error code int iErrorCode; iErrorCode=GetSystemLastError(); //Report it SetLastError("Connect"); //Do we need to call event? if (bForceErrorEvent) SocketConnected(iErrorCode); //Exit return FALSE; } //Set our timeout if (m_ulTimeout && !IsBlocking()) if (!SetSystemTimeout(m_ulTimeout)) { //Report it ReportError("LocalConnect","Failed to set timer!"); //Do we need to call event? if (bForceErrorEvent) SocketConnected(GetErrorCode()); //Exit return FALSE; } } //Set to non blocking! else if (!Block()) return FALSE; //Set the flag m_bDisabledConnect=bDisableAsync; //Call the original connect BOOL bResult; bResult=CTCPSocket::Connect(usSourcePort, aDestinationAddress, usDestinationPort); //Reset the flag m_bDisabledConnect=FALSE; if (bResult) { //Call event, but only if in async if (!bDisableAsync && !IsBlocking()) //Call user, will add socket automatically return SocketConnected(0); else //Set as async return SetAsync(); } else if (GetSystemLastError()!=WSAEWOULDBLOCK || bDisableAsync || IsBlocking()) { if (m_ulTimeout) //Kill the timer KillSystemTimer(); //Get the error code int iErrorCode; iErrorCode=GetSystemLastError(); //Report it SetLastError("Connect"); //Do we need to call event? if (bForceErrorEvent && !bDisableAsync) SocketConnected(iErrorCode); //Exit return FALSE; } else return TRUE; } ERROR_HANDLER_RETURN("LocalConnect",FALSE) }
/***************************************************************** * CreateCaret (USER32.@) */ BOOL WINAPI CreateCaret( HWND hwnd, HBITMAP bitmap, INT width, INT height ) { BOOL ret; RECT r; int old_state = 0; int hidden = 0; HBITMAP hBmp = 0; HWND prev = 0; TRACE("hwnd=%p\n", hwnd); if (!hwnd) return FALSE; if (bitmap && (bitmap != (HBITMAP)1)) { BITMAP bmp; if (!GetObjectA( bitmap, sizeof(bmp), &bmp )) return FALSE; width = bmp.bmWidth; height = bmp.bmHeight; bmp.bmBits = NULL; hBmp = CreateBitmapIndirect(&bmp); if (hBmp) { /* copy the bitmap */ LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, bmp.bmWidthBytes * bmp.bmHeight); GetBitmapBits(bitmap, bmp.bmWidthBytes * bmp.bmHeight, buf); SetBitmapBits(hBmp, bmp.bmWidthBytes * bmp.bmHeight, buf); HeapFree(GetProcessHeap(), 0, buf); } } else { HDC hdc; if (!width) width = GetSystemMetrics(SM_CXBORDER); if (!height) height = GetSystemMetrics(SM_CYBORDER); /* create the uniform bitmap on the fly */ hdc = GetDC(hwnd); if (hdc) { HDC hMemDC = CreateCompatibleDC(hdc); if (hMemDC) { if ((hBmp = CreateCompatibleBitmap(hMemDC, width, height ))) { HBITMAP hPrevBmp = SelectObject(hMemDC, hBmp); SetRect( &r, 0, 0, width, height ); FillRect(hMemDC, &r, ULongToHandle((bitmap ? COLOR_GRAYTEXT : COLOR_WINDOW) + 1)); SelectObject(hMemDC, hPrevBmp); } DeleteDC(hMemDC); } ReleaseDC(hwnd, hdc); } } if (!hBmp) return FALSE; SERVER_START_REQ( set_caret_window ) { req->handle = wine_server_user_handle( hwnd ); req->width = width; req->height = height; if ((ret = !wine_server_call_err( req ))) { prev = wine_server_ptr_handle( reply->previous ); r.left = reply->old_rect.left; r.top = reply->old_rect.top; r.right = reply->old_rect.right; r.bottom = reply->old_rect.bottom; old_state = reply->old_state; hidden = reply->old_hide; } } SERVER_END_REQ; if (!ret) return FALSE; if (prev && !hidden) /* hide the previous one */ { /* FIXME: won't work if prev belongs to a different process */ KillSystemTimer( prev, TIMERID ); if (old_state) CARET_DisplayCaret( prev, &r ); } if (Caret.hBmp) DeleteObject( Caret.hBmp ); Caret.hBmp = hBmp; Caret.timeout = GetProfileIntA( "windows", "CursorBlinkRate", 500 ); return TRUE; }
static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt) { /* Previous mouse position for timer events */ static POINT prevPt; /* Thumb position when tracking started. */ static UINT trackThumbPos; /* Position in the scroll-bar of the last button-down event. */ static INT lastClickPos; /* Position in the scroll-bar of the last mouse event. */ static INT lastMousePos; enum SCROLL_HITTEST hittest; HWND hwndOwner, hwndCtl; BOOL vertical; SCROLLINFO si; SCROLLBARINFO sbi; DRAW_CONTEXT context; si.cbSize = sizeof(si); sbi.cbSize = sizeof(sbi); si.fMask = SIF_ALL; GetScrollInfo(hwnd, nBar, &si); GetScrollBarInfo(hwnd, SCROLL_getObjectId(nBar), &sbi); vertical = SCROLL_IsVertical(hwnd, nBar); if(sbi.rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_UNAVAILABLE && sbi.rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_UNAVAILABLE ) { return; } ThemeInitDrawContext(&context, hwnd, 0); #ifndef ROS_SUCKS /* The scrollbar rect is in screen coordinates */ // OffsetRect(&sbi.rcScrollBar, -context.wi.rcWindow.left, -context.wi.rcWindow.top); #endif if ((SCROLL_trackHitTest == SCROLL_NOWHERE) && (msg != WM_LBUTTONDOWN)) return; hwndOwner = (nBar == SB_CTL) ? GetParent(hwnd) : hwnd; hwndCtl = (nBar == SB_CTL) ? hwnd : 0; switch(msg) { case WM_LBUTTONDOWN: /* Initialise mouse tracking */ HideCaret(hwnd); /* hide caret while holding down LBUTTON */ SCROLL_trackVertical = vertical; SCROLL_trackHitTest = hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt, FALSE ); lastClickPos = vertical ? (pt.y - sbi.rcScrollBar.top) : (pt.x - sbi.rcScrollBar.left); lastMousePos = lastClickPos; trackThumbPos = sbi.xyThumbTop; prevPt = pt; SetCapture( hwnd ); break; case WM_MOUSEMOVE: hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt, TRUE ); prevPt = pt; break; case WM_LBUTTONUP: hittest = SCROLL_NOWHERE; ReleaseCapture(); /* if scrollbar has focus, show back caret */ if (hwnd==GetFocus()) ShowCaret(hwnd); break; case WM_SYSTIMER: pt = prevPt; hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt, FALSE ); break; default: return; /* Should never happen */ } //TRACE("Event: hwnd=%p bar=%d msg=%s pt=%d,%d hit=%d\n", // hwnd, nBar, SPY_GetMsgName(msg,hwnd), pt.x, pt.y, hittest ); switch(SCROLL_trackHitTest) { case SCROLL_NOWHERE: /* No tracking in progress */ break; case SCROLL_TOP_ARROW: if (hittest == SCROLL_trackHitTest) { SCROLL_DrawArrows( &context, &sbi, vertical, SCROLL_trackHitTest, 0 ); if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER)) { SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, SB_LINEUP, (LPARAM)hwndCtl ); } SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, NULL ); } else { SCROLL_DrawArrows( &context, &sbi, vertical, 0, 0 ); KillSystemTimer( hwnd, SCROLL_TIMER ); } break; case SCROLL_TOP_RECT: SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical, SCROLL_trackHitTest, 0); if (hittest == SCROLL_trackHitTest) { if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER)) { SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, SB_PAGEUP, (LPARAM)hwndCtl ); } SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, NULL ); } else KillSystemTimer( hwnd, SCROLL_TIMER ); break; case SCROLL_THUMB: if (msg == WM_LBUTTONDOWN) { SCROLL_TrackingWin = hwnd; SCROLL_TrackingBar = nBar; SCROLL_TrackingPos = trackThumbPos + lastMousePos - lastClickPos; SCROLL_TrackingVal = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar, vertical, SCROLL_TrackingPos ); if (!SCROLL_MovingThumb) SCROLL_DrawMovingThumb(&context, &sbi, vertical); } else if (msg == WM_LBUTTONUP) { if (SCROLL_MovingThumb) SCROLL_DrawMovingThumb(&context, &sbi, vertical); SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical, 0, SCROLL_trackHitTest ); } else /* WM_MOUSEMOVE */ { INT pos; if (!SCROLL_PtInRectEx( &sbi.rcScrollBar, pt, vertical )) pos = lastClickPos; else { pt = SCROLL_ClipPos( &sbi.rcScrollBar, pt ); pos = vertical ? (pt.y - sbi.rcScrollBar.top) : (pt.x - sbi.rcScrollBar.left); } if ( (pos != lastMousePos) || (!SCROLL_MovingThumb) ) { if (SCROLL_MovingThumb) SCROLL_DrawMovingThumb( &context, &sbi, vertical); lastMousePos = pos; SCROLL_TrackingPos = trackThumbPos + pos - lastClickPos; SCROLL_TrackingVal = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar, vertical, SCROLL_TrackingPos ); SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, MAKEWPARAM( SB_THUMBTRACK, SCROLL_TrackingVal), (LPARAM)hwndCtl ); if (!SCROLL_MovingThumb) SCROLL_DrawMovingThumb( &context, &sbi, vertical); } } break; case SCROLL_BOTTOM_RECT: if (hittest == SCROLL_trackHitTest) { SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical, SCROLL_trackHitTest, 0 ); if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER)) { SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, SB_PAGEDOWN, (LPARAM)hwndCtl ); } SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, NULL ); } else { SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical, 0, 0 ); KillSystemTimer( hwnd, SCROLL_TIMER ); } break; case SCROLL_BOTTOM_ARROW: if (hittest == SCROLL_trackHitTest) { SCROLL_DrawArrows( &context, &sbi, vertical, SCROLL_trackHitTest, 0 ); if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER)) { SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, SB_LINEDOWN, (LPARAM)hwndCtl ); } SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, NULL ); } else { SCROLL_DrawArrows( &context, &sbi, vertical, 0, 0 ); KillSystemTimer( hwnd, SCROLL_TIMER ); } break; } if (msg == WM_LBUTTONDOWN) { if (hittest == SCROLL_THUMB) { UINT val = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar, vertical, trackThumbPos + lastMousePos - lastClickPos ); SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, MAKEWPARAM( SB_THUMBTRACK, val ), (LPARAM)hwndCtl ); } } if (msg == WM_LBUTTONUP) { hittest = SCROLL_trackHitTest; SCROLL_trackHitTest = SCROLL_NOWHERE; /* Terminate tracking */ if (hittest == SCROLL_THUMB) { UINT val = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar, vertical, trackThumbPos + lastMousePos - lastClickPos ); SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, MAKEWPARAM( SB_THUMBPOSITION, val ), (LPARAM)hwndCtl ); } /* SB_ENDSCROLL doesn't report thumb position */ SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, SB_ENDSCROLL, (LPARAM)hwndCtl ); /* Terminate tracking */ SCROLL_TrackingWin = 0; } ThemeCleanupDrawContext(&context); }
/*********************************************************************** * IntScrollHandleScrollEvent * * Handle a mouse or timer event for the scrollbar. * 'Pt' is the location of the mouse event in drawing coordinates */ static VOID FASTCALL IntScrollHandleScrollEvent(HWND Wnd, INT SBType, UINT Msg, POINT Pt) { static POINT PrevPt; /* Previous mouse position for timer events */ static UINT TrackThumbPos; /* Thumb position when tracking started. */ static INT LastClickPos; /* Position in the scroll-bar of the last button-down event. */ static INT LastMousePos; /* Position in the scroll-bar of the last mouse event. */ DWORD HitTest; HWND WndOwner, WndCtl; BOOL Vertical; HDC Dc; SCROLLBARINFO ScrollBarInfo; SETSCROLLBARINFO NewInfo; if (! IntGetScrollBarInfo(Wnd, SBType, &ScrollBarInfo)) { return; } if (SCROLL_NOWHERE == ScrollTrackHitTest && WM_LBUTTONDOWN != Msg) { return; } NewInfo.nTrackPos = ScrollTrackingVal; NewInfo.reserved = ScrollBarInfo.reserved; memcpy(NewInfo.rgstate, ScrollBarInfo.rgstate, (CCHILDREN_SCROLLBAR + 1) * sizeof(DWORD)); if (SB_CTL == SBType && 0 != (GetWindowLongPtrW(Wnd, GWL_STYLE) & (SBS_SIZEGRIP | SBS_SIZEBOX))) { switch(Msg) { case WM_LBUTTONDOWN: /* Initialise mouse tracking */ HideCaret(Wnd); /* hide caret while holding down LBUTTON */ SetCapture(Wnd); PrevPt = Pt; ScrollTrackHitTest = HitTest = SCROLL_THUMB; break; case WM_MOUSEMOVE: GetClientRect(GetParent(GetParent(Wnd)), &ScrollBarInfo.rcScrollBar); PrevPt = Pt; break; case WM_LBUTTONUP: ReleaseCapture(); ScrollTrackHitTest = HitTest = SCROLL_NOWHERE; if (Wnd == GetFocus()) { ShowCaret(Wnd); } break; case WM_SYSTIMER: Pt = PrevPt; break; } return; } Dc = GetDCEx(Wnd, 0, DCX_CACHE | ((SB_CTL == SBType) ? 0 : DCX_WINDOW)); if (SB_VERT == SBType) { Vertical = TRUE; } else if (SB_HORZ == SBType) { Vertical = FALSE; } else { Vertical = (0 != (GetWindowLongPtrW(Wnd, GWL_STYLE) & SBS_VERT)); } WndOwner = (SB_CTL == SBType) ? GetParent(Wnd) : Wnd; WndCtl = (SB_CTL == SBType) ? Wnd : NULL; switch (Msg) { case WM_LBUTTONDOWN: /* Initialise mouse tracking */ HideCaret(Wnd); /* hide caret while holding down LBUTTON */ ScrollTrackVertical = Vertical; ScrollTrackHitTest = HitTest = IntScrollHitTest(&ScrollBarInfo, Vertical, Pt, FALSE ); LastClickPos = Vertical ? (Pt.y - ScrollBarInfo.rcScrollBar.top) : (Pt.x - ScrollBarInfo.rcScrollBar.left); LastMousePos = LastClickPos; TrackThumbPos = ScrollBarInfo.xyThumbTop; PrevPt = Pt; if (SB_CTL == SBType && 0 != (GetWindowLongPtrW(Wnd, GWL_STYLE) & WS_TABSTOP)) { SetFocus(Wnd); } SetCapture(Wnd); ScrollBarInfo.rgstate[ScrollTrackHitTest] |= STATE_SYSTEM_PRESSED; NewInfo.rgstate[ScrollTrackHitTest] = ScrollBarInfo.rgstate[ScrollTrackHitTest]; NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo); break; case WM_MOUSEMOVE: HitTest = IntScrollHitTest(&ScrollBarInfo, Vertical, Pt, TRUE); PrevPt = Pt; break; case WM_LBUTTONUP: HitTest = SCROLL_NOWHERE; ReleaseCapture(); /* if scrollbar has focus, show back caret */ if (Wnd == GetFocus()) { ShowCaret(Wnd); } ScrollBarInfo.rgstate[ScrollTrackHitTest] &= ~STATE_SYSTEM_PRESSED; NewInfo.rgstate[ScrollTrackHitTest] = ScrollBarInfo.rgstate[ScrollTrackHitTest]; NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo); break; case WM_SYSTIMER: Pt = PrevPt; HitTest = IntScrollHitTest(&ScrollBarInfo, Vertical, Pt, FALSE); break; default: return; /* Should never happen */ } switch (ScrollTrackHitTest) { case SCROLL_NOWHERE: /* No tracking in progress */ break; case SCROLL_TOP_ARROW: if (HitTest == ScrollTrackHitTest) { if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg)) { SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, SB_LINEUP, (LPARAM) WndCtl); } SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, (TIMERPROC) NULL); } else { KillSystemTimer(Wnd, SCROLL_TIMER); } break; case SCROLL_TOP_RECT: if (HitTest == ScrollTrackHitTest) { if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg)) { SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, SB_PAGEUP, (LPARAM) WndCtl); } SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, (TIMERPROC) NULL); } else { KillSystemTimer(Wnd, SCROLL_TIMER); } break; case SCROLL_THUMB: if (WM_LBUTTONDOWN == Msg) { ScrollTrackingWin = Wnd; ScrollTrackingBar = SBType; ScrollTrackingPos = TrackThumbPos + LastMousePos - LastClickPos; ScrollTrackingVal = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo, Vertical, ScrollTrackingPos); NewInfo.nTrackPos = ScrollTrackingVal; NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo); IntScrollDrawMovingThumb(Dc, &ScrollBarInfo, Vertical); } else if (WM_LBUTTONUP == Msg) { ScrollTrackingWin = 0; ScrollTrackingVal = 0; IntDrawScrollInterior(Wnd, Dc, SBType, Vertical, &ScrollBarInfo); } else /* WM_MOUSEMOVE */ { UINT Pos; if (! IntScrollPtInRectEx(&ScrollBarInfo.rcScrollBar, Pt, Vertical)) { Pos = LastClickPos; } else { Pt = IntScrollClipPos(&ScrollBarInfo.rcScrollBar, Pt); Pos = Vertical ? (Pt.y - ScrollBarInfo.rcScrollBar.top) : (Pt.x - ScrollBarInfo.rcScrollBar.left); } if (Pos != LastMousePos || ! ScrollMovingThumb) { LastMousePos = Pos; ScrollTrackingPos = TrackThumbPos + Pos - LastClickPos; ScrollTrackingVal = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo, Vertical, ScrollTrackingPos); NewInfo.nTrackPos = ScrollTrackingVal; NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo); IntScrollDrawMovingThumb(Dc, &ScrollBarInfo, Vertical); SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, MAKEWPARAM(SB_THUMBTRACK, ScrollTrackingVal), (LPARAM) WndCtl); } } break; case SCROLL_BOTTOM_RECT: if (HitTest == ScrollTrackHitTest) { if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg)) { SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, SB_PAGEDOWN, (LPARAM) WndCtl); } SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, (TIMERPROC) NULL); } else { KillSystemTimer(Wnd, SCROLL_TIMER); } break; case SCROLL_BOTTOM_ARROW: if (HitTest == ScrollTrackHitTest) { if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg)) { SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, SB_LINEDOWN, (LPARAM) WndCtl); } SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, (TIMERPROC) NULL); } else { KillSystemTimer(Wnd, SCROLL_TIMER); } break; } if (WM_LBUTTONDOWN == Msg) { if (SCROLL_THUMB == HitTest) { UINT Val = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo, Vertical, TrackThumbPos + LastMousePos - LastClickPos); SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, MAKEWPARAM(SB_THUMBTRACK, Val), (LPARAM) WndCtl); } } if (WM_LBUTTONUP == Msg) { HitTest = ScrollTrackHitTest; ScrollTrackHitTest = SCROLL_NOWHERE; /* Terminate tracking */ if (SCROLL_THUMB == HitTest) { UINT Val = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo, Vertical, TrackThumbPos + LastMousePos - LastClickPos); SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, Val), (LPARAM) WndCtl); } SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, SB_ENDSCROLL, (LPARAM) WndCtl); } ReleaseDC(Wnd, Dc); }
BOOL ZKillSystemTimer( HWND h, UINT u ) { return KillSystemTimer(h, u ) ; }