mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[Win32SS|UxTheme]
- Move Menu to server side. See CORE-7797 and CORE-8299. - This was for speed while moving windows about the desktop and fixed test results too. svn path=/trunk/; revision=68904
This commit is contained in:
parent
eebbf23330
commit
6dfa71c487
41 changed files with 7700 additions and 6800 deletions
|
@ -1070,7 +1070,13 @@ ThemeWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, WNDPROC DefWndPr
|
|||
{
|
||||
case WM_NCPAINT:
|
||||
return ThemeHandleNCPaint(hWnd, (HRGN)wParam);
|
||||
//
|
||||
// WM_NCUAHDRAWCAPTION : wParam are DC_* flags.
|
||||
//
|
||||
case WM_NCUAHDRAWCAPTION:
|
||||
//
|
||||
// WM_NCUAHDRAWFRAME : wParam is HDC, lParam are DC_ACTIVE and or DC_REDRAWHUNGWND.
|
||||
//
|
||||
case WM_NCUAHDRAWFRAME:
|
||||
case WM_NCACTIVATE:
|
||||
ThemeHandleNCPaint(hWnd, (HRGN)1);
|
||||
|
|
|
@ -186,12 +186,6 @@ ThemeDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|||
{
|
||||
if(!IsAppThemed())
|
||||
{
|
||||
if (Msg == WM_NCUAHDRAWCAPTION)
|
||||
{
|
||||
user32ApiHook.DrawCaption(hWnd, NULL, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return user32ApiHook.DefWindowProcW(hWnd,
|
||||
Msg,
|
||||
wParam,
|
||||
|
@ -210,12 +204,6 @@ ThemeDefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|||
{
|
||||
if(!IsAppThemed())
|
||||
{
|
||||
if (Msg == WM_NCUAHDRAWCAPTION)
|
||||
{
|
||||
user32ApiHook.DrawCaption(hWnd, NULL, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return user32ApiHook.DefWindowProcA(hWnd,
|
||||
Msg,
|
||||
wParam,
|
||||
|
|
|
@ -43,6 +43,7 @@ extern "C" {
|
|||
#define WM_LBTRACKPOINT 0x00000131
|
||||
#define LB_CARETON 0x000001a3
|
||||
#define LB_CARETOFF 0x000001a4
|
||||
#define MN_SETHMENU 0x000001e0
|
||||
#define WM_DROPOBJECT 0x0000022A
|
||||
#define WM_QUERYDROPOBJECT 0x0000022B
|
||||
#define WM_BEGINDRAG 0x0000022C
|
||||
|
@ -60,6 +61,9 @@ extern "C" {
|
|||
#define DCX_KEEPLAYOUT 0x40000000
|
||||
#define DCX_PROCESSOWNED 0x80000000
|
||||
|
||||
/* Non SDK TPM types.*/
|
||||
#define TPM_SYSTEM_MENU 0x00000200
|
||||
|
||||
/* NtUserCreateWindowEx dwFlags bits. */
|
||||
#define NUCWE_ANSI 0x00000001
|
||||
#define NUCWE_SIDEBYSIDE 0x40000000
|
||||
|
@ -132,7 +136,20 @@ extern "C" {
|
|||
//
|
||||
// Undocumented flags for DrawCaptionTemp
|
||||
//
|
||||
#define DC_NOVISIBLE 0x0800
|
||||
#define DC_NOSENDMSG 0x2000
|
||||
#define DC_FRAME 0x8000 // Missing from WinUser.H!
|
||||
|
||||
#define DC_DRAWCAPTIONMD 0x10000000
|
||||
#define DC_REDRAWHUNGWND 0x20000000
|
||||
#define DC_DRAWFRAMEMD 0x80000000
|
||||
|
||||
//
|
||||
// Undocumented states for DrawFrameControl
|
||||
//
|
||||
#define DFCS_MENUARROWUP 0x0008
|
||||
#define DFCS_MENUARROWDOWN 0x0010
|
||||
|
||||
|
||||
#define STARTF_SCRNSAVER 0x80000000
|
||||
|
||||
|
|
|
@ -149,6 +149,7 @@ list(APPEND SOURCE
|
|||
user/ntuser/winpos.c
|
||||
user/ntuser/winsta.c
|
||||
user/ntuser/object.c
|
||||
user/rtl/text.c
|
||||
gdi/ntgdi/arc.c
|
||||
gdi/ntgdi/bezier.c
|
||||
gdi/ntgdi/bitblt.c
|
||||
|
|
|
@ -375,6 +375,9 @@ typedef struct tagMENULIST
|
|||
/* Hack */
|
||||
#define MNF_SYSMENU 0x0200
|
||||
|
||||
/* (other FocusedItem values give the position of the focused item) */
|
||||
#define NO_SELECTED_ITEM 0xffff
|
||||
|
||||
typedef struct tagMENU
|
||||
{
|
||||
PROCDESKHEAD head;
|
||||
|
@ -3515,58 +3518,6 @@ NtUserGetMonitorInfo(
|
|||
|
||||
/* Should be done in usermode */
|
||||
|
||||
/* (other FocusedItem values give the position of the focused item) */
|
||||
#define NO_SELECTED_ITEM 0xffff
|
||||
|
||||
typedef struct tagROSMENUINFO
|
||||
{
|
||||
/* ----------- MENUINFO ----------- */
|
||||
DWORD cbSize;
|
||||
DWORD fMask;
|
||||
DWORD dwStyle;
|
||||
UINT cyMax;
|
||||
HBRUSH hbrBack;
|
||||
DWORD dwContextHelpID;
|
||||
ULONG_PTR dwMenuData;
|
||||
/* ----------- Extra ----------- */
|
||||
ULONG fFlags; /* Menu flags (MF_POPUP, MF_SYSMENU) */
|
||||
UINT iItem; /* Currently focused item */
|
||||
UINT cItems; /* Number of items in the menu */
|
||||
WORD cxMenu; /* Width of the whole menu */
|
||||
WORD cyMenu; /* Height of the whole menu */
|
||||
ULONG cxTextAlign;
|
||||
PWND spwndNotify; /* window receiving the messages for ownerdraw */
|
||||
INT iTop;
|
||||
INT iMaxTop;
|
||||
DWORD dwArrowsOn:2;
|
||||
|
||||
HMENU Self; /* Handle of this menu */
|
||||
HWND Wnd; /* Window containing the menu */
|
||||
BOOL TimeToHide; /* Request hiding when receiving a second click in the top-level menu item */
|
||||
} ROSMENUINFO, *PROSMENUINFO;
|
||||
|
||||
typedef struct tagROSMENUITEMINFO
|
||||
{
|
||||
/* ----------- MENUITEMINFOW ----------- */
|
||||
UINT cbSize;
|
||||
UINT fMask;
|
||||
UINT fType;
|
||||
UINT fState;
|
||||
UINT wID;
|
||||
HMENU hSubMenu;
|
||||
HBITMAP hbmpChecked;
|
||||
HBITMAP hbmpUnchecked;
|
||||
DWORD dwItemData;
|
||||
LPWSTR dwTypeData;
|
||||
UINT cch;
|
||||
HBITMAP hbmpItem;
|
||||
/* ----------- Extra ----------- */
|
||||
RECT Rect; /* Item area (relative to menu window) */
|
||||
UINT dxTab; /* X position of text after Tab */
|
||||
LPWSTR lpstr; /* Copy of the text pointer in MenuItem->Text */
|
||||
SIZE maxBmpSize; /* Maximum size of the bitmap items in MIIM_BITMAP state */
|
||||
} ROSMENUITEMINFO, *PROSMENUITEMINFO;
|
||||
|
||||
HMONITOR
|
||||
NTAPI
|
||||
NtUserMonitorFromPoint(
|
||||
|
|
|
@ -393,6 +393,8 @@ co_IntCallWindowProc(WNDPROC Proc,
|
|||
case WM_WINDOWPOSCHANGING:
|
||||
case WM_SIZING:
|
||||
case WM_MOVING:
|
||||
case WM_MEASUREITEM:
|
||||
case WM_NEXTMENU:
|
||||
TRACE("Copy lParam, Message %u Size %d lParam %d!\n", Message, lParamBufferSize, lParam);
|
||||
if (InSendMessage)
|
||||
// Copy into kernel space.
|
||||
|
|
|
@ -2556,6 +2556,15 @@ InvalidParameter:
|
|||
Offset,
|
||||
dwNewLong,
|
||||
Ansi);
|
||||
switch(Offset)
|
||||
{
|
||||
case GCLP_HICONSM:
|
||||
case GCLP_HICON:
|
||||
{
|
||||
if (Ret && Ret != dwNewLong)
|
||||
UserPaintCaption(Window, DC_ICON);
|
||||
}
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
|
|
@ -11,6 +11,23 @@
|
|||
|
||||
DBG_DEFAULT_CHANNEL(UserDefwnd);
|
||||
|
||||
INT WINAPI DrawTextExWorker( HDC hdc, LPWSTR str, INT i_count,
|
||||
LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp );
|
||||
|
||||
INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags )
|
||||
{
|
||||
DRAWTEXTPARAMS dtp;
|
||||
|
||||
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)
|
||||
|
@ -171,6 +188,19 @@ DefWndHandleSysCommand(PWND pWnd, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
}
|
||||
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:
|
||||
|
@ -362,6 +392,138 @@ 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 sovled 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
|
||||
*/
|
||||
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);
|
||||
hIcon = UserGetProp(pWnd, gpsi->atomIconProp);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
IntSetProp(pWnd, gpsi->atomIconProp, hIcon);
|
||||
IntSetProp(pWnd, gpsi->atomIconSmProp, hIconSmall);
|
||||
|
||||
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);
|
||||
break;
|
||||
case ICON_SMALL:
|
||||
case ICON_SMALL2:
|
||||
hIconRet = UserGetProp(pWnd, gpsi->atomIconSmProp);
|
||||
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
|
||||
|
@ -374,6 +536,7 @@ IntDefWindowProc(
|
|||
LPARAM lParam,
|
||||
BOOL Ansi)
|
||||
{
|
||||
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
|
||||
LRESULT lResult = 0;
|
||||
USER_REFERENCE_ENTRY Ref;
|
||||
|
||||
|
@ -381,12 +544,74 @@ IntDefWindowProc(
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -411,7 +636,6 @@ IntDefWindowProc(
|
|||
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) )
|
||||
{
|
||||
|
@ -424,6 +648,241 @@ IntDefWindowProc(
|
|||
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_LBUTTONDBLCLK:
|
||||
return (NC_HandleNCLButtonDblClk( Wnd, HTCLIENT, lParam));
|
||||
|
||||
case WM_NCLBUTTONDBLCLK:
|
||||
return (NC_HandleNCLButtonDblClk( Wnd, wParam, lParam));
|
||||
|
||||
case WM_NCRBUTTONDOWN:
|
||||
return NC_HandleNCRButtonDown( 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_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));
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
@ -457,6 +916,18 @@ IntDefWindowProc(
|
|||
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 */
|
||||
|
@ -523,6 +994,18 @@ IntDefWindowProc(
|
|||
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:
|
||||
{
|
||||
|
@ -548,7 +1031,9 @@ IntDefWindowProc(
|
|||
IntGetClientRect(Wnd, &ClientRect);
|
||||
x = (ClientRect.right - ClientRect.left - UserGetSystemMetrics(SM_CXICON)) / 2;
|
||||
y = (ClientRect.bottom - ClientRect.top - UserGetSystemMetrics(SM_CYICON)) / 2;
|
||||
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);
|
||||
|
@ -578,7 +1063,6 @@ IntDefWindowProc(
|
|||
}
|
||||
|
||||
case WM_SETREDRAW:
|
||||
ERR("WM_SETREDRAW\n");
|
||||
if (wParam)
|
||||
{
|
||||
if (!(Wnd->style & WS_VISIBLE))
|
||||
|
@ -607,6 +1091,53 @@ IntDefWindowProc(
|
|||
return (DefWndHandleWindowPosChanged(Wnd, (WINDOWPOS*)lParam));
|
||||
}
|
||||
|
||||
case WM_NCCALCSIZE:
|
||||
{
|
||||
return NC_HandleNCCalcSize( Wnd, wParam, (RECTL *)lParam );
|
||||
}
|
||||
|
||||
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:
|
||||
{
|
||||
|
|
|
@ -664,6 +664,7 @@ DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *lRe
|
|||
case WM_SYSCOLORCHANGE:
|
||||
co_UserRedrawWindow(Wnd, NULL, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN);
|
||||
return TRUE;
|
||||
|
||||
case WM_SETCURSOR:
|
||||
{
|
||||
PCURICON_OBJECT pcurOld, pcurNew;
|
||||
|
@ -691,8 +692,11 @@ DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *lRe
|
|||
HDESK hdesk = IntGetDesktopObjectHandle(gpdeskInputDesktop);
|
||||
IntSetThreadDesktop(hdesk, FALSE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
TRACE("DWP calling IDWP Msg %d\n",Msg);
|
||||
*lResult = IntDefWindowProc(Wnd, Msg, wParam, lParam, FALSE);
|
||||
}
|
||||
return TRUE; /* We are done. Do not do any callbacks to user mode */
|
||||
}
|
||||
|
@ -711,6 +715,9 @@ UserMessageWindowProc(PWND pwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT
|
|||
case WM_DESTROY:
|
||||
pwnd->fnid |= FNID_DESTROY;
|
||||
break;
|
||||
default:
|
||||
ERR("UMWP calling IDWP\n");
|
||||
*lResult = IntDefWindowProc(pwnd, Msg, wParam, lParam, FALSE);
|
||||
}
|
||||
|
||||
return TRUE; /* We are done. Do not do any callbacks to user mode */
|
||||
|
|
|
@ -948,6 +948,14 @@ BOOL FASTCALL UITOOLS95_DrawFrameMenu(HDC dc, LPRECT r, UINT uFlags)
|
|||
WCHAR Symbol;
|
||||
switch(uFlags & 0xff)
|
||||
{
|
||||
case DFCS_MENUARROWUP:
|
||||
Symbol = '5';
|
||||
break;
|
||||
|
||||
case DFCS_MENUARROWDOWN:
|
||||
Symbol = '6';
|
||||
break;
|
||||
|
||||
case DFCS_MENUARROW:
|
||||
Symbol = '8';
|
||||
break;
|
||||
|
@ -980,8 +988,6 @@ BOOL FASTCALL UITOOLS95_DrawFrameMenu(HDC dc, LPRECT r, UINT uFlags)
|
|||
hFont = GreCreateFontIndirectW(&lf);
|
||||
/* save font */
|
||||
hOldFont = NtGdiSelectFont(dc, hFont);
|
||||
// FIXME selecting color doesn't work
|
||||
#if 0
|
||||
if(uFlags & DFCS_INACTIVE)
|
||||
{
|
||||
/* draw shadow */
|
||||
|
@ -989,7 +995,6 @@ BOOL FASTCALL UITOOLS95_DrawFrameMenu(HDC dc, LPRECT r, UINT uFlags)
|
|||
GreTextOutW(dc, r->left + 1, r->top + 1, &Symbol, 1);
|
||||
}
|
||||
IntGdiSetTextColor(dc, IntGetSysColor((uFlags & DFCS_INACTIVE) ? COLOR_BTNSHADOW : COLOR_BTNTEXT));
|
||||
#endif
|
||||
/* draw selected symbol */
|
||||
GreTextOutW(dc, r->left, r->top, &Symbol, 1);
|
||||
/* restore previous settings */
|
||||
|
@ -1005,6 +1010,25 @@ BOOL FASTCALL UITOOLS95_DrawFrameMenu(HDC dc, LPRECT r, UINT uFlags)
|
|||
//
|
||||
|
||||
|
||||
INT WINAPI
|
||||
FrameRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr)
|
||||
{
|
||||
HBRUSH oldbrush;
|
||||
RECT r = *lprc;
|
||||
|
||||
if ((r.right <= r.left) || (r.bottom <= r.top)) return 0;
|
||||
if (!(oldbrush = NtGdiSelectBrush(hDC, hbr))) return 0;
|
||||
|
||||
NtGdiPatBlt(hDC, r.left, r.top, 1, r.bottom - r.top, PATCOPY);
|
||||
NtGdiPatBlt(hDC, r.right - 1, r.top, 1, r.bottom - r.top, PATCOPY);
|
||||
NtGdiPatBlt(hDC, r.left, r.top, r.right - r.left, 1, PATCOPY);
|
||||
NtGdiPatBlt(hDC, r.left, r.bottom - 1, r.right - r.left, 1, PATCOPY);
|
||||
|
||||
NtGdiSelectBrush(hDC, oldbrush);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
INT WINAPI
|
||||
FillRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr)
|
||||
{
|
||||
|
|
|
@ -66,7 +66,7 @@ co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd)
|
|||
(LPARAM)hWnd);
|
||||
|
||||
if (WndPrev)
|
||||
WndPrev->state &= ~WNDS_ACTIVEFRAME;
|
||||
WndPrev->state &= ~(WNDS_ACTIVEFRAME|WNDS_HASCAPTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -700,7 +700,7 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, BOOL bMouse, BOOL bFocus, BOOL Async)
|
|||
}
|
||||
|
||||
// FIXME: Used in the menu loop!!!
|
||||
//ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;
|
||||
ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;
|
||||
|
||||
//ERR("co_IntSetActiveWindow Exit\n");
|
||||
if (Wnd) Wnd->state &= ~WNDS_BEINGACTIVATED;
|
||||
|
@ -946,7 +946,11 @@ co_UserSetCapture(HWND hWnd)
|
|||
if (Window)
|
||||
IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
|
||||
|
||||
if (hWndPrev && hWndPrev != hWnd)
|
||||
//
|
||||
// Only send the message if we have a previous Window!
|
||||
// Fix msg_menu tracking popup menu and win test_capture_4!!!!
|
||||
//
|
||||
if (hWndPrev)
|
||||
{
|
||||
if (ThreadQueue->MenuOwner && Window) ThreadQueue->QF_flags |= QF_CAPTURELOCKED;
|
||||
|
||||
|
|
|
@ -936,7 +936,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
|
|||
/* FIXME: Set KF_DLGMODE and KF_MENUMODE when needed */
|
||||
if (pFocusQueue->QF_flags & QF_DIALOGACTIVE)
|
||||
Msg.lParam |= KF_DLGMODE << 16;
|
||||
if (pFocusQueue->MenuOwner) // pFocusQueue->MenuState) // MenuState needs a start flag...
|
||||
if (pFocusQueue->MenuOwner) // pti->pMenuState->fMenuStarted
|
||||
Msg.lParam |= KF_MENUMODE << 16;
|
||||
}
|
||||
|
||||
|
@ -951,7 +951,6 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
|
|||
if (!Wnd) {ERR("Window is NULL\n");}
|
||||
MsqPostMessage(pti, &Msg, TRUE, QS_KEY, 0, dwExtraInfo);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -66,6 +66,62 @@ typedef struct _SETMENUITEMRECT
|
|||
RECTL rcRect;
|
||||
} SETMENUITEMRECT, *PSETMENUITEMRECT;
|
||||
|
||||
|
||||
//
|
||||
// Legacy ReactOS Menu transfer structures.
|
||||
//
|
||||
typedef struct tagROSMENUINFO
|
||||
{
|
||||
/* ----------- MENUINFO ----------- */
|
||||
DWORD cbSize;
|
||||
DWORD fMask;
|
||||
DWORD dwStyle;
|
||||
UINT cyMax;
|
||||
HBRUSH hbrBack;
|
||||
DWORD dwContextHelpID;
|
||||
ULONG_PTR dwMenuData;
|
||||
/* ----------- Extra ----------- */
|
||||
ULONG fFlags; /* Menu flags (MF_POPUP, MF_SYSMENU) */
|
||||
UINT iItem; /* Currently focused item */
|
||||
UINT cItems; /* Number of items in the menu */
|
||||
WORD cxMenu; /* Width of the whole menu */
|
||||
WORD cyMenu; /* Height of the whole menu */
|
||||
ULONG cxTextAlign;
|
||||
PWND spwndNotify; /* window receiving the messages for ownerdraw */
|
||||
INT iTop;
|
||||
INT iMaxTop;
|
||||
DWORD dwArrowsOn:2;
|
||||
|
||||
HMENU Self; /* Handle of this menu */
|
||||
HWND Wnd; /* Window containing the menu */
|
||||
BOOL TimeToHide; /* Request hiding when receiving a second click in the top-level menu item */
|
||||
} ROSMENUINFO, *PROSMENUINFO;
|
||||
|
||||
typedef struct tagROSMENUITEMINFO
|
||||
{
|
||||
/* ----------- MENUITEMINFOW ----------- */
|
||||
UINT cbSize;
|
||||
UINT fMask;
|
||||
UINT fType;
|
||||
UINT fState;
|
||||
UINT wID;
|
||||
HMENU hSubMenu;
|
||||
HBITMAP hbmpChecked;
|
||||
HBITMAP hbmpUnchecked;
|
||||
DWORD dwItemData;
|
||||
LPWSTR dwTypeData;
|
||||
UINT cch;
|
||||
HBITMAP hbmpItem;
|
||||
/* ----------- Extra ----------- */
|
||||
RECT Rect; /* Item area (relative to menu window) */
|
||||
UINT dxTab; /* X position of text after Tab */
|
||||
LPWSTR lpstr; /* Copy of the text pointer in MenuItem->Text */
|
||||
SIZE maxBmpSize; /* Maximum size of the bitmap items in MIIM_BITMAP state */
|
||||
} ROSMENUITEMINFO, *PROSMENUITEMINFO;
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
PMENU FASTCALL
|
||||
IntGetMenuObject(HMENU hMenu);
|
||||
|
||||
|
@ -101,3 +157,14 @@ BOOL FASTCALL IntRemoveMenuItem(PMENU Menu, UINT uPosition, UINT uFlags, BOOL bR
|
|||
PITEM FASTCALL MENU_FindItem( PMENU *pmenu, UINT *nPos, UINT wFlags );
|
||||
BOOL FASTCALL IntMenuItemInfo(PMENU Menu, UINT Item, BOOL ByPosition, PROSMENUITEMINFO UnsafeItemInfo, BOOL SetOrGet, PUNICODE_STRING lpstr);
|
||||
BOOL FASTCALL IntSetMenu(PWND Wnd,HMENU Menu,BOOL *Changed);
|
||||
UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, PWND pWnd, BOOL suppress_draw );
|
||||
BOOL MenuInit(VOID);
|
||||
VOID MENU_TrackKbdMenuBar(PWND pwnd, UINT wParam, WCHAR wChar);
|
||||
VOID MENU_TrackMouseMenuBar( PWND pWnd, ULONG ht, POINT pt);
|
||||
BOOL WINAPI PopupMenuWndProc(PWND Wnd,UINT Message,WPARAM wParam,LPARAM lParam,LRESULT *lResult);
|
||||
BOOL FASTCALL IntSetMenuItemInfo(PMENU, PITEM, PROSMENUITEMINFO, PUNICODE_STRING);
|
||||
PWND MENU_IsMenuActive(VOID);
|
||||
void MENU_EndMenu( PWND pwnd );
|
||||
void FASTCALL MENU_InitSysMenuPopup(PMENU menu, DWORD style, DWORD clsStyle, LONG HitTest );
|
||||
INT FASTCALL IntMenuItemFromPoint(PWND pWnd, HMENU hMenu, POINT ptScreen);
|
||||
BOOL WINAPI IntTrackPopupMenuEx( PMENU menu, UINT wFlags, int x, int y, PWND pWnd, LPTPMPARAMS lpTpm);
|
||||
|
|
|
@ -136,6 +136,10 @@ static MSGMEMORY g_MsgMemory[] =
|
|||
{ WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
|
||||
{ WM_SIZING, sizeof(RECT), MMS_FLAG_READWRITE },
|
||||
{ WM_MOVING, sizeof(RECT), MMS_FLAG_READWRITE },
|
||||
{ WM_MEASUREITEM, sizeof(MEASUREITEMSTRUCT), MMS_FLAG_READWRITE },
|
||||
{ WM_DRAWITEM, sizeof(DRAWITEMSTRUCT), MMS_FLAG_READWRITE },
|
||||
{ WM_HELP, sizeof(HELPINFO), MMS_FLAG_READWRITE },
|
||||
{ WM_NEXTMENU, sizeof(MDINEXTMENU), MMS_FLAG_READWRITE },
|
||||
};
|
||||
|
||||
static PMSGMEMORY FASTCALL
|
||||
|
@ -745,7 +749,13 @@ IntDispatchMessage(PMSG pMsg)
|
|||
pMsg->message,
|
||||
pMsg->wParam,
|
||||
pMsg->lParam,
|
||||
&retval);
|
||||
&retval);
|
||||
case FNID_MENU:
|
||||
DoCallBack = !PopupMenuWndProc( Window,
|
||||
pMsg->message,
|
||||
pMsg->wParam,
|
||||
pMsg->lParam,
|
||||
&retval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -949,7 +959,7 @@ co_IntPeekMessage( PMSG Msg,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL FASTCALL
|
||||
BOOL FASTCALL
|
||||
co_IntWaitMessage( PWND Window,
|
||||
UINT MsgFilterMin,
|
||||
UINT MsgFilterMax )
|
||||
|
@ -1353,6 +1363,9 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
|
|||
case FNID_MESSAGEWND:
|
||||
DoCallBack = !UserMessageWindowProc(Window, Msg, wParam, lParam,(LRESULT*)&Result);
|
||||
break;
|
||||
case FNID_MENU:
|
||||
DoCallBack = !PopupMenuWndProc( Window, Msg, wParam, lParam,(LRESULT*)&Result);
|
||||
break;
|
||||
}
|
||||
if (!DoCallBack)
|
||||
{
|
||||
|
@ -1644,6 +1657,9 @@ co_IntSendMessageWithCallBack( HWND hWnd,
|
|||
case FNID_MESSAGEWND:
|
||||
DoCallBack = !UserMessageWindowProc(Window, Msg, wParam, lParam,(LRESULT*)&Result);
|
||||
break;
|
||||
case FNID_MENU:
|
||||
DoCallBack = !PopupMenuWndProc( Window, Msg, wParam, lParam,(LRESULT*)&Result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2333,13 +2349,21 @@ NtUserMessageCall( HWND hWnd,
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case FNID_MENU:
|
||||
{
|
||||
Window = UserGetWindowObject(hWnd);
|
||||
if (Window)
|
||||
{
|
||||
Ret = PopupMenuWndProc( Window, Msg, wParam, lParam, &lResult);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FNID_MESSAGEWND:
|
||||
{
|
||||
Window = UserGetWindowObject(hWnd);
|
||||
if (Window)
|
||||
{
|
||||
Ret = !UserMessageWindowProc(Window, Msg, wParam, lParam,&lResult);
|
||||
Ret = !UserMessageWindowProc(Window, Msg, wParam, lParam, &lResult);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2832,6 +2856,7 @@ NtUserMessageCall( HWND hWnd,
|
|||
case FNID_CALLWNDPROCRET:
|
||||
case FNID_SCROLLBAR:
|
||||
case FNID_DESKTOP:
|
||||
case FNID_MENU:
|
||||
if (ResultInfo)
|
||||
{
|
||||
_SEH2_TRY
|
||||
|
|
|
@ -397,6 +397,28 @@ NtUserGetGUIThreadInfo(
|
|||
CaretInfo = MsgQueue->CaretInfo;
|
||||
|
||||
SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0);
|
||||
/*
|
||||
if (W32Thread->pMenuState->pGlobalPopupMenu)
|
||||
{
|
||||
SafeGui.flags |= GUI_INMENUMODE;
|
||||
|
||||
if (W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify)
|
||||
SafeGui.hwndMenuOwner = UserHMGetHandle(W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify);
|
||||
|
||||
if (W32Thread->pMenuState->pGlobalPopupMenu->fHasMenuBar)
|
||||
{
|
||||
if (W32Thread->pMenuState->pGlobalPopupMenu->fIsSysMenu)
|
||||
{
|
||||
SafeGui.flags |= GUI_SYSTEMMENUMODE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SafeGui.flags |= GUI_POPUPMENUMODE;
|
||||
}
|
||||
}
|
||||
*/
|
||||
SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;
|
||||
|
||||
if (MsgQueue->MenuOwner)
|
||||
SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState;
|
||||
|
@ -409,7 +431,6 @@ NtUserGetGUIThreadInfo(
|
|||
SafeGui.hwndActive = MsgQueue->spwndActive ? UserHMGetHandle(MsgQueue->spwndActive) : 0;
|
||||
SafeGui.hwndFocus = MsgQueue->spwndFocus ? UserHMGetHandle(MsgQueue->spwndFocus) : 0;
|
||||
SafeGui.hwndCapture = MsgQueue->spwndCapture ? UserHMGetHandle(MsgQueue->spwndCapture) : 0;
|
||||
SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;
|
||||
SafeGui.hwndMoveSize = MsgQueue->MoveSize;
|
||||
SafeGui.hwndCaret = CaretInfo->hWnd;
|
||||
|
||||
|
|
|
@ -2005,8 +2005,28 @@ NTSTATUS FASTCALL
|
|||
co_MsqWaitForNewMessages(PTHREADINFO pti, PWND WndFilter,
|
||||
UINT MsgFilterMin, UINT MsgFilterMax)
|
||||
{
|
||||
NTSTATUS ret;
|
||||
NTSTATUS ret = STATUS_SUCCESS;
|
||||
|
||||
// Post mouse moves before waiting for messages.
|
||||
if (pti->MessageQueue->QF_flags & QF_MOUSEMOVED)
|
||||
{
|
||||
IntCoalesceMouseMove(pti);
|
||||
}
|
||||
|
||||
if ( pti->nCntsQBits[QSRosMouseButton] != 0 ||
|
||||
pti->nCntsQBits[QSRosMouseMove] != 0 ||
|
||||
pti->nCntsQBits[QSRosKey] != 0 ||
|
||||
pti->nCntsQBits[QSRosSendMessage] != 0 ||
|
||||
pti->nCntsQBits[QSRosPostMessage] != 0 )
|
||||
{
|
||||
TRACE("No time to wait!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
UserLeaveCo();
|
||||
|
||||
ZwYieldExecution(); // Let someone else run!
|
||||
|
||||
ret = KeWaitForSingleObject( pti->pEventQueueServer,
|
||||
UserRequest,
|
||||
UserMode,
|
||||
|
|
|
@ -274,5 +274,9 @@ UserPostThreadMessage( PTHREADINFO pti,
|
|||
UINT Msg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam );
|
||||
BOOL FASTCALL
|
||||
co_IntWaitMessage( PWND Window,
|
||||
UINT MsgFilterMin,
|
||||
UINT MsgFilterMax );
|
||||
|
||||
/* EOF */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -921,23 +921,6 @@ NtUserCtxDisplayIOCtl(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
APIENTRY
|
||||
NtUserDrawMenuBarTemp(
|
||||
HWND hWnd,
|
||||
HDC hDC,
|
||||
PRECT hRect,
|
||||
HMENU hMenu,
|
||||
HFONT hFont)
|
||||
{
|
||||
/* We'll use this function just for caching the menu bar */
|
||||
STUB
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* FillWindow: Called from User; Dialog, Edit and ListBox procs during a WM_ERASEBKGND.
|
||||
*/
|
||||
|
@ -1013,35 +996,6 @@ NtUserUpdateLayeredWindow(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL APIENTRY
|
||||
NtUserEndMenu(VOID)
|
||||
{
|
||||
STUB
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
/* NOTE: unused function */
|
||||
BOOL APIENTRY
|
||||
NtUserTrackPopupMenuEx(
|
||||
HMENU hMenu,
|
||||
UINT fuFlags,
|
||||
int x,
|
||||
int y,
|
||||
HWND hWnd,
|
||||
LPTPMPARAMS lptpm)
|
||||
{
|
||||
STUB
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD APIENTRY
|
||||
NtUserQuerySendMessage(DWORD Unknown0)
|
||||
{
|
||||
|
|
|
@ -1865,8 +1865,6 @@ CLEANUP:
|
|||
END_CLEANUP;
|
||||
}
|
||||
|
||||
static const WCHAR ELLIPSISW[] = {'.','.','.', 0};
|
||||
|
||||
BOOL
|
||||
UserDrawCaptionText(
|
||||
PWND pWnd,
|
||||
|
@ -1884,7 +1882,6 @@ UserDrawCaptionText(
|
|||
SIZE Size;
|
||||
BOOL Ret = TRUE;
|
||||
ULONG fit = 0, Length;
|
||||
WCHAR szText[128];
|
||||
RECTL r = *lpRc;
|
||||
|
||||
TRACE("UserDrawCaptionText: %wZ\n", Text);
|
||||
|
@ -1936,26 +1933,33 @@ UserDrawCaptionText(
|
|||
GreGetTextExtentExW(hDc, Text->Buffer, Text->Length/sizeof(WCHAR), r.right - r.left, &fit, 0, &Size, 0);
|
||||
|
||||
Length = (Text->Length/sizeof(WCHAR) == fit ? fit : fit+1);
|
||||
|
||||
RtlZeroMemory(&szText, sizeof(szText));
|
||||
RtlCopyMemory(&szText, Text->Buffer, Text->Length);
|
||||
|
||||
if (Text->Length/sizeof(WCHAR) > Length && Length > 3)
|
||||
if (Text->Length/sizeof(WCHAR) > Length)
|
||||
{
|
||||
RtlCopyMemory(&szText[Length-3], ELLIPSISW, sizeof(ELLIPSISW));
|
||||
Ret = FALSE;
|
||||
}
|
||||
|
||||
GreExtTextOutW( hDc,
|
||||
lpRc->left,
|
||||
lpRc->top + (lpRc->bottom - lpRc->top) / 2 - Size.cy / 2, // DT_SINGLELINE && DT_VCENTER
|
||||
ETO_CLIPPED,
|
||||
(RECTL *)lpRc,
|
||||
(LPWSTR)&szText,
|
||||
Length,
|
||||
NULL,
|
||||
0 );
|
||||
|
||||
if (Ret)
|
||||
{ // Faster while in setup.
|
||||
GreExtTextOutW( hDc,
|
||||
lpRc->left,
|
||||
lpRc->top + (lpRc->bottom - lpRc->top) / 2 - Size.cy / 2, // DT_SINGLELINE && DT_VCENTER
|
||||
ETO_CLIPPED,
|
||||
(RECTL *)lpRc,
|
||||
Text->Buffer,
|
||||
Length,
|
||||
NULL,
|
||||
0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTextW( hDc,
|
||||
Text->Buffer,
|
||||
Text->Length/sizeof(WCHAR),
|
||||
(RECTL *)&r,
|
||||
DT_END_ELLIPSIS|DT_SINGLELINE|DT_VCENTER|DT_NOPREFIX|DT_LEFT);
|
||||
}
|
||||
|
||||
IntGdiSetTextColor(hDc, OldTextColor);
|
||||
|
||||
if (hOldFont)
|
||||
|
@ -2209,8 +2213,26 @@ NtUserDrawCaptionTemp(
|
|||
if (str != NULL)
|
||||
Ret = UserDrawCaption(pWnd, hDC, &SafeRect, hFont, hIcon, &SafeStr, uFlags);
|
||||
else
|
||||
{
|
||||
if ( RECTL_bIsEmptyRect(&SafeRect) && hFont == 0 && hIcon == 0 )
|
||||
{
|
||||
Ret = TRUE;
|
||||
if (uFlags & DC_DRAWCAPTIONMD)
|
||||
{
|
||||
ERR("NC Caption Mode\n");
|
||||
UserDrawCaptionBar(pWnd, hDC, uFlags);
|
||||
goto Exit;
|
||||
}
|
||||
else if (uFlags & DC_DRAWFRAMEMD)
|
||||
{
|
||||
ERR("NC Paint Mode\n");
|
||||
NC_DoNCPaint(pWnd, hDC, uFlags); // Update Menus too!
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
Ret = UserDrawCaption(pWnd, hDC, &SafeRect, hFont, hIcon, NULL, uFlags);
|
||||
|
||||
}
|
||||
Exit:
|
||||
UserLeave();
|
||||
return Ret;
|
||||
}
|
||||
|
@ -2222,7 +2244,7 @@ NtUserDrawCaption(HWND hWnd,
|
|||
LPCRECT lpRc,
|
||||
UINT uFlags)
|
||||
{
|
||||
return NtUserDrawCaptionTemp(hWnd, hDC, lpRc, 0, 0, NULL, uFlags);
|
||||
return NtUserDrawCaptionTemp(hWnd, hDC, lpRc, 0, 0, NULL, uFlags);
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
|
|
@ -33,4 +33,6 @@ HDC FASTCALL IntBeginPaint(PWND,PPAINTSTRUCT);
|
|||
PCURICON_OBJECT FASTCALL NC_IconForWindow( PWND );
|
||||
BOOL FASTCALL IntFlashWindowEx(PWND,PFLASHWINFO);
|
||||
BOOL FASTCALL IntIntersectWithParents(PWND, RECTL *);
|
||||
BOOL FASTCALL IntIsWindowDrawable(PWND);
|
||||
BOOL FASTCALL IntIsWindowDrawable(PWND);
|
||||
BOOL UserDrawCaption(PWND,HDC,RECTL*,HFONT,HICON,const PUNICODE_STRING,UINT);
|
||||
|
||||
|
|
|
@ -39,5 +39,11 @@ typedef struct _SBINFOEX
|
|||
#define SBOBJ_TO_SBID(Obj) ((Obj) - OBJID_HSCROLL)
|
||||
#define SBID_IS_VALID(id) (id == SB_HORZ || id == SB_VERT || id == SB_CTL)
|
||||
|
||||
BOOL FASTCALL co_IntCreateScrollBars(PWND Window);
|
||||
BOOL FASTCALL IntDestroyScrollBars(PWND Window);
|
||||
BOOL FASTCALL co_IntCreateScrollBars(PWND);
|
||||
BOOL FASTCALL IntDestroyScrollBars(PWND);
|
||||
DWORD FASTCALL co_UserShowScrollBar(PWND,int,BOOL,BOOL);
|
||||
BOOL FASTCALL co_IntGetScrollBarInfo(PWND,LONG,PSCROLLBARINFO);
|
||||
BOOL FASTCALL co_IntSetScrollBarInfo(PWND,LONG,PSETSCROLLBARINFO);
|
||||
void IntDrawScrollBar(PWND,HDC,INT);
|
||||
BOOL FASTCALL IntScrollWindow(PWND,int,int,CONST RECT*,CONST RECT*);
|
||||
DWORD FASTCALL IntScrollWindowEx(PWND,INT,INT,const RECT*,const RECT*,HRGN,LPRECT,UINT);
|
||||
|
|
|
@ -10,6 +10,32 @@
|
|||
#include <win32k.h>
|
||||
DBG_DEFAULT_CHANNEL(UserScrollbar);
|
||||
|
||||
/* Definitions for scrollbar hit testing [See SCROLLBARINFO in MSDN] */
|
||||
#define SCROLL_NOWHERE 0x00 /* Outside the scroll bar */
|
||||
#define SCROLL_TOP_ARROW 0x01 /* Top or left arrow */
|
||||
#define SCROLL_TOP_RECT 0x02 /* Rectangle between the top arrow and the thumb */
|
||||
#define SCROLL_THUMB 0x03 /* Thumb rectangle */
|
||||
#define SCROLL_BOTTOM_RECT 0x04 /* Rectangle between the thumb and the bottom arrow */
|
||||
#define SCROLL_BOTTOM_ARROW 0x05 /* Bottom or right arrow */
|
||||
|
||||
#define SCROLL_FIRST_DELAY 200 /* Delay (in ms) before first repetition when
|
||||
holding the button down */
|
||||
#define SCROLL_REPEAT_DELAY 50 /* Delay (in ms) between scroll repetitions */
|
||||
|
||||
#define SCROLL_TIMER 0 /* Scroll timer id */
|
||||
|
||||
/* Minimum size of the rectangle between the arrows */
|
||||
#define SCROLL_MIN_RECT 4
|
||||
|
||||
/* Minimum size of the thumb in pixels */
|
||||
#define SCROLL_MIN_THUMB 6
|
||||
|
||||
/* Overlap between arrows and thumb */
|
||||
#define SCROLL_ARROW_THUMB_OVERLAP 0
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
#define MINTRACKTHUMB 8 /* Minimum size of the rectangle between the arrows */
|
||||
|
||||
/* What to do after SetScrollInfo() */
|
||||
|
@ -554,6 +580,39 @@ co_IntGetScrollBarInfo(PWND Window, LONG idObject, PSCROLLBARINFO psbi)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FASTCALL
|
||||
co_IntSetScrollBarInfo(PWND Window, LONG idObject, PSETSCROLLBARINFO psbi)
|
||||
{
|
||||
INT Bar;
|
||||
PSCROLLBARINFO sbi;
|
||||
LPSCROLLINFO psi;
|
||||
ASSERT_REFS_CO(Window);
|
||||
|
||||
Bar = SBOBJ_TO_SBID(idObject);
|
||||
|
||||
if(!SBID_IS_VALID(Bar))
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||
ERR("Trying to get scrollinfo for unknown scrollbar type %d\n", Bar);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(!co_IntCreateScrollBars(Window))
|
||||
{
|
||||
ERR("Failed to create scrollbars for window.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sbi = IntGetScrollbarInfoFromWindow(Window, Bar);
|
||||
psi = IntGetScrollInfoFromWindow(Window, Bar);
|
||||
|
||||
psi->nTrackPos = psbi->nTrackPos;
|
||||
sbi->reserved = psbi->reserved;
|
||||
RtlCopyMemory(&sbi->rgstate, &psbi->rgstate, sizeof(psbi->rgstate));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FASTCALL
|
||||
co_IntCreateScrollBars(PWND Window)
|
||||
{
|
||||
|
@ -709,6 +768,248 @@ co_UserShowScrollBar(PWND Wnd, int nBar, BOOL fShowH, BOOL fShowV)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
IntDrawScrollInterior(PWND pWnd, HDC hDC, INT nBar, BOOL Vertical, PSCROLLBARINFO ScrollBarInfo)
|
||||
{
|
||||
INT ThumbSize = ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
|
||||
INT ThumbTop = ScrollBarInfo->xyThumbTop;
|
||||
RECT Rect;
|
||||
HBRUSH hSaveBrush, hBrush;
|
||||
BOOL TopSelected = FALSE, BottomSelected = FALSE;
|
||||
|
||||
if (ScrollBarInfo->rgstate[SCROLL_TOP_RECT] & STATE_SYSTEM_PRESSED)
|
||||
TopSelected = TRUE;
|
||||
if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_RECT] & STATE_SYSTEM_PRESSED)
|
||||
BottomSelected = TRUE;
|
||||
|
||||
/*
|
||||
* Only scrollbar controls send WM_CTLCOLORSCROLLBAR.
|
||||
* The window-owned scrollbars need to call DefWndControlColor
|
||||
* to correctly setup default scrollbar colors
|
||||
*/
|
||||
if (nBar == SB_CTL)
|
||||
{
|
||||
hBrush = GetControlBrush( pWnd, hDC, WM_CTLCOLORSCROLLBAR);
|
||||
if (!hBrush)
|
||||
hBrush = IntGetSysColorBrush(COLOR_SCROLLBAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
hBrush = DefWndControlColor(hDC, CTLCOLOR_SCROLLBAR);
|
||||
}
|
||||
|
||||
hSaveBrush = NtGdiSelectBrush(hDC, hBrush);
|
||||
|
||||
/* Calculate the scroll rectangle */
|
||||
if (Vertical)
|
||||
{
|
||||
Rect.top = ScrollBarInfo->rcScrollBar.top + ScrollBarInfo->dxyLineButton;
|
||||
Rect.bottom = ScrollBarInfo->rcScrollBar.bottom - ScrollBarInfo->dxyLineButton;
|
||||
Rect.left = ScrollBarInfo->rcScrollBar.left;
|
||||
Rect.right = ScrollBarInfo->rcScrollBar.right;
|
||||
}
|
||||
else
|
||||
{
|
||||
Rect.top = ScrollBarInfo->rcScrollBar.top;
|
||||
Rect.bottom = ScrollBarInfo->rcScrollBar.bottom;
|
||||
Rect.left = ScrollBarInfo->rcScrollBar.left + ScrollBarInfo->dxyLineButton;
|
||||
Rect.right = ScrollBarInfo->rcScrollBar.right - ScrollBarInfo->dxyLineButton;
|
||||
}
|
||||
|
||||
/* Draw the scroll rectangles and thumb */
|
||||
if (!ScrollBarInfo->xyThumbBottom)
|
||||
{
|
||||
NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right - Rect.left,
|
||||
Rect.bottom - Rect.top, PATCOPY);
|
||||
|
||||
/* Cleanup and return */
|
||||
NtGdiSelectBrush(hDC, hSaveBrush);
|
||||
return;
|
||||
}
|
||||
|
||||
ThumbTop -= ScrollBarInfo->dxyLineButton;
|
||||
|
||||
if (ScrollBarInfo->dxyLineButton)
|
||||
{
|
||||
if (Vertical)
|
||||
{
|
||||
if (ThumbSize)
|
||||
{
|
||||
NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right - Rect.left,
|
||||
ThumbTop, TopSelected ? BLACKNESS : PATCOPY);
|
||||
Rect.top += ThumbTop;
|
||||
NtGdiPatBlt(hDC, Rect.left, Rect.top + ThumbSize, Rect.right - Rect.left,
|
||||
Rect.bottom - Rect.top - ThumbSize, BottomSelected ? BLACKNESS : PATCOPY);
|
||||
Rect.bottom = Rect.top + ThumbSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ThumbTop)
|
||||
{
|
||||
NtGdiPatBlt(hDC, Rect.left, ScrollBarInfo->dxyLineButton,
|
||||
Rect.right - Rect.left, Rect.bottom - Rect.top, PATCOPY);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ThumbSize)
|
||||
{
|
||||
NtGdiPatBlt(hDC, Rect.left, Rect.top, ThumbTop,
|
||||
Rect.bottom - Rect.top, TopSelected ? BLACKNESS : PATCOPY);
|
||||
Rect.left += ThumbTop;
|
||||
NtGdiPatBlt(hDC, Rect.left + ThumbSize, Rect.top,
|
||||
Rect.right - Rect.left - ThumbSize, Rect.bottom - Rect.top,
|
||||
BottomSelected ? BLACKNESS : PATCOPY);
|
||||
Rect.right = Rect.left + ThumbSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ThumbTop)
|
||||
{
|
||||
NtGdiPatBlt(hDC, ScrollBarInfo->dxyLineButton, Rect.top,
|
||||
Rect.right - Rect.left, Rect.bottom - Rect.top, PATCOPY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw the thumb */
|
||||
if (ThumbSize)
|
||||
DrawEdge(hDC, &Rect, EDGE_RAISED, BF_RECT | BF_MIDDLE);
|
||||
|
||||
/* Cleanup */
|
||||
NtGdiSelectBrush(hDC, hSaveBrush);
|
||||
}
|
||||
|
||||
|
||||
static VOID FASTCALL
|
||||
IntDrawScrollArrows(HDC hDC, PSCROLLBARINFO ScrollBarInfo, BOOL Vertical)
|
||||
{
|
||||
RECT RectLT, RectRB;
|
||||
INT ScrollDirFlagLT, ScrollDirFlagRB;
|
||||
|
||||
RectLT = RectRB = ScrollBarInfo->rcScrollBar;
|
||||
if (Vertical)
|
||||
{
|
||||
ScrollDirFlagLT = DFCS_SCROLLUP;
|
||||
ScrollDirFlagRB = DFCS_SCROLLDOWN;
|
||||
RectLT.bottom = RectLT.top + ScrollBarInfo->dxyLineButton;
|
||||
RectRB.top = RectRB.bottom - ScrollBarInfo->dxyLineButton;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScrollDirFlagLT = DFCS_SCROLLLEFT;
|
||||
ScrollDirFlagRB = DFCS_SCROLLRIGHT;
|
||||
RectLT.right = RectLT.left + ScrollBarInfo->dxyLineButton;
|
||||
RectRB.left = RectRB.right - ScrollBarInfo->dxyLineButton;
|
||||
}
|
||||
|
||||
if (ScrollBarInfo->rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_PRESSED)
|
||||
{
|
||||
ScrollDirFlagLT |= DFCS_PUSHED | DFCS_FLAT;
|
||||
}
|
||||
if (ScrollBarInfo->rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_UNAVAILABLE)
|
||||
{
|
||||
ScrollDirFlagLT |= DFCS_INACTIVE;
|
||||
}
|
||||
if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_PRESSED)
|
||||
{
|
||||
ScrollDirFlagRB |= DFCS_PUSHED | DFCS_FLAT;
|
||||
}
|
||||
if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_UNAVAILABLE)
|
||||
{
|
||||
ScrollDirFlagRB |= DFCS_INACTIVE;
|
||||
}
|
||||
|
||||
DrawFrameControl(hDC, &RectLT, DFC_SCROLL, ScrollDirFlagLT);
|
||||
DrawFrameControl(hDC, &RectRB, DFC_SCROLL, ScrollDirFlagRB);
|
||||
}
|
||||
|
||||
static LONG FASTCALL
|
||||
IntScrollGetObjectId(INT SBType)
|
||||
{
|
||||
if (SBType == SB_VERT)
|
||||
return OBJID_VSCROLL;
|
||||
if (SBType == SB_HORZ)
|
||||
return OBJID_HSCROLL;
|
||||
return OBJID_CLIENT;
|
||||
}
|
||||
|
||||
void
|
||||
IntDrawScrollBar(PWND Wnd, HDC DC, INT Bar)
|
||||
{
|
||||
//PSBWND pSBWnd;
|
||||
//INT ThumbSize;
|
||||
PTHREADINFO pti;
|
||||
SCROLLBARINFO Info;
|
||||
BOOL Vertical;
|
||||
|
||||
pti = PsGetCurrentThreadWin32Thread();
|
||||
|
||||
/*
|
||||
* Get scroll bar info.
|
||||
*/
|
||||
switch (Bar)
|
||||
{
|
||||
case SB_HORZ:
|
||||
Vertical = FALSE;
|
||||
break;
|
||||
|
||||
case SB_VERT:
|
||||
Vertical = TRUE;
|
||||
break;
|
||||
|
||||
case SB_CTL:
|
||||
Vertical = (Wnd->style & SBS_VERT) != 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (!co_IntGetScrollBarInfo(Wnd, IntScrollGetObjectId(Bar), &Info))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (RECTL_bIsEmptyRect(&Info.rcScrollBar))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//ThumbSize = pSBWnd->pSBCalc->pxThumbBottom - pSBWnd->pSBCalc->pxThumbTop;
|
||||
|
||||
/*
|
||||
* Draw the arrows.
|
||||
*/
|
||||
if (Info.dxyLineButton)
|
||||
{
|
||||
IntDrawScrollArrows(DC, &Info, Vertical);
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw the interior.
|
||||
*/
|
||||
IntDrawScrollInterior(Wnd, DC, Bar, Vertical, &Info);
|
||||
|
||||
/*
|
||||
* If scroll bar has focus, reposition the caret.
|
||||
*/
|
||||
if ( Wnd == pti->MessageQueue->spwndFocus && Bar == SB_CTL )
|
||||
{
|
||||
if (Vertical)
|
||||
{
|
||||
co_IntSetCaretPos(Info.rcScrollBar.top + 1, Info.dxyLineButton + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
co_IntSetCaretPos(Info.dxyLineButton + 1, Info.rcScrollBar.top + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LRESULT APIENTRY
|
||||
ScrollBarWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
|
|
@ -226,6 +226,241 @@ UserScrollDC(
|
|||
return Result;
|
||||
}
|
||||
|
||||
DWORD
|
||||
FASTCALL
|
||||
IntScrollWindowEx(
|
||||
PWND Window,
|
||||
INT dx,
|
||||
INT dy,
|
||||
const RECT *prcScroll,
|
||||
const RECT *prcClip,
|
||||
HRGN hrgnUpdate,
|
||||
LPRECT prcUpdate,
|
||||
UINT flags)
|
||||
{
|
||||
RECTL rcScroll, rcClip, rcCaret;
|
||||
INT Result;
|
||||
PWND CaretWnd;
|
||||
HDC hDC;
|
||||
PREGION RgnUpdate = NULL, RgnTemp, RgnWinupd = NULL;
|
||||
HWND hwndCaret;
|
||||
DWORD dcxflags = 0;
|
||||
int rdw_flags;
|
||||
USER_REFERENCE_ENTRY CaretRef;
|
||||
|
||||
IntGetClientRect(Window, &rcClip);
|
||||
|
||||
if (prcScroll)
|
||||
{
|
||||
RECTL_bIntersectRect(&rcScroll, &rcClip, prcScroll);
|
||||
}
|
||||
else
|
||||
rcScroll = rcClip;
|
||||
|
||||
if (prcClip)
|
||||
{
|
||||
RECTL_bIntersectRect(&rcClip, &rcClip, prcClip);
|
||||
}
|
||||
|
||||
if (rcClip.right <= rcClip.left || rcClip.bottom <= rcClip.top ||
|
||||
(dx == 0 && dy == 0))
|
||||
{
|
||||
return NULLREGION;
|
||||
}
|
||||
|
||||
/* We must use a copy of the region, as we can't hold an exclusive lock
|
||||
* on it while doing callouts to user-mode */
|
||||
RgnUpdate = IntSysCreateRectpRgn(0, 0, 0, 0);
|
||||
if(!RgnUpdate)
|
||||
{
|
||||
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (hrgnUpdate)
|
||||
{
|
||||
RgnTemp = REGION_LockRgn(hrgnUpdate);
|
||||
if (!RgnTemp)
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return ERROR;
|
||||
}
|
||||
IntGdiCombineRgn(RgnUpdate, RgnTemp, NULL, RGN_COPY);
|
||||
REGION_UnlockRgn(RgnTemp);
|
||||
}
|
||||
|
||||
/* ScrollWindow uses the window DC, ScrollWindowEx doesn't */
|
||||
if (flags & SW_SCROLLWNDDCE)
|
||||
{
|
||||
dcxflags = DCX_USESTYLE;
|
||||
|
||||
if (!(Window->pcls->style & (CS_OWNDC|CS_CLASSDC)))
|
||||
dcxflags |= DCX_CACHE; // AH??? wine~ If not Powned or with Class go Cheap!
|
||||
|
||||
if (flags & SW_SCROLLCHILDREN && Window->style & WS_CLIPCHILDREN)
|
||||
dcxflags |= DCX_CACHE|DCX_NOCLIPCHILDREN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* So in this case ScrollWindowEx uses Cache DC. */
|
||||
dcxflags = DCX_CACHE|DCX_USESTYLE;
|
||||
if (flags & SW_SCROLLCHILDREN) dcxflags |= DCX_NOCLIPCHILDREN;
|
||||
}
|
||||
|
||||
hDC = UserGetDCEx(Window, 0, dcxflags);
|
||||
if (!hDC)
|
||||
{
|
||||
/* FIXME: SetLastError? */
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
rdw_flags = (flags & SW_ERASE) && (flags & SW_INVALIDATE) ? RDW_INVALIDATE | RDW_ERASE : RDW_INVALIDATE ;
|
||||
|
||||
rcCaret = rcScroll;
|
||||
hwndCaret = co_IntFixCaret(Window, &rcCaret, flags);
|
||||
|
||||
Result = UserScrollDC( hDC,
|
||||
dx,
|
||||
dy,
|
||||
&rcScroll,
|
||||
&rcClip,
|
||||
NULL,
|
||||
RgnUpdate,
|
||||
prcUpdate);
|
||||
|
||||
UserReleaseDC(Window, hDC, FALSE);
|
||||
|
||||
/*
|
||||
* Take into account the fact that some damage may have occurred during
|
||||
* the scroll. Keep a copy in hrgnWinupd to be added to hrngUpdate at the end.
|
||||
*/
|
||||
|
||||
RgnTemp = IntSysCreateRectpRgn(0, 0, 0, 0);
|
||||
if (!RgnTemp)
|
||||
{
|
||||
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (co_IntGetUpdateRgn(Window, RgnTemp, FALSE) != NULLREGION)
|
||||
{
|
||||
PREGION RgnClip = IntSysCreateRectpRgnIndirect(&rcClip);
|
||||
if (RgnClip)
|
||||
{
|
||||
if (hrgnUpdate)
|
||||
{
|
||||
RgnWinupd = IntSysCreateRectpRgn( 0, 0, 0, 0);
|
||||
IntGdiCombineRgn( RgnWinupd, RgnTemp, 0, RGN_COPY);
|
||||
}
|
||||
|
||||
REGION_bOffsetRgn(RgnTemp, dx, dy);
|
||||
|
||||
IntGdiCombineRgn(RgnTemp, RgnTemp, RgnClip, RGN_AND);
|
||||
|
||||
if (hrgnUpdate)
|
||||
IntGdiCombineRgn( RgnWinupd, RgnWinupd, RgnTemp, RGN_OR );
|
||||
|
||||
co_UserRedrawWindow(Window, NULL, RgnTemp, rdw_flags );
|
||||
|
||||
REGION_Delete(RgnClip);
|
||||
}
|
||||
}
|
||||
REGION_Delete(RgnTemp);
|
||||
|
||||
if (flags & SW_SCROLLCHILDREN)
|
||||
{
|
||||
PWND Child;
|
||||
RECTL rcChild;
|
||||
POINT ClientOrigin;
|
||||
USER_REFERENCE_ENTRY WndRef;
|
||||
RECTL rcDummy;
|
||||
LPARAM lParam;
|
||||
|
||||
IntGetClientOrigin(Window, &ClientOrigin);
|
||||
|
||||
for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
|
||||
{
|
||||
rcChild = Child->rcWindow;
|
||||
rcChild.left -= ClientOrigin.x;
|
||||
rcChild.top -= ClientOrigin.y;
|
||||
rcChild.right -= ClientOrigin.x;
|
||||
rcChild.bottom -= ClientOrigin.y;
|
||||
|
||||
if (!prcScroll || RECTL_bIntersectRect(&rcDummy, &rcChild, &rcScroll))
|
||||
{
|
||||
UserRefObjectCo(Child, &WndRef);
|
||||
|
||||
if (Window->spwndParent == UserGetDesktopWindow()) // Window->spwndParent->fnid == FNID_DESKTOP )
|
||||
lParam = MAKELONG(Child->rcClient.left, Child->rcClient.top);
|
||||
else
|
||||
lParam = MAKELONG(rcChild.left + dx, rcChild.top + dy);
|
||||
|
||||
/* wine sends WM_POSCHANGING, WM_POSCHANGED messages */
|
||||
/* windows sometimes a WM_MOVE */
|
||||
co_IntSendMessage(UserHMGetHandle(Child), WM_MOVE, 0, lParam);
|
||||
|
||||
UserDerefObjectCo(Child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & (SW_INVALIDATE | SW_ERASE))
|
||||
{
|
||||
co_UserRedrawWindow( Window,
|
||||
NULL,
|
||||
RgnUpdate,
|
||||
rdw_flags | /* HACK */
|
||||
((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : RDW_NOCHILDREN) );
|
||||
}
|
||||
|
||||
if (hwndCaret && (CaretWnd = UserGetWindowObject(hwndCaret)))
|
||||
{
|
||||
UserRefObjectCo(CaretWnd, &CaretRef);
|
||||
|
||||
co_IntSetCaretPos(rcCaret.left + dx, rcCaret.top + dy);
|
||||
co_UserShowCaret(CaretWnd);
|
||||
|
||||
UserDerefObjectCo(CaretWnd);
|
||||
}
|
||||
|
||||
if (hrgnUpdate && (Result != ERROR))
|
||||
{
|
||||
/* Give everything back to the caller */
|
||||
RgnTemp = REGION_LockRgn(hrgnUpdate);
|
||||
/* The handle should still be valid */
|
||||
ASSERT(RgnTemp);
|
||||
if (RgnWinupd)
|
||||
IntGdiCombineRgn(RgnTemp, RgnUpdate, RgnWinupd, RGN_OR);
|
||||
else
|
||||
IntGdiCombineRgn(RgnTemp, RgnUpdate, NULL, RGN_COPY);
|
||||
REGION_UnlockRgn(RgnTemp);
|
||||
}
|
||||
|
||||
if (RgnWinupd)
|
||||
{
|
||||
REGION_Delete(RgnWinupd);
|
||||
}
|
||||
|
||||
if (RgnUpdate)
|
||||
{
|
||||
REGION_Delete(RgnUpdate);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
BOOL FASTCALL
|
||||
IntScrollWindow(PWND pWnd,
|
||||
int dx,
|
||||
int dy,
|
||||
CONST RECT *lpRect,
|
||||
CONST RECT *prcClip)
|
||||
{
|
||||
return IntScrollWindowEx( pWnd, dx, dy, lpRect, prcClip, 0, NULL,
|
||||
(lpRect ? 0 : SW_SCROLLCHILDREN) | (SW_ERASE|SW_INVALIDATE|SW_SCROLLWNDDCE)) != ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* NtUserScrollDC
|
||||
*
|
||||
|
|
|
@ -2,7 +2,12 @@
|
|||
|
||||
FORCEINLINE PMENU UserGetMenuObject(HMENU hMenu)
|
||||
{
|
||||
return UserGetObject(gHandleTable, hMenu, TYPE_MENU);
|
||||
PMENU pMenu = UserGetObject(gHandleTable, hMenu, TYPE_MENU);
|
||||
if (!pMenu)
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_MENU_HANDLE);
|
||||
}
|
||||
return pMenu;
|
||||
}
|
||||
|
||||
#define ASSERT_REFS_CO(_obj_) \
|
||||
|
@ -97,14 +102,11 @@ UserSystemParametersInfo(
|
|||
VOID FASTCALL IntSetWindowState(PWND, UINT);
|
||||
VOID FASTCALL IntClearWindowState(PWND, UINT);
|
||||
PTHREADINFO FASTCALL IntTID2PTI(HANDLE);
|
||||
HBRUSH FASTCALL GetControlBrush(PWND pwnd,HDC hdc,UINT ctlType);
|
||||
|
||||
/*************** MESSAGE.C ***************/
|
||||
|
||||
BOOL FASTCALL
|
||||
UserPostMessage(HWND Wnd,
|
||||
UINT Msg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
BOOL FASTCALL UserPostMessage(HWND Wnd,UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
/*************** WINDOW.C ***************/
|
||||
|
||||
|
@ -114,6 +116,8 @@ HWND FASTCALL UserGetShellWindow(VOID);
|
|||
HDC FASTCALL UserGetDCEx(PWND Window OPTIONAL, HANDLE ClipRegion, ULONG Flags);
|
||||
BOOLEAN co_UserDestroyWindow(PVOID Object);
|
||||
PWND FASTCALL UserGetAncestor(PWND Wnd, UINT Type);
|
||||
BOOL APIENTRY DefSetText(PWND Wnd, PCWSTR WindowText);
|
||||
DWORD FASTCALL IntGetWindowContextHelpId( PWND pWnd );
|
||||
|
||||
/*************** MENU.C ***************/
|
||||
|
||||
|
@ -121,12 +125,24 @@ HMENU FASTCALL UserCreateMenu(PDESKTOP Desktop, BOOL PopupMenu);
|
|||
BOOL FASTCALL UserSetMenuDefaultItem(PMENU Menu, UINT uItem, UINT fByPos);
|
||||
BOOL FASTCALL UserDestroyMenu(HMENU hMenu);
|
||||
|
||||
/*************** SCROLLBAR.C ***************/
|
||||
|
||||
DWORD FASTCALL co_UserShowScrollBar(PWND Wnd, int nBar, BOOL fShowH, BOOL fShowV);
|
||||
|
||||
/************** NONCLIENT **************/
|
||||
|
||||
VOID FASTCALL DefWndDoSizeMove(PWND pwnd, WORD wParam);
|
||||
LRESULT NC_DoNCPaint(PWND,HDC,INT);
|
||||
void FASTCALL NC_GetSysPopupPos(PWND, RECT *);
|
||||
LRESULT NC_HandleNCActivate( PWND Wnd, WPARAM wParam, LPARAM lParam );
|
||||
LRESULT NC_HandleNCCalcSize( PWND wnd, WPARAM wparam, RECTL *winRect );
|
||||
VOID NC_DrawFrame( HDC hDC, RECT *CurrentRect, BOOL Active, DWORD Style, DWORD ExStyle);
|
||||
VOID UserDrawCaptionBar( PWND pWnd, HDC hDC, INT Flags);
|
||||
void UserGetInsideRectNC(PWND Wnd, RECT *rect);
|
||||
LRESULT NC_HandleNCLButtonDown(PWND Wnd, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT NC_HandleNCLButtonDblClk(PWND Wnd, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT NC_HandleNCRButtonDown( PWND wnd, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
/************** DEFWND **************/
|
||||
|
||||
HBRUSH FASTCALL DefWndControlColor(HDC hDC,UINT ctlType);
|
||||
BOOL UserDrawSysMenuButton(PWND pWnd, HDC hDC, LPRECT Rect, BOOL Down);
|
||||
BOOL UserPaintCaption(PWND pWnd, INT Flags);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -52,8 +52,6 @@ extern HANDLE hModuleWin; // This Win32k Instance.
|
|||
extern struct _CLS *SystemClassList;
|
||||
extern BOOL RegisteredSysClasses;
|
||||
|
||||
typedef struct tagMENUSTATE MENUSTATE, *PMENUSTATE;
|
||||
|
||||
#include <pshpack1.h>
|
||||
// FIXME: Move to ntuser.h
|
||||
typedef struct _TL
|
||||
|
@ -110,7 +108,7 @@ typedef struct _THREADINFO
|
|||
HDESK hdesk;
|
||||
UINT cPaintsReady; /* Count of paints pending. */
|
||||
UINT cTimersReady; /* Count of timers pending. */
|
||||
PMENUSTATE pMenuState;
|
||||
struct tagMENUSTATE* pMenuState;
|
||||
DWORD dwExpWinVer;
|
||||
DWORD dwCompatFlags;
|
||||
DWORD dwCompatFlags2;
|
||||
|
|
|
@ -65,9 +65,12 @@ PWND FASTCALL VerifyWnd(PWND pWnd)
|
|||
{
|
||||
HWND hWnd;
|
||||
UINT State, State2;
|
||||
ULONG Error;
|
||||
|
||||
if (!pWnd) return NULL;
|
||||
|
||||
Error = EngGetLastError();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
hWnd = UserHMGetHandle(pWnd);
|
||||
|
@ -76,6 +79,7 @@ PWND FASTCALL VerifyWnd(PWND pWnd)
|
|||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
EngSetLastError(Error);
|
||||
_SEH2_YIELD(return NULL);
|
||||
}
|
||||
_SEH2_END
|
||||
|
@ -83,8 +87,9 @@ PWND FASTCALL VerifyWnd(PWND pWnd)
|
|||
if ( UserObjectInDestroy(hWnd) ||
|
||||
State & WNDS_DESTROYED ||
|
||||
State2 & WNDS2_INDESTROY )
|
||||
return NULL;
|
||||
pWnd = NULL;
|
||||
|
||||
EngSetLastError(Error);
|
||||
return pWnd;
|
||||
}
|
||||
|
||||
|
@ -362,6 +367,20 @@ IntGetWindow(HWND hWnd,
|
|||
return Ret;
|
||||
}
|
||||
|
||||
DWORD FASTCALL IntGetWindowContextHelpId( PWND pWnd )
|
||||
{
|
||||
PPROPERTY HelpId;
|
||||
|
||||
do
|
||||
{
|
||||
HelpId = IntGetProp(pWnd, gpsi->atomContextHelpIdProp);
|
||||
if (!HelpId) break;
|
||||
pWnd = IntGetParent(pWnd);
|
||||
}
|
||||
while (pWnd && pWnd->fnid != FNID_DESKTOP);
|
||||
return (DWORD) (HelpId ? HelpId->Data : 0 );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* IntSendDestroyMsg
|
||||
*/
|
||||
|
@ -593,6 +612,7 @@ LRESULT co_UserFreeWindow(PWND Window,
|
|||
Window->IDMenu &&
|
||||
(Menu = UserGetMenuObject((HMENU)Window->IDMenu)))
|
||||
{
|
||||
TRACE("UFW: IDMenu %p\n",Window->IDMenu);
|
||||
IntDestroyMenuObject(Menu, TRUE);
|
||||
Window->IDMenu = 0;
|
||||
}
|
||||
|
@ -3497,7 +3517,7 @@ co_IntSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi, BOOL bAlte
|
|||
Ansi);
|
||||
if (!OldValue) return 0;
|
||||
}
|
||||
*/
|
||||
*/
|
||||
*((LONG *)((PCHAR)(Window + 1) + Index)) = NewValue;
|
||||
}
|
||||
else
|
||||
|
@ -3913,6 +3933,78 @@ CLEANUP:
|
|||
END_CLEANUP;
|
||||
}
|
||||
|
||||
BOOL APIENTRY
|
||||
DefSetText(PWND Wnd, PCWSTR WindowText)
|
||||
{
|
||||
UNICODE_STRING UnicodeString;
|
||||
BOOL Ret = FALSE;
|
||||
|
||||
RtlInitUnicodeString(&UnicodeString, WindowText);
|
||||
|
||||
if (UnicodeString.Length != 0)
|
||||
{
|
||||
if (Wnd->strName.MaximumLength > 0 &&
|
||||
UnicodeString.Length <= Wnd->strName.MaximumLength - sizeof(UNICODE_NULL))
|
||||
{
|
||||
ASSERT(Wnd->strName.Buffer != NULL);
|
||||
|
||||
Wnd->strName.Length = UnicodeString.Length;
|
||||
Wnd->strName.Buffer[UnicodeString.Length / sizeof(WCHAR)] = L'\0';
|
||||
RtlCopyMemory(Wnd->strName.Buffer,
|
||||
UnicodeString.Buffer,
|
||||
UnicodeString.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
PWCHAR buf;
|
||||
Wnd->strName.MaximumLength = Wnd->strName.Length = 0;
|
||||
buf = Wnd->strName.Buffer;
|
||||
Wnd->strName.Buffer = NULL;
|
||||
if (buf != NULL)
|
||||
{
|
||||
DesktopHeapFree(Wnd->head.rpdesk, buf);
|
||||
}
|
||||
|
||||
Wnd->strName.Buffer = DesktopHeapAlloc(Wnd->head.rpdesk,
|
||||
UnicodeString.Length + sizeof(UNICODE_NULL));
|
||||
if (Wnd->strName.Buffer != NULL)
|
||||
{
|
||||
Wnd->strName.Buffer[UnicodeString.Length / sizeof(WCHAR)] = L'\0';
|
||||
RtlCopyMemory(Wnd->strName.Buffer,
|
||||
UnicodeString.Buffer,
|
||||
UnicodeString.Length);
|
||||
Wnd->strName.MaximumLength = UnicodeString.Length + sizeof(UNICODE_NULL);
|
||||
Wnd->strName.Length = UnicodeString.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Wnd->strName.Length = 0;
|
||||
if (Wnd->strName.Buffer != NULL)
|
||||
Wnd->strName.Buffer[0] = L'\0';
|
||||
}
|
||||
|
||||
// FIXME: HAX! Windows does not do this in here!
|
||||
// In User32, these are called after: NotifyWinEvent EVENT_OBJECT_NAMECHANGE than
|
||||
// RepaintButton, StaticRepaint, NtUserCallHwndLock HWNDLOCK_ROUTINE_REDRAWFRAMEANDHOOK, etc.
|
||||
/* Send shell notifications */
|
||||
if (!Wnd->spwndOwner && !IntGetParent(Wnd))
|
||||
{
|
||||
co_IntShellHookNotify(HSHELL_REDRAW, (WPARAM) UserHMGetHandle(Wnd), FALSE); // FIXME Flashing?
|
||||
}
|
||||
|
||||
Ret = TRUE;
|
||||
Exit:
|
||||
if (UnicodeString.Buffer) RtlFreeUnicodeString(&UnicodeString);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* NtUserDefSetText
|
||||
*
|
||||
|
|
|
@ -55,6 +55,10 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
|
|||
PWND OwnerWindow,
|
||||
PVOID acbiBuffer,
|
||||
PDESKTOP pdeskCreated);
|
||||
PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW* Cs,
|
||||
PUNICODE_STRING ClassName,
|
||||
PLARGE_STRING WindowName,
|
||||
PVOID acbiBuffer);
|
||||
BOOL FASTCALL IntEnableWindow(HWND,BOOL);
|
||||
BOOL FASTCALL IntIsWindowVisible(PWND);
|
||||
DWORD FASTCALL GetNCHitEx(PWND,POINT);
|
||||
|
|
|
@ -2280,7 +2280,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
|
|||
Cmd = SW_SHOWDEFAULT;
|
||||
}
|
||||
FirstTime = TRUE;
|
||||
ERR("co_WPSW FT 1\n");
|
||||
TRACE("co_WPSW FT 1\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2292,7 +2292,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
|
|||
{
|
||||
Cmd = pti->ppi->usi.wShowWindow;
|
||||
FirstTime = TRUE;
|
||||
ERR("co_WPSW FT 2\n");
|
||||
TRACE("co_WPSW FT 2\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,3 +69,5 @@ PWND FASTCALL IntRealChildWindowFromPoint(PWND,LONG,LONG);
|
|||
BOOL FASTCALL IntScreenToClient(PWND,LPPOINT);
|
||||
BOOL FASTCALL IntClientToScreen(PWND,LPPOINT);
|
||||
BOOL FASTCALL IntGetWindowRect(PWND,RECTL*);
|
||||
BOOL UserHasWindowEdge(DWORD,DWORD);
|
||||
VOID UserGetWindowBorders(DWORD,DWORD,SIZE*,BOOL);
|
||||
|
|
|
@ -297,6 +297,9 @@ co_IntInitializeDesktopGraphics(VOID)
|
|||
/* Setup the icons */
|
||||
co_IntSetWndIcons();
|
||||
|
||||
/* Setup Menu */
|
||||
MenuInit();
|
||||
|
||||
/* Show the desktop */
|
||||
pdesk = IntGetActiveDesktop();
|
||||
ASSERT(pdesk);
|
||||
|
|
1365
reactos/win32ss/user/rtl/text.c
Normal file
1365
reactos/win32ss/user/rtl/text.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -60,6 +60,7 @@ list(APPEND SOURCE
|
|||
windows/text.c
|
||||
windows/window.c
|
||||
windows/winpos.c
|
||||
${REACTOS_SOURCE_DIR}/win32ss/user/rtl/text.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user32_stubs.c
|
||||
include/user32.h)
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ LRESULT WINAPI RealUserDrawCaption(HWND hWnd, HDC hDC, LPCRECT lpRc, UINT uFlags
|
|||
|
||||
DWORD gcLoadUserApiHook = 0;
|
||||
LONG gcCallUserApiHook = 0;
|
||||
DWORD gfUserApiHook;
|
||||
DWORD gfUserApiHook = 0;
|
||||
HINSTANCE ghmodUserApiHook = NULL;
|
||||
USERAPIHOOKPROC gpfnInitUserApi;
|
||||
RTL_CRITICAL_SECTION gcsUserApiHook;
|
||||
|
|
|
@ -184,7 +184,7 @@
|
|||
@ stdcall DrawIcon(long long long long)
|
||||
@ stdcall DrawIconEx(long long long long long long long long long)
|
||||
@ stdcall DrawMenuBar(long)
|
||||
@ stdcall DrawMenuBarTemp(long long long long long)
|
||||
@ stdcall DrawMenuBarTemp(long long long long long) NtUserDrawMenuBarTemp
|
||||
@ stdcall DrawStateA(long long ptr long long long long long long long)
|
||||
@ stdcall DrawStateW(long long ptr long long long long long long long)
|
||||
@ stdcall DrawTextA(long str long ptr long)
|
||||
|
@ -198,7 +198,7 @@
|
|||
@ stdcall EnableWindow(long long)
|
||||
@ stdcall EndDeferWindowPos(long)
|
||||
@ stdcall EndDialog(long long)
|
||||
@ stdcall EndMenu()
|
||||
@ stdcall EndMenu() NtUserEndMenu
|
||||
@ stdcall EndPaint(long ptr) NtUserEndPaint
|
||||
@ stdcall EndTask(ptr long long)
|
||||
@ stdcall EnterReaderModeHelper(ptr)
|
||||
|
@ -302,7 +302,7 @@
|
|||
@ stdcall GetLayeredWindowAttributes(long ptr ptr ptr) NtUserGetLayeredWindowAttributes
|
||||
@ stdcall GetListBoxInfo(long) NtUserGetListBoxInfo
|
||||
@ stdcall GetMenu(long)
|
||||
@ stdcall GetMenuBarInfo(long long long ptr) ; tempo haxzo NtUserGetMenuBarInfo
|
||||
@ stdcall GetMenuBarInfo(long long long ptr) NtUserGetMenuBarInfo
|
||||
@ stdcall GetMenuCheckMarkDimensions()
|
||||
@ stdcall GetMenuContextHelpId(long)
|
||||
@ stdcall GetMenuDefaultItem(long long long)
|
||||
|
@ -349,7 +349,7 @@
|
|||
@ stdcall GetSubMenu(long long)
|
||||
@ stdcall GetSysColor(long)
|
||||
@ stdcall GetSysColorBrush(long)
|
||||
@ stdcall GetSystemMenu(long long) ; Direct call NtUserGetSystemMenu
|
||||
@ stdcall GetSystemMenu(long long) ; NtUserGetSystemMenu
|
||||
@ stdcall GetSystemMetrics(long)
|
||||
@ stdcall GetTabbedTextExtentA(long str long long ptr)
|
||||
@ stdcall GetTabbedTextExtentW(long wstr long long ptr)
|
||||
|
@ -387,7 +387,7 @@
|
|||
@ stdcall GrayStringA(long long ptr long long long long long long)
|
||||
@ stdcall GrayStringW(long long ptr long long long long long long)
|
||||
@ stdcall HideCaret(long) NtUserHideCaret
|
||||
@ stdcall HiliteMenuItem(long long long long) ; Use both ReactOS and wine NtUserHiliteMenuItem
|
||||
@ stdcall HiliteMenuItem(long long long long) NtUserHiliteMenuItem
|
||||
@ stdcall IMPGetIMEA(long ptr)
|
||||
@ stdcall IMPGetIMEW(long ptr)
|
||||
@ stdcall IMPQueryIMEA(ptr)
|
||||
|
@ -478,7 +478,7 @@
|
|||
@ stdcall MapVirtualKeyExW(long long long)
|
||||
@ stdcall MapVirtualKeyW(long long)
|
||||
@ stdcall MapWindowPoints(long long ptr long)
|
||||
@ stdcall MenuItemFromPoint(long long double) ; Direct call NtUserMenuItemFromPoint
|
||||
@ stdcall MenuItemFromPoint(long long double) NtUserMenuItemFromPoint
|
||||
@ stdcall MenuWindowProcA (long ptr long long long)
|
||||
@ stdcall MenuWindowProcW (long ptr long long long)
|
||||
@ stdcall MessageBeep(long)
|
||||
|
@ -635,7 +635,7 @@
|
|||
@ stdcall SetSysColors(long ptr ptr)
|
||||
@ stdcall SetSysColorsTemp(ptr ptr long)
|
||||
@ stdcall SetSystemCursor(long long)
|
||||
@ stdcall SetSystemMenu(long long) ; Direct call NtUserSetSystemMenu
|
||||
@ stdcall SetSystemMenu(long long) ; NtUserSetSystemMenu
|
||||
@ stdcall SetSystemTimer(long long long ptr) NtUserSetSystemTimer
|
||||
@ stdcall SetTaskmanWindow (long)
|
||||
@ stdcall SetThreadDesktop(long) NtUserSetThreadDesktop
|
||||
|
@ -684,7 +684,7 @@
|
|||
@ stdcall ToUnicodeEx(long long ptr ptr long long long)
|
||||
@ stdcall TrackMouseEvent(ptr) NtUserTrackMouseEvent
|
||||
@ stdcall TrackPopupMenu(long long long long long long ptr)
|
||||
@ stdcall TrackPopupMenuEx(long long long long long ptr) ; Direct call NtUserTrackPopupMenuEx
|
||||
@ stdcall TrackPopupMenuEx(long long long long long ptr) NtUserTrackPopupMenuEx
|
||||
@ stdcall TranslateAccelerator(long long ptr) TranslateAcceleratorA
|
||||
@ stdcall TranslateAcceleratorA(long long ptr)
|
||||
@ stdcall TranslateAcceleratorW(long long ptr)
|
||||
|
|
|
@ -16,21 +16,10 @@
|
|||
#include <wine/debug.h>
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(user32);
|
||||
|
||||
LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
|
||||
LRESULT DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect);
|
||||
LRESULT DefWndNCActivate(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT DefWndNCHitTest(HWND hWnd, POINT Point);
|
||||
LRESULT DefWndNCLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT DefWndNCLButtonDblClk(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT NC_HandleNCRButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam );
|
||||
void FASTCALL MenuInitSysMenuPopup(HMENU Menu, DWORD Style, DWORD ClsStyle, LONG HitTest );
|
||||
void MENU_EndMenu( HWND );
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
static short iF10Key = 0;
|
||||
static short iMenuSysKey = 0;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
|
@ -219,6 +208,21 @@ DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
if (!IsWindowEnabled( hWnd )) return 0;
|
||||
|
||||
switch (wParam & 0xfff0)
|
||||
{
|
||||
case SC_MOVE:
|
||||
case SC_SIZE:
|
||||
// case SC_DEFAULT:
|
||||
case SC_MOUSEMENU:
|
||||
case SC_KEYMENU:
|
||||
case SC_SCREENSAVE:
|
||||
NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ISITHOOKED(WH_CBT))
|
||||
{
|
||||
NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
|
||||
|
@ -227,10 +231,6 @@ DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
switch (wParam & 0xfff0)
|
||||
{
|
||||
case SC_MOVE:
|
||||
case SC_SIZE:
|
||||
NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
|
||||
break;
|
||||
|
||||
case SC_MINIMIZE:
|
||||
if (hWnd == GetActiveWindow())
|
||||
|
@ -253,17 +253,6 @@ DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||
case SC_CLOSE:
|
||||
return SendMessageW(hWnd, WM_CLOSE, 0, 0);
|
||||
|
||||
// case SC_DEFAULT:
|
||||
case SC_MOUSEMENU:
|
||||
{
|
||||
Pt.x = (short)LOWORD(lParam);
|
||||
Pt.y = (short)HIWORD(lParam);
|
||||
MenuTrackMouseMenuBar(hWnd, wParam & 0x000f, Pt);
|
||||
}
|
||||
break;
|
||||
case SC_KEYMENU:
|
||||
MenuTrackKbdMenuBar(hWnd, wParam, (WCHAR)lParam);
|
||||
break;
|
||||
case SC_VSCROLL:
|
||||
case SC_HSCROLL:
|
||||
{
|
||||
|
@ -277,9 +266,6 @@ DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||
WinExec( "taskman.exe", SW_SHOWNORMAL );
|
||||
break;
|
||||
|
||||
case SC_SCREENSAVE:
|
||||
NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
|
||||
break;
|
||||
|
||||
case SC_NEXTWINDOW:
|
||||
case SC_PREVWINDOW:
|
||||
|
@ -359,38 +345,6 @@ DefWndControlColor(HDC hDC, UINT ctlType)
|
|||
return GetSysColorBrush(COLOR_WINDOW);
|
||||
}
|
||||
|
||||
static void DefWndPrint( HWND hwnd, HDC hdc, ULONG uFlags)
|
||||
{
|
||||
/*
|
||||
* Visibility flag.
|
||||
*/
|
||||
if ( (uFlags & PRF_CHECKVISIBLE) &&
|
||||
!IsWindowVisible(hwnd) )
|
||||
return;
|
||||
|
||||
/*
|
||||
* Unimplemented flags.
|
||||
*/
|
||||
if ( (uFlags & PRF_CHILDREN) ||
|
||||
(uFlags & PRF_OWNED) ||
|
||||
(uFlags & PRF_NONCLIENT) )
|
||||
{
|
||||
FIXME("WM_PRINT message with unsupported flags\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Background
|
||||
*/
|
||||
if ( uFlags & PRF_ERASEBKGND)
|
||||
SendMessageW(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
|
||||
|
||||
/*
|
||||
* Client area
|
||||
*/
|
||||
if ( uFlags & PRF_CLIENT)
|
||||
SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
|
||||
}
|
||||
|
||||
static BOOL CALLBACK
|
||||
UserSendUiUpdateMsg(HWND hwnd, LPARAM lParam)
|
||||
{
|
||||
|
@ -398,21 +352,13 @@ UserSendUiUpdateMsg(HWND hwnd, LPARAM lParam)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
RealUserDrawCaption: This function is passed through RegisterUserApiHook to uxtheme
|
||||
to call it when the classic caption is needed to be drawn.
|
||||
*/
|
||||
LRESULT WINAPI
|
||||
RealUserDrawCaption(HWND hWnd, HDC hDC, LPCRECT lpRc, UINT uFlags)
|
||||
{
|
||||
return DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
UserPaintCaption(HWND hwnd)
|
||||
UserPaintCaption(PWND pwnd, INT Flags)
|
||||
{
|
||||
/* FIXME: this is not 100% correct */
|
||||
|
||||
if ( pwnd->style & WS_VISIBLE && (pwnd->style & WS_CAPTION) == WS_CAPTION )
|
||||
{
|
||||
if (pwnd->state & WNDS_HASCAPTION && NtUserQueryWindow(UserHMGetHandle(pwnd), QUERY_WINDOW_FOREGROUND))
|
||||
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.
|
||||
|
@ -426,51 +372,16 @@ UserPaintCaption(HWND hwnd)
|
|||
* RealUserDrawCaption in order to draw the classic caption when themes
|
||||
* are disabled but the themes service is enabled
|
||||
*/
|
||||
SendMessage(hwnd, WM_NCUAHDRAWCAPTION,0,0);
|
||||
SendMessageW(UserHMGetHandle(pwnd), WM_NCUAHDRAWCAPTION, Flags, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
DefWndNCPaint(hwnd, HRGN_WINDOW, -1);
|
||||
RECT rc = {0,0,0,0};
|
||||
HDC hDC = GetDCEx(UserHMGetHandle(pwnd), NULL, DCX_WINDOW|DCX_USESTYLE);
|
||||
NtUserDrawCaption(UserHMGetHandle(pwnd), hDC, &rc, DC_DRAWCAPTIONMD|Flags);
|
||||
ReleaseDC(UserHMGetHandle(pwnd), hDC);
|
||||
}
|
||||
}
|
||||
|
||||
// WM_SETICON
|
||||
LRESULT FASTCALL
|
||||
DefWndSetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HICON hIcon, hIconSmall, hIconOld;
|
||||
|
||||
if ( wParam > ICON_SMALL2 )
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
hIconSmall = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconSmProp);
|
||||
hIcon = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconProp);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
NtUserSetProp(UserHMGetHandle(pWnd), gpsi->atomIconProp, hIcon);
|
||||
NtUserSetProp(UserHMGetHandle(pWnd), gpsi->atomIconSmProp, hIconSmall);
|
||||
|
||||
if ((pWnd->style & WS_CAPTION ) == WS_CAPTION)
|
||||
UserPaintCaption(UserHMGetHandle(pWnd)); /* Repaint caption */
|
||||
|
||||
return (LRESULT)hIconOld;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT FASTCALL
|
||||
|
@ -497,41 +408,6 @@ DefWndGetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
|
|||
return (LRESULT)hIconRet;
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
DefWndScreenshot(HWND hWnd)
|
||||
{
|
||||
RECT rect;
|
||||
HDC hdc;
|
||||
INT w;
|
||||
INT h;
|
||||
HBITMAP hbitmap;
|
||||
HDC hdc2;
|
||||
|
||||
OpenClipboard(hWnd);
|
||||
EmptyClipboard();
|
||||
|
||||
hdc = GetWindowDC(hWnd);
|
||||
GetWindowRect(hWnd, &rect);
|
||||
w = rect.right - rect.left;
|
||||
h = rect.bottom - rect.top;
|
||||
|
||||
hbitmap = CreateCompatibleBitmap(hdc, w, h);
|
||||
hdc2 = CreateCompatibleDC(hdc);
|
||||
SelectObject(hdc2, hbitmap);
|
||||
|
||||
BitBlt(hdc2, 0, 0, w, h,
|
||||
hdc, 0, 0,
|
||||
SRCCOPY);
|
||||
|
||||
SetClipboardData(CF_BITMAP, hbitmap);
|
||||
|
||||
ReleaseDC(hWnd, hdc);
|
||||
ReleaseDC(hWnd, hdc2);
|
||||
|
||||
CloseClipboard();
|
||||
}
|
||||
|
||||
|
||||
|
||||
LRESULT WINAPI
|
||||
User32DefWindowProc(HWND hWnd,
|
||||
|
@ -549,33 +425,18 @@ User32DefWindowProc(HWND hWnd,
|
|||
|
||||
switch (Msg)
|
||||
{
|
||||
case WM_NCPAINT:
|
||||
{
|
||||
return DefWndNCPaint(hWnd, (HRGN)wParam, -1);
|
||||
}
|
||||
|
||||
case WM_NCCALCSIZE:
|
||||
{
|
||||
return DefWndNCCalcSize(hWnd, (BOOL)wParam, (RECT*)lParam);
|
||||
}
|
||||
|
||||
case WM_POPUPSYSTEMMENU:
|
||||
{
|
||||
/* This is an undocumented message used by the windows taskbar to
|
||||
display the system menu of windows that belong to other processes. */
|
||||
HMENU menu = GetSystemMenu(hWnd, FALSE);
|
||||
|
||||
ERR("WM_POPUPSYSTEMMENU\n");
|
||||
if (menu)
|
||||
TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
|
||||
TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_SYSTEM_MENU,
|
||||
LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_NCACTIVATE:
|
||||
{
|
||||
return DefWndNCActivate(hWnd, wParam, lParam);
|
||||
}
|
||||
|
||||
case WM_NCHITTEST:
|
||||
{
|
||||
POINT Point;
|
||||
|
@ -584,32 +445,9 @@ User32DefWindowProc(HWND hWnd,
|
|||
return (DefWndNCHitTest(hWnd, Point));
|
||||
}
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
iF10Key = iMenuSysKey = 0;
|
||||
break;
|
||||
|
||||
case WM_NCLBUTTONDOWN:
|
||||
{
|
||||
return (DefWndNCLButtonDown(hWnd, wParam, lParam));
|
||||
}
|
||||
|
||||
case WM_LBUTTONDBLCLK:
|
||||
return (DefWndNCLButtonDblClk(hWnd, HTCLIENT, lParam));
|
||||
|
||||
case WM_NCLBUTTONDBLCLK:
|
||||
{
|
||||
return (DefWndNCLButtonDblClk(hWnd, wParam, lParam));
|
||||
}
|
||||
|
||||
case WM_NCRBUTTONDOWN:
|
||||
return NC_HandleNCRButtonDown( hWnd, wParam, lParam );
|
||||
|
||||
case WM_RBUTTONUP:
|
||||
{
|
||||
POINT Pt;
|
||||
|
||||
Pt.x = GET_X_LPARAM(lParam);
|
||||
Pt.y = GET_Y_LPARAM(lParam);
|
||||
ClientToScreen(hWnd, &Pt);
|
||||
|
@ -632,6 +470,7 @@ User32DefWindowProc(HWND hWnd,
|
|||
* "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_CONTEXTMENU:
|
||||
|
@ -649,96 +488,11 @@ User32DefWindowProc(HWND hWnd,
|
|||
}
|
||||
else
|
||||
{
|
||||
POINT Pt;
|
||||
LONG_PTR Style;
|
||||
LONG HitCode;
|
||||
|
||||
Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
|
||||
|
||||
Pt.x = GET_X_LPARAM(lParam);
|
||||
Pt.y = GET_Y_LPARAM(lParam);
|
||||
if (Style & WS_CHILD)
|
||||
{
|
||||
ScreenToClient(GetParent(hWnd), &Pt);
|
||||
}
|
||||
|
||||
HitCode = DefWndNCHitTest(hWnd, Pt);
|
||||
|
||||
if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
|
||||
{
|
||||
HMENU SystemMenu;
|
||||
UINT Flags;
|
||||
|
||||
if((SystemMenu = GetSystemMenu(hWnd, FALSE)))
|
||||
{
|
||||
MenuInitSysMenuPopup(SystemMenu, GetWindowLongPtrW(hWnd, GWL_STYLE),
|
||||
GetClassLongPtrW(hWnd, GCL_STYLE), HitCode);
|
||||
|
||||
if(HitCode == HTCAPTION)
|
||||
Flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON;
|
||||
else
|
||||
Flags = TPM_LEFTBUTTON;
|
||||
|
||||
TrackPopupMenu(SystemMenu, Flags,
|
||||
Pt.x, Pt.y, 0, hWnd, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
goto GoSS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_PRINT:
|
||||
{
|
||||
DefWndPrint(hWnd, (HDC)wParam, lParam);
|
||||
return (0);
|
||||
}
|
||||
|
||||
case WM_SYSCOLORCHANGE:
|
||||
{
|
||||
/* force to redraw non-client area */
|
||||
DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
|
||||
/* Use InvalidateRect to redraw client area, enable
|
||||
* erase to redraw all subcontrols otherwise send the
|
||||
* WM_SYSCOLORCHANGE to child windows/controls is required
|
||||
*/
|
||||
InvalidateRect(hWnd,NULL,TRUE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
case WM_PAINTICON:
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT Ps;
|
||||
HDC hDC;
|
||||
|
||||
/* If already in Paint and Client area is not empty just return. */
|
||||
if (pWnd->state2 & WNDS2_STARTPAINT && !IsRectEmpty(&pWnd->rcClient))
|
||||
{
|
||||
ERR("In Paint and Client area is not empty!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
hDC = BeginPaint(hWnd, &Ps);
|
||||
if (hDC)
|
||||
{
|
||||
HICON hIcon;
|
||||
|
||||
if (IsIconic(hWnd) && ((hIcon = (HICON)GetClassLongPtrW( hWnd, GCLP_HICON))))
|
||||
{
|
||||
RECT ClientRect;
|
||||
INT x, y;
|
||||
GetClientRect(hWnd, &ClientRect);
|
||||
x = (ClientRect.right - ClientRect.left -
|
||||
GetSystemMetrics(SM_CXICON)) / 2;
|
||||
y = (ClientRect.bottom - ClientRect.top -
|
||||
GetSystemMetrics(SM_CYICON)) / 2;
|
||||
DrawIcon(hDC, x, y, hIcon);
|
||||
}
|
||||
EndPaint(hWnd, &Ps);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
case WM_CLOSE:
|
||||
DestroyWindow(hWnd);
|
||||
return (0);
|
||||
|
@ -806,109 +560,6 @@ User32DefWindowProc(HWND hWnd,
|
|||
case WM_SYSCOMMAND:
|
||||
return (DefWndHandleSysCommand(hWnd, wParam, lParam));
|
||||
|
||||
case WM_KEYDOWN:
|
||||
if(wParam == VK_F10) iF10Key = VK_F10;
|
||||
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 ) && !iMenuSysKey )
|
||||
iMenuSysKey = 1;
|
||||
else
|
||||
iMenuSysKey = 0;
|
||||
}
|
||||
|
||||
iF10Key = 0;
|
||||
|
||||
if (wParam == VK_F4) /* Try to close the window */
|
||||
{
|
||||
HWND top = GetAncestor(hWnd, GA_ROOT);
|
||||
if (!(GetClassLongPtrW(top, GCL_STYLE) & CS_NOCLOSE))
|
||||
PostMessageW(top, WM_SYSCOMMAND, SC_CLOSE, 0);
|
||||
}
|
||||
else if (wParam == VK_SNAPSHOT) // Alt-VK_SNAPSHOT?
|
||||
{
|
||||
HWND hwnd = hWnd;
|
||||
while (GetParent(hwnd) != NULL)
|
||||
{
|
||||
hwnd = GetParent(hwnd);
|
||||
}
|
||||
DefWndScreenshot(hwnd);
|
||||
}
|
||||
else if ( wParam == VK_ESCAPE || wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC
|
||||
{
|
||||
WPARAM wParamTmp;
|
||||
HWND Active = GetActiveWindow(); // Noticed MDI problem.
|
||||
if (!Active)
|
||||
{
|
||||
FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n");
|
||||
break;
|
||||
}
|
||||
wParamTmp = GetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW;
|
||||
SendMessageW( Active, WM_SYSCOMMAND, wParamTmp, wParam );
|
||||
}
|
||||
}
|
||||
else if( wParam == VK_F10 )
|
||||
{
|
||||
if (GetKeyState(VK_SHIFT) & 0x8000)
|
||||
SendMessageW( hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, MAKELPARAM(-1, -1) );
|
||||
iF10Key = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
/* Press and release F10 or ALT */
|
||||
if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU)
|
||||
&& iMenuSysKey) || ((wParam == VK_F10) && iF10Key))
|
||||
SendMessageW( GetAncestor( hWnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L );
|
||||
iMenuSysKey = iF10Key = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SYSCHAR:
|
||||
{
|
||||
iMenuSysKey = 0;
|
||||
if (wParam == VK_RETURN && IsIconic(hWnd))
|
||||
{
|
||||
PostMessageW( hWnd, WM_SYSCOMMAND, SC_RESTORE, 0L );
|
||||
break;
|
||||
}
|
||||
if ((HIWORD(lParam) & KF_ALTDOWN) && wParam)
|
||||
{
|
||||
if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
|
||||
if (wParam == VK_SPACE && (GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD))
|
||||
SendMessageW( GetParent(hWnd), Msg, wParam, lParam );
|
||||
else
|
||||
SendMessageW( hWnd, WM_SYSCOMMAND, SC_KEYMENU, wParam );
|
||||
}
|
||||
else /* check for Ctrl-Esc */
|
||||
if (wParam != VK_ESCAPE) MessageBeep(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_CANCELMODE:
|
||||
{
|
||||
iMenuSysKey = 0;
|
||||
/* FIXME: Check for a desktop. */
|
||||
//if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
|
||||
MENU_EndMenu( hWnd );
|
||||
if (GetCapture() == hWnd)
|
||||
{
|
||||
ReleaseCapture();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_VKEYTOITEM:
|
||||
case WM_CHARTOITEM:
|
||||
return (-1);
|
||||
|
@ -959,11 +610,6 @@ User32DefWindowProc(HWND hWnd,
|
|||
break;
|
||||
}
|
||||
|
||||
case WM_SETICON:
|
||||
{
|
||||
return DefWndSetIcon(pWnd, wParam, lParam);
|
||||
}
|
||||
|
||||
case WM_GETICON:
|
||||
{
|
||||
return DefWndGetIcon(pWnd, wParam, lParam);
|
||||
|
@ -1201,6 +847,30 @@ User32DefWindowProc(HWND hWnd,
|
|||
/* Move to Win32k !*/
|
||||
case WM_SHOWWINDOW:
|
||||
if (!lParam) break; // Call when it is necessary.
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_NCLBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_NCLBUTTONDBLCLK:
|
||||
case WM_NCRBUTTONDOWN:
|
||||
case WM_KEYF1:
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSCHAR:
|
||||
case WM_CANCELMODE:
|
||||
case WM_PAINTICON:
|
||||
case WM_PAINT:
|
||||
case WM_PRINT:
|
||||
case WM_SETICON:
|
||||
case WM_SYSCOLORCHANGE:
|
||||
case WM_NCUAHDRAWCAPTION:
|
||||
case WM_NCUAHDRAWFRAME:
|
||||
case WM_NCPAINT:
|
||||
case WM_NCACTIVATE:
|
||||
case WM_NCCALCSIZE:
|
||||
case WM_SYNCPAINT:
|
||||
case WM_SETREDRAW:
|
||||
case WM_CLIENTSHUTDOWN:
|
||||
|
@ -1210,6 +880,7 @@ User32DefWindowProc(HWND hWnd,
|
|||
case WM_WINDOWPOSCHANGED:
|
||||
case WM_APPCOMMAND:
|
||||
case WM_SETCURSOR:
|
||||
GoSS:
|
||||
{
|
||||
LRESULT lResult;
|
||||
NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, !bUnicode);
|
||||
|
@ -1399,7 +1070,7 @@ RealDefWindowProcA(HWND hWnd,
|
|||
|
||||
if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
|
||||
{
|
||||
UserPaintCaption(hWnd);
|
||||
UserPaintCaption(Wnd, DC_TEXT);
|
||||
IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
|
||||
}
|
||||
Result = 1;
|
||||
|
@ -1564,7 +1235,7 @@ RealDefWindowProcW(HWND hWnd,
|
|||
DefSetText(hWnd, (PCWSTR)lParam, FALSE);
|
||||
|
||||
if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
|
||||
UserPaintCaption(hWnd);
|
||||
UserPaintCaption(Wnd, DC_TEXT);
|
||||
Result = 1;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -979,6 +979,14 @@ static BOOL UITOOLS95_DrawFrameMenu(HDC dc, LPRECT r, UINT uFlags)
|
|||
TCHAR Symbol;
|
||||
switch(uFlags & 0xff)
|
||||
{
|
||||
case DFCS_MENUARROWUP:
|
||||
Symbol = '5';
|
||||
break;
|
||||
|
||||
case DFCS_MENUARROWDOWN:
|
||||
Symbol = '6';
|
||||
break;
|
||||
|
||||
case DFCS_MENUARROW:
|
||||
Symbol = '8';
|
||||
break;
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -43,35 +43,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32);
|
|||
(WindowRect.right - WindowRect.left == ParentClientRect.right) && \
|
||||
(WindowRect.bottom - WindowRect.top == ParentClientRect.bottom)))
|
||||
|
||||
#ifndef STATE_SYSTEM_OFFSCREEN
|
||||
#define STATE_SYSTEM_OFFSCREEN 0x00010000
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FIXME: This should be moved to a header
|
||||
*/
|
||||
VOID
|
||||
IntDrawScrollBar(HWND hWnd, HDC hDC, INT nBar);
|
||||
DWORD
|
||||
IntScrollHitTest(HWND hWnd, INT nBar, POINT pt, BOOL bDragging);
|
||||
|
||||
BOOL WINAPI GdiGradientFill(HDC,PTRIVERTEX,ULONG,PVOID,ULONG,ULONG);
|
||||
|
||||
extern ATOM AtomInternalPos;
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
BOOL
|
||||
IntIsScrollBarVisible(HWND hWnd, INT hBar)
|
||||
{
|
||||
SCROLLBARINFO sbi;
|
||||
sbi.cbSize = sizeof(SCROLLBARINFO);
|
||||
if(!NtUserGetScrollBarInfo(hWnd, hBar, &sbi))
|
||||
return FALSE;
|
||||
|
||||
return !(sbi.rgstate[0] & STATE_SYSTEM_OFFSCREEN);
|
||||
}
|
||||
|
||||
BOOL
|
||||
UserHasWindowEdge(DWORD Style, DWORD ExStyle)
|
||||
{
|
||||
|
@ -112,582 +86,6 @@ UserGetWindowBorders(DWORD Style, DWORD ExStyle, SIZE *Size, BOOL WithClient)
|
|||
Size->cy *= GetSystemMetrics(SM_CYBORDER);
|
||||
}
|
||||
|
||||
BOOL
|
||||
UserHasMenu(HWND hWnd, ULONG Style)
|
||||
{
|
||||
return (!(Style & WS_CHILD) && GetMenu(hWnd) != 0);
|
||||
}
|
||||
|
||||
HICON
|
||||
UserGetWindowIcon(HWND hwnd)
|
||||
{
|
||||
HICON hIcon = 0;
|
||||
|
||||
SendMessageTimeout(hwnd, WM_GETICON, ICON_SMALL2, 0, SMTO_ABORTIFHUNG, 1000, (PDWORD_PTR)&hIcon);
|
||||
|
||||
if (!hIcon) hIcon = UserGetProp(hwnd, gpsi->atomIconSmProp);
|
||||
if (!hIcon) hIcon = UserGetProp(hwnd, gpsi->atomIconProp);
|
||||
if (!hIcon) hIcon = (HICON)GetClassLongPtr(hwnd, GCL_HICONSM);
|
||||
if (!hIcon) hIcon = (HICON)GetClassLongPtr(hwnd, GCL_HICON);
|
||||
if (!hIcon && (GetWindowLongW( hwnd, GWL_STYLE ) & DS_MODALFRAME))
|
||||
{
|
||||
if (!hIcon) hIcon = gpsi->hIconSmWindows; // Both are IDI_WINLOGO Small
|
||||
if (!hIcon) hIcon = gpsi->hIconWindows; // Reg size.
|
||||
}
|
||||
return hIcon;
|
||||
}
|
||||
|
||||
BOOL
|
||||
UserDrawSysMenuButton(HWND hWnd, HDC hDC, LPRECT Rect, BOOL Down)
|
||||
{
|
||||
HICON WindowIcon;
|
||||
|
||||
if ((WindowIcon = UserGetWindowIcon(hWnd)))
|
||||
{
|
||||
return DrawIconEx(hDC, Rect->left + 2, Rect->top + 2, WindowIcon,
|
||||
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
|
||||
0, NULL, DI_NORMAL);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
* - Cache bitmaps, then just bitblt instead of calling DFC() (and
|
||||
* wasting precious CPU cycles) every time
|
||||
* - Center the buttons verticaly in the rect
|
||||
*/
|
||||
VOID
|
||||
UserDrawCaptionButton(HWND hWnd, LPRECT Rect, DWORD Style, DWORD ExStyle, HDC hDC, BOOL bDown, ULONG Type)
|
||||
{
|
||||
RECT TempRect;
|
||||
|
||||
if (!(Style & WS_SYSMENU))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TempRect = *Rect;
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case DFCS_CAPTIONMIN:
|
||||
{
|
||||
if (ExStyle & WS_EX_TOOLWINDOW)
|
||||
return; /* ToolWindows don't have min/max buttons */
|
||||
|
||||
if (Style & WS_SYSMENU)
|
||||
TempRect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
|
||||
if (Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
|
||||
TempRect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
|
||||
TempRect.left = TempRect.right - GetSystemMetrics(SM_CXSIZE) + 1;
|
||||
TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSIZE) - 2;
|
||||
TempRect.top += 2;
|
||||
TempRect.right -= 1;
|
||||
|
||||
DrawFrameControl(hDC, &TempRect, DFC_CAPTION,
|
||||
((Style & WS_MINIMIZE) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMIN) |
|
||||
(bDown ? DFCS_PUSHED : 0) |
|
||||
((Style & WS_MINIMIZEBOX) ? 0 : DFCS_INACTIVE));
|
||||
break;
|
||||
}
|
||||
case DFCS_CAPTIONMAX:
|
||||
{
|
||||
if (ExStyle & WS_EX_TOOLWINDOW)
|
||||
return; /* ToolWindows don't have min/max buttons */
|
||||
|
||||
if (Style & WS_SYSMENU)
|
||||
TempRect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
|
||||
TempRect.left = TempRect.right - GetSystemMetrics(SM_CXSIZE) + 1;
|
||||
TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSIZE) - 2;
|
||||
TempRect.top += 2;
|
||||
TempRect.right -= 1;
|
||||
|
||||
DrawFrameControl(hDC, &TempRect, DFC_CAPTION,
|
||||
((Style & WS_MAXIMIZE) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX) |
|
||||
(bDown ? DFCS_PUSHED : 0) |
|
||||
((Style & WS_MAXIMIZEBOX) ? 0 : DFCS_INACTIVE));
|
||||
break;
|
||||
}
|
||||
case DFCS_CAPTIONCLOSE:
|
||||
{
|
||||
HMENU hSysMenu = GetSystemMenu(hWnd, FALSE);
|
||||
UINT MenuState = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND); /* in case of error MenuState==0xFFFFFFFF */
|
||||
|
||||
/* FIXME: A tool window has a smaller Close button */
|
||||
|
||||
if (ExStyle & WS_EX_TOOLWINDOW)
|
||||
{
|
||||
TempRect.left = TempRect.right - GetSystemMetrics(SM_CXSMSIZE);
|
||||
TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSMSIZE) - 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
TempRect.left = TempRect.right - GetSystemMetrics(SM_CXSIZE);
|
||||
TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSIZE) - 2;
|
||||
}
|
||||
TempRect.top += 2;
|
||||
TempRect.right -= 2;
|
||||
|
||||
DrawFrameControl(hDC, &TempRect, DFC_CAPTION,
|
||||
(DFCS_CAPTIONCLOSE | (bDown ? DFCS_PUSHED : 0) |
|
||||
((!(MenuState & (MF_GRAYED|MF_DISABLED)) && !(GetClassLong(hWnd, GCL_STYLE) & CS_NOCLOSE)) ? 0 : DFCS_INACTIVE)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
UserDrawCaptionButtonWnd(HWND hWnd, HDC hDC, BOOL bDown, ULONG Type)
|
||||
{
|
||||
RECT WindowRect;
|
||||
SIZE WindowBorder;
|
||||
DWORD Style, ExStyle;
|
||||
|
||||
GetWindowRect(hWnd, &WindowRect);
|
||||
WindowRect.right -= WindowRect.left;
|
||||
WindowRect.bottom -= WindowRect.top;
|
||||
WindowRect.left = WindowRect.top = 0;
|
||||
Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
|
||||
ExStyle = GetWindowLongPtrW(hWnd, GWL_EXSTYLE);
|
||||
UserGetWindowBorders(Style, ExStyle, &WindowBorder, FALSE);
|
||||
InflateRect(&WindowRect, -WindowBorder.cx, -WindowBorder.cy);
|
||||
UserDrawCaptionButton(hWnd, &WindowRect, Style, ExStyle, hDC, bDown, Type);
|
||||
}
|
||||
|
||||
// Note from Wine:
|
||||
/* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
|
||||
the call to GetDCEx implying that it is allowed not to use it either.
|
||||
However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
|
||||
will cause clipRgn to be deleted after ReleaseDC().
|
||||
Now, how is the "system" supposed to tell what happened?
|
||||
*/
|
||||
/*
|
||||
* FIXME:
|
||||
* - Drawing of WS_BORDER after scrollbars
|
||||
* - Correct drawing of size-box
|
||||
*/
|
||||
LRESULT
|
||||
DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active)
|
||||
{
|
||||
HDC hDC;
|
||||
DWORD Style, ExStyle;
|
||||
HWND Parent;
|
||||
RECT ClientRect, WindowRect, CurrentRect, TempRect;
|
||||
|
||||
if (!IsWindowVisible(hWnd))
|
||||
return 0;
|
||||
|
||||
Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
|
||||
|
||||
TRACE("DefWndNCPaint: hWnd %p, hRgn %p, Active %s.\n",
|
||||
hWnd, hRgn, Active ? "TRUE" : "FALSE");
|
||||
|
||||
hDC = GetDCEx(hWnd, hRgn, DCX_WINDOW | DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN);
|
||||
if (hDC == 0)
|
||||
{
|
||||
ERR("hDC is NULL!\n");
|
||||
if (hRgn != HRGN_WINDOW)
|
||||
DeleteObject(hRgn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Parent = GetParent(hWnd);
|
||||
ExStyle = GetWindowLongPtrW(hWnd, GWL_EXSTYLE);
|
||||
if (Active == -1)
|
||||
{
|
||||
if (ExStyle & WS_EX_MDICHILD)
|
||||
{
|
||||
Active = IsChild(GetForegroundWindow(), hWnd);
|
||||
if (Active)
|
||||
Active = (hWnd == (HWND)SendMessageW(Parent, WM_MDIGETACTIVE, 0, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
Active = (GetForegroundWindow() == hWnd);
|
||||
}
|
||||
}
|
||||
GetWindowRect(hWnd, &WindowRect);
|
||||
GetClientRect(hWnd, &ClientRect);
|
||||
|
||||
CurrentRect.top = CurrentRect.left = 0;
|
||||
CurrentRect.right = WindowRect.right - WindowRect.left;
|
||||
CurrentRect.bottom = WindowRect.bottom - WindowRect.top;
|
||||
|
||||
/* Draw outer edge */
|
||||
if (UserHasWindowEdge(Style, ExStyle))
|
||||
{
|
||||
DrawEdge(hDC, &CurrentRect, EDGE_RAISED, BF_RECT | BF_ADJUST);
|
||||
} else
|
||||
if (ExStyle & WS_EX_STATICEDGE)
|
||||
{
|
||||
#if 0
|
||||
DrawEdge(hDC, &CurrentRect, BDR_SUNKENINNER, BF_RECT | BF_ADJUST | BF_FLAT);
|
||||
#else
|
||||
SelectObject(hDC, GetSysColorBrush(COLOR_BTNSHADOW));
|
||||
PatBlt(hDC, CurrentRect.left, CurrentRect.top, CurrentRect.right - CurrentRect.left, 1, PATCOPY);
|
||||
PatBlt(hDC, CurrentRect.left, CurrentRect.top, 1, CurrentRect.bottom - CurrentRect.top, PATCOPY);
|
||||
|
||||
SelectObject(hDC, GetSysColorBrush(COLOR_BTNHIGHLIGHT));
|
||||
PatBlt(hDC, CurrentRect.left, CurrentRect.bottom - 1, CurrentRect.right - CurrentRect.left, 1, PATCOPY);
|
||||
PatBlt(hDC, CurrentRect.right - 1, CurrentRect.top, 1, CurrentRect.bottom - CurrentRect.top, PATCOPY);
|
||||
|
||||
InflateRect(&CurrentRect, -1, -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Firstly the "thick" frame */
|
||||
if ((Style & WS_THICKFRAME) && !(Style & WS_MINIMIZE))
|
||||
{
|
||||
LONG Width =
|
||||
(GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME)) *
|
||||
GetSystemMetrics(SM_CXBORDER);
|
||||
LONG Height =
|
||||
(GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYDLGFRAME)) *
|
||||
GetSystemMetrics(SM_CYBORDER);
|
||||
|
||||
SelectObject(hDC, GetSysColorBrush(Active ? COLOR_ACTIVEBORDER :
|
||||
COLOR_INACTIVEBORDER));
|
||||
|
||||
/* Draw frame */
|
||||
PatBlt(hDC, CurrentRect.left, CurrentRect.top, CurrentRect.right - CurrentRect.left, Height, PATCOPY);
|
||||
PatBlt(hDC, CurrentRect.left, CurrentRect.top, Width, CurrentRect.bottom - CurrentRect.top, PATCOPY);
|
||||
#ifdef __REACTOS__
|
||||
PatBlt(hDC, CurrentRect.left, CurrentRect.bottom - 1, CurrentRect.right - CurrentRect.left, -Height, PATCOPY);
|
||||
PatBlt(hDC, CurrentRect.right - 1, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY);
|
||||
#else
|
||||
PatBlt(hDC, CurrentRect.left, CurrentRect.bottom, CurrentRect.right - CurrentRect.left, -Height, PATCOPY);
|
||||
PatBlt(hDC, CurrentRect.right, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY);
|
||||
#endif
|
||||
|
||||
InflateRect(&CurrentRect, -Width, -Height);
|
||||
}
|
||||
|
||||
/* Now the other bit of the frame */
|
||||
if (Style & (WS_DLGFRAME | WS_BORDER) || ExStyle & WS_EX_DLGMODALFRAME)
|
||||
{
|
||||
DWORD Width = GetSystemMetrics(SM_CXBORDER);
|
||||
DWORD Height = GetSystemMetrics(SM_CYBORDER);
|
||||
|
||||
SelectObject(hDC, GetSysColorBrush(
|
||||
(ExStyle & (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE)) ? COLOR_3DFACE :
|
||||
(ExStyle & WS_EX_STATICEDGE) ? COLOR_WINDOWFRAME :
|
||||
(Style & (WS_DLGFRAME | WS_THICKFRAME)) ? COLOR_3DFACE :
|
||||
COLOR_WINDOWFRAME));
|
||||
|
||||
/* Draw frame */
|
||||
PatBlt(hDC, CurrentRect.left, CurrentRect.top, CurrentRect.right - CurrentRect.left, Height, PATCOPY);
|
||||
PatBlt(hDC, CurrentRect.left, CurrentRect.top, Width, CurrentRect.bottom - CurrentRect.top, PATCOPY);
|
||||
#ifdef __REACTOS__
|
||||
PatBlt(hDC, CurrentRect.left, CurrentRect.bottom - 1, CurrentRect.right - CurrentRect.left, -Height, PATCOPY);
|
||||
PatBlt(hDC, CurrentRect.right - 1, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY);
|
||||
#else
|
||||
PatBlt(hDC, CurrentRect.left, CurrentRect.bottom, CurrentRect.right - CurrentRect.left, -Height, PATCOPY);
|
||||
PatBlt(hDC, CurrentRect.right, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY);
|
||||
#endif
|
||||
|
||||
InflateRect(&CurrentRect, -Width, -Height);
|
||||
}
|
||||
|
||||
/* Draw caption */
|
||||
if ((Style & WS_CAPTION) == WS_CAPTION)
|
||||
{
|
||||
DWORD CaptionFlags = DC_ICON | DC_TEXT | DC_BUTTONS;
|
||||
HPEN PreviousPen;
|
||||
BOOL Gradient = FALSE;
|
||||
|
||||
if(SystemParametersInfoW(SPI_GETGRADIENTCAPTIONS, 0, &Gradient, 0) && Gradient)
|
||||
{
|
||||
CaptionFlags |= DC_GRADIENT;
|
||||
}
|
||||
|
||||
TempRect = CurrentRect;
|
||||
|
||||
if (Active)
|
||||
{
|
||||
CaptionFlags |= DC_ACTIVE;
|
||||
}
|
||||
|
||||
if (ExStyle & WS_EX_TOOLWINDOW)
|
||||
{
|
||||
CaptionFlags |= DC_SMALLCAP;
|
||||
TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSMCAPTION) - 1;
|
||||
CurrentRect.top += GetSystemMetrics(SM_CYSMCAPTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYCAPTION) - 1;
|
||||
CurrentRect.top += GetSystemMetrics(SM_CYCAPTION);
|
||||
}
|
||||
|
||||
NtUserDrawCaption(hWnd, hDC, &TempRect, CaptionFlags);
|
||||
|
||||
/* Draw buttons */
|
||||
if (Style & WS_SYSMENU)
|
||||
{
|
||||
UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONCLOSE);
|
||||
if ((Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) && !(ExStyle & WS_EX_TOOLWINDOW))
|
||||
{
|
||||
UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMIN);
|
||||
UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMAX);
|
||||
}
|
||||
}
|
||||
if(!(Style & WS_MINIMIZE))
|
||||
{
|
||||
/* Line under caption */
|
||||
PreviousPen = SelectObject(hDC, GetStockObject(DC_PEN));
|
||||
SetDCPenColor(hDC, GetSysColor(
|
||||
((ExStyle & (WS_EX_STATICEDGE | WS_EX_CLIENTEDGE |
|
||||
WS_EX_DLGMODALFRAME)) == WS_EX_STATICEDGE) ?
|
||||
COLOR_WINDOWFRAME : COLOR_3DFACE));
|
||||
MoveToEx(hDC, TempRect.left, TempRect.bottom, NULL);
|
||||
LineTo(hDC, TempRect.right, TempRect.bottom);
|
||||
SelectObject(hDC, PreviousPen);
|
||||
}
|
||||
}
|
||||
|
||||
if(!(Style & WS_MINIMIZE))
|
||||
{
|
||||
HMENU menu = GetMenu(hWnd);
|
||||
/* Draw menu bar */
|
||||
if (menu && !(Style & WS_CHILD))
|
||||
{
|
||||
TempRect = CurrentRect;
|
||||
TempRect.bottom = TempRect.top + (UINT)NtUserxSetMenuBarHeight(menu, 0);
|
||||
CurrentRect.top += MenuDrawMenuBar(hDC, &TempRect, hWnd, FALSE);
|
||||
}
|
||||
|
||||
if (ExStyle & WS_EX_CLIENTEDGE)
|
||||
{
|
||||
DrawEdge(hDC, &CurrentRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
|
||||
}
|
||||
|
||||
/* Draw the scrollbars */
|
||||
if ((Style & WS_VSCROLL) && (Style & WS_HSCROLL) &&
|
||||
IntIsScrollBarVisible(hWnd, OBJID_VSCROLL) && IntIsScrollBarVisible(hWnd, OBJID_HSCROLL))
|
||||
{
|
||||
RECT ParentClientRect;
|
||||
|
||||
TempRect = CurrentRect;
|
||||
if (ExStyle & WS_EX_LEFTSCROLLBAR)
|
||||
TempRect.right = TempRect.left + GetSystemMetrics(SM_CXVSCROLL);
|
||||
else
|
||||
TempRect.left = TempRect.right - GetSystemMetrics(SM_CXVSCROLL);
|
||||
TempRect.top = TempRect.bottom - GetSystemMetrics(SM_CYHSCROLL);
|
||||
FillRect(hDC, &TempRect, GetSysColorBrush(COLOR_BTNFACE));
|
||||
/* FIXME: Correct drawing of size-box with WS_EX_LEFTSCROLLBAR */
|
||||
if(Parent)
|
||||
GetClientRect(Parent, &ParentClientRect);
|
||||
if (HASSIZEGRIP(Style, ExStyle, GetWindowLongPtrW(Parent, GWL_STYLE), WindowRect, ParentClientRect))
|
||||
{
|
||||
DrawFrameControl(hDC, &TempRect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
|
||||
}
|
||||
IntDrawScrollBar(hWnd, hDC, SB_VERT);
|
||||
IntDrawScrollBar(hWnd, hDC, SB_HORZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Style & WS_VSCROLL && IntIsScrollBarVisible(hWnd, OBJID_VSCROLL))
|
||||
IntDrawScrollBar(hWnd, hDC, SB_VERT);
|
||||
else if (Style & WS_HSCROLL && IntIsScrollBarVisible(hWnd, OBJID_HSCROLL))
|
||||
IntDrawScrollBar(hWnd, hDC, SB_HORZ);
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseDC(hWnd, hDC);
|
||||
if (hRgn != HRGN_WINDOW)
|
||||
DeleteObject(hRgn); // We use DCX_KEEPCLIPRGN
|
||||
|
||||
return 0; // For WM_NCPAINT message, return 0.
|
||||
}
|
||||
|
||||
LRESULT
|
||||
DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect)
|
||||
{
|
||||
LRESULT Result = 0;
|
||||
DWORD Style = GetClassLongPtrW(hWnd, GCL_STYLE);
|
||||
DWORD ExStyle;
|
||||
SIZE WindowBorders;
|
||||
RECT OrigRect;
|
||||
|
||||
if (Rect == NULL)
|
||||
{
|
||||
return Result;
|
||||
}
|
||||
OrigRect = *Rect;
|
||||
|
||||
if (CalcSizeStruct)
|
||||
{
|
||||
if (Style & CS_VREDRAW)
|
||||
{
|
||||
Result |= WVR_VREDRAW;
|
||||
}
|
||||
if (Style & CS_HREDRAW)
|
||||
{
|
||||
Result |= WVR_HREDRAW;
|
||||
}
|
||||
Result |= WVR_VALIDRECTS;
|
||||
}
|
||||
|
||||
Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
|
||||
ExStyle = GetWindowLongPtrW(hWnd, GWL_EXSTYLE);
|
||||
|
||||
if (!(Style & WS_MINIMIZE))
|
||||
{
|
||||
HMENU menu = GetMenu(hWnd);
|
||||
|
||||
if (UserHasWindowEdge(Style, ExStyle))
|
||||
{
|
||||
UserGetWindowBorders(Style, ExStyle, &WindowBorders, FALSE);
|
||||
InflateRect(Rect, -WindowBorders.cx, -WindowBorders.cy);
|
||||
} else
|
||||
if ((ExStyle & WS_EX_STATICEDGE) || (Style & WS_BORDER))
|
||||
{
|
||||
InflateRect(Rect, -1, -1);
|
||||
}
|
||||
|
||||
if ((Style & WS_CAPTION) == WS_CAPTION)
|
||||
{
|
||||
if (ExStyle & WS_EX_TOOLWINDOW)
|
||||
Rect->top += GetSystemMetrics(SM_CYSMCAPTION);
|
||||
else
|
||||
Rect->top += GetSystemMetrics(SM_CYCAPTION);
|
||||
}
|
||||
|
||||
if (menu && !(Style & WS_CHILD))
|
||||
{
|
||||
HDC hDC = GetWindowDC(hWnd);
|
||||
if(hDC)
|
||||
{
|
||||
RECT CliRect = *Rect;
|
||||
CliRect.bottom -= OrigRect.top;
|
||||
CliRect.right -= OrigRect.left;
|
||||
CliRect.left -= OrigRect.left;
|
||||
CliRect.top -= OrigRect.top;
|
||||
Rect->top += MenuDrawMenuBar(hDC, &CliRect, hWnd, TRUE);
|
||||
ReleaseDC(hWnd, hDC);
|
||||
}
|
||||
}
|
||||
|
||||
if (ExStyle & WS_EX_CLIENTEDGE)
|
||||
{
|
||||
InflateRect(Rect, -2 * GetSystemMetrics(SM_CXBORDER),
|
||||
-2 * GetSystemMetrics(SM_CYBORDER));
|
||||
}
|
||||
|
||||
if(Style & (WS_VSCROLL | WS_HSCROLL))
|
||||
{
|
||||
SCROLLBARINFO sbi;
|
||||
SETSCROLLBARINFO ssbi;
|
||||
|
||||
sbi.cbSize = sizeof(SCROLLBARINFO);
|
||||
if((Style & WS_VSCROLL) && NtUserGetScrollBarInfo(hWnd, OBJID_VSCROLL, &sbi))
|
||||
{
|
||||
int i;
|
||||
LONG sx = Rect->right;
|
||||
|
||||
sx -= GetSystemMetrics(SM_CXVSCROLL);
|
||||
for(i = 0; i <= CCHILDREN_SCROLLBAR; i++)
|
||||
ssbi.rgstate[i] = sbi.rgstate[i];
|
||||
if(sx <= Rect->left)
|
||||
ssbi.rgstate[0] |= STATE_SYSTEM_OFFSCREEN;
|
||||
else
|
||||
ssbi.rgstate[0] &= ~STATE_SYSTEM_OFFSCREEN;
|
||||
NtUserSetScrollBarInfo(hWnd, OBJID_VSCROLL, &ssbi);
|
||||
if(ssbi.rgstate[0] & STATE_SYSTEM_OFFSCREEN)
|
||||
Style &= ~WS_VSCROLL;
|
||||
}
|
||||
else
|
||||
Style &= ~WS_VSCROLL;
|
||||
|
||||
if((Style & WS_HSCROLL) && NtUserGetScrollBarInfo(hWnd, OBJID_HSCROLL, &sbi))
|
||||
{
|
||||
int i;
|
||||
LONG sy = Rect->bottom;
|
||||
|
||||
sy -= GetSystemMetrics(SM_CYHSCROLL);
|
||||
for(i = 0; i <= CCHILDREN_SCROLLBAR; i++)
|
||||
ssbi.rgstate[i] = sbi.rgstate[i];
|
||||
if(sy <= Rect->top)
|
||||
ssbi.rgstate[0] |= STATE_SYSTEM_OFFSCREEN;
|
||||
else
|
||||
ssbi.rgstate[0] &= ~STATE_SYSTEM_OFFSCREEN;
|
||||
NtUserSetScrollBarInfo(hWnd, OBJID_HSCROLL, &ssbi);
|
||||
if(ssbi.rgstate[0] & STATE_SYSTEM_OFFSCREEN)
|
||||
Style &= ~WS_HSCROLL;
|
||||
}
|
||||
else
|
||||
Style &= ~WS_HSCROLL;
|
||||
}
|
||||
|
||||
if ((Style & WS_VSCROLL) && (Style & WS_HSCROLL))
|
||||
{
|
||||
if ((ExStyle & WS_EX_LEFTSCROLLBAR) != 0)
|
||||
Rect->left += GetSystemMetrics(SM_CXVSCROLL);
|
||||
else
|
||||
Rect->right -= GetSystemMetrics(SM_CXVSCROLL);
|
||||
Rect->bottom -= GetSystemMetrics(SM_CYHSCROLL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Style & WS_VSCROLL)
|
||||
{
|
||||
if ((ExStyle & WS_EX_LEFTSCROLLBAR) != 0)
|
||||
Rect->left += GetSystemMetrics(SM_CXVSCROLL);
|
||||
else
|
||||
Rect->right -= GetSystemMetrics(SM_CXVSCROLL);
|
||||
}
|
||||
else if (Style & WS_HSCROLL)
|
||||
Rect->bottom -= GetSystemMetrics(SM_CYHSCROLL);
|
||||
}
|
||||
if (Rect->top > Rect->bottom)
|
||||
Rect->bottom = Rect->top;
|
||||
if (Rect->left > Rect->right)
|
||||
Rect->right = Rect->left;
|
||||
}
|
||||
else
|
||||
{
|
||||
Rect->right = Rect->left;
|
||||
Rect->bottom = Rect->top;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
LRESULT
|
||||
DefWndNCActivate(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
PWND Wnd = ValidateHwnd(hWnd);
|
||||
|
||||
if (!Wnd) return 0;
|
||||
|
||||
/* Lotus Notes draws menu descriptions in the caption of its main
|
||||
* window. When it wants to restore original "system" view, it just
|
||||
* sends WM_NCACTIVATE message to itself. Any optimizations here in
|
||||
* attempt to minimize redrawings lead to a not restored caption.
|
||||
*/
|
||||
if (wParam)
|
||||
NtUserxSetWindowState(Wnd, WNDSACTIVEFRAME);
|
||||
else
|
||||
NtUserxClearWindowState(Wnd, WNDSACTIVEFRAME);
|
||||
|
||||
if (Wnd->state & WNDS_NONCPAINT)
|
||||
return 0;
|
||||
|
||||
/* This isn't documented but is reproducible in at least XP SP2 and
|
||||
* Outlook 2007 depends on it
|
||||
*/
|
||||
// MSDN:
|
||||
// If this parameter is set to -1, DefWindowProc does not repaint the
|
||||
// nonclient area to reflect the state change.
|
||||
if (lParam != -1)
|
||||
{
|
||||
DefWndNCPaint(hWnd, HRGN_WINDOW, wParam);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
* - Check the scrollbar handling
|
||||
|
@ -902,334 +300,17 @@ DefWndNCHitTest(HWND hWnd, POINT Point)
|
|||
return HTNOWHERE;
|
||||
}
|
||||
|
||||
VOID
|
||||
DefWndDoButton(HWND hWnd, WPARAM wParam)
|
||||
{
|
||||
MSG Msg;
|
||||
HDC WindowDC;
|
||||
BOOL Pressed = TRUE, OldState;
|
||||
WPARAM SCMsg;
|
||||
HMENU hSysMenu;
|
||||
ULONG ButtonType;
|
||||
DWORD Style;
|
||||
UINT MenuState;
|
||||
|
||||
Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
|
||||
switch (wParam)
|
||||
{
|
||||
case HTCLOSE:
|
||||
hSysMenu = GetSystemMenu(hWnd, FALSE);
|
||||
MenuState = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND); /* in case of error MenuState==0xFFFFFFFF */
|
||||
if (!(Style & WS_SYSMENU) || (MenuState & (MF_GRAYED|MF_DISABLED)) || (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_NOCLOSE))
|
||||
return;
|
||||
ButtonType = DFCS_CAPTIONCLOSE;
|
||||
SCMsg = SC_CLOSE;
|
||||
break;
|
||||
case HTMINBUTTON:
|
||||
if (!(Style & WS_MINIMIZEBOX))
|
||||
return;
|
||||
ButtonType = DFCS_CAPTIONMIN;
|
||||
SCMsg = ((Style & WS_MINIMIZE) ? SC_RESTORE : SC_MINIMIZE);
|
||||
break;
|
||||
case HTMAXBUTTON:
|
||||
if (!(Style & WS_MAXIMIZEBOX))
|
||||
return;
|
||||
ButtonType = DFCS_CAPTIONMAX;
|
||||
SCMsg = ((Style & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: Not sure where to do this, but we must flush the pending
|
||||
* window updates when someone clicks on the close button and at
|
||||
* the same time the window is overlapped with another one. This
|
||||
* looks like a good place for now...
|
||||
*/
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
WindowDC = GetWindowDC(hWnd);
|
||||
UserDrawCaptionButtonWnd(hWnd, WindowDC, TRUE, ButtonType);
|
||||
|
||||
SetCapture(hWnd);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (GetMessageW(&Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST) <= 0)
|
||||
break;
|
||||
if (CallMsgFilterW( &Msg, MSGF_MAX )) continue;
|
||||
|
||||
if (Msg.message == WM_LBUTTONUP)
|
||||
break;
|
||||
|
||||
if (Msg.message != WM_MOUSEMOVE)
|
||||
continue;
|
||||
|
||||
OldState = Pressed;
|
||||
Pressed = (DefWndNCHitTest(hWnd, Msg.pt) == wParam);
|
||||
if (Pressed != OldState)
|
||||
UserDrawCaptionButtonWnd(hWnd, WindowDC, Pressed, ButtonType);
|
||||
}
|
||||
|
||||
if (Pressed)
|
||||
UserDrawCaptionButtonWnd(hWnd, WindowDC, FALSE, ButtonType);
|
||||
ReleaseCapture();
|
||||
ReleaseDC(hWnd, WindowDC);
|
||||
if (Pressed)
|
||||
SendMessageW(hWnd, WM_SYSCOMMAND, SCMsg, MAKELONG(Msg.pt.x,Msg.pt.y));
|
||||
}
|
||||
|
||||
|
||||
LRESULT
|
||||
DefWndNCLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
PWND Wnd = ValidateHwnd(hWnd);
|
||||
|
||||
switch (wParam)
|
||||
{
|
||||
case HTCAPTION:
|
||||
{
|
||||
HWND hTopWnd = hWnd, parent;
|
||||
while(1)
|
||||
{
|
||||
if ((GetWindowLongW( hTopWnd, GWL_STYLE ) & (WS_POPUP|WS_CHILD)) != WS_CHILD)
|
||||
break;
|
||||
parent = GetAncestor( hTopWnd, GA_PARENT );
|
||||
if (!parent || parent == GetDesktopWindow()) break;
|
||||
hTopWnd = parent;
|
||||
}
|
||||
|
||||
if ( NtUserCallHwndLock(hTopWnd, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOWMOUSE) ||
|
||||
GetActiveWindow() == hTopWnd)
|
||||
{
|
||||
SendMessageW(hWnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HTSYSMENU:
|
||||
{
|
||||
LONG style = GetWindowLongPtrW( hWnd, GWL_STYLE );
|
||||
if (style & WS_SYSMENU)
|
||||
{
|
||||
if( Wnd && !(style & WS_MINIMIZE) )
|
||||
{
|
||||
RECT rect;
|
||||
HDC hDC = GetWindowDC(hWnd);
|
||||
UserGetInsideRectNC(Wnd, &rect);
|
||||
UserDrawSysMenuButton(hWnd, hDC, &rect, TRUE);
|
||||
ReleaseDC( hWnd, hDC );
|
||||
}
|
||||
SendMessageW(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HTMENU:
|
||||
{
|
||||
SendMessageW(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTMENU, lParam);
|
||||
break;
|
||||
}
|
||||
case HTHSCROLL:
|
||||
{
|
||||
SendMessageW(hWnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam);
|
||||
break;
|
||||
}
|
||||
case HTVSCROLL:
|
||||
{
|
||||
SendMessageW(hWnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam);
|
||||
break;
|
||||
}
|
||||
case HTMINBUTTON:
|
||||
case HTMAXBUTTON:
|
||||
case HTCLOSE:
|
||||
{
|
||||
DefWndDoButton(hWnd, wParam);
|
||||
break;
|
||||
}
|
||||
case HTLEFT:
|
||||
case HTRIGHT:
|
||||
case HTTOP:
|
||||
case HTBOTTOM:
|
||||
case HTTOPLEFT:
|
||||
case HTTOPRIGHT:
|
||||
case HTBOTTOMLEFT:
|
||||
case HTBOTTOMRIGHT:
|
||||
{
|
||||
/* Old comment:
|
||||
* "make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU"
|
||||
* This was previously done by setting wParam=SC_SIZE + wParam - 2
|
||||
*/
|
||||
/* But that is not what WinNT does. Instead it sends this. This
|
||||
* is easy to differentiate from HTSYSMENU, because HTSYSMENU adds
|
||||
* SC_MOUSEMENU into wParam.
|
||||
*/
|
||||
SendMessageW(hWnd, WM_SYSCOMMAND, SC_SIZE + wParam - (HTLEFT - WMSZ_LEFT), lParam);
|
||||
break;
|
||||
}
|
||||
case HTBORDER:
|
||||
break;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
LRESULT
|
||||
DefWndNCLButtonDblClk(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
ULONG Style;
|
||||
|
||||
Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
|
||||
switch(wParam)
|
||||
{
|
||||
case HTCAPTION:
|
||||
{
|
||||
/* Maximize/Restore the window */
|
||||
if((Style & WS_CAPTION) == WS_CAPTION && (Style & WS_MAXIMIZEBOX))
|
||||
{
|
||||
SendMessageW(hWnd, WM_SYSCOMMAND, ((Style & (WS_MINIMIZE | WS_MAXIMIZE)) ? SC_RESTORE : SC_MAXIMIZE), 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HTSYSMENU:
|
||||
{
|
||||
HMENU hSysMenu = GetSystemMenu(hWnd, FALSE);
|
||||
UINT state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
|
||||
|
||||
/* If the close item of the sysmenu is disabled or not present do nothing */
|
||||
if ((state & (MF_DISABLED | MF_GRAYED)) || (state == 0xFFFFFFFF))
|
||||
break;
|
||||
|
||||
SendMessageW(hWnd, WM_SYSCOMMAND, SC_CLOSE, lParam);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return DefWndNCLButtonDown(hWnd, wParam, lParam);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NC_HandleNCRButtonDown
|
||||
*
|
||||
* Handle a WM_NCRBUTTONDOWN message. Called from DefWindowProc().
|
||||
/*
|
||||
RealUserDrawCaption: This function is passed through RegisterUserApiHook to uxtheme
|
||||
to call it when the classic caption is needed to be drawn.
|
||||
*/
|
||||
LRESULT NC_HandleNCRButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
|
||||
LRESULT WINAPI
|
||||
RealUserDrawCaption(HWND hWnd, HDC hDC, LPCRECT lpRc, UINT uFlags)
|
||||
{
|
||||
MSG msg;
|
||||
INT hittest = wParam;
|
||||
|
||||
switch (hittest)
|
||||
{
|
||||
case HTCAPTION:
|
||||
case HTSYSMENU:
|
||||
if (!GetSystemMenu( hwnd, FALSE )) break;
|
||||
|
||||
SetCapture( hwnd );
|
||||
for (;;)
|
||||
{
|
||||
if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
|
||||
if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
|
||||
if (msg.message == WM_RBUTTONUP)
|
||||
{
|
||||
hittest = DefWndNCHitTest( hwnd, msg.pt );
|
||||
break;
|
||||
}
|
||||
if (hwnd != GetCapture()) return 0;
|
||||
}
|
||||
ReleaseCapture();
|
||||
if (hittest == HTCAPTION || hittest == HTSYSMENU || hittest == HTHSCROLL || hittest == HTVSCROLL)
|
||||
{
|
||||
TRACE("Msg pt %x and Msg.lParam %x and lParam %x\n",MAKELONG(msg.pt.x,msg.pt.y),msg.lParam,lParam);
|
||||
SendMessageW( hwnd, WM_CONTEXTMENU, (WPARAM)hwnd, MAKELONG(msg.pt.x,msg.pt.y));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
ERR("Real DC flags %08x\n",uFlags);
|
||||
return NtUserDrawCaption(hWnd, hDC, lpRc, uFlags);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NcGetInsideRect
|
||||
*
|
||||
* Get the 'inside' rectangle of a window, i.e. the whole window rectangle
|
||||
* but without the borders (if any).
|
||||
* The rectangle is in window coordinates (for drawing with GetWindowDC()).
|
||||
*/
|
||||
static void FASTCALL
|
||||
NcGetInsideRect(HWND Wnd, RECT *Rect)
|
||||
{
|
||||
DWORD Style;
|
||||
DWORD ExStyle;
|
||||
|
||||
GetWindowRect(Wnd, Rect);
|
||||
Rect->right = Rect->right - Rect->left;
|
||||
Rect->left = 0;
|
||||
Rect->bottom = Rect->bottom - Rect->top;
|
||||
Rect->top = 0;
|
||||
|
||||
Style = GetWindowLongPtrW(Wnd, GWL_STYLE);
|
||||
if (0 != (Style & WS_ICONIC))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove frame from rectangle */
|
||||
ExStyle = GetWindowLongPtrW(Wnd, GWL_EXSTYLE);
|
||||
if (HAS_THICKFRAME(Style, ExStyle))
|
||||
{
|
||||
InflateRect(Rect, - GetSystemMetrics(SM_CXFRAME), - GetSystemMetrics(SM_CYFRAME));
|
||||
}
|
||||
else if (HAS_DLGFRAME(Style, ExStyle))
|
||||
{
|
||||
InflateRect(Rect, - GetSystemMetrics(SM_CXDLGFRAME), - GetSystemMetrics(SM_CYDLGFRAME));
|
||||
}
|
||||
else if (HAS_THINFRAME(Style, ExStyle))
|
||||
{
|
||||
InflateRect(Rect, - GetSystemMetrics(SM_CXBORDER), - GetSystemMetrics(SM_CYBORDER));
|
||||
}
|
||||
|
||||
/* We have additional border information if the window
|
||||
* is a child (but not an MDI child) */
|
||||
if (0 != (Style & WS_CHILD)
|
||||
&& 0 == (ExStyle & WS_EX_MDICHILD))
|
||||
{
|
||||
if (0 != (ExStyle & WS_EX_CLIENTEDGE))
|
||||
{
|
||||
InflateRect(Rect, - GetSystemMetrics(SM_CXEDGE), - GetSystemMetrics(SM_CYEDGE));
|
||||
}
|
||||
if (0 != (ExStyle & WS_EX_STATICEDGE))
|
||||
{
|
||||
InflateRect(Rect, - GetSystemMetrics(SM_CXBORDER), - GetSystemMetrics(SM_CYBORDER));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NcGetSysPopupPos
|
||||
*/
|
||||
void FASTCALL
|
||||
NcGetSysPopupPos(HWND Wnd, RECT *Rect)
|
||||
{
|
||||
RECT WindowRect;
|
||||
|
||||
if (IsIconic(Wnd))
|
||||
{
|
||||
GetWindowRect(Wnd, Rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
NcGetInsideRect(Wnd, Rect);
|
||||
GetWindowRect(Wnd, &WindowRect);
|
||||
OffsetRect(Rect, WindowRect.left, WindowRect.top);
|
||||
if (0 != (GetWindowLongPtrW(Wnd, GWL_STYLE) & WS_CHILD))
|
||||
{
|
||||
ClientToScreen(GetParent(Wnd), (POINT *) Rect);
|
||||
}
|
||||
Rect->right = Rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
|
||||
Rect->bottom = Rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
|
|
Loading…
Reference in a new issue