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

📄 window.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:

      lParam = MAKE_LONG(Window->ClientRect.right -
                         Window->ClientRect.left,
                         Window->ClientRect.bottom -
                         Window->ClientRect.top);
      co_IntSendMessage(Window->hSelf, WM_SIZE, SIZE_RESTORED,
                        lParam);


      DPRINT("IntCreateWindow(): About to send WM_MOVE\n");

      if (0 != (Window->Style & WS_CHILD) && ParentWindow)
      {
         lParam = MAKE_LONG(Window->ClientRect.left - ParentWindow->ClientRect.left,
                            Window->ClientRect.top - ParentWindow->ClientRect.top);
      }
      else
      {
         lParam = MAKE_LONG(Window->ClientRect.left,
                            Window->ClientRect.top);
      }


      co_IntSendMessage(Window->hSelf, WM_MOVE, 0, lParam);


      /* Call WNDOBJ change procs */
      IntEngWindowChanged(Window, WOC_RGN_CLIENT);


   }

   /* Show or maybe minimize or maximize the window. */
   if (Window->Style & (WS_MINIMIZE | WS_MAXIMIZE))
   {
      RECT NewPos;
      UINT16 SwFlag;

      SwFlag = (Window->Style & WS_MINIMIZE) ? SW_MINIMIZE :
               SW_MAXIMIZE;
      co_WinPosMinMaximize(Window, SwFlag, &NewPos);
      SwFlag =
         ((Window->Style & WS_CHILD) || UserGetActiveWindow()) ?
         SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED :
         SWP_NOZORDER | SWP_FRAMECHANGED;
      DPRINT("IntCreateWindow(): About to minimize/maximize\n");
      DPRINT("%d,%d %dx%d\n", NewPos.left, NewPos.top, NewPos.right, NewPos.bottom);
      co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top,
                            NewPos.right, NewPos.bottom, SwFlag);
   }

   /* Notify the parent window of a new child. */
   if ((Window->Style & WS_CHILD) &&
         (!(Window->ExStyle & WS_EX_NOPARENTNOTIFY)) && ParentWindow)
   {
      DPRINT("IntCreateWindow(): About to notify parent\n");
      co_IntSendMessage(ParentWindow->hSelf,
                        WM_PARENTNOTIFY,
                        MAKEWPARAM(WM_CREATE, Window->IDMenu),
                        (LPARAM)Window->hSelf);
   }

   if ((!hWndParent) && (!HasOwner))
   {
      DPRINT("Sending CREATED notify\n");
      co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)hWnd);
   }
   else
   {
      DPRINT("Not sending CREATED notify, %x %d\n", ParentWindow, HasOwner);
   }

   /* Initialize and show the window's scrollbars */
   if (Window->Style & WS_VSCROLL)
   {
      co_UserShowScrollBar(Window, SB_VERT, TRUE);
   }
   if (Window->Style & WS_HSCROLL)
   {
      co_UserShowScrollBar(Window, SB_HORZ, TRUE);
   }

   if (dwStyle & WS_VISIBLE)
   {
      DPRINT("IntCreateWindow(): About to show window\n");
      co_WinPosShowWindow(Window, dwShowMode);
   }

   DPRINT("IntCreateWindow(): = %X\n", hWnd);
   DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu);
   RETURN(hWnd);

CLEANUP:
   if (Window) UserDerefObjectCo(Window);
   if (ParentWindow) UserDerefObjectCo(ParentWindow);
   if (!_ret_ && ti != NULL)
   {
       if (Class != NULL)
       {
           IntDereferenceClass(Class,
                               ti->Desktop,
                               ti->kpi);
       }
   }
   END_CLEANUP;
}

HWND STDCALL
NtUserCreateWindowEx(DWORD dwExStyle,
                     PUNICODE_STRING UnsafeClassName,
                     PUNICODE_STRING UnsafeWindowName,
                     DWORD dwStyle,
                     LONG x,
                     LONG y,
                     LONG nWidth,
                     LONG nHeight,
                     HWND hWndParent,
                     HMENU hMenu,
                     HINSTANCE hInstance,
                     LPVOID lpParam,
                     DWORD dwShowMode,
                     BOOL bUnicodeWindow)
{
   NTSTATUS Status;
   UNICODE_STRING WindowName;
   UNICODE_STRING ClassName;
   HWND NewWindow;
   DECLARE_RETURN(HWND);

   DPRINT("Enter NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight);
   UserEnterExclusive();

   /* Get the class name (string or atom) */
   Status = MmCopyFromCaller(&ClassName, UnsafeClassName, sizeof(UNICODE_STRING));
   if (! NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN( NULL);
   }
   if (ClassName.Length != 0)
   {
      Status = IntSafeCopyUnicodeStringTerminateNULL(&ClassName, UnsafeClassName);
      if (! NT_SUCCESS(Status))
      {
         SetLastNtError(Status);
         RETURN( NULL);
      }
   }
   else if (! IS_ATOM(ClassName.Buffer))
   {
       SetLastWin32Error(ERROR_INVALID_PARAMETER);
       return NULL;
   }

   /* safely copy the window name */
   if (NULL != UnsafeWindowName)
   {
      Status = IntSafeCopyUnicodeString(&WindowName, UnsafeWindowName);
      if (! NT_SUCCESS(Status))
      {
         if (! IS_ATOM(ClassName.Buffer))
         {
            RtlFreeUnicodeString(&ClassName);
         }
         SetLastNtError(Status);
         RETURN( NULL);
      }
   }
   else
   {
      RtlInitUnicodeString(&WindowName, NULL);
   }

   NewWindow = co_IntCreateWindowEx(dwExStyle, &ClassName, &WindowName, dwStyle, x, y, nWidth, nHeight,
                                    hWndParent, hMenu, hInstance, lpParam, dwShowMode, bUnicodeWindow);

   RtlFreeUnicodeString(&WindowName);
   if (! IS_ATOM(ClassName.Buffer))
   {
      RtlFreeUnicodeString(&ClassName);
   }

   RETURN( NewWindow);

CLEANUP:
   DPRINT("Leave NtUserCreateWindowEx, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}

/*
 * @unimplemented
 */
HDWP STDCALL
NtUserDeferWindowPos(HDWP WinPosInfo,
                     HWND Wnd,
                     HWND WndInsertAfter,
                     int x,
                     int y,
                     int cx,
                     int cy,
                     UINT Flags)
{
   UNIMPLEMENTED

   return 0;
}


BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
{
   BOOLEAN isChild;

   ASSERT_REFS_CO(Window); //fixme: temp hack?

   /* Check for owner thread */
   if ((Window->OwnerThread != PsGetCurrentThread()))
   {
      SetLastWin32Error(ERROR_ACCESS_DENIED);
      return FALSE;
   }

   /* Look whether the focus is within the tree of windows we will
    * be destroying.
    */
   if (!co_WinPosShowWindow(Window, SW_HIDE))
   {
      if (UserGetActiveWindow() == Window->hSelf)
      {
         co_WinPosActivateOtherWindow(Window);
      }
   }

   if (Window->MessageQueue->ActiveWindow == Window->hSelf)
      Window->MessageQueue->ActiveWindow = NULL;
   if (Window->MessageQueue->FocusWindow == Window->hSelf)
      Window->MessageQueue->FocusWindow = NULL;
   if (Window->MessageQueue->CaptureWindow == Window->hSelf)
      Window->MessageQueue->CaptureWindow = NULL;

   IntDereferenceMessageQueue(Window->MessageQueue);
   /* Call hooks */
#if 0 /* FIXME */

   if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hwnd, 0, TRUE))
   {
      return FALSE;
   }
#endif

   IntEngWindowChanged(Window, WOC_DELETE);
   isChild = (0 != (Window->Style & WS_CHILD));

#if 0 /* FIXME */

   if (isChild)
   {
      if (! USER_IsExitingThread(GetCurrentThreadId()))
      {
         send_parent_notify(hwnd, WM_DESTROY);
      }
   }
   else if (NULL != GetWindow(Wnd, GW_OWNER))
   {
      co_HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L, TRUE );
      /* FIXME: clean up palette - see "Internals" p.352 */
   }
#endif

   if (!IntIsWindow(Window->hSelf))
   {
      return TRUE;
   }

   /* Recursively destroy owned windows */
   if (! isChild)
   {
      for (;;)
      {
         BOOL GotOne = FALSE;
         HWND *Children;
         HWND *ChildHandle;
         PWINDOW_OBJECT Child, Desktop;

         Desktop = IntIsDesktopWindow(Window) ? Window :
                   UserGetWindowObject(IntGetDesktopWindow());
         Children = IntWinListChildren(Desktop);

         if (Children)
         {
            for (ChildHandle = Children; *ChildHandle; ++ChildHandle)
            {
               Child = UserGetWindowObject(*ChildHandle);
               if (Child == NULL)
                  continue;
               if (Child->hOwner != Window->hSelf)
               {
                  continue;
               }

               if (IntWndBelongsToThread(Child, PsGetCurrentThreadWin32Thread()))
               {
                  USER_REFERENCE_ENTRY ChildRef;
                  UserRefObjectCo(Child, &ChildRef);//temp hack?
                  co_UserDestroyWindow(Child);
                  UserDerefObjectCo(Child);//temp hack?

                  GotOne = TRUE;
                  continue;
               }

               if (Child->hOwner != NULL)
               {
                  Child->hOwner = NULL;
               }

            }
            ExFreePool(Children);
         }
         if (! GotOne)
         {
            break;
         }
      }
   }

   if (!IntIsWindow(Window->hSelf))
   {
      return TRUE;
   }

   /* Destroy the window storage */
   co_UserFreeWindow(Window, PsGetCurrentProcessWin32Process(), PsGetCurrentThreadWin32Thread(), TRUE);

   return TRUE;
}




/*
 * @implemented
 */
BOOLEAN STDCALL
NtUserDestroyWindow(HWND Wnd)
{
   PWINDOW_OBJECT Window;
   DECLARE_RETURN(BOOLEAN);
   BOOLEAN ret;
   USER_REFERENCE_ENTRY Ref;

   DPRINT("Enter NtUserDestroyWindow\n");
   UserEnterExclusive();

   if (!(Window = UserGetWindowObject(Wnd)))
   {
      RETURN(FALSE);
   }

   UserRefObjectCo(Window, &Ref);//faxme: dunno if win should be reffed during destroy..
   ret = co_UserDestroyWindow(Window);
   UserDerefObjectCo(Window);//faxme: dunno if win should be reffed during destroy..

   RETURN(ret);

CLEANUP:
   DPRINT("Leave NtUserDestroyWindow, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}



/*
 * @unimplemented
 */
DWORD
STDCALL
NtUserDrawMenuBarTemp(
   HWND hWnd,
   HDC hDC,
   PRECT hRect,
   HMENU hMenu,
   HFONT hFont)
{
   /* we'll use this function just for caching the menu bar */
   UNIMPLEMENTED
   return 0;
}


/*
 * @unimplemented
 */
DWORD STDCALL
NtUserEndDeferWindowPosEx(DWORD Unknown0,
                          DWORD Unknown1)
{
   UNIMPLEMENTED

   return 0;
}


/*
 * @unimplemented
 */
DWORD STDCALL
NtUserFillWindow(DWORD Unknown0,
                 DWORD Unknown1,
                 DWORD Unknown2,
                 DWORD Unknown3)
{
   UNIMPLEMENTED

   return 0;
}


static HWND FASTCALL
IntFindWindow(PWINDOW_OBJECT Parent,
              PWINDOW_OBJECT ChildAfter,
              RTL_ATOM ClassAtom,
              PUNICODE_STRING WindowName)
{
   BOOL CheckWindowName;
   HWND *List, *phWnd;
   HWND Ret = NULL;

   ASSERT(Parent);

   CheckWindowName = WindowName->Length != 0;

   if((List = IntWinListChildren(Parent)))
   {
      phWnd = List;
      if(ChildAfter)
      {
         /* skip handles before and including ChildAfter */
         while(*phWnd && (*(phWnd++) != ChildAfter->hSelf))
            ;
      }

      /* search children */
      while(*phWnd)
      {
         PWINDOW_OBJECT Child;
         if(!(Child = UserGetWindowObject(*(phWnd++))))
         {
            continue;
         }

         /* Do not send WM_GETTEXT messages in the kernel mode version!
            The user mode version however calls GetWindowText() which will
            send WM_GETTEXT messages to windows belonging to its processes */
         if((!CheckWindowName || !RtlCompareUnicodeString(WindowName, &(Child->WindowName), TRUE)) &&
               (!ClassAtom || Child->Class->Atom == ClassAtom))
         {
            Ret = Child->hSelf;
            break;
         }

      }
      ExFreePool(List);
   }

   return Ret;
}

/*
 * FUNCTION:
 *   Searches a window's children for a window with the specified
 *   class and name
 * ARGUMENTS:
 *   hwndParent     = The window whose childs are to be searched.
 *       NULL = desktop
 *       HWND_MESSAGE = message-only windows
 *
 *   hwndChildAfter = Search starts after this child window.
 *       NULL = start from beginning
 *
 *   ucClassName    = Class name to search for
 *       Reguired parameter.
 *
 *   ucWindowName   = Window name
 *       ->Buffer == NULL = don't care
 *
 * RETURNS:
 *   The HWND of the window if it was found, otherwise NULL
 */
/*
 * @implemented

⌨️ 快捷键说明

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