- Fix hot tracking but does not clear it properly. See bug 6257.
- Ported NC_HandleNCHitTest from wine, will sync User32 later.

svn path=/trunk/; revision=52163
This commit is contained in:
James Tabor 2011-06-09 20:00:43 +00:00
parent 262ddc034b
commit 69a5b343d1
3 changed files with 258 additions and 12 deletions

View file

@ -28,6 +28,21 @@ BOOL FASTCALL UserUpdateUiState(PWND Wnd, WPARAM wParam);
#define HAS_THINFRAME(Style, ExStyle) \
(((Style) & WS_BORDER) || (!((Style) & (WS_CHILD | WS_POPUP))))
#define HAS_BIGFRAME(style,exStyle) \
(((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
((exStyle) & WS_EX_DLGMODALFRAME))
#define HAS_STATICOUTERFRAME(style,exStyle) \
(((exStyle) & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) == \
WS_EX_STATICEDGE)
#define HAS_ANYFRAME(style,exStyle) \
(((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
((exStyle) & WS_EX_DLGMODALFRAME) || \
!((style) & (WS_CHILD | WS_POPUP)))
#define HAS_MENU(pWnd,style) ((((style) & (WS_CHILD | WS_POPUP)) != WS_CHILD) && pWnd->IDMenu)
#define IntIsDesktopWindow(WndObj) \
(WndObj->spwndParent == NULL)
@ -112,5 +127,6 @@ PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW*, PUNICODE_STRING, PLARGE_STRI
WNDPROC FASTCALL IntGetWindowProc(PWND,BOOL);
BOOL FASTCALL IntEnableWindow(HWND,BOOL);
DWORD FASTCALL GetNCHitEx(PWND pWnd, POINT pt);
/* EOF */

View file

@ -215,5 +215,207 @@ IntDefWindowProc(
return lResult;
}
static HICON NC_IconForWindow( PWND pWnd )
{
HICON hIcon = 0;
if (!pWnd->pcls || pWnd->fnid == FNID_DESKTOP) return hIcon;
if (!hIcon) hIcon = pWnd->pcls->hIconSm;
if (!hIcon) hIcon = pWnd->pcls->hIcon;
if (!hIcon && pWnd->style & DS_MODALFRAME)
{ // Fake it out for now, we use it as a test.
hIcon = (HICON)1;
/* FIXME: Need to setup Registry System Cursor & Icons via Callbacks at init time! */
if (!hIcon) hIcon = gpsi->hIconSmWindows; // Both are IDI_WINLOGO Small
if (!hIcon) hIcon = gpsi->hIcoWindows; // Reg size.
}
return hIcon;
}
DWORD FASTCALL
GetNCHitEx(PWND pWnd, POINT pt)
{
RECT rcWindow, rcClient;
DWORD Style, ExStyle;
if (!pWnd) return HTNOWHERE;
rcClient.left = rcClient.top = rcWindow.left = rcWindow.top = 0;
rcWindow.right = pWnd->rcWindow.right;
rcWindow.bottom = pWnd->rcWindow.bottom;
rcClient.right = pWnd->rcClient.right;
rcClient.bottom = pWnd->rcClient.bottom;
if (!IntPtInRect(&rcWindow, pt)) return HTNOWHERE;
Style = pWnd->style;
ExStyle = pWnd->ExStyle;
if (Style & WS_MINIMIZE) return HTCAPTION;
if (IntPtInRect( &rcClient, pt )) return HTCLIENT;
/* Check borders */
if (HAS_THICKFRAME( Style, ExStyle ))
{
RECTL_vInflateRect(&rcWindow, -UserGetSystemMetrics(SM_CXFRAME), -UserGetSystemMetrics(SM_CYFRAME) );
if (!IntPtInRect(&rcWindow, pt))
{
/* 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 (!IntPtInRect( &rcWindow, pt )) 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 (!IntPtInRect( &rcWindow, pt ))
{
BOOL min_or_max_box = (Style & WS_MAXIMIZEBOX) ||
(Style & WS_MINIMIZEBOX);
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 (IntPtInRect( &rcClient, pt )) return HTVSCROLL;
}
/* Check horizontal scroll bar */
if (Style & WS_HSCROLL)
{
rcClient.bottom += UserGetSystemMetrics(SM_CYHSCROLL);
if (IntPtInRect( &rcClient, pt ))
{
/* 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;
}
/* EOF */

View file

@ -43,6 +43,39 @@ MsqInitializeImpl(VOID)
return(STATUS_SUCCESS);
}
PWND FASTCALL
IntChildrenWindowFromPoint(PWND pWndTop, INT x, INT y)
{
PWND pWnd, pWndChild;
if (!(pWndTop->style & WS_VISIBLE)) return NULL;
if ((pWndTop->style & WS_DISABLED)) return NULL;
if (!IntPtInWindow(pWndTop, x, y)) return NULL;
if (x - pWndTop->rcClient.left < pWndTop->rcClient.right &&
y - pWndTop->rcClient.top < pWndTop->rcClient.bottom )
{
for (pWnd = pWndTop->spwndChild;
pWnd != NULL;
pWnd = pWnd->spwndNext)
{
if (pWnd->state2 & WNDS2_INDESTROY || pWnd->state & WNDS_DESTROYED )
{
DPRINT("The Window is in DESTROY!\n");
continue;
}
pWndChild = IntChildrenWindowFromPoint(pWnd, x, y);
if (pWndChild)
{
return pWndChild;
}
}
}
return pWndTop;
}
PWND FASTCALL
IntTopLevelWindowFromPoint(INT x, INT y)
{
@ -503,22 +536,17 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
if (Msg->hwnd != NULL)
{
pwnd = UserGetWindowObject(Msg->hwnd);
if ((pwnd->style & WS_VISIBLE) &&
IntPtInWindow(pwnd, Msg->pt.x, Msg->pt.y))
{
pDesk->htEx = HTCLIENT;
pDesk->spwndTrack = pwnd;
}
}
else
{
pwnd = IntTopLevelWindowFromPoint(Msg->pt.x, Msg->pt.y);
if (pwnd)
{
Msg->hwnd = pwnd->head.h;
pDesk->htEx = HTCLIENT;
pDesk->spwndTrack = pwnd;
}
if (pwnd) Msg->hwnd = pwnd->head.h;
}
if (pwnd)
{
pDesk->spwndTrack = IntChildrenWindowFromPoint(pwnd, Msg->pt.x, Msg->pt.y);
pDesk->htEx = GetNCHitEx(pDesk->spwndTrack, Msg->pt);
}
hdcScreen = IntGetScreenDC();