📄 defwnd.c
字号:
/* $Id: defwnd.c 23823 2006-08-30 20:40:07Z weiden $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/window.c
* PURPOSE: Window management
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
* 06-06-2001 CSH Created
*/
/* INCLUDES ******************************************************************/
#include <user32.h>
#include <wine/debug.h>
#ifndef WM_SETVISIBLE
#define WM_SETVISIBLE 9
#endif
#ifndef WM_QUERYDROPOBJECT
#define WM_QUERYDROPOBJECT 0x022B
#endif
LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
LRESULT DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect);
LRESULT DefWndNCActivate(HWND hWnd, WPARAM wParam);
LRESULT DefWndNCHitTest(HWND hWnd, POINT Point);
LRESULT DefWndNCLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam);
LRESULT DefWndNCLButtonDblClk(HWND hWnd, WPARAM wParam, LPARAM lParam);
void FASTCALL MenuInitSysMenuPopup(HMENU Menu, DWORD Style, DWORD ClsStyle, LONG HitTest );
/* GLOBALS *******************************************************************/
COLORREF SysColors[NUM_SYSCOLORS] = {0};
HPEN SysPens[NUM_SYSCOLORS] = {0};
HBRUSH SysBrushes[NUM_SYSCOLORS] = {0};
/* Bits in the dwKeyData */
#define KEYDATA_ALT 0x2000
#define KEYDATA_PREVSTATE 0x4000
static short iF10Key = 0;
static short iMenuSysKey = 0;
/* FUNCTIONS *****************************************************************/
void
InitStockObjects(void)
{
/* FIXME - Instead of copying the stuff to usermode we should map the tables to
userland. The current implementation has one big flaw: the system color
table doesn't get updated when another process changes them. That's why
we should rather map the table into usermode. But it only affects the
SysColors table - the pens, brushes and stock objects are not affected
as their handles never change. But it'd be faster to map them, too. */
if(SysBrushes[0] == NULL)
{
/* only initialize once */
(void)NtUserGetSysColors(SysColors, NUM_SYSCOLORS);
(void)NtUserGetSysColorPens(SysPens, NUM_SYSCOLORS);
(void)NtUserGetSysColorBrushes(SysBrushes, NUM_SYSCOLORS);
}
}
/*
* @implemented
*/
DWORD STDCALL
GetSysColor(int nIndex)
{
if(nIndex >= 0 && nIndex <= NUM_SYSCOLORS)
{
return SysColors[nIndex];
}
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
/*
* @implemented
*/
HPEN STDCALL
GetSysColorPen(int nIndex)
{
if(nIndex >= 0 && nIndex <= NUM_SYSCOLORS)
{
return SysPens[nIndex];
}
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
/*
* @implemented
*/
HBRUSH STDCALL
GetSysColorBrush(int nIndex)
{
if(nIndex >= 0 && nIndex <= NUM_SYSCOLORS)
{
return SysBrushes[nIndex];
}
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
/*
* @implemented
*/
BOOL
STDCALL
SetSysColors(
int cElements,
CONST INT *lpaElements,
CONST COLORREF *lpaRgbValues)
{
BOOL Ret;
struct
{
INT *Elements;
COLORREF *Colors;
} ChangeSysColors;
ChangeSysColors.Elements = (INT*)lpaElements;
ChangeSysColors.Colors = (COLORREF*)lpaRgbValues;
if(cElements > 0)
{
Ret = NtUserSetSysColors(&ChangeSysColors, cElements);
if(Ret)
{
/* FIXME - just change it in the usermode structure, too, instead of asking win32k again */
(void)NtUserGetSysColors(SysColors, NUM_SYSCOLORS);
}
}
else
{
SetLastError(ERROR_INVALID_PARAMETER);
Ret = FALSE;
}
return Ret;
}
void
UserGetInsideRectNC(HWND hWnd, RECT *rect)
{
RECT WindowRect;
ULONG Style;
ULONG ExStyle;
Style = GetWindowLongW(hWnd, GWL_STYLE);
ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
GetWindowRect(hWnd, &WindowRect);
rect->top = rect->left = 0;
rect->right = WindowRect.right - WindowRect.left;
rect->bottom = WindowRect.bottom - WindowRect.top;
if (Style & WS_ICONIC)
{
return;
}
/* Remove frame from rectangle */
if (UserHasThickFrameStyle(Style, ExStyle ))
{
InflateRect(rect, -GetSystemMetrics(SM_CXFRAME),
-GetSystemMetrics(SM_CYFRAME));
}
else
{
if (UserHasDlgFrameStyle(Style, ExStyle ))
{
InflateRect(rect, -GetSystemMetrics(SM_CXDLGFRAME),
-GetSystemMetrics(SM_CYDLGFRAME));
/* FIXME: this isn't in NC_AdjustRect? why not? */
if (ExStyle & WS_EX_DLGMODALFRAME)
InflateRect( rect, -1, 0 );
}
else
{
if (UserHasThinFrameStyle(Style, ExStyle))
{
InflateRect(rect, -GetSystemMetrics(SM_CXBORDER),
-GetSystemMetrics(SM_CYBORDER));
}
}
}
}
VOID
DefWndSetRedraw(HWND hWnd, WPARAM wParam)
{
LONG Style = GetWindowLong(hWnd, GWL_STYLE);
/* Content can be redrawn after a change. */
if (wParam)
{
if (!(Style & WS_VISIBLE)) /* Not Visible */
{
SetWindowLong(hWnd, GWL_STYLE, WS_VISIBLE);
}
}
else /* Content cannot be redrawn after a change. */
{
if (Style & WS_VISIBLE) /* Visible */
{
RedrawWindow( hWnd, NULL, 0, RDW_ALLCHILDREN | RDW_VALIDATE );
Style &= ~WS_VISIBLE;
SetWindowLong(hWnd, GWL_STYLE, Style); /* clear bits */
}
}
return;
}
LRESULT
DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam, ULONG Style)
{
/* Not for child windows. */
if (hWnd != (HWND)wParam)
{
return(0);
}
switch((INT_PTR) LOWORD(lParam))
{
case HTERROR:
{
WORD Msg = HIWORD(lParam);
if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
Msg == WM_RBUTTONDOWN || Msg == WM_XBUTTONDOWN)
{
MessageBeep(0);
}
break;
}
case HTCLIENT:
{
HICON hCursor = (HICON)GetClassLongW(hWnd, GCL_HCURSOR);
if (hCursor)
{
SetCursor(hCursor);
return(TRUE);
}
return(FALSE);
}
case HTLEFT:
case HTRIGHT:
{
if (Style & WS_MAXIMIZE)
{
break;
}
return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZEWE)));
}
case HTTOP:
case HTBOTTOM:
{
if (Style & WS_MAXIMIZE)
{
break;
}
return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENS)));
}
case HTTOPLEFT:
case HTBOTTOMRIGHT:
{
if (Style & WS_MAXIMIZE)
{
break;
}
return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENWSE)));
}
case HTBOTTOMLEFT:
case HTTOPRIGHT:
{
if (GetWindowLongW(hWnd, GWL_STYLE) & WS_MAXIMIZE)
{
break;
}
return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENESW)));
}
}
return((LRESULT)SetCursor(LoadCursorW(0, IDC_ARROW)));
}
static LONG
DefWndStartSizeMove(HWND hWnd, WPARAM wParam, POINT *capturePoint)
{
LONG hittest = 0;
POINT pt;
MSG msg;
RECT rectWindow;
ULONG Style = GetWindowLongW(hWnd, GWL_STYLE);
GetWindowRect(hWnd, &rectWindow);
if ((wParam & 0xfff0) == SC_MOVE)
{
/* Move pointer at the center of the caption */
RECT rect;
UserGetInsideRectNC(hWnd, &rect);
if (Style & WS_SYSMENU)
rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
if (Style & WS_MINIMIZEBOX)
rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
if (Style & WS_MAXIMIZEBOX)
rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
pt.x = rectWindow.left + (rect.right - rect.left) / 2;
pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
hittest = HTCAPTION;
*capturePoint = pt;
}
else /* SC_SIZE */
{
pt.x = pt.y = 0;
while(!hittest)
{
if (GetMessageW(&msg, NULL, 0, 0) <= 0)
break;
switch(msg.message)
{
case WM_MOUSEMOVE:
hittest = DefWndNCHitTest(hWnd, msg.pt);
if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
hittest = 0;
break;
case WM_LBUTTONUP:
return 0;
case WM_KEYDOWN:
switch(msg.wParam)
{
case VK_UP:
hittest = HTTOP;
pt.x =(rectWindow.left+rectWindow.right)/2;
pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
break;
case VK_DOWN:
hittest = HTBOTTOM;
pt.x =(rectWindow.left+rectWindow.right)/2;
pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
break;
case VK_LEFT:
hittest = HTLEFT;
pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
pt.y =(rectWindow.top+rectWindow.bottom)/2;
break;
case VK_RIGHT:
hittest = HTRIGHT;
pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
pt.y =(rectWindow.top+rectWindow.bottom)/2;
break;
case VK_RETURN:
case VK_ESCAPE: return 0;
}
}
}
*capturePoint = pt;
}
SetCursorPos( pt.x, pt.y );
DefWndHandleSetCursor(hWnd, (WPARAM)hWnd, MAKELONG(hittest, WM_MOUSEMOVE), Style);
return hittest;
}
#define ON_LEFT_BORDER(hit) \
(((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
#define ON_RIGHT_BORDER(hit) \
(((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
#define ON_TOP_BORDER(hit) \
(((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
#define ON_BOTTOM_BORDER(hit) \
(((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
static VOID
UserDrawWindowFrame(HDC hdc, const RECT *rect,
ULONG width, ULONG height)
{
static HBRUSH hDraggingRectBrush = NULL;
HBRUSH hbrush;
if(!hDraggingRectBrush)
{
static HBITMAP hDraggingPattern = NULL;
const DWORD Pattern[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
hDraggingPattern = CreateBitmap(8, 8, 1, 1, Pattern);
hDraggingRectBrush = CreatePatternBrush(hDraggingPattern);
}
hbrush = SelectObject( hdc, hDraggingRectBrush );
PatBlt( hdc, rect->left, rect->top,
rect->right - rect->left - width, height, PATINVERT );
PatBlt( hdc, rect->left, rect->top + height, width,
rect->bottom - rect->top - height, PATINVERT );
PatBlt( hdc, rect->left + width, rect->bottom - 1,
rect->right - rect->left - width, -height, PATINVERT );
PatBlt( hdc, rect->right - 1, rect->top, -width,
rect->bottom - rect->top - height, PATINVERT );
SelectObject( hdc, hbrush );
}
static VOID
UserDrawMovingFrame(HDC hdc, RECT *rect, BOOL thickframe)
{
if(thickframe)
{
UserDrawWindowFrame(hdc, rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));
}
else
{
UserDrawWindowFrame(hdc, rect, 1, 1);
}
}
static VOID
DefWndDoSizeMove(HWND hwnd, WORD wParam)
{
HRGN DesktopRgn;
MSG msg;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -