*
*/
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "wine/unicode.h"
-#include "user32/regcontrol.h"
-#include <winnls.h>
-#include "wine/debug.h"
-#include "dlgs.h"
+#include <user32.h>
+#define NDEBUG
+#include <debug.h>
+
WINE_DEFAULT_DEBUG_CHANNEL(mdi);
static LRESULT WINAPI MDIClientWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
static LRESULT WINAPI MDIClientWndProcW( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
+
+static
+HWND* WIN_ListChildren (HWND hWndparent)
+{
+
+ DWORD dwCount = 0;
+ HWND* pHwnd = NULL;
+ HANDLE hHeap;
+
+ SetLastError(0);
+
+ dwCount = NtUserBuildHwndList ( NULL, hWndparent, FALSE, 0, 0, NULL, 0 );
+
+ if ( !dwCount || GetLastError() )
+ return 0;
+
+ /* allocate buffer to receive HWND handles */
+ hHeap = GetProcessHeap();
+
+ pHwnd = HeapAlloc ( hHeap, 0, sizeof(HWND)*(dwCount+1) );
+ if ( !pHwnd )
+ {
+ SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
+ return 0;
+ }
+
+ /* now call kernel again to fill the buffer this time */
+ dwCount = NtUserBuildHwndList (NULL, hWndparent, FALSE, 0, 0, pHwnd, dwCount );
+
+ if ( !dwCount || GetLastError() )
+ {
+ if ( pHwnd )
+ HeapFree ( hHeap, 0, pHwnd );
+ return 0;
+ }
+
+ return pHwnd;
+}
+
+
+
#ifdef __REACTOS__
void WINAPI ScrollChildren(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void WINAPI CalcChildScroll(HWND hwnd, INT scroll);
{
DWORD *control = (DWORD *)lParam;
if(*control == GetWindowLongW( hwnd, GWL_ID ))
- {
- *control = (DWORD)hwnd;
+ {
+ *control = (DWORD)hwnd;
return FALSE;
}
return TRUE;
{
#ifdef __REACTOS__
DWORD Control = id;
- if (hwnd && !EnumChildWindows(hwnd, (ENUMWINDOWSPROC)&MDI_GetChildByID_EnumProc, (LPARAM)&Control))
+ if (hwnd && !EnumChildWindows(hwnd, (WNDENUMPROC)&MDI_GetChildByID_EnumProc, (LPARAM)&Control))
{
return (HWND)Control;
}
#endif
}
+static BOOL is_close_enabled(HWND hwnd, HMENU hSysMenu)
+{
+ if (GetClassLongW(hwnd, GCL_STYLE) & CS_NOCLOSE) return FALSE;
+
+ if (!hSysMenu) hSysMenu = GetSystemMenu(hwnd, FALSE);
+ if (hSysMenu)
+ {
+ UINT state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
+ if (state == 0xFFFFFFFF || (state & (MF_DISABLED | MF_GRAYED)))
+ return FALSE;
+ }
+ return TRUE;
+}
+
/**********************************************************************
* MDI_MenuModifyItem
*/
if (clientInfo->nActiveChildren - 1 > MDI_MOREWINDOWSLIMIT)
{
WCHAR szTmp[50];
- LoadStringW(GetModuleHandleA("USER32"), IDS_MDI_MOREWINDOWS, szTmp, sizeof(szTmp)/sizeof(szTmp[0]));
+ LoadStringW(User32Instance, IDS_MDI_MOREWINDOWS, szTmp, sizeof(szTmp)/sizeof(szTmp[0]));
AppendMenuW(clientInfo->hWindowMenu, MF_STRING, clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT, szTmp);
}
return TRUE;
static HWND MDI_GetWindow(MDICLIENTINFO *clientInfo, HWND hWnd, BOOL bNext,
DWORD dwStyleMask )
{
-#ifdef __REACTOS__
- /* FIXME */
- return 0;
-#else
int i;
HWND *list;
HWND last = 0;
found:
HeapFree( GetProcessHeap(), 0, list );
return last;
-#endif
}
/**********************************************************************
if (ci->nActiveChildren == MDI_MOREWINDOWSLIMIT + 1)
{
WCHAR szTmp[50];
- LoadStringW(GetModuleHandleA("USER32"), IDS_MDI_MOREWINDOWS, szTmp, sizeof(szTmp)/sizeof(szTmp[0]));
+ LoadStringW(User32Instance, IDS_MDI_MOREWINDOWS, szTmp, sizeof(szTmp)/sizeof(szTmp[0]));
ModifyMenuW(ci->hWindowMenu,
ci->idFirstChild + MDI_MOREWINDOWSLIMIT,
return hbCopy;
}
+
+
+
/**********************************************************************
* MDICascade
*/
static LONG MDICascade( HWND client, MDICLIENTINFO *ci )
{
-#ifdef __REACTOS__
- /* FIXME */
- return 0;
-#else
HWND *win_array;
BOOL has_icons = FALSE;
int i, total;
+DbgPrint("MDICascade\n");
+
if (ci->hwndChildMaximized)
SendMessageA( client, WM_MDIRESTORE,
(WPARAM)ci->hwndChildMaximized, 0);
if (has_icons) ArrangeIconicWindows( client );
return 0;
-#endif
}
/**********************************************************************
*/
static void MDITile( HWND client, MDICLIENTINFO *ci, WPARAM wParam )
{
-#ifdef __REACTOS__
- /* FIXME */
- return;
-#else
HWND *win_array;
int i, total;
BOOL has_icons = FALSE;
+DbgPrint("MDITile\n");
+
if (ci->hwndChildMaximized)
SendMessageA( client, WM_MDIRESTORE, (WPARAM)ci->hwndChildMaximized, 0);
}
HeapFree( GetProcessHeap(), 0, win_array );
if (has_icons) ArrangeIconicWindows( client );
-#endif
}
/* ----------------------- Frame window ---------------------------- */
static BOOL MDI_AugmentFrameMenu( HWND frame, HWND hChild )
{
HMENU menu = GetMenu( frame );
-#ifndef __REACTOS__
- WND* child = WIN_FindWndPtr(hChild);
-#endif
HMENU hSysPopup = 0;
HBITMAP hSysMenuBitmap = 0;
+ INT nItems;
+ UINT iId;
+ HICON hIcon;
TRACE("frame %p,child %p\n",frame,hChild);
-#ifndef __REACTOS__
- if( !menu || !child->hSysMenu )
- {
- WIN_ReleaseWndPtr(child);
- return 0;
- }
- WIN_ReleaseWndPtr(child);
-#else
- if( !menu || !GetSystemMenu(hChild, FALSE) )
- {
+ if( !menu ) return 0;
+
+ /* if the system buttons already exist do not add them again */
+ nItems = GetMenuItemCount(menu) - 1;
+ iId = GetMenuItemID(menu,nItems) ;
+ if (iId == SC_RESTORE || iId == SC_CLOSE)
return 0;
- }
-#endif
/* create a copy of sysmenu popup and insert it into frame menu bar */
-
- if (!(hSysPopup = LoadMenuA(GetModuleHandleA("USER32"), "SYSMENU")))
+ if (!(hSysPopup = GetSystemMenu(hChild, FALSE)))
return 0;
- AppendMenuA(menu,MF_HELP | MF_BITMAP,
- SC_MINIMIZE, (LPSTR)(DWORD)HBMMENU_MBAR_MINIMIZE ) ;
- AppendMenuA(menu,MF_HELP | MF_BITMAP,
- SC_RESTORE, (LPSTR)(DWORD)HBMMENU_MBAR_RESTORE );
+ AppendMenuW(menu, MF_HELP | MF_BITMAP,
+ SC_MINIMIZE, (LPCWSTR)HBMMENU_MBAR_MINIMIZE ) ;
+ AppendMenuW(menu, MF_HELP | MF_BITMAP,
+ SC_RESTORE, (LPCWSTR)HBMMENU_MBAR_RESTORE );
+ AppendMenuW(menu, MF_HELP | MF_BITMAP,
+ SC_CLOSE, is_close_enabled(hChild, hSysPopup) ?
+ (LPCWSTR)HBMMENU_MBAR_CLOSE : (LPCWSTR)HBMMENU_MBAR_CLOSE_D );
- /* In Win 95 look, the system menu is replaced by the child icon */
-#ifndef __REACTOS__
- if(TWEAK_WineLook > WIN31_LOOK)
-#endif
- {
- HICON hIcon = (HICON)GetClassLongA(hChild, GCL_HICONSM);
+ /* The system menu is replaced by the child icon */
+ hIcon = (HICON)GetClassLongW(hChild, GCL_HICONSM);
if (!hIcon)
- hIcon = (HICON)GetClassLongA(hChild, GCL_HICON);
+ hIcon = (HICON)GetClassLongW(hChild, GCL_HICON);
+ if (!hIcon)
+ hIcon = LoadIconW(NULL, IDI_APPLICATION);
if (hIcon)
{
HDC hMemDC;
hSysMenuBitmap = hBitmap;
}
}
- }
-#ifndef __REACTOS__
- else
- hSysMenuBitmap = hBmpClose;
-#endif
if( !InsertMenuA(menu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP,
(UINT_PTR)hSysPopup, (LPSTR)hSysMenuBitmap))
return 0;
}
- /* The close button is only present in Win 95 look */
-#ifndef __REACTOS__
- if(TWEAK_WineLook > WIN31_LOOK)
-#endif
- {
- AppendMenuA(menu,MF_HELP | MF_BITMAP,
- SC_CLOSE, (LPSTR)(DWORD)HBMMENU_MBAR_CLOSE );
- }
-
EnableMenuItem(hSysPopup, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
*/
memset(&menuInfo, 0, sizeof(menuInfo));
menuInfo.cbSize = sizeof(menuInfo);
- menuInfo.fMask = MIIM_DATA | MIIM_TYPE;
+ menuInfo.fMask = MIIM_DATA | MIIM_TYPE | MIIM_BITMAP;
GetMenuItemInfoW(menu,
0,
RemoveMenu(menu,0,MF_BYPOSITION);
-#ifndef __REACTOS__
- if ( (menuInfo.fType & MFT_BITMAP) &&
- (LOWORD(menuInfo.dwTypeData)!=0) &&
- (LOWORD(menuInfo.dwTypeData)!=HBITMAP_16(hBmpClose)) )
- {
- DeleteObject(HBITMAP_32(LOWORD(menuInfo.dwTypeData)));
- }
-#else
- if ( (menuInfo.fType & MFT_BITMAP) &&
- (LOWORD(menuInfo.dwTypeData)!=0))
- {
- DeleteObject((HBITMAP)(LOWORD(menuInfo.dwTypeData) & 0x50000));
- }
-#endif
+ if ( menuInfo.hbmpItem != 0 )
+ DeleteObject(menuInfo.hbmpItem);
-#ifndef __REACTOS__
- if(TWEAK_WineLook > WIN31_LOOK)
-#endif
- {
- /* close */
- DeleteMenu(menu,GetMenuItemCount(menu) - 1,MF_BYPOSITION);
- }
+ /* close */
+ DeleteMenu(menu,GetMenuItemCount(menu) - 1,MF_BYPOSITION);
/* restore */
DeleteMenu(menu,GetMenuItemCount(menu) - 1,MF_BYPOSITION);
/* minimize */
{
MDICLIENTINFO *ci = NULL;
- if (WM_NCCREATE != message && WM_CREATE != message
+ if (WM_NCCREATE != message
&& NULL == (ci = get_client_info(hwnd)))
{
return 0;
SetWindowLongPtrW( hwnd, 0, (LONG_PTR)ci );
return TRUE;
#endif
-
+
case WM_CREATE:
{
RECT rect;
#ifndef __REACTOS__
WND *wndPtr = WIN_GetPtr( hwnd );
#endif
- ci = HeapAlloc(GetProcessHeap(), 0, sizeof(MDICLIENTINFO));
- if (NULL == ci)
- {
- return -1;
- }
- SetWindowLongPtr(hwnd, 0, (LONG_PTR) ci);
/* Translation layer doesn't know what's in the cs->lpCreateParams
* so we have to keep track of what environment we're in. */
if( !ci->hwndChildMaximized ) break;
switch( id )
{
+ case SC_CLOSE:
+ if (!is_close_enabled(ci->hwndActiveChild, 0)) break;
case SC_SIZE:
case SC_MOVE:
case SC_MINIMIZE:
case SC_MAXIMIZE:
case SC_NEXTWINDOW:
case SC_PREVWINDOW:
- case SC_CLOSE:
case SC_RESTORE:
return SendMessageW( ci->hwndChildMaximized, WM_SYSCOMMAND,
wParam, lParam);
case WM_SETFOCUS:
case WM_CHILDACTIVATE:
case WM_SYSCOMMAND:
-/* FIXME */
#ifndef __REACTOS__
case WM_SETVISIBLE:
#endif
+ case WM_SHOWWINDOW:
case WM_SIZE:
case WM_NEXTMENU:
case WM_SYSCHAR:
}
break;
-/* FIXME */
#ifndef __REACTOS__
case WM_SETVISIBLE:
+#endif
+ case WM_SHOWWINDOW:
if( ci->hwndChildMaximized) ci->mdiFlags &= ~MDIF_NEEDUPDATE;
else MDI_PostUpdate(client, ci, SB_BOTH+1);
break;
-#endif
case WM_SIZE:
if( ci->hwndActiveChild == hwnd && wParam != SIZE_MAXIMIZED )
break;
case VK_F4:
case VK_RBUTTON:
- wParam = SC_CLOSE;
- break;
+ if (is_close_enabled(ci->hwndActiveChild, 0))
+ {
+ wParam = SC_CLOSE;
+ break;
+ }
+ /* fall through */
default:
return 0;
}
#ifndef __REACTOS__
HWND *list;
#else
+ WINDOWINFO WindowInfo;
HWND hWndCurrent;
#endif
+ /* The rectangle returned by GetClientRect always has 0,0 as top left
+ * because it is in client coordinates. The rectangles returned by
+ * GetWindowRect are in screen coordinates to make this complicated.
+ *
+ * Apparently (in ReactOS at least) the rcClient returned by GetWindowInfo
+ * is in screen coordinates too.
+ */
GetClientRect( hwnd, &clientRect );
SetRectEmpty( &childRect );
HeapFree( GetProcessHeap(), 0, list );
}
#else
+ WindowInfo.cbSize = sizeof(WindowInfo);
+ if (!GetWindowInfo(hwnd, &WindowInfo))
+ {
+ ERR("Can't get window info\n");
+ return;
+ }
+
hWndCurrent = GetWindow(hwnd, GW_CHILD);
while (hWndCurrent != NULL)
{
RECT WindowRect;
GetWindowRect( hWndCurrent, &WindowRect );
+ OffsetRect(&WindowRect,
+ -WindowInfo.rcClient.left,
+ -WindowInfo.rcClient.top);
UnionRect( &childRect, &WindowRect, &childRect );
}
hWndCurrent = GetWindow(hWndCurrent, GW_HWNDNEXT);
/* set common info values */
info.cbSize = sizeof(info);
- info.fMask = SIF_POS | SIF_RANGE;
+ info.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
- /* set the specific */
+ /* set the specific scrollbars*/
+ /* Note how we set nPos to 0 because we scroll the clients instead of
+ * the window, and we set nPage to 1 bigger than the clientRect because
+ * otherwise the scrollbar never disables. This causes a somewhat ugly
+ * effect though while scrolling.
+ */
switch( scroll )
{
case SB_BOTH:
case SB_HORZ:
info.nMin = childRect.left;
- info.nMax = childRect.right - clientRect.right;
- info.nPos = clientRect.left - childRect.left;
- SetScrollInfo(hwnd, scroll, &info, TRUE);
+ info.nMax = childRect.right;
+ info.nPos = 0;
+ info.nPage = 1 + clientRect.right - clientRect.left;
+ SetScrollInfo(hwnd, SB_HORZ, &info, TRUE);
if (scroll == SB_HORZ) break;
/* fall through */
case SB_VERT:
info.nMin = childRect.top;
- info.nMax = childRect.bottom - clientRect.bottom;
- info.nPos = clientRect.top - childRect.top;
- SetScrollInfo(hwnd, scroll, &info, TRUE);
+ info.nMax = childRect.bottom;
+ info.nPos = 0;
+ info.nPage = 1 + clientRect.bottom - clientRect.top;
+ SetScrollInfo(hwnd, SB_VERT, &info, TRUE);
break;
}
}
{
case WM_INITDIALOG:
{
-#ifdef __REACTOS__
- /* FIXME */
- return FALSE;
-#else
UINT widest = 0;
UINT length;
UINT i;
/* Set the current selection */
SendMessageW(hListBox, LB_SETCURSEL, MDI_MOREWINDOWSLIMIT, 0);
return TRUE;
-#endif
}
case WM_COMMAND:
HRSRC hRes;
HANDLE hDlgTmpl;
- hRes = FindResourceA(GetModuleHandleA("USER32"), "MDI_MOREWINDOWS", (LPSTR)RT_DIALOG);
+ hRes = FindResourceA(User32Instance, "MDI_MOREWINDOWS", (LPSTR)RT_DIALOG);
if (hRes == 0)
return 0;
- hDlgTmpl = LoadResource(GetModuleHandleA("USER32"), hRes );
+ hDlgTmpl = LoadResource(User32Instance, hRes);
if (hDlgTmpl == 0)
return 0;
if (template == 0)
return 0;
- return (HWND) DialogBoxIndirectParamA(GetModuleHandleA("USER32"),
+ return (HWND) DialogBoxIndirectParamA(User32Instance,
(LPDLGTEMPLATE) template,
hwnd, MDI_MoreWindowsDlgProc, (LPARAM) hwnd);
}
static void MDI_SwapMenuItems(HWND parent, UINT pos1, UINT pos2)
{
-/* FIXME */
-#ifndef __REACTOS__
HWND *list;
int i;
else if (id == pos2) SetWindowLongW( list[i], GWL_ID, pos1 );
}
HeapFree( GetProcessHeap(), 0, list );
-#endif
}