DWORD FASTCALL GetNCHitEx(PWND pWnd, POINT pt) { RECT rcWindow, rcClient; DWORD Style, ExStyle; if (!pWnd) return HTNOWHERE; if (pWnd == UserGetDesktopWindow()) // pWnd->fnid == FNID_DESKTOP) { rcClient.left = rcClient.top = rcWindow.left = rcWindow.top = 0; rcWindow.right = UserGetSystemMetrics(SM_CXSCREEN); rcWindow.bottom = UserGetSystemMetrics(SM_CYSCREEN); rcClient.right = UserGetSystemMetrics(SM_CXSCREEN); rcClient.bottom = UserGetSystemMetrics(SM_CYSCREEN); } else { rcClient = pWnd->rcClient; rcWindow = pWnd->rcWindow; } if (!RECTL_bPointInRect(&rcWindow, pt.x, pt.y)) return HTNOWHERE; Style = pWnd->style; ExStyle = pWnd->ExStyle; if (Style & WS_MINIMIZE) return HTCAPTION; if (RECTL_bPointInRect( &rcClient, pt.x, pt.y )) return HTCLIENT; /* Check borders */ if (HAS_THICKFRAME( Style, ExStyle )) { RECTL_vInflateRect(&rcWindow, -UserGetSystemMetrics(SM_CXFRAME), -UserGetSystemMetrics(SM_CYFRAME) ); if (!RECTL_bPointInRect(&rcWindow, pt.x, pt.y )) { /* Check top sizing border */ if (pt.y < rcWindow.top) { if (pt.x < rcWindow.left+UserGetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT; if (pt.x >= rcWindow.right-UserGetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT; return HTTOP; } /* Check bottom sizing border */ if (pt.y >= rcWindow.bottom) { if (pt.x < rcWindow.left+UserGetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT; if (pt.x >= rcWindow.right-UserGetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT; return HTBOTTOM; } /* Check left sizing border */ if (pt.x < rcWindow.left) { if (pt.y < rcWindow.top+UserGetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT; if (pt.y >= rcWindow.bottom-UserGetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT; return HTLEFT; } /* Check right sizing border */ if (pt.x >= rcWindow.right) { if (pt.y < rcWindow.top+UserGetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT; if (pt.y >= rcWindow.bottom-UserGetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT; return HTRIGHT; } } } else /* No thick frame */ { if (HAS_DLGFRAME( Style, ExStyle )) RECTL_vInflateRect(&rcWindow, -UserGetSystemMetrics(SM_CXDLGFRAME), -UserGetSystemMetrics(SM_CYDLGFRAME)); else if (HAS_THINFRAME( Style, ExStyle )) RECTL_vInflateRect(&rcWindow, -UserGetSystemMetrics(SM_CXBORDER), -UserGetSystemMetrics(SM_CYBORDER)); if (!RECTL_bPointInRect( &rcWindow, pt.x, pt.y )) return HTBORDER; } /* Check caption */ if ((Style & WS_CAPTION) == WS_CAPTION) { if (ExStyle & WS_EX_TOOLWINDOW) rcWindow.top += UserGetSystemMetrics(SM_CYSMCAPTION) - 1; else rcWindow.top += UserGetSystemMetrics(SM_CYCAPTION) - 1; if (!RECTL_bPointInRect( &rcWindow, pt.x, pt.y )) { BOOL min_or_max_box = (Style & WS_SYSMENU) && (Style & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX)); if (ExStyle & WS_EX_LAYOUTRTL) { /* Check system menu */ if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW) && NC_IconForWindow(pWnd)) { rcWindow.right -= UserGetSystemMetrics(SM_CYCAPTION) - 1; if (pt.x > rcWindow.right) return HTSYSMENU; } /* Check close button */ if (Style & WS_SYSMENU) { rcWindow.left += UserGetSystemMetrics(SM_CYCAPTION); if (pt.x < rcWindow.left) return HTCLOSE; } /* Check maximize box */ /* In Win95 there is automatically a Maximize button when there is a minimize one */ if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW)) { rcWindow.left += UserGetSystemMetrics(SM_CXSIZE); if (pt.x < rcWindow.left) return HTMAXBUTTON; } /* Check minimize box */ if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW)) { rcWindow.left += UserGetSystemMetrics(SM_CXSIZE); if (pt.x < rcWindow.left) return HTMINBUTTON; } } else { /* Check system menu */ if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW) && NC_IconForWindow(pWnd)) { rcWindow.left += UserGetSystemMetrics(SM_CYCAPTION) - 1; if (pt.x < rcWindow.left) return HTSYSMENU; } /* Check close button */ if (Style & WS_SYSMENU) { rcWindow.right -= UserGetSystemMetrics(SM_CYCAPTION); if (pt.x > rcWindow.right) return HTCLOSE; } /* Check maximize box */ /* In Win95 there is automatically a Maximize button when there is a minimize one */ if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW)) { rcWindow.right -= UserGetSystemMetrics(SM_CXSIZE); if (pt.x > rcWindow.right) return HTMAXBUTTON; } /* Check minimize box */ if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW)) { rcWindow.right -= UserGetSystemMetrics(SM_CXSIZE); if (pt.x > rcWindow.right) return HTMINBUTTON; } } return HTCAPTION; } } /* Check menu bar */ if (HAS_MENU( pWnd, Style ) && (pt.y < rcClient.top) && (pt.x >= rcClient.left) && (pt.x < rcClient.right)) return HTMENU; /* Check vertical scroll bar */ if (ExStyle & WS_EX_LAYOUTRTL) ExStyle ^= WS_EX_LEFTSCROLLBAR; if (Style & WS_VSCROLL) { if((ExStyle & WS_EX_LEFTSCROLLBAR) != 0) rcClient.left -= UserGetSystemMetrics(SM_CXVSCROLL); else rcClient.right += UserGetSystemMetrics(SM_CXVSCROLL); if (RECTL_bPointInRect( &rcClient, pt.x, pt.y )) return HTVSCROLL; } /* Check horizontal scroll bar */ if (Style & WS_HSCROLL) { rcClient.bottom += UserGetSystemMetrics(SM_CYHSCROLL); if (RECTL_bPointInRect( &rcClient, pt.x, pt.y )) { /* Check size box */ if ((Style & WS_VSCROLL) && ((((ExStyle & WS_EX_LEFTSCROLLBAR) != 0) && (pt.x <= rcClient.left + UserGetSystemMetrics(SM_CXVSCROLL))) || (((ExStyle & WS_EX_LEFTSCROLLBAR) == 0) && (pt.x >= rcClient.right - UserGetSystemMetrics(SM_CXVSCROLL))))) return HTSIZE; return HTHSCROLL; } } /* Has to return HTNOWHERE if nothing was found Could happen when a window has a customized non client area */ return HTNOWHERE; }
// // Process win32k system timers. // VOID CALLBACK SystemTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { PDESKTOP pDesk; PWND pWnd = NULL; if (hwnd) { pWnd = UserGetWindowObject(hwnd); if (!pWnd) { ERR( "System Timer Proc has invalid window handle! 0x%x Id: %d\n", hwnd, idEvent); return; } } else { TRACE( "Windowless Timer Running!\n" ); return; } switch (idEvent) { /* Used in NtUserTrackMouseEvent. */ case ID_EVENT_SYSTIMER_MOUSEHOVER: { POINT Point; UINT Msg; WPARAM wParam; pDesk = pWnd->head.rpdesk; if ( pDesk->dwDTFlags & DF_TME_HOVER && pWnd == pDesk->spwndTrack ) { Point = gpsi->ptCursor; if ( RECTL_bPointInRect(&pDesk->rcMouseHover, Point.x, Point.y) ) { if (pDesk->htEx == HTCLIENT) // In a client area. { wParam = get_key_state(); Msg = WM_MOUSEHOVER; if (pWnd->ExStyle & WS_EX_LAYOUTRTL) { Point.x = pWnd->rcClient.right - Point.x - 1; } else Point.x -= pWnd->rcClient.left; Point.y -= pWnd->rcClient.top; } else { wParam = pDesk->htEx; // Need to support all HTXYZ hits. Msg = WM_NCMOUSEHOVER; } UserPostMessage(hwnd, Msg, wParam, MAKELPARAM(Point.x, Point.y)); pDesk->dwDTFlags &= ~DF_TME_HOVER; break; // Kill this timer. } } } return; // Not this window so just return. default: ERR( "System Timer Proc invalid id %d!\n", idEvent ); break; } IntKillTimer(pWnd, idEvent, TRUE); }