* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Win32k subsystem
* PURPOSE: Miscellaneous User functions
- * FILE: subsystems/win32/win32k/ntuser/defwnd.c
+ * FILE: win32ss/user/ntuser/defwnd.c
* PROGRAMER:
*/
#include <win32k.h>
-
#include <windowsx.h>
DBG_DEFAULT_CHANNEL(UserDefwnd);
-#define UserHasDlgFrameStyle(Style, ExStyle) \
- (((ExStyle) & WS_EX_DLGMODALFRAME) || \
- (((Style) & WS_DLGFRAME) && (!((Style) & WS_THICKFRAME))))
-
-#define UserHasThickFrameStyle(Style, ExStyle) \
- (((Style) & WS_THICKFRAME) && \
- (!(((Style) & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)))
-
-#define UserHasThinFrameStyle(Style, ExStyle) \
- (((Style) & WS_BORDER) || (!((Style) & (WS_CHILD | WS_POPUP))))
-
-#define ON_LEFT_BORDER(hit) \
- (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
-#define ON_RIGHT_BORDER(hit) \
- (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
-#define ON_TOP_BORDER(hit) \
- (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
-#define ON_BOTTOM_BORDER(hit) \
- (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
-
-// Client Shutdown messages
-#define MCS_SHUTDOWNTIMERS 1
-#define MCS_QUERYENDSESSION 2
-// Client Shutdown returns
-#define MCSR_GOODFORSHUTDOWN 1
-#define MCSR_SHUTDOWNFINISHED 2
-#define MCSR_DONOTSHUTDOWN 3
+INT WINAPI DrawTextExWorker( HDC hdc, LPWSTR str, INT i_count,
+ LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp );
-/*
- * Based on CSRSS and described in pages 1115 - 1118 "Windows Internals, Fifth Edition".
- * Apparently CSRSS sends out messages to do this w/o going into win32k internals.
- */
-static
-LRESULT FASTCALL
-IntClientShutdown(
- PWND pWindow,
- WPARAM wParam,
- LPARAM lParam
-)
+INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags )
{
- LPARAM lParams;
- BOOL KillTimers;
- INT i;
- LRESULT lResult = MCSR_GOODFORSHUTDOWN;
- HWND *List;
-
- lParams = wParam & (ENDSESSION_LOGOFF|ENDSESSION_CRITICAL|ENDSESSION_CLOSEAPP);
- KillTimers = wParam & MCS_SHUTDOWNTIMERS ? TRUE : FALSE;
-/*
- First, send end sessions to children.
- */
- List = IntWinListChildren(pWindow);
-
- if (List)
- {
- for (i = 0; List[i]; i++)
- {
- PWND WndChild;
-
- if (!(WndChild = UserGetWindowObject(List[i])))
- continue;
+ DRAWTEXTPARAMS dtp;
- if (wParam & MCS_QUERYENDSESSION)
- {
- if (!co_IntSendMessage(WndChild->head.h, WM_QUERYENDSESSION, 0, lParams))
- {
- lResult = MCSR_DONOTSHUTDOWN;
- break;
- }
- }
- else
- {
- co_IntSendMessage(WndChild->head.h, WM_ENDSESSION, KillTimers, lParams);
- if (KillTimers)
- {
- DestroyTimersForWindow(WndChild->head.pti, WndChild);
- }
- lResult = MCSR_SHUTDOWNFINISHED;
- }
- }
- ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
- }
- if (List && (lResult == MCSR_DONOTSHUTDOWN)) return lResult;
-/*
- Send to the caller.
- */
- if (wParam & MCS_QUERYENDSESSION)
- {
- if (!co_IntSendMessage(pWindow->head.h, WM_QUERYENDSESSION, 0, lParams))
- {
- lResult = MCSR_DONOTSHUTDOWN;
- }
- }
- else
- {
- co_IntSendMessage(pWindow->head.h, WM_ENDSESSION, KillTimers, lParams);
- if (KillTimers)
- {
- DestroyTimersForWindow(pWindow->head.pti, pWindow);
- }
- lResult = MCSR_SHUTDOWNFINISHED;
- }
- return lResult;
+ memset (&dtp, 0, sizeof(dtp));
+ dtp.cbSize = sizeof(dtp);
+ if (flags & DT_TABSTOP)
+ {
+ dtp.iTabLength = (flags >> 8) & 0xff;
+ flags &= 0xffff00ff;
+ }
+ return DrawTextExWorker(hdc, (LPWSTR)str, count, rect, flags, &dtp);
}
+
HBRUSH FASTCALL
DefWndControlColor(HDC hDC, UINT ctlType)
{
return 0;
}
-VOID FASTCALL
-UserDrawWindowFrame(HDC hdc,
- RECTL *rect,
- ULONG width,
- ULONG height)
-{
- HBRUSH hbrush = NtGdiSelectBrush( hdc, gpsi->hbrGray );
- NtGdiPatBlt( hdc, rect->left, rect->top, rect->right - rect->left - width, height, PATINVERT );
- NtGdiPatBlt( hdc, rect->left, rect->top + height, width, rect->bottom - rect->top - height, PATINVERT );
- NtGdiPatBlt( hdc, rect->left + width, rect->bottom - 1, rect->right - rect->left - width, -height, PATINVERT );
- NtGdiPatBlt( hdc, rect->right - 1, rect->top, -width, rect->bottom - rect->top - height, PATINVERT );
- NtGdiSelectBrush( hdc, hbrush );
-}
-
-VOID FASTCALL
-UserDrawMovingFrame(HDC hdc,
- RECTL *rect,
- BOOL thickframe)
-{
- if (thickframe) UserDrawWindowFrame(hdc, rect, UserGetSystemMetrics(SM_CXFRAME), UserGetSystemMetrics(SM_CYFRAME));
- else UserDrawWindowFrame(hdc, rect, 1, 1);
-}
-
-/***********************************************************************
- * NC_GetInsideRect
- *
- * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
- * but without the borders (if any).
- */
-void FASTCALL
-NC_GetInsideRect(PWND Wnd, RECT *rect)
-{
- ULONG Style;
- ULONG ExStyle;
-
- Style = Wnd->style;
- ExStyle = Wnd->ExStyle;
-
- rect->top = rect->left = 0;
- rect->right = Wnd->rcWindow.right - Wnd->rcWindow.left;
- rect->bottom = Wnd->rcWindow.bottom - Wnd->rcWindow.top;
-
- if (Style & WS_ICONIC) return;
-
- /* Remove frame from rectangle */
- if (UserHasThickFrameStyle(Style, ExStyle ))
- {
- RECTL_vInflateRect(rect, -UserGetSystemMetrics(SM_CXFRAME), -UserGetSystemMetrics(SM_CYFRAME));
- }
- else
- {
- if (UserHasDlgFrameStyle(Style, ExStyle ))
- {
- RECTL_vInflateRect(rect, -UserGetSystemMetrics(SM_CXDLGFRAME), -UserGetSystemMetrics(SM_CYDLGFRAME));
- /* FIXME: this isn't in NC_AdjustRect? why not? */
- if (ExStyle & WS_EX_DLGMODALFRAME)
- RECTL_vInflateRect( rect, -1, 0 );
- }
- else
- {
- if (UserHasThinFrameStyle(Style, ExStyle))
- {
- RECTL_vInflateRect(rect, -UserGetSystemMetrics(SM_CXBORDER), -UserGetSystemMetrics(SM_CYBORDER));
- }
- }
- }
- /* We have additional border information if the window
- * is a child (but not an MDI child) */
- if ((Style & WS_CHILD) && !(ExStyle & WS_EX_MDICHILD))
- {
- if (ExStyle & WS_EX_CLIENTEDGE)
- RECTL_vInflateRect (rect, -UserGetSystemMetrics(SM_CXEDGE), -UserGetSystemMetrics(SM_CYEDGE));
- if (ExStyle & WS_EX_STATICEDGE)
- RECTL_vInflateRect (rect, -UserGetSystemMetrics(SM_CXBORDER), -UserGetSystemMetrics(SM_CYBORDER));
- }
-}
-
-LONG FASTCALL
-DefWndStartSizeMove(PWND Wnd, WPARAM wParam, POINT *capturePoint)
-{
- LONG hittest = 0;
- POINT pt;
- MSG msg;
- RECT rectWindow;
- ULONG Style = Wnd->style;
- PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
-
- rectWindow = Wnd->rcWindow;
-
- if ((wParam & 0xfff0) == SC_MOVE)
- {
- /* Move pointer at the center of the caption */
- RECT rect = rectWindow;
- /* Note: to be exactly centered we should take the different types
- * of border into account, but it shouldn't make more than a few pixels
- * of difference so let's not bother with that */
- if (Style & WS_SYSMENU)
- rect.left += UserGetSystemMetrics(SM_CXSIZE) + 1;
- if (Style & WS_MINIMIZEBOX)
- rect.right -= UserGetSystemMetrics(SM_CXSIZE) + 1;
- if (Style & WS_MAXIMIZEBOX)
- rect.right -= UserGetSystemMetrics(SM_CXSIZE) + 1;
- pt.x = (rect.right + rect.left) / 2;
- pt.y = rect.top + UserGetSystemMetrics(SM_CYSIZE)/2;
- hittest = HTCAPTION;
- *capturePoint = pt;
- }
- else /* SC_SIZE */
- {
- pt.x = pt.y = 0;
- while (!hittest)
- {
- if (!co_IntGetPeekMessage(&msg, 0, 0, 0, PM_REMOVE, TRUE)) return 0;
- if (IntCallMsgFilter( &msg, MSGF_SIZE )) continue;
-
- switch(msg.message)
- {
- case WM_MOUSEMOVE:
- //// Clamp the mouse position to the window rectangle when starting a window resize.
- pt.x = min( max( msg.pt.x, rectWindow.left ), rectWindow.right - 1 );
- pt.y = min( max( msg.pt.y, rectWindow.top ), rectWindow.bottom - 1 );
- hittest = GetNCHitEx(Wnd, pt);
- if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT)) hittest = 0;
- break;
-
- case WM_LBUTTONUP:
- return 0;
-
- case WM_KEYDOWN:
- switch (msg.wParam)
- {
- case VK_UP:
- hittest = HTTOP;
- pt.x = (rectWindow.left+rectWindow.right)/2;
- pt.y = rectWindow.top + UserGetSystemMetrics(SM_CYFRAME) / 2;
- break;
- case VK_DOWN:
- hittest = HTBOTTOM;
- pt.x = (rectWindow.left+rectWindow.right)/2;
- pt.y = rectWindow.bottom - UserGetSystemMetrics(SM_CYFRAME) / 2;
- break;
- case VK_LEFT:
- hittest = HTLEFT;
- pt.x = rectWindow.left + UserGetSystemMetrics(SM_CXFRAME) / 2;
- pt.y = (rectWindow.top+rectWindow.bottom)/2;
- break;
- case VK_RIGHT:
- hittest = HTRIGHT;
- pt.x = rectWindow.right - UserGetSystemMetrics(SM_CXFRAME) / 2;
- pt.y = (rectWindow.top+rectWindow.bottom)/2;
- break;
- case VK_RETURN:
- case VK_ESCAPE:
- return 0;
- }
- default:
- IntTranslateKbdMessage( &msg, 0 );
- pti->TIF_flags |= TIF_MOVESIZETRACKING;
- IntDispatchMessage( &msg );
- pti->TIF_flags |= TIF_MOVESIZETRACKING;
- break;
- }
- }
- *capturePoint = pt;
- }
- UserSetCursorPos(pt.x, pt.y, 0, 0, FALSE);
- co_IntSendMessage(UserHMGetHandle(Wnd), WM_SETCURSOR, (WPARAM)UserHMGetHandle(Wnd), MAKELONG(hittest, WM_MOUSEMOVE));
- return hittest;
-}
-
-//
-// System Command Size and Move
-//
-// Perform SC_MOVE and SC_SIZE commands.
-//
-VOID FASTCALL
-DefWndDoSizeMove(PWND pwnd, WORD wParam)
-{
- MSG msg;
- RECT sizingRect, mouseRect, origRect, unmodRect;
- HDC hdc;
- LONG hittest = (LONG)(wParam & 0x0f);
- HCURSOR hDragCursor = 0, hOldCursor = 0;
- POINT minTrack, maxTrack;
- POINT capturePoint, pt;
- ULONG Style, ExStyle;
- BOOL thickframe;
- BOOL iconic;
- BOOL moved = FALSE;
- BOOL DragFullWindows = FALSE;
- PWND pWndParent = NULL;
- WPARAM syscommand = (wParam & 0xfff0);
- PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
- //PMONITOR mon = 0; Don't port sync from wine!!! This breaks explorer task bar sizing!!
- // The task bar can grow in size and can not reduce due to the change
- // in the work area.
-
- Style = pwnd->style;
- ExStyle = pwnd->ExStyle;
- iconic = (Style & WS_MINIMIZE) != 0;
-
- if ((Style & WS_MAXIMIZE) || !IntIsWindowVisible(pwnd)) return;
-
- thickframe = UserHasThickFrameStyle(Style, ExStyle) && !iconic;
-
- //
- // Show window contents while dragging the window, get flag from registry data.
- //
- UserSystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
-
- pt.x = pti->ptLast.x;
- pt.y = pti->ptLast.y;
- capturePoint = pt;
- UserClipCursor( NULL );
-
- TRACE("pwnd %p command %04lx, hittest %d, pos %d,%d\n",
- pwnd, syscommand, hittest, pt.x, pt.y);
-
- if (syscommand == SC_MOVE)
- {
- if (!hittest) hittest = DefWndStartSizeMove(pwnd, wParam, &capturePoint);
- if (!hittest) return;
- }
- else /* SC_SIZE */
- {
- if (!thickframe) return;
- if (hittest && (syscommand != SC_MOUSEMENU))
- {
- hittest += (HTLEFT - WMSZ_LEFT);
- }
- else
- {
- co_UserSetCapture(UserHMGetHandle(pwnd));
- hittest = DefWndStartSizeMove(pwnd, wParam, &capturePoint);
- if (!hittest)
- {
- IntReleaseCapture();
- return;
- }
- }
- }
-
- /* Get min/max info */
-
- co_WinPosGetMinMaxInfo(pwnd, NULL, NULL, &minTrack, &maxTrack);
- sizingRect = pwnd->rcWindow;
- origRect = sizingRect;
- if (Style & WS_CHILD)
- {
- pWndParent = IntGetParent(pwnd);
- IntGetClientRect( pWndParent, &mouseRect );
- IntMapWindowPoints( pWndParent, 0, (LPPOINT)&mouseRect, 2 );
- IntMapWindowPoints( 0, pWndParent, (LPPOINT)&sizingRect, 2 );
- unmodRect = sizingRect;
- }
- else
- {
- if (!(ExStyle & WS_EX_TOPMOST))
- {
- UserSystemParametersInfo(SPI_GETWORKAREA, 0, &mouseRect, 0);
- }
- else
- {
- RECTL_vSetRect(&mouseRect, 0, 0, UserGetSystemMetrics(SM_CXSCREEN), UserGetSystemMetrics(SM_CYSCREEN));
- }
- unmodRect = sizingRect;
- }
-
- if (ON_LEFT_BORDER(hittest))
- {
- mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x+capturePoint.x-sizingRect.left );
- mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x+capturePoint.x-sizingRect.left );
- }
- else if (ON_RIGHT_BORDER(hittest))
- {
- mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x+capturePoint.x-sizingRect.right );
- mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x+capturePoint.x-sizingRect.right );
- }
- if (ON_TOP_BORDER(hittest))
- {
- mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y+capturePoint.y-sizingRect.top );
- mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y+capturePoint.y-sizingRect.top);
- }
- else if (ON_BOTTOM_BORDER(hittest))
- {
- mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y+capturePoint.y-sizingRect.bottom );
- mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y+capturePoint.y-sizingRect.bottom );
- }
-
- hdc = UserGetDCEx( pWndParent, 0, DCX_CACHE );
-
- if ( iconic ) /* create a cursor for dragging */
- {
- hDragCursor = pwnd->pcls->hIcon;;
- if ( !hDragCursor ) hDragCursor = (HCURSOR)co_IntSendMessage( UserHMGetHandle(pwnd), WM_QUERYDRAGICON, 0, 0 );
- if ( !hDragCursor ) iconic = FALSE;
- }
-
- /* repaint the window before moving it around */
- co_UserRedrawWindow( pwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN);
-
- IntNotifyWinEvent( EVENT_SYSTEM_MOVESIZESTART, pwnd, OBJID_WINDOW, CHILDID_SELF, 0);
-
- co_IntSendMessage( UserHMGetHandle(pwnd), WM_ENTERSIZEMOVE, 0, 0 );
-
- MsqSetStateWindow(pti, MSQ_STATE_MOVESIZE, UserHMGetHandle(pwnd));
-
- if (IntGetCapture() != UserHMGetHandle(pwnd)) co_UserSetCapture( UserHMGetHandle(pwnd) );
-
- pwnd->head.pti->TIF_flags |= TIF_MOVESIZETRACKING;
-
- for(;;)
- {
- int dx = 0, dy = 0;
-
- if (!co_IntGetPeekMessage(&msg, 0, 0, 0, PM_REMOVE, TRUE)) break;
- if (IntCallMsgFilter( &msg, MSGF_SIZE )) continue;
-
- /* Exit on button-up, Return, or Esc */
- if ((msg.message == WM_LBUTTONUP) ||
- ((msg.message == WM_KEYDOWN) &&
- ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
-
- if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
- {
- IntTranslateKbdMessage( &msg , 0 );
- IntDispatchMessage( &msg );
- continue; /* We are not interested in other messages */
- }
-
- pt = msg.pt;
-
- if (msg.message == WM_KEYDOWN) switch(msg.wParam)
- {
- case VK_UP: pt.y -= 8; break;
- case VK_DOWN: pt.y += 8; break;
- case VK_LEFT: pt.x -= 8; break;
- case VK_RIGHT: pt.x += 8; break;
- }
-
- pt.x = max( pt.x, mouseRect.left );
- pt.x = min( pt.x, mouseRect.right - 1 );
- pt.y = max( pt.y, mouseRect.top );
- pt.y = min( pt.y, mouseRect.bottom - 1 );
-
- dx = pt.x - capturePoint.x;
- dy = pt.y - capturePoint.y;
-
- if (dx || dy)
- {
- if ( !moved )
- {
- moved = TRUE;
-
- if ( iconic ) /* ok, no system popup tracking */
- {
- hOldCursor = IntSetCursor(hDragCursor);
- UserShowCursor( TRUE );
- }
- else if(!DragFullWindows)
- UserDrawMovingFrame( hdc, &sizingRect, thickframe );
- }
-
- if (msg.message == WM_KEYDOWN) UserSetCursorPos(pt.x, pt.y, 0, 0, FALSE);
- else
- {
- RECT newRect = unmodRect;
-
- if (!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
- if (hittest == HTCAPTION) RECTL_vOffsetRect( &newRect, dx, dy );
- if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
- else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
- if (ON_TOP_BORDER(hittest)) newRect.top += dy;
- else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
- capturePoint = pt;
-
- //
- // Save the new position to the unmodified rectangle. This allows explorer task bar
- // sizing. Explorer will forces back the position unless a certain amount of sizing
- // has occurred.
- //
- unmodRect = newRect;
-
- /* determine the hit location */
- if (syscommand == SC_SIZE)
- {
- WPARAM wpSizingHit = 0;
-
- if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
- wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
- co_IntSendMessage( UserHMGetHandle(pwnd), WM_SIZING, wpSizingHit, (LPARAM)&newRect );
- }
- else
- co_IntSendMessage( UserHMGetHandle(pwnd), WM_MOVING, 0, (LPARAM)&newRect );
-
- if (!iconic)
- {
- if (!DragFullWindows)
- UserDrawMovingFrame( hdc, &newRect, thickframe );
- else
- { // Moving the whole window now!
- PWND pwndTemp;
- //// This causes the mdi child window to jump up when it is moved.
- //IntMapWindowPoints( 0, pWndParent, (POINT *)&rect, 2 );
- co_WinPosSetWindowPos( pwnd,
- 0,
- newRect.left,
- newRect.top,
- newRect.right - newRect.left,
- newRect.bottom - newRect.top,
- ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
-
- // Update all the windows after the move or size, including this window.
- for ( pwndTemp = pwnd->head.rpdesk->pDeskInfo->spwnd->spwndChild;
- pwndTemp;
- pwndTemp = pwndTemp->spwndNext )
- {
- RECTL rect;
- // Only the windows that overlap will be redrawn.
- if (RECTL_bIntersectRect( &rect, &pwnd->rcWindow, &pwndTemp->rcWindow ))
- {
- co_UserRedrawWindow( pwndTemp, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN);
- }
- }
- }
- }
- sizingRect = newRect;
- }
- }
- }
-
- pwnd->head.pti->TIF_flags &= ~TIF_MOVESIZETRACKING;
-
- IntReleaseCapture();
-
- if ( iconic )
- {
- if ( moved ) /* restore cursors, show icon title later on */
- {
- UserShowCursor( FALSE );
- IntSetCursor( hOldCursor );
- }
- IntDestroyCursor( hDragCursor, FALSE );
- }
- else if ( moved && !DragFullWindows )
- UserDrawMovingFrame( hdc, &sizingRect, thickframe );
-
- UserReleaseDC(NULL, hdc, FALSE);
-
- //// This causes the mdi child window to jump up when it is moved.
- //if (pWndParent) IntMapWindowPoints( 0, pWndParent, (POINT *)&sizingRect, 2 );
-
- if (co_HOOK_CallHooks(WH_CBT, HCBT_MOVESIZE, (WPARAM)UserHMGetHandle(pwnd), (LPARAM)&sizingRect))
- {
- ERR("DoSizeMove : WH_CBT Call Hook return!\n");
- moved = FALSE;
- }
-
- IntNotifyWinEvent( EVENT_SYSTEM_MOVESIZEEND, pwnd, OBJID_WINDOW, CHILDID_SELF, 0);
-
- MsqSetStateWindow(pti, MSQ_STATE_MOVESIZE, NULL);
-
- co_IntSendMessage( UserHMGetHandle(pwnd), WM_EXITSIZEMOVE, 0, 0 );
- //// wine mdi hack
- co_IntSendMessage( UserHMGetHandle(pwnd), WM_SETVISIBLE, !!(pwnd->style & WS_MINIMIZE), 0L);
- ////
- /* window moved or resized */
- if (moved)
- {
- /* if the moving/resizing isn't canceled call SetWindowPos
- * with the new position or the new size of the window
- */
- if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
- {
- /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
- if (!DragFullWindows || iconic )
- {
- co_WinPosSetWindowPos( pwnd,
- 0,
- sizingRect.left,
- sizingRect.top,
- sizingRect.right - sizingRect.left,
- sizingRect.bottom - sizingRect.top,
- ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
- }
- }
- else
- { /* restore previous size/position */
- if ( DragFullWindows )
- {
- co_WinPosSetWindowPos( pwnd,
- 0,
- origRect.left,
- origRect.top,
- origRect.right - origRect.left,
- origRect.bottom - origRect.top,
- ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
- }
- }
- }
-
- if ( IntIsWindow(UserHMGetHandle(pwnd)) )
- if ( iconic )
- {
- /* Single click brings up the system menu when iconized */
- if ( !moved )
- {
- if( Style & WS_SYSMENU )
- co_IntSendMessage( UserHMGetHandle(pwnd), WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
- }
- }
-}
-
//
// Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
//
}
}
break;
+// case SC_DEFAULT:
+ case SC_MOUSEMENU:
+ {
+ POINT Pt;
+ Pt.x = (short)LOWORD(lParam);
+ Pt.y = (short)HIWORD(lParam);
+ MENU_TrackMouseMenuBar(pWnd, wParam & 0x000f, Pt);
+ }
+ break;
+
+ case SC_KEYMENU:
+ MENU_TrackKbdMenuBar(pWnd, wParam, (WCHAR)lParam);
+ break;
default:
return(Hook ? 1 : 0); // Don't call us again from user space.
}
+PWND FASTCALL
+co_IntFindChildWindowToOwner(PWND Root, PWND Owner)
+{
+ PWND Ret;
+ PWND Child, OwnerWnd;
+
+ for(Child = Root->spwndChild; Child; Child = Child->spwndNext)
+ {
+ OwnerWnd = Child->spwndOwner;
+ if(!OwnerWnd)
+ continue;
+
+ if (!(Child->style & WS_POPUP) ||
+ !(Child->style & WS_VISIBLE) ||
+ /* Fixes CMD pop up properties window from having foreground. */
+ Owner->head.pti->MessageQueue != Child->head.pti->MessageQueue)
+ continue;
+
+ if(OwnerWnd == Owner)
+ {
+ Ret = Child;
+ return Ret;
+ }
+ }
+ return NULL;
+}
+
+LRESULT
+DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam)
+{
+ PWND pwndPopUP = NULL;
+ WORD Msg = HIWORD(lParam);
+
+ /* Not for child windows. */
+ if (UserHMGetHandle(pWnd) != (HWND)wParam)
+ {
+ return FALSE;
+ }
+
+ switch((short)LOWORD(lParam))
+ {
+ case HTERROR:
+ {
+ //// This is the real fix for CORE-6129! This was a "Code hole".
+ USER_REFERENCE_ENTRY Ref;
+
+ if (Msg == WM_LBUTTONDOWN)
+ {
+ // Find a pop up window to bring active.
+ pwndPopUP = co_IntFindChildWindowToOwner(UserGetDesktopWindow(), pWnd);
+ if (pwndPopUP)
+ {
+ // Not a child pop up from desktop.
+ if ( pwndPopUP != UserGetDesktopWindow()->spwndChild )
+ {
+ // Get original active window.
+ PWND pwndOrigActive = gpqForeground->spwndActive;
+
+ co_WinPosSetWindowPos(pWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
+ UserRefObjectCo(pwndPopUP, &Ref);
+ //UserSetActiveWindow(pwndPopUP);
+ co_IntSetForegroundWindow(pwndPopUP); // HACK
+ UserDerefObjectCo(pwndPopUP);
+
+ // If the change was made, break out.
+ if (pwndOrigActive != gpqForeground->spwndActive)
+ break;
+ }
+ }
+ }
+ ////
+ if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
+ Msg == WM_RBUTTONDOWN || Msg == WM_XBUTTONDOWN)
+ {
+ if (pwndPopUP)
+ {
+ FLASHWINFO fwi =
+ {sizeof(FLASHWINFO),
+ UserHMGetHandle(pwndPopUP),
+ FLASHW_ALL,
+ gspv.dwForegroundFlashCount,
+ (gpsi->dtCaretBlink >> 3)};
+
+ // Now shake that window!
+ IntFlashWindowEx(pwndPopUP, &fwi);
+ }
+ UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, 0);
+ }
+ break;
+ }
+
+ case HTCLIENT:
+ {
+ if (pWnd->pcls->spcur)
+ {
+ IntSystemSetCursor(pWnd->pcls->spcur);
+ }
+ return FALSE;
+ }
+
+ case HTLEFT:
+ case HTRIGHT:
+ {
+ if (pWnd->style & WS_MAXIMIZE)
+ {
+ break;
+ }
+ IntSystemSetCursor(SYSTEMCUR(SIZEWE));
+ return TRUE;
+ }
+
+ case HTTOP:
+ case HTBOTTOM:
+ {
+ if (pWnd->style & WS_MAXIMIZE)
+ {
+ break;
+ }
+ IntSystemSetCursor(SYSTEMCUR(SIZENS));
+ return TRUE;
+ }
+
+ case HTTOPLEFT:
+ case HTBOTTOMRIGHT:
+ {
+ if (pWnd->style & WS_MAXIMIZE)
+ {
+ break;
+ }
+ IntSystemSetCursor(SYSTEMCUR(SIZENWSE));
+ return TRUE;
+ }
+
+ case HTBOTTOMLEFT:
+ case HTTOPRIGHT:
+ {
+ if (pWnd->style & WS_MAXIMIZE)
+ {
+ break;
+ }
+ IntSystemSetCursor(SYSTEMCUR(SIZENESW));
+ return TRUE;
+ }
+ }
+ IntSystemSetCursor(SYSTEMCUR(ARROW));
+ return FALSE;
+}
+
VOID FASTCALL DefWndPrint( PWND pwnd, HDC hdc, ULONG uFlags)
{
/*
co_IntSendMessage(UserHMGetHandle(pwnd), WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
}
+BOOL
+UserPaintCaption(PWND pWnd, INT Flags)
+{
+ BOOL Ret = FALSE;
+
+ if ( (pWnd->style & WS_VISIBLE) && ((pWnd->style & WS_CAPTION) == WS_CAPTION) )
+ {
+ if (pWnd->state & WNDS_HASCAPTION && pWnd->head.pti->MessageQueue == gpqForeground)
+ Flags |= DC_ACTIVE;
+ /*
+ * When themes are not enabled we can go on and paint the non client area.
+ * However if we do that with themes enabled we will draw a classic frame.
+ * This is solved by sending a themes specific message to notify the themes
+ * engine that the caption needs to be redrawn
+ */
+ if (gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
+ {
+ /*
+ * This will cause uxtheme to either paint the themed caption or call
+ * RealUserDrawCaption in order to draw the classic caption when themes
+ * are disabled but the themes service is enabled
+ */
+ TRACE("UDCB Flags %08x\n");
+ co_IntSendMessage(UserHMGetHandle(pWnd), WM_NCUAHDRAWCAPTION, Flags, 0);
+ }
+ else
+ {
+ HDC hDC = UserGetDCEx(pWnd, NULL, DCX_WINDOW|DCX_USESTYLE);
+ UserDrawCaptionBar(pWnd, hDC, Flags);
+ UserReleaseDC(pWnd, hDC, FALSE);
+ }
+ Ret = TRUE;
+ }
+ // Support window tray
+ return Ret;
+}
+
+// WM_SETICON
+LRESULT FASTCALL
+DefWndSetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
+{
+ HICON hIcon, hIconSmall, hIconOld;
+
+ if ( wParam > ICON_SMALL2 )
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ hIconSmall = UserGetProp(pWnd, gpsi->atomIconSmProp, TRUE);
+ hIcon = UserGetProp(pWnd, gpsi->atomIconProp, TRUE);
+
+ hIconOld = wParam == ICON_BIG ? hIcon : hIconSmall;
+
+ switch(wParam)
+ {
+ case ICON_BIG:
+ hIcon = (HICON)lParam;
+ break;
+ case ICON_SMALL:
+ hIconSmall = (HICON)lParam;
+ break;
+ case ICON_SMALL2:
+ ERR("FIXME: Set ICON_SMALL2 support!\n");
+ default:
+ break;
+ }
+
+ UserSetProp(pWnd, gpsi->atomIconProp, hIcon, TRUE);
+ UserSetProp(pWnd, gpsi->atomIconSmProp, hIconSmall, TRUE);
+
+ if ((pWnd->style & WS_CAPTION ) == WS_CAPTION)
+ UserPaintCaption(pWnd, DC_ICON);
+
+ return (LRESULT)hIconOld;
+}
+
+LRESULT FASTCALL
+DefWndGetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
+{
+ HICON hIconRet;
+ if ( wParam > ICON_SMALL2 )
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ switch(wParam)
+ {
+ case ICON_BIG:
+ hIconRet = UserGetProp(pWnd, gpsi->atomIconProp, TRUE);
+ break;
+ case ICON_SMALL:
+ case ICON_SMALL2:
+ hIconRet = UserGetProp(pWnd, gpsi->atomIconSmProp, TRUE);
+ break;
+ default:
+ break;
+ }
+ return (LRESULT)hIconRet;
+}
+
+VOID FASTCALL
+DefWndScreenshot(PWND pWnd)
+{
+ RECT rect;
+ HDC hdc;
+ INT w;
+ INT h;
+ HBITMAP hbitmap;
+ HDC hdc2;
+ SETCLIPBDATA scd = {FALSE, FALSE};
+
+ UserOpenClipboard(UserHMGetHandle(pWnd));
+ UserEmptyClipboard();
+
+ hdc = UserGetWindowDC(pWnd);
+ IntGetWindowRect(pWnd, &rect);
+ w = rect.right - rect.left;
+ h = rect.bottom - rect.top;
+
+ hbitmap = NtGdiCreateCompatibleBitmap(hdc, w, h);
+ hdc2 = NtGdiCreateCompatibleDC(hdc);
+ NtGdiSelectBitmap(hdc2, hbitmap);
+
+ NtGdiBitBlt(hdc2, 0, 0, w, h, hdc, 0, 0, SRCCOPY, 0, 0);
+
+ UserSetClipboardData(CF_BITMAP, hbitmap, &scd);
+
+ UserReleaseDC(pWnd, hdc, FALSE);
+ UserReleaseDC(pWnd, hdc2, FALSE);
+
+ UserCloseClipboard();
+}
/*
Win32k counterpart of User DefWindowProc
LPARAM lParam,
BOOL Ansi)
{
+ PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
LRESULT lResult = 0;
USER_REFERENCE_ENTRY Ref;
- if (Msg > WM_USER) return 0;
+ if (Msg > WM_USER) return 0;
+
+ switch (Msg)
+ {
+ case WM_GETTEXTLENGTH:
+ {
+ PWSTR buf;
+ ULONG len;
+
+ if (Wnd != NULL && Wnd->strName.Length != 0)
+ {
+ buf = Wnd->strName.Buffer;
+ if (buf != NULL &&
+ NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
+ buf,
+ Wnd->strName.Length)))
+ {
+ lResult = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR));
+ }
+ }
+ else lResult = 0L;
+
+ break;
+ }
+
+ case WM_GETTEXT: // FIXME: Handle Ansi
+ {
+ PWSTR buf = NULL;
+ PWSTR outbuf = (PWSTR)lParam;
+
+ if (Wnd != NULL && wParam != 0)
+ {
+ if (Wnd->strName.Buffer != NULL)
+ buf = Wnd->strName.Buffer;
+ else
+ outbuf[0] = L'\0';
+
+ if (buf != NULL)
+ {
+ if (Wnd->strName.Length != 0)
+ {
+ lResult = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
+ RtlCopyMemory(outbuf,
+ buf,
+ lResult * sizeof(WCHAR));
+ outbuf[lResult] = L'\0';
+ }
+ else
+ outbuf[0] = L'\0';
+ }
+ }
+ break;
+ }
+
+ case WM_SETTEXT: // FIXME: Handle Ansi
+ {
+ DefSetText(Wnd, (PCWSTR)lParam);
+
+ if ((Wnd->style & WS_CAPTION) == WS_CAPTION)
+ UserPaintCaption(Wnd, DC_TEXT);
+ IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, Wnd, OBJID_WINDOW, CHILDID_SELF, 0);
+ lResult = 1;
+ break;
+ }
- switch (Msg)
- {
case WM_SYSCOMMAND:
{
- ERR("hwnd %p WM_SYSCOMMAND %lx %lx\n", Wnd->head.h, wParam, lParam );
+ TRACE("hwnd %p WM_SYSCOMMAND %lx %lx\n", Wnd->head.h, wParam, lParam );
lResult = DefWndHandleSysCommand(Wnd, wParam, lParam);
break;
}
+
case WM_SHOWWINDOW:
{
if ((Wnd->style & WS_VISIBLE) && wParam) break;
if (!Wnd->spwndOwner) break;
if (LOWORD(lParam))
{
- if (wParam)
- {
- if (!(Wnd->state & WNDS_HIDDENPOPUP)) break;
- Wnd->state &= ~WNDS_HIDDENPOPUP;
- }
- else
- Wnd->state |= WNDS_HIDDENPOPUP;
-
co_WinPosShowWindow(Wnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE);
}
+ break;
}
- break;
+
case WM_CLIENTSHUTDOWN:
return IntClientShutdown(Wnd, wParam, lParam);
case WM_APPCOMMAND:
- ERR("WM_APPCOMMAND\n");
if ( (Wnd->style & (WS_POPUP|WS_CHILD)) != WS_CHILD &&
Wnd != co_GetDesktopWindow(Wnd) )
{
UserDerefObjectCo(Wnd->spwndParent);
break;
+ case WM_KEYF1:
+ {
+ HELPINFO hi;
+ HMENU hMenu = UlongToHandle(Wnd->IDMenu);
+ PWND pwndActive = MENU_IsMenuActive();
+ hi.cbSize = sizeof(HELPINFO);
+ hi.MousePos = gpsi->ptCursor;
+ hi.iContextType = HELPINFO_MENUITEM;
+ hi.hItemHandle = pwndActive ? UserHMGetHandle(pwndActive) : UserHMGetHandle(Wnd);
+ hi.iCtrlId = (Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD ? IntMenuItemFromPoint(Wnd, hMenu, hi.MousePos) : 0;
+ hi.dwContextId = IntGetWindowContextHelpId(Wnd);
+
+ co_IntSendMessage( UserHMGetHandle(Wnd), WM_HELP, 0, (LPARAM)&hi );
+ break;
+ }
+
+ case WM_SETICON:
+ {
+ return DefWndSetIcon(Wnd, wParam, lParam);
+ }
+
+ case WM_GETICON:
+ {
+ return DefWndGetIcon(Wnd, wParam, lParam);
+ }
+
+ case WM_HELP:
+ {
+ PWND Parent = IntGetParent(Wnd);
+ co_IntSendMessage(UserHMGetHandle(Parent), Msg, wParam, lParam);
+ break;
+ }
+
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK);
+ break;
+
+ case WM_NCLBUTTONDOWN:
+ return NC_HandleNCLButtonDown(Wnd, wParam, lParam);
+
+ case WM_NCRBUTTONDOWN:
+ return NC_HandleNCRButtonDown(Wnd, wParam, lParam);
+
+ case WM_LBUTTONDBLCLK:
+ return NC_HandleNCLButtonDblClk(Wnd, HTCLIENT, lParam);
+
+ case WM_NCLBUTTONDBLCLK:
+ return NC_HandleNCLButtonDblClk(Wnd, wParam, lParam);
+
+ case WM_RBUTTONUP:
+ {
+ POINT Pt;
+
+ Pt.x = GET_X_LPARAM(lParam);
+ Pt.y = GET_Y_LPARAM(lParam);
+ IntClientToScreen(Wnd, &Pt);
+ lParam = MAKELPARAM(Pt.x, Pt.y);
+ co_IntSendMessage(UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), lParam);
+ break;
+ }
+
+ case WM_NCRBUTTONUP:
+ /*
+ * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
+ * in Windows), but what _should_ we do? According to MSDN :
+ * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
+ * message to the window". When is it appropriate?
+ */
+ ERR("WM_NCRBUTTONUP\n");
+ break;
+
+ case WM_XBUTTONUP:
+ case WM_NCXBUTTONUP:
+ if (HIWORD(wParam) == XBUTTON1 || HIWORD(wParam) == XBUTTON2)
+ {
+ co_IntSendMessage(UserHMGetHandle(Wnd), WM_APPCOMMAND, (WPARAM)UserHMGetHandle(Wnd),
+ MAKELPARAM(LOWORD(wParam), FAPPCOMMAND_MOUSE | HIWORD(wParam)));
+ }
+ break;
+
+
+ case WM_CONTEXTMENU:
+ {
+ if (Wnd->style & WS_CHILD)
+ {
+ co_IntSendMessage(UserHMGetHandle(IntGetParent(Wnd)), Msg, wParam, lParam);
+ }
+ else
+ {
+ POINT Pt;
+ LONG_PTR Style;
+ LONG HitCode;
+
+ Style = Wnd->style;
+
+ Pt.x = GET_X_LPARAM(lParam);
+ Pt.y = GET_Y_LPARAM(lParam);
+ if (Style & WS_CHILD)
+ {
+ IntScreenToClient(IntGetParent(Wnd), &Pt);
+ }
+
+ HitCode = GetNCHitEx(Wnd, Pt);
+
+ if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
+ {
+ PMENU SystemMenu;
+ UINT Flags;
+
+ if((SystemMenu = IntGetSystemMenu(Wnd, FALSE)))
+ {
+ MENU_InitSysMenuPopup(SystemMenu, Wnd->style, Wnd->pcls->style, HitCode);
+
+ if(HitCode == HTCAPTION)
+ Flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON;
+ else
+ Flags = TPM_LEFTBUTTON;
+
+ IntTrackPopupMenuEx(SystemMenu, Flags|TPM_SYSTEM_MENU, Pt.x, Pt.y, Wnd, NULL);
+ }
+ }
+ if (HitCode == HTHSCROLL || HitCode == HTVSCROLL)
+ {
+ WARN("Scroll Menu Not Supported\n");
+ }
+ }
+ break;
+ }
+
+ case WM_KEYDOWN:
+ if (wParam == VK_F10)
+ {
+ pti->MessageQueue->QF_flags |= QF_FF10STATUS;
+
+ if (UserGetKeyState(VK_SHIFT) & 0x8000)
+ {
+ co_IntSendMessage(UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), MAKELPARAM(-1, -1));
+ }
+ }
+ if (IS_KEY_DOWN(gafAsyncKeyState, VK_LWIN) || IS_KEY_DOWN(gafAsyncKeyState, VK_RWIN))
+ {
+ HWND hwndTop = UserGetForegroundWindow();
+ PWND topWnd = UserGetWindowObject(hwndTop);
+ if (topWnd)
+ {
+ if ((topWnd->style & WS_THICKFRAME) == 0)
+ {
+ return 0;
+ }
+
+ if (wParam == VK_DOWN)
+ {
+ if (topWnd->style & WS_MAXIMIZE)
+ co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_RESTORE, lParam);
+ else
+ co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_MINIMIZE, lParam);
+ }
+ else if (wParam == VK_UP)
+ {
+ RECT currentRect;
+ if ((topWnd->InternalPos.NormalRect.right == topWnd->InternalPos.NormalRect.left) ||
+ (topWnd->InternalPos.NormalRect.top == topWnd->InternalPos.NormalRect.bottom))
+ {
+ currentRect = topWnd->rcWindow;
+ }
+ else
+ {
+ currentRect = topWnd->InternalPos.NormalRect;
+ }
+ co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
+
+ // save normal rect if maximazing snapped window
+ topWnd->InternalPos.NormalRect = currentRect;
+ }
+ else if (wParam == VK_LEFT || wParam == VK_RIGHT)
+ {
+ RECT snapRect, normalRect, windowRect;
+ BOOL snapped;
+ normalRect = topWnd->InternalPos.NormalRect;
+ snapped = (normalRect.left != 0 && normalRect.right != 0 &&
+ normalRect.top != 0 && normalRect.bottom != 0);
+
+ if (topWnd->style & WS_MAXIMIZE)
+ {
+ co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_RESTORE, lParam);
+ snapped = FALSE;
+ }
+ windowRect = topWnd->rcWindow;
+
+ UserSystemParametersInfo(SPI_GETWORKAREA, 0, &snapRect, 0);
+ if (wParam == VK_LEFT)
+ {
+ snapRect.right = (snapRect.left + snapRect.right) / 2;
+ }
+ else // VK_RIGHT
+ {
+ snapRect.left = (snapRect.left + snapRect.right) / 2;
+ }
+
+ if (snapped)
+ {
+ // if window was snapped but moved to other location - restore normal size
+ if (!IntEqualRect(&snapRect, &windowRect))
+ {
+ RECT empty = {0, 0, 0, 0};
+ co_WinPosSetWindowPos(topWnd,
+ 0,
+ normalRect.left,
+ normalRect.top,
+ normalRect.right - normalRect.left,
+ normalRect.bottom - normalRect.top,
+ 0);
+ topWnd->InternalPos.NormalRect = empty;
+ }
+ }
+ else
+ {
+ co_WinPosSetWindowPos(topWnd,
+ 0,
+ snapRect.left,
+ snapRect.top,
+ snapRect.right - snapRect.left,
+ snapRect.bottom - snapRect.top,
+ 0);
+ topWnd->InternalPos.NormalRect = windowRect;
+ }
+ }
+ }
+ }
+ break;
+
+ case WM_SYSKEYDOWN:
+ {
+ if (HIWORD(lParam) & KF_ALTDOWN)
+ { /* Previous state, if the key was down before this message,
+ this is a cheap way to ignore autorepeat keys. */
+ if ( !(HIWORD(lParam) & KF_REPEAT) )
+ {
+ if ( ( wParam == VK_MENU ||
+ wParam == VK_LMENU ||
+ wParam == VK_RMENU ) && !(pti->MessageQueue->QF_flags & QF_FMENUSTATUS)) //iMenuSysKey )
+ pti->MessageQueue->QF_flags |= QF_FMENUSTATUS; //iMenuSysKey = 1;
+ else
+ pti->MessageQueue->QF_flags &= ~QF_FMENUSTATUS; //iMenuSysKey = 0;
+ }
+
+ pti->MessageQueue->QF_flags &= ~QF_FF10STATUS; //iF10Key = 0;
+
+ if (wParam == VK_F4) /* Try to close the window */
+ {
+ PWND top = UserGetAncestor(Wnd, GA_ROOT);
+ if (!(top->style & CS_NOCLOSE))
+ UserPostMessage(UserHMGetHandle(top), WM_SYSCOMMAND, SC_CLOSE, 0);
+ }
+ else if (wParam == VK_SNAPSHOT) // Alt-VK_SNAPSHOT?
+ {
+ PWND pwnd = Wnd;
+ while (IntGetParent(pwnd) != NULL)
+ {
+ pwnd = IntGetParent(pwnd);
+ }
+ ERR("DefWndScreenshot\n");
+ DefWndScreenshot(pwnd);
+ }
+ else if ( wParam == VK_ESCAPE || wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC
+ {
+ WPARAM wParamTmp;
+ HWND Active = UserGetActiveWindow(); // Noticed MDI problem.
+ if (!Active)
+ {
+ FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n");
+ break;
+ }
+ wParamTmp = UserGetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW;
+ co_IntSendMessage( Active, WM_SYSCOMMAND, wParamTmp, wParam );
+ }
+ }
+ else if( wParam == VK_F10 )
+ {
+ if (UserGetKeyState(VK_SHIFT) & 0x8000)
+ co_IntSendMessage( UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), MAKELPARAM(-1, -1) );
+ pti->MessageQueue->QF_flags |= QF_FF10STATUS; //iF10Key = 1;
+ }
+ else if( wParam == VK_ESCAPE && (UserGetKeyState(VK_SHIFT) & 0x8000))
+ co_IntSendMessage( UserHMGetHandle(Wnd), WM_SYSCOMMAND, SC_KEYMENU, ' ' );
+ break;
+ }
+
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ {
+ /* Press and release F10 or ALT */
+ if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU)
+ && (pti->MessageQueue->QF_flags & (QF_FMENUSTATUS|QF_FMENUSTATUSBREAK)) == QF_FMENUSTATUS /*iMenuSysKey*/) ||
+ ((wParam == VK_F10) && pti->MessageQueue->QF_flags & QF_FF10STATUS /*iF10Key*/))
+ co_IntSendMessage( UserHMGetHandle(UserGetAncestor( Wnd, GA_ROOT )), WM_SYSCOMMAND, SC_KEYMENU, 0L );
+ pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK|QF_FF10STATUS); //iMenuSysKey = iF10Key = 0;
+ break;
+ }
+
+ case WM_SYSCHAR:
+ {
+ pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK); //iMenuSysKey = 0;
+ if (wParam == VK_RETURN && (Wnd->style & WS_MINIMIZE) != 0)
+ {
+ UserPostMessage( UserHMGetHandle(Wnd), WM_SYSCOMMAND, SC_RESTORE, 0L );
+ break;
+ }
+ if ((HIWORD(lParam) & KF_ALTDOWN) && wParam)
+ {
+ if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
+ if (wParam == VK_SPACE && Wnd->style & WS_CHILD)
+ co_IntSendMessage( UserHMGetHandle(IntGetParent(Wnd)), Msg, wParam, lParam );
+ else
+ co_IntSendMessage( UserHMGetHandle(Wnd), WM_SYSCOMMAND, SC_KEYMENU, wParam );
+ }
+ else /* check for Ctrl-Esc */
+ if (wParam != VK_ESCAPE) UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, 0); //MessageBeep(0);
+ break;
+ }
+
+ case WM_CANCELMODE:
+ {
+ pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK);
+
+ MENU_EndMenu( Wnd );
+ if (IntGetCaptureWindow() == UserHMGetHandle(Wnd))
+ {
+ IntReleaseCapture();
+ }
+ break;
+ }
+
case WM_CLOSE:
co_UserDestroyWindow(Wnd);
break;
case WM_CTLCOLOR:
return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam));
+ case WM_SETCURSOR:
+ {
+ if (Wnd->style & WS_CHILD)
+ {
+ /* with the exception of the border around a resizable wnd,
+ * give the parent first chance to set the cursor */
+ if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
+ {
+ PWND parent = Wnd->spwndParent;//IntGetParent( Wnd );
+ if (parent != UserGetDesktopWindow() &&
+ co_IntSendMessage( UserHMGetHandle(parent), WM_SETCURSOR, wParam, lParam))
+ return TRUE;
+ }
+ }
+ return DefWndHandleSetCursor(Wnd, wParam, lParam);
+ }
+
+ case WM_MOUSEACTIVATE:
+ if (Wnd->style & WS_CHILD)
+ {
+ LONG Ret;
+ HWND hwndParent;
+ PWND pwndParent = IntGetParent(Wnd);
+ hwndParent = pwndParent ? UserHMGetHandle(pwndParent) : NULL;
+ if (hwndParent) Ret = co_IntSendMessage(hwndParent, WM_MOUSEACTIVATE, wParam, lParam);
+ if (Ret) return (Ret);
+ }
+ return ( (HIWORD(lParam) == WM_LBUTTONDOWN && LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE );
+
case WM_ACTIVATE:
/* The default action in Windows is to set the keyboard focus to
* the window, if it's being activated and not minimized */
if (!hBrush) return 0;
if (hBrush <= (HBRUSH)COLOR_MENUBAR)
{
- hBrush = IntGetSysColorBrush((INT)hBrush);
+ hBrush = IntGetSysColorBrush(HandleToUlong(hBrush));
}
if (Wnd->pcls->style & CS_PARENTDC)
{
return (0);
}
+ case WM_SYSCOLORCHANGE:
+ {
+ /* force to redraw non-client area */
+ UserPaintCaption(Wnd, DC_NC);
+ /* Use InvalidateRect to redraw client area, enable
+ * erase to redraw all subcontrols otherwise send the
+ * WM_SYSCOLORCHANGE to child windows/controls is required
+ */
+ co_UserRedrawWindow( Wnd, NULL, NULL, RDW_ALLCHILDREN|RDW_INVALIDATE|RDW_ERASE);
+ return (0);
+ }
+
case WM_PAINTICON:
case WM_PAINT:
{
hDC = IntBeginPaint(Wnd, &Ps);
if (hDC)
{
- HICON hIcon;
- if (((Wnd->style & WS_MINIMIZE) != 0) && (hIcon = Wnd->pcls->hIcon))
+ if (((Wnd->style & WS_MINIMIZE) != 0) && (Wnd->pcls->spicn))
{
RECT ClientRect;
INT x, y;
- PCURICON_OBJECT pIcon;
- if (!(pIcon = UserGetCurIconObject(hIcon))) return 0;
+
ERR("Doing Paint and Client area is empty!\n");
IntGetClientRect(Wnd, &ClientRect);
x = (ClientRect.right - ClientRect.left - UserGetSystemMetrics(SM_CXICON)) / 2;
y = (ClientRect.bottom - ClientRect.top - UserGetSystemMetrics(SM_CYICON)) / 2;
- UserDrawIconEx( hDC, x, y, pIcon, 0, 0, 0, 0, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE );
+ UserReferenceObject(Wnd->pcls->spicn);
+ UserDrawIconEx(hDC, x, y, Wnd->pcls->spicn, 0, 0, 0, 0, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
+ UserDereferenceObject(Wnd->pcls->spicn);
}
+
IntEndPaint(Wnd, &Ps);
}
return (0);
{
HRGN hRgn;
Wnd->state &= ~WNDS_SYNCPAINTPENDING;
- ERR("WM_SYNCPAINT\n");
- hRgn = IntSysCreateRectRgn(0, 0, 0, 0);
- if (co_UserGetUpdateRgn(Wnd, hRgn, FALSE) != NULLREGION)
+ TRACE("WM_SYNCPAINT\n");
+ hRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+ if (hRgn)
{
- if (!wParam) wParam = (RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN);
- co_UserRedrawWindow(Wnd, NULL, hRgn, wParam);
+ if (co_UserGetUpdateRgn(Wnd, hRgn, FALSE) != NULLREGION)
+ {
+ PREGION pRgn = REGION_LockRgn(hRgn);
+ if (pRgn) REGION_UnlockRgn(pRgn);
+ if (!wParam)
+ wParam = (RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN);
+ co_UserRedrawWindow(Wnd, NULL, pRgn, wParam);
+ }
+ GreDeleteObject(hRgn);
}
- GreDeleteObject(hRgn);
return 0;
}
case WM_SETREDRAW:
- ERR("WM_SETREDRAW\n");
if (wParam)
{
if (!(Wnd->style & WS_VISIBLE))
return (DefWndHandleWindowPosChanging(Wnd, (WINDOWPOS*)lParam));
}
- case WM_WINDOWPOSCHANGED:
+ case WM_WINDOWPOSCHANGED:
{
return (DefWndHandleWindowPosChanged(Wnd, (WINDOWPOS*)lParam));
}
+ case WM_NCCALCSIZE:
+ {
+ return NC_HandleNCCalcSize( Wnd, wParam, (RECTL *)lParam, FALSE );
+ }
+
+ case WM_NCACTIVATE:
+ {
+ return NC_HandleNCActivate( Wnd, wParam, lParam );
+ }
+
+ //
+ // NC Paint mode.
+ //
+ case WM_NCPAINT:
+ {
+ HDC hDC = UserGetDCEx(Wnd, (HRGN)wParam, DCX_WINDOW | DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN);
+ Wnd->state |= WNDS_FORCEMENUDRAW;
+ NC_DoNCPaint(Wnd, hDC, -1);
+ Wnd->state &= ~WNDS_FORCEMENUDRAW;
+ UserReleaseDC(Wnd, hDC, FALSE);
+ return 0;
+ }
+ //
+ // Draw Caption mode.
+ //
+ // wParam are DC_* flags.
+ //
+ case WM_NCUAHDRAWCAPTION:
+ {
+ HDC hDC = UserGetDCEx(Wnd, NULL, DCX_WINDOW|DCX_USESTYLE);
+ TRACE("WM_NCUAHDRAWCAPTION: wParam DC_ flags %08x\n",wParam);
+ UserDrawCaptionBar(Wnd, hDC, wParam|DC_FRAME); // Include DC_FRAME to comp for drawing glich.
+ UserReleaseDC(Wnd, hDC, FALSE);
+ return 0;
+ }
+ //
+ // Draw Frame mode.
+ //
+ // wParam is HDC, lParam are DC_ACTIVE and or DC_REDRAWHUNGWND.
+ //
+ case WM_NCUAHDRAWFRAME:
+ {
+ TRACE("WM_NCUAHDRAWFRAME: wParam hDC %p lParam DC_ flags %08x\n",wParam,lParam);
+ NC_DoNCPaint(Wnd, (HDC)wParam, lParam|DC_NC);
+ return 0;
+ }
+
/* ReactOS only. */
case WM_CBT:
{
return lResult;
}
-HICON FASTCALL NC_IconForWindow( PWND pWnd )
-{
- HICON hIcon = 0;
- // First thing to do, init the Window Logo icons.
- if (!gpsi->hIconSmWindows) co_IntSetWndIcons();
-
- if (!hIcon) hIcon = UserGetProp(pWnd, gpsi->atomIconSmProp);
- if (!hIcon) hIcon = UserGetProp(pWnd, gpsi->atomIconProp);
- if (!hIcon) hIcon = pWnd->pcls->hIconSm;
- if (!hIcon) hIcon = pWnd->pcls->hIcon;
-
- if (!hIcon && pWnd->style & DS_MODALFRAME)
- {
- if (!hIcon) hIcon = gpsi->hIconSmWindows; // Both are IDI_WINLOGO Small
- if (!hIcon) hIcon = gpsi->hIconWindows; // Reg size.
- }
- return hIcon;
-}
-
-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;
-}
-
/* EOF */