return Window;
}
+PWND FASTCALL VerifyWnd(PWND pWnd)
+{
+ HWND hWnd;
+ UINT State, State2;
+
+ if (!pWnd) return NULL;
+
+ _SEH2_TRY
+ {
+ hWnd = UserHMGetHandle(pWnd);
+ State = pWnd->state;
+ State2 = pWnd->state2;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return NULL);
+ }
+ _SEH2_END
+
+ if ( UserObjectInDestroy(hWnd) ||
+ State & WNDS_DESTROYED ||
+ State2 & WNDS2_INDESTROY )
+ return NULL;
+
+ return pWnd;
+}
+
/* Temp HACK */
PWND FASTCALL UserGetWindowObject(HWND hWnd)
{
return Window;
}
+ULONG FASTCALL
+IntSetStyle( PWND pwnd, ULONG set_bits, ULONG clear_bits )
+{
+ ULONG styleOld, styleNew;
+ styleOld = pwnd->style;
+ styleNew = (pwnd->style | set_bits) & ~clear_bits;
+ if (styleNew == styleOld) return styleNew;
+ pwnd->style = styleNew;
+ if ((styleOld ^ styleNew) & WS_VISIBLE) DceResetActiveDCEs( pwnd );
+ return styleOld;
+}
/*
* IntIsWindow
{
if (Wnd->style & WS_POPUP)
{
- return Wnd->spwndOwner;
+ return Wnd->spwndOwner;
}
else if (Wnd->style & WS_CHILD)
{
if (bEnable)
{
- pWnd->style &= ~WS_DISABLED;
+ IntSetStyle( pWnd, 0, WS_DISABLED );
}
else
{
{
co_UserSetFocus(NULL);
}
- pWnd->style |= WS_DISABLED;
+ IntSetStyle( pWnd, WS_DISABLED, 0 );
}
if (Update)
return 0;
}
-VOID FASTCALL
-IntGetWindowBorderMeasures(PWND Wnd, UINT *cx, UINT *cy)
-{
- if(HAS_DLGFRAME(Wnd->style, Wnd->ExStyle) && !(Wnd->style & WS_MINIMIZE))
- {
- *cx = UserGetSystemMetrics(SM_CXDLGFRAME);
- *cy = UserGetSystemMetrics(SM_CYDLGFRAME);
- }
- else
- {
- if(HAS_THICKFRAME(Wnd->style, Wnd->ExStyle)&& !(Wnd->style & WS_MINIMIZE))
- {
- *cx = UserGetSystemMetrics(SM_CXFRAME);
- *cy = UserGetSystemMetrics(SM_CYFRAME);
- }
- else if(HAS_THINFRAME(Wnd->style, Wnd->ExStyle))
- {
- *cx = UserGetSystemMetrics(SM_CXBORDER);
- *cy = UserGetSystemMetrics(SM_CYBORDER);
- }
- else
- {
- *cx = *cy = 0;
- }
- }
-}
-
//
// Same as User32:IntGetWndProc.
//
}
}
-/*!
- * Internal function.
- * Returns client window rectangle relative to the upper-left corner of client area.
- *
- * \note Does not check the validity of the parameters
-*/
-VOID FASTCALL
-IntGetClientRect(PWND Wnd, RECTL *Rect)
-{
- ASSERT( Wnd );
- ASSERT( Rect );
- if (Wnd->style & WS_MINIMIZED)
- {
- Rect->left = Rect->top = 0;
- Rect->right = UserGetSystemMetrics(SM_CXMINIMIZED);
- Rect->bottom = UserGetSystemMetrics(SM_CYMINIMIZED);
- return;
- }
- if ( Wnd != UserGetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
- {
- *Rect = Wnd->rcClient;
- RECTL_vOffsetRect(Rect, -Wnd->rcClient.left, -Wnd->rcClient.top);
- }
- else
- {
- Rect->left = Rect->top = 0;
- Rect->right = Wnd->rcClient.right;
- Rect->bottom = Wnd->rcClient.bottom;
- /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
- Rect->right = UserGetSystemMetrics(SM_CXSCREEN);
- Rect->bottom = UserGetSystemMetrics(SM_CYSCREEN);
- */
- }
-}
-
PMENU_OBJECT FASTCALL
IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
{
}
}
-
+/*
+ Note: Wnd->spwndParent can be null if it is the desktop.
+*/
VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
{
if (hWndPrev == HWND_NOTOPMOST)
{
PWND WndOldParent, pWndExam;
BOOL WasVisible;
+ POINT pt;
+ int swFlags = SWP_NOSIZE|SWP_NOZORDER;
ASSERT(Wnd);
ASSERT(WndNewParent);
WasVisible = co_WinPosShowWindow(Wnd, SW_HIDE);
/* Window must belong to current process */
- if (Wnd->head.pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
+ if (Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process())
return NULL;
WndOldParent = Wnd->spwndParent;
+ if ( WndOldParent &&
+ WndOldParent->ExStyle & WS_EX_LAYOUTRTL)
+ pt.x = Wnd->rcWindow.right;
+ else
+ pt.x = Wnd->rcWindow.left;
+ pt.y = Wnd->rcWindow.top;
+
if (WndOldParent) UserReferenceObject(WndOldParent); /* Caller must deref */
if (WndNewParent != WndOldParent)
/* Set the new parent */
Wnd->spwndParent = WndNewParent;
+ if ( Wnd->style & WS_CHILD &&
+ Wnd->spwndOwner &&
+ Wnd->spwndOwner->ExStyle & WS_EX_TOPMOST )
+ {
+ ERR("SetParent Top Most from Pop up!\n");
+ Wnd->ExStyle |= WS_EX_TOPMOST;
+ }
+
/* Link the window with its new siblings */
- IntLinkHwnd(Wnd, HWND_TOP);
+ IntLinkHwnd( Wnd,
+ ((0 == (Wnd->ExStyle & WS_EX_TOPMOST) &&
+ WndNewParent == UserGetDesktopWindow() ) ? HWND_TOP : HWND_TOPMOST ) );
}
+ if (WndOldParent == UserGetMessageWindow() || WndNewParent == UserGetMessageWindow())
+ swFlags |= SWP_NOACTIVATE;
+
IntNotifyWinEvent(EVENT_OBJECT_PARENTCHANGE, Wnd ,OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
/*
* SetParent additionally needs to make hwnd the top window
* in the z-order and send the expected WM_WINDOWPOSCHANGING and
* WM_WINDOWPOSCHANGED notification messages.
*/
- co_WinPosSetWindowPos(Wnd, (0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
- 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE
- | (WasVisible ? SWP_SHOWWINDOW : 0));
+ co_WinPosSetWindowPos( Wnd,
+ (0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
+ pt.x, pt.y, 0, 0, swFlags);
- /*
- * FIXME: A WM_MOVE is also generated (in the DefWindowProc handler
- * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE.
- */
if (WasVisible) co_WinPosShowWindow(Wnd, SW_SHOWNORMAL);
return WndOldParent;
UserRefObjectCo(Wnd, &Ref);
UserRefObjectCo(WndParent, &ParentRef);
-
+ //ERR("Enter co_IntSetParent\n");
WndOldParent = co_IntSetParent(Wnd, WndParent);
-
+ //ERR("Leave co_IntSetParent\n");
UserDerefObjectCo(WndParent);
UserDerefObjectCo(Wnd);
* Dialog boxes and message boxes do not inherit layout, so you must
* set the layout explicitly.
*/
- if ( Class->fnid != FNID_DIALOG)
+ if ( Class->fnid != FNID_DIALOG )
{
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
if (ppi->dwLayout & LAYOUT_RTL)
pWnd->spwndParent = ParentWindow;
pWnd->spwndOwner = OwnerWindow;
pWnd->fnid = 0;
- pWnd->hWndLastActive = hWnd;
+ pWnd->spwndLastActive = pWnd;
pWnd->state2 |= WNDS2_WIN40COMPAT; // FIXME!!!
pWnd->pcls = Class;
pWnd->hModule = Cs->hInstance;
}
}
- /*
- * WS_EX_WINDOWEDGE appears to be enforced based on the other styles, so
- * why does the user get to set it?
- */
-
- if ((pWnd->ExStyle & WS_EX_DLGMODALFRAME) ||
- (pWnd->style & (WS_DLGFRAME | WS_THICKFRAME)))
- pWnd->ExStyle |= WS_EX_WINDOWEDGE;
+ /* WS_EX_WINDOWEDGE depends on some other styles */
+ if (pWnd->ExStyle & WS_EX_DLGMODALFRAME)
+ pWnd->ExStyle |= WS_EX_WINDOWEDGE;
+ else if (pWnd->style & (WS_DLGFRAME | WS_THICKFRAME))
+ {
+ if (!((pWnd->ExStyle & WS_EX_STATICEDGE) &&
+ (pWnd->style & (WS_CHILD | WS_POPUP))))
+ pWnd->ExStyle |= WS_EX_WINDOWEDGE;
+ }
else
pWnd->ExStyle &= ~WS_EX_WINDOWEDGE;
PLARGE_STRING WindowName,
PVOID acbiBuffer)
{
+ ULONG style;
PWND Window = NULL, ParentWindow = NULL, OwnerWindow;
HWND hWnd, hWndParent, hWndOwner, hwndInsertAfter;
PWINSTATION_OBJECT WinSta;
Window->rcWindow.bottom = Cs->y + Size.cy;
if (0 != (Window->style & WS_CHILD) && ParentWindow)
{
+// ERR("co_UserCreateWindowEx(): Offset rcWindow\n");
RECTL_vOffsetRect(&Window->rcWindow,
ParentWindow->rcClient.left,
ParentWindow->rcClient.top);
}
/* Show or maybe minimize or maximize the window. */
- if (Window->style & (WS_MINIMIZE | WS_MAXIMIZE))
+
+ style = IntSetStyle( Window, 0, WS_MAXIMIZE | WS_MINIMIZE );
+ if (style & (WS_MINIMIZE | WS_MAXIMIZE))
{
RECTL 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;
+ UINT SwFlag = (style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
+ SwFlag = co_WinPosMinMaximize(Window, SwFlag, &NewPos);
+ SwFlag |= SWP_NOZORDER|SWP_FRAMECHANGED; /* Frame always gets changed */
+ if (!(style & WS_VISIBLE) || (style & WS_CHILD) || UserGetActiveWindow()) SwFlag |= SWP_NOACTIVATE;
co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top,
NewPos.right, NewPos.bottom, SwFlag);
}
ASSERT_REFS_CO(Window); // FIXME: Temp HACK?
hWnd = Window->head.h;
+ ti = PsGetCurrentThreadWin32Thread();
TRACE("co_UserDestroyWindow \n");
* be destroying.
*/
if (!co_WinPosShowWindow(Window, SW_HIDE))
- {
- if (UserGetActiveWindow() == Window->head.h)
- {
+ { // Rule #1.
+ if (ti->MessageQueue->spwndActive == Window && ti->MessageQueue == IntGetFocusMessageQueue())
+ { //ERR("DestroyWindow AOW\n");
co_WinPosActivateOtherWindow(Window);
}
}
- if (Window->head.pti->MessageQueue->ActiveWindow == Window->head.h)
- Window->head.pti->MessageQueue->ActiveWindow = NULL;
- if (Window->head.pti->MessageQueue->FocusWindow == Window->head.h)
- Window->head.pti->MessageQueue->FocusWindow = NULL;
+ if (Window->head.pti->MessageQueue->spwndActive == Window)
+ Window->head.pti->MessageQueue->spwndActive = NULL;
+ if (Window->head.pti->MessageQueue->spwndFocus == Window)
+ Window->head.pti->MessageQueue->spwndFocus = NULL;
+ if (Window->head.pti->MessageQueue->spwndActivePrev == Window)
+ Window->head.pti->MessageQueue->spwndActivePrev = NULL;
if (Window->head.pti->MessageQueue->CaptureWindow == Window->head.h)
Window->head.pti->MessageQueue->CaptureWindow = NULL;
* Check if this window is the Shell's Desktop Window. If so set hShellWindow to NULL
*/
- ti = PsGetCurrentThreadWin32Thread();
-
if ((ti != NULL) & (ti->pDeskInfo != NULL))
{
if (ti->pDeskInfo->hShellWindow == hWnd)
ASSERT(Parent);
- CheckWindowName = WindowName->Length != 0;
+ CheckWindowName = WindowName->Buffer != 0;
if((List = IntWinListChildren(Parent)))
{
PWND Parent, ChildAfter;
UNICODE_STRING ClassName = {0}, WindowName = {0};
HWND Desktop, Ret = NULL;
+ BOOL DoMessageWnd = FALSE;
RTL_ATOM ClassAtom = (RTL_ATOM)0;
DECLARE_RETURN(HWND);
Desktop = IntGetCurrentThreadDesktopWindow();
if(hwndParent == NULL)
+ {
hwndParent = Desktop;
+ DoMessageWnd = TRUE;
+ }
else if(hwndParent == HWND_MESSAGE)
{
hwndParent = IntGetMessageWindow();
;
}
- CheckWindowName = WindowName.Length != 0;
+ CheckWindowName = WindowName.Buffer != 0;
/* search children */
while(*phWnd)
}
}
else
+ {
+ ERR("FindWindowEx: Not Desktop Parent!\n");
Ret = IntFindWindow(Parent, ChildAfter, ClassAtom, &WindowName);
+ }
-#if 0
-
- if(Ret == NULL && hwndParent == NULL && hwndChildAfter == NULL)
+ if (Ret == NULL && DoMessageWnd)
{
- /* FIXME: If both hwndParent and hwndChildAfter are NULL, we also should
- search the message-only windows. Should this also be done if
- Parent is the desktop window??? */
PWND MsgWindows;
if((MsgWindows = UserGetWindowObject(IntGetMessageWindow())))
Ret = IntFindWindow(MsgWindows, ChildAfter, ClassAtom, &WindowName);
}
}
-#endif
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
* -- Filip, 01/nov/2003
*/
#if 0
- co_WinPosSetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
+ co_WinPosSetWindowPos(WndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
#endif
if (WndListView->ExStyle & WS_EX_TOPMOST)
END_CLEANUP;
}
+// Fixes wine Win test_window_styles and todo tests...
+static BOOL FASTCALL
+IntCheckFrameEdge(ULONG Style, ULONG ExStyle)
+{
+ if (ExStyle & WS_EX_DLGMODALFRAME)
+ return TRUE;
+ else if (!(ExStyle & WS_EX_STATICEDGE) && (Style & (WS_DLGFRAME | WS_THICKFRAME)))
+ return TRUE;
+ else
+ return FALSE;
+}
+
LONG FASTCALL
co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
{
Style.styleOld = OldValue;
Style.styleNew = NewValue;
+ co_IntSendMessage(hWnd, WM_STYLECHANGING, GWL_EXSTYLE, (LPARAM) &Style);
+
/*
* Remove extended window style bit WS_EX_TOPMOST for shell windows.
*/
if (hWnd == WindowStation->ShellWindow || hWnd == WindowStation->ShellListView)
Style.styleNew &= ~WS_EX_TOPMOST;
}
+ /* WS_EX_WINDOWEDGE depends on some other styles */
+ if (IntCheckFrameEdge(Window->style, NewValue))
+ Style.styleNew |= WS_EX_WINDOWEDGE;
+ else
+ Style.styleNew &= ~WS_EX_WINDOWEDGE;
- co_IntSendMessage(hWnd, WM_STYLECHANGING, GWL_EXSTYLE, (LPARAM) &Style);
Window->ExStyle = (DWORD)Style.styleNew;
co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_EXSTYLE, (LPARAM) &Style);
break;
Style.styleOld = OldValue;
Style.styleNew = NewValue;
co_IntSendMessage(hWnd, WM_STYLECHANGING, GWL_STYLE, (LPARAM) &Style);
+
+ /* WS_CLIPSIBLINGS can't be reset on top-level windows */
+ if (Window->spwndParent == UserGetDesktopWindow()) Style.styleNew |= WS_CLIPSIBLINGS;
+ /* Fixes wine FIXME: changing WS_DLGFRAME | WS_THICKFRAME is supposed to change WS_EX_WINDOWEDGE too */
+ if (IntCheckFrameEdge(NewValue, Window->ExStyle))
+ Window->ExStyle |= WS_EX_WINDOWEDGE;
+ else
+ Window->ExStyle &= ~WS_EX_WINDOWEDGE;
+
Window->style = (DWORD)Style.styleNew;
co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_STYLE, (LPARAM) &Style);
break;
break;
case QUERY_WINDOW_ACTIVE:
- Result = (DWORD)pWnd->head.pti->MessageQueue->ActiveWindow;
+ Result = (DWORD)(pWnd->head.pti->MessageQueue->spwndActive ? UserHMGetHandle(pWnd->head.pti->MessageQueue->spwndActive) : 0);
break;
case QUERY_WINDOW_FOCUS:
- Result = (DWORD)pWnd->head.pti->MessageQueue->FocusWindow;
+ Result = (DWORD)(pWnd->head.pti->MessageQueue->spwndFocus ? UserHMGetHandle(pWnd->head.pti->MessageQueue->spwndFocus) : 0);
break;
case QUERY_WINDOW_ISHUNG:
Result = (DWORD)pWnd->head.pti->pEThread->Cid.UniqueProcess;
break;
+ case QUERY_WINDOW_FOREGROUND:
+ Result = (pWnd->head.pti->MessageQueue == gpqForeground);
+ break;
+
default:
Result = (DWORD)NULL;
break;