⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 defwnd.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
/* $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 + -