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

📄 window.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: window.c 23228 2006-07-22 17:03:00Z turner $
 *
 * 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 ******************************************************************/
#define DEBUG
#include <user32.h>

#include <wine/debug.h>

BOOL ControlsInitialized = FALSE;

LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id );

#define CW_USEDEFAULT16 0x00008000

/* FUNCTIONS *****************************************************************/


NTSTATUS STDCALL
User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength)
{
  PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs;

  DPRINT("User32CallSendAsyncProcKernel()\n");
  CallbackArgs = (PSENDASYNCPROC_CALLBACK_ARGUMENTS)Arguments;
  if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
    {
      return(STATUS_INFO_LENGTH_MISMATCH);
    }
  CallbackArgs->Callback(CallbackArgs->Wnd, CallbackArgs->Msg,
			 CallbackArgs->Context, CallbackArgs->Result);
  return(STATUS_SUCCESS);
}


/*
 * @unimplemented
 */
BOOL STDCALL
AllowSetForegroundWindow(DWORD dwProcessId)
{
  UNIMPLEMENTED;
  return(FALSE);
}


/*
 * @unimplemented
 */
HDWP STDCALL
BeginDeferWindowPos(int nNumWindows)
{
#if 0
  UNIMPLEMENTED;
  return (HDWP)0;
#else
  return (HDWP)1;
#endif
}


/*
 * @implemented
 */
BOOL STDCALL
BringWindowToTop(HWND hWnd)
{
    return NtUserSetWindowPos( hWnd,
                               HWND_TOP,
                               0,
                               0,
                               0,
                               0,
                               SWP_NOSIZE | SWP_NOMOVE );
}


/*
 * @unimplemented
 */
/*
WORD STDCALL
CascadeWindows(HWND hwndParent,
	       UINT wHow,
	       CONST RECT *lpRect,
	       UINT cKids,
	       const HWND *lpKids)
{
  UNIMPLEMENTED;
  return 0;
}
*/

VOID
STDCALL
SwitchToThisWindow ( HWND hwnd, BOOL fUnknown )
{
  ShowWindow ( hwnd, SW_SHOW );
}

/*
 * @implemented
 */
HWND STDCALL
ChildWindowFromPoint(HWND hWndParent,
		     POINT Point)
{
  return (HWND) NtUserChildWindowFromPointEx(hWndParent, Point.x, Point.y, 0);
}


/*
 * @implemented
 */
HWND STDCALL
ChildWindowFromPointEx(HWND hwndParent,
		       POINT pt,
		       UINT uFlags)
{
  return (HWND) NtUserChildWindowFromPointEx(hwndParent, pt.x, pt.y, uFlags);
}


/*
 * @implemented
 */
BOOL STDCALL
CloseWindow(HWND hWnd)
{
    SendMessageA(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);

    return (BOOL)(hWnd);
}


HWND STDCALL
User32CreateWindowEx(DWORD dwExStyle,
		LPCSTR lpClassName,
		LPCSTR lpWindowName,
		DWORD dwStyle,
		int x,
		int y,
		int nWidth,
		int nHeight,
		HWND hWndParent,
		HMENU hMenu,
		HINSTANCE hInstance,
		LPVOID lpParam,
		BOOL Unicode)
{
  UNICODE_STRING WindowName;
  UNICODE_STRING ClassName;
  WNDCLASSEXA wceA;
  WNDCLASSEXW wceW;
  HWND Handle;
  MDICREATESTRUCTA mdi;

#if 0
  DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
#endif
  
  if (IS_ATOM(lpClassName))
    {
      RtlInitUnicodeString(&ClassName, NULL);
      ClassName.Buffer = (LPWSTR)lpClassName;
    }
  else
    {
       if(Unicode)
           RtlInitUnicodeString(&ClassName, (PCWSTR)lpClassName);
       else
       {
          if (!RtlCreateUnicodeStringFromAsciiz(&(ClassName), (PCSZ)lpClassName))
          {
	     SetLastError(ERROR_OUTOFMEMORY);
	     return (HWND)0;
	  }
       }
    }

  /* Register built-in controls if not already done */
  if (! ControlsInitialized)
    {
      ControlsInitialized = ControlsInit(ClassName.Buffer);
    }

  if (dwExStyle & WS_EX_MDICHILD)
  {
      POINT mPos[2];
      UINT id = 0;
  /* lpParams of WM_[NC]CREATE is different for MDI children.
   * MDICREATESTRUCT members have the originally passed values.
   *
   * Note: we rely on the fact that MDICREATESTRUCTA and MDICREATESTRUCTW
   * have the same layout.
   */
      mdi.szClass = (LPCSTR)lpClassName;
      mdi.szTitle = (LPCSTR)lpWindowName;
      mdi.hOwner = hInstance;
      mdi.x = x;
      mdi.y = y;
      mdi.cx = nWidth;
      mdi.cy = nHeight;
      mdi.style = dwStyle;
      mdi.lParam = (LPARAM)lpParam;

      lpParam = (LPVOID)&mdi;

      if (GetWindowLongW(hWndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
      {
        if (dwStyle & WS_POPUP)
        {
           DPRINT1("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
           return(0);
        }
        dwStyle |= (WS_CHILD | WS_CLIPSIBLINGS);
      }
      else
      {
        dwStyle &= ~WS_POPUP;
        dwStyle |= (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION |
                WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
      }

      HWND top_child = GetWindow(hWndParent, GW_CHILD);

      if (top_child)
      {
        /* Restore current maximized child */
        if((dwStyle & WS_VISIBLE) && IsZoomed(top_child))
        {
           DPRINT("Restoring current maximized child %p\n", top_child);
           SendMessageW( top_child, WM_SETREDRAW, FALSE, 0 );
           ShowWindow(top_child, SW_RESTORE);
           SendMessageW( top_child, WM_SETREDRAW, TRUE, 0 );
        }
      }
    
      MDI_CalcDefaultChildPos(hWndParent, -1, mPos, 0, &id);

      if (!(dwStyle & WS_POPUP)) hMenu = (HMENU)id;

      if (dwStyle & (WS_CHILD | WS_POPUP))
      {
         if (x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
         {
            x = mPos[0].x;
            y = mPos[0].y;
         }
         if (nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16 || !nWidth)
             nWidth = mPos[1].x;
         if (nHeight == CW_USEDEFAULT || nHeight == CW_USEDEFAULT16 || !nHeight)
             nHeight = mPos[1].y;
      }
  }

  if (Unicode)
    RtlInitUnicodeString(&WindowName, (PCWSTR)lpWindowName);
  else
  {
    if (!RtlCreateUnicodeStringFromAsciiz(&WindowName, (PCSZ)lpWindowName))
      {
        if (!IS_ATOM(lpClassName))
	  {
	    RtlFreeUnicodeString(&ClassName);
	  }
        SetLastError(ERROR_OUTOFMEMORY);
        return (HWND)0;
      }
  }
  
  if(!hMenu && (dwStyle & (WS_OVERLAPPEDWINDOW | WS_POPUP)))
  {
    if(Unicode)
    {
       wceW.cbSize = sizeof(WNDCLASSEXW);
       if(GetClassInfoExW(hInstance, (LPCWSTR)lpClassName, &wceW) && wceW.lpszMenuName)
       {DbgPrint("LoadingMenu 0x%p %d\n", wceW.lpszMenuName, IS_INTRESOURCE(wceW.lpszMenuName));
       hMenu = LoadMenuW(hInstance, wceW.lpszMenuName);DbgPrint("Loaded menu: 0x%p\n", hMenu);
       }
    }
    else
    {
       wceA.cbSize = sizeof(WNDCLASSEXA);
       if(GetClassInfoExA(hInstance, lpClassName, &wceA) && wceA.lpszMenuName)
       {
         hMenu = LoadMenuA(hInstance, wceA.lpszMenuName);
       }
    }
  }

  Handle = NtUserCreateWindowEx(dwExStyle,
				&ClassName,
				&WindowName,
				dwStyle,
				x,
				y,
				nWidth,
				nHeight,
				hWndParent,
				hMenu,
				hInstance,
				lpParam,
				SW_SHOW,
				FALSE);

#if 0
  DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle);
#endif

   if ((dwStyle & WS_VISIBLE) && (dwExStyle & WS_EX_MDICHILD))
   {
      SendMessageW(hWndParent, WM_MDIREFRESHMENU, 0, 0);
      SetWindowPos(Handle, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW |
                                                SWP_NOMOVE | SWP_NOSIZE);
   }

  if(!Unicode)
  {
    RtlFreeUnicodeString(&WindowName);

    if (!IS_ATOM(lpClassName))
      {
        RtlFreeUnicodeString(&ClassName);
      }
  }
  return Handle;
}


/*
 * @implemented
 */
HWND STDCALL
CreateWindowExA(DWORD dwExStyle,
		LPCSTR lpClassName,
		LPCSTR lpWindowName,
		DWORD dwStyle,
		int x,
		int y,
		int nWidth,
		int nHeight,
		HWND hWndParent,
		HMENU hMenu,
		HINSTANCE hInstance,
		LPVOID lpParam)
{
   return User32CreateWindowEx(dwExStyle,
                               lpClassName,
                               lpWindowName,
                               dwStyle,
                               x,
                               y,
                               nWidth,
                               nHeight,
                               hWndParent,
                               hMenu,
                               hInstance,
                               lpParam,
                               FALSE);
}


/*
 * @implemented
 */
HWND STDCALL
CreateWindowExW(DWORD dwExStyle,
		LPCWSTR lpClassName,
		LPCWSTR lpWindowName,
		DWORD dwStyle,
		int x,
		int y,
		int nWidth,
		int nHeight,
		HWND hWndParent,
		HMENU hMenu,
		HINSTANCE hInstance,
		LPVOID lpParam)
{
   return User32CreateWindowEx(dwExStyle,
                               (LPCSTR) lpClassName,
                               (LPCSTR) lpWindowName,
                               dwStyle,
                               x,
                               y,
                               nWidth,
                               nHeight,
                               hWndParent,
                               hMenu,
                               hInstance,
                               lpParam,
                               TRUE);
}

/*
 * @unimplemented
 */
HDWP STDCALL
DeferWindowPos(HDWP hWinPosInfo,
	       HWND hWnd,
	       HWND hWndInsertAfter,
	       int x,
	       int y,
	       int cx,
	       int cy,
	       UINT uFlags)
{
#if 0
  return NtUserDeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
#else
  SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
  return hWinPosInfo;
#endif
}


/*
 * @implemented
 */
BOOL STDCALL
DestroyWindow(HWND hWnd)
{
  return NtUserDestroyWindow(hWnd);
}


/*
 * @unimplemented
 */
BOOL STDCALL
EndDeferWindowPos(HDWP hWinPosInfo)
{
#if 0
  UNIMPLEMENTED;
  return FALSE;
#else
  return TRUE;
#endif
}


/*
 * @implemented
 */
HWND STDCALL
GetDesktopWindow(VOID)
{
	return NtUserGetDesktopWindow();
}


/*
 * @unimplemented
 */
HWND STDCALL
GetForegroundWindow(VOID)
{
   return NtUserGetForegroundWindow();
}

static
BOOL
User32EnumWindows (
	HDESK hDesktop,
	HWND hWndparent,
	WNDENUMPROC lpfn,
	LPARAM lParam,
	DWORD dwThreadId,
	BOOL bChildren )
{
  DWORD i, dwCount = 0;
  HWND* pHwnd = NULL;
  HANDLE hHeap;

  if ( !lpfn )
    {
      SetLastError ( ERROR_INVALID_PARAMETER );
      return FALSE;
    }

  /* FIXME instead of always making two calls, should we use some
     sort of persistent buffer and only grow it ( requiring a 2nd
     call ) when the buffer wasn't already big enough? */
  /* first get how many window entries there are */
  SetLastError(0);
  dwCount = NtUserBuildHwndList (
    hDesktop, hWndparent, bChildren, dwThreadId, lParam, NULL, 0 );
  if ( !dwCount || GetLastError() )
    return FALSE;

  /* allocate buffer to receive HWND handles */
  hHeap = GetProcessHeap();
  pHwnd = HeapAlloc ( hHeap, 0, sizeof(HWND)*(dwCount+1) );
  if ( !pHwnd )
    {
      SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
      return FALSE;
    }

  /* now call kernel again to fill the buffer this time */
  dwCount = NtUserBuildHwndList (
    hDesktop, hWndparent, bChildren, dwThreadId, lParam, pHwnd, dwCount );
  if ( !dwCount || GetLastError() )
    {
      if ( pHwnd )
	HeapFree ( hHeap, 0, pHwnd );
      return FALSE;
    }

  /* call the user's callback function until we're done or
     they tell us to quit */
  for ( i = 0; i < dwCount; i++ )
  {
    /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
     * probably because I'm not doing it right in NtUserBuildHwndList.
     * Once that's fixed, we shouldn't have to check for a NULL HWND
     * here
     */
    if ( !(ULONG)pHwnd[i] ) /* don't enumerate a NULL HWND */
      continue;
    if ( !(*lpfn)( pHwnd[i], lParam ) )
    {
      HeapFree ( hHeap, 0, pHwnd );
      return FALSE;
    }
  }
  if ( pHwnd )
    HeapFree ( hHeap, 0, pHwnd );
  return TRUE;
}


/*
 * @implemented
 */
BOOL
STDCALL
EnumChildWindows(
	HWND hWndParent,
	WNDENUMPROC lpEnumFunc,
	LPARAM lParam)
{
  if ( !hWndParent )
    hWndParent = GetDesktopWindow();
  return User32EnumWindows ( NULL, hWndParent, lpEnumFunc, lParam, 0, FALSE );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -