From 35b93a79d688f42613c26e423b46f6c40e496b59 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Mon, 18 Jul 2005 03:12:01 +0000 Subject: [PATCH] Implement ShowOwnedPopups and ArrangeIconicWindows. Based on Wine. svn path=/trunk/; revision=16629 --- reactos/subsys/win32k/include/window.h | 3 ++ reactos/subsys/win32k/include/winpos.h | 2 + reactos/subsys/win32k/ntuser/misc.c | 35 ++++++++++++--- reactos/subsys/win32k/ntuser/window.c | 61 ++++++++++++++++++++++++++ reactos/subsys/win32k/ntuser/winpos.c | 46 ++++++++++++++++++- 5 files changed, 140 insertions(+), 7 deletions(-) diff --git a/reactos/subsys/win32k/include/window.h b/reactos/subsys/win32k/include/window.h index 8dd0a7cd976..92220612b1a 100644 --- a/reactos/subsys/win32k/include/window.h +++ b/reactos/subsys/win32k/include/window.h @@ -228,6 +228,9 @@ DWORD IntRemoveWndProcHandle(WNDPROC Handle); DWORD IntRemoveProcessWndProcHandles(HANDLE ProcessID); DWORD IntAddWndProcHandle(WNDPROC WindowProc, BOOL IsUnicode); +BOOL FASTCALL +IntShowOwnedPopups( HWND owner, BOOL fShow ); + #endif /* _WIN32K_WINDOW_H */ /* EOF */ diff --git a/reactos/subsys/win32k/include/winpos.h b/reactos/subsys/win32k/include/winpos.h index 5d2b2c621e9..6a97e653a2d 100644 --- a/reactos/subsys/win32k/include/winpos.h +++ b/reactos/subsys/win32k/include/winpos.h @@ -14,6 +14,8 @@ NtGdiPtInRegion((WndObject)->WindowRegion, (INT)((x) - (WndObject)->WindowRect.left), \ (INT)((y) - (WndObject)->WindowRect.top)))) +UINT +FASTCALL WinPosArrangeIconicWindows(PWINDOW_OBJECT parent); BOOL FASTCALL IntGetClientOrigin(HWND hWnd, LPPOINT Point); LRESULT FASTCALL diff --git a/reactos/subsys/win32k/ntuser/misc.c b/reactos/subsys/win32k/ntuser/misc.c index 961a7aced41..dda13a615f6 100644 --- a/reactos/subsys/win32k/ntuser/misc.c +++ b/reactos/subsys/win32k/ntuser/misc.c @@ -11,7 +11,7 @@ #include -#define NDEBUG +#define DEBUG #include /* registered Logon process */ @@ -453,9 +453,32 @@ NtUserCallTwoParam( return 0; case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS: - UNIMPLEMENTED - return 0; + return (DWORD)IntShowOwnedPopups((HWND) Param1, (BOOL) Param2); + case TWOPARAM_ROUTINE_ROS_SHOWWINDOW: + { +#define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040) + PWINDOW_OBJECT Window = IntGetWindowObject((HWND)Param1); + DPRINT1("ROS_SHOWWINDOW\n"); + if (Window == 0) + { + SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + return FALSE; + } + if (Param2) + { + if (!(Window->Flags & WIN_NEEDS_SHOW_OWNEDPOPUP)) + { + IntReleaseWindowObject(Window); + return TRUE; + } + Window->Flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP; + } + else Window->Flags |= WIN_NEEDS_SHOW_OWNEDPOPUP; + DPRINT1("ROS_SHOWWINDOW ---> 0x%x\n",Window->Flags); + IntReleaseWindowObject(Window); + return TRUE; + } case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW: UNIMPLEMENTED return 0; @@ -570,6 +593,8 @@ NtUserCallTwoParam( ExFreePool(Buffer); } + + return Ret; } @@ -619,7 +644,6 @@ NtUserCallTwoParam( ExFreePool(Buffer.Pointer); } - return Ret; } @@ -630,6 +654,7 @@ NtUserCallTwoParam( return 0; } + /* * @unimplemented */ @@ -653,7 +678,7 @@ NtUserCallHwndLock( switch (Routine) { case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS: - /* FIXME */ + WinPosArrangeIconicWindows(Window); break; case HWNDLOCK_ROUTINE_DRAWMENUBAR: diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index cc8a82c416d..77f68d17760 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -4314,4 +4314,65 @@ IntRemoveProcessWndProcHandles(HANDLE ProcessID) return TRUE; } +#define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040) + +BOOL +FASTCALL +IntShowOwnedPopups( HWND owner, BOOL fShow ) +{ + int count = 0; + PWINDOW_OBJECT Window, pWnd; + HWND *win_array; + + if(!(Window = IntGetWindowObject(owner))) + { + SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + return FALSE; + } + + win_array = IntWinListChildren( Window); + IntReleaseWindowObject(Window); + + if (!win_array) return TRUE; + + while (win_array[count]) count++; + while (--count >= 0) + { + if (NtUserGetWindow( win_array[count], GW_OWNER ) != owner) continue; + if (!(pWnd = IntGetWindowObject( win_array[count] ))) continue; +// if (pWnd == WND_OTHER_PROCESS) continue; + + if (fShow) + { + if (pWnd->Flags & WIN_NEEDS_SHOW_OWNEDPOPUP) + { + IntReleaseWindowObject( pWnd ); + /* In Windows, ShowOwnedPopups(TRUE) generates + * WM_SHOWWINDOW messages with SW_PARENTOPENING, + * regardless of the state of the owner + */ + IntSendMessage(win_array[count], WM_SHOWWINDOW, SW_SHOWNORMAL, SW_PARENTOPENING); + continue; + } + } + else + { + if (pWnd->Style & WS_VISIBLE) + { + IntReleaseWindowObject( pWnd ); + /* In Windows, ShowOwnedPopups(FALSE) generates + * WM_SHOWWINDOW messages with SW_PARENTCLOSING, + * regardless of the state of the owner + */ + IntSendMessage(win_array[count], WM_SHOWWINDOW, SW_HIDE, SW_PARENTCLOSING); + continue; + } + } + IntReleaseWindowObject( pWnd ); + } + ExFreePool( win_array ); + return TRUE; +} + + /* EOF */ diff --git a/reactos/subsys/win32k/ntuser/winpos.c b/reactos/subsys/win32k/ntuser/winpos.c index e7a21d385be..4e4831f1eed 100644 --- a/reactos/subsys/win32k/ntuser/winpos.c +++ b/reactos/subsys/win32k/ntuser/winpos.c @@ -165,6 +165,47 @@ WinPosActivateOtherWindow(PWINDOW_OBJECT Window) IntReleaseWindowObject(Wnd); } + +UINT +FASTCALL +WinPosArrangeIconicWindows(PWINDOW_OBJECT parent) +{ + RECT rectParent; + HWND hwndChild; + INT i, x, y, xspacing, yspacing; + HWND *List = IntWinListChildren(parent); + + IntGetClientRect( parent, &rectParent ); + x = rectParent.left; + y = rectParent.bottom; + + xspacing = NtUserGetSystemMetrics(SM_CXMINSPACING); + yspacing = NtUserGetSystemMetrics(SM_CYMINSPACING); + + DPRINT("X:%d Y:%d XS:%d YS:%d\n",x,y,xspacing,yspacing); + + for( i = 0; List[i]; i++) + { + hwndChild = List[i]; + + if((NtUserGetWindowLong( hwndChild, GWL_STYLE, FALSE) & WS_MINIMIZE) != 0 ) + { + WinPosSetWindowPos( hwndChild, 0, x + NtUserGetSystemMetrics(SM_CXBORDER), + y - yspacing - NtUserGetSystemMetrics(SM_CYBORDER) + , 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); + if (x <= rectParent.right - xspacing) x += xspacing; + else + { + x = rectParent.left; + y -= yspacing; + } + } + } + ExFreePool(List); + return yspacing; +} + + VOID STATIC FASTCALL WinPosFindIconPos(PWINDOW_OBJECT Window, POINT *Pos) { @@ -1210,8 +1251,9 @@ WinPosShowWindow(HWND Wnd, INT Cmd) ObmDereferenceObject(Window); return(FALSE); } - Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | - SWP_NOZORDER; + Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE; + if (Window->Self != NtUserGetActiveWindow()) + Swp |= SWP_NOACTIVATE | SWP_NOZORDER; break; }