📄 window.c
字号:
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 + -