Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

mdiwin.c File Reference

#include "precomp.h"

Go to the source code of this file.

Classes

struct  tagARRANGEWINDOWSDATA

Defines

#define TITLE_EXTRA   5
#define MAX_TITLE_LEN   160
#define SBJ_HORZ   HAS_SBHORZ
#define SBJ_VERT   HAS_SBVERT
#define SBJ_BOTH   (SBJ_HORZ | SBJ_VERT)

Typedefs

typedef tagARRANGEWINDOWSDATA ARRANGEWINDOWSDATA
typedef tagARRANGEWINDOWSDATAPARRANGEWINDOWSDATA

Functions

void xxxSetFrameTitle (PWND pwndFrame, PWND pwndMDI, LPWSTR lpch)
BOOL TranslateMDISysAccel (HWND hwnd, LPMSG lpMsg)
void ByteOutsetRect (LPRECT lprc)
void CalcClientScrolling (HWND hwnd, UINT sbj, BOOL fIgnoreMin)
void ScrollMDIChildren (HWND hwnd, int nCtl, UINT wCmd, int iThumbPos)
VOID ScrollChildren (HWND hwnd, UINT wMsg, DWORD wParam)
void RecalculateScrollRanges (PWND pwndParent, BOOL fIgnoreMin)
void GetCascadeWindowPos (LPCRECT prcClient, int iWindow, LPRECT lprc)
void MDICheckCascadeRect (PWND pwndClient, LPRECT lprc)
BOOL UnmaximizeChildWindows (HWND hwndParent)
WORD ArrangeWindows (HWND hwndParent, UINT flags, CONST RECT *lpRect, UINT chwnd, CONST HWND *ahwnd, MONITORENUMPROC lpfnEnum)
void GetParentArrangeRect (PARRANGEWINDOWSDATA pawd, PMONITOR pMonitor, LPRECT lprc)
PWND ValidatePositionableWindow (HWND hwndChild, PWND pwndParent, PWND pwndDesktop, DWORD dwMDIFlags, PMONITOR pMonitor, DWORD *pdwSWPFlags)
BOOL CALLBACK CascadeWindowsEnum (HMONITOR hmonitor, HDC hdc, LPRECT lprc, LPARAM lparam)
WORD CascadeWindows (HWND hwndParent, UINT flags, CONST RECT *lpRect, UINT chwnd, CONST HWND *ahwnd)
BOOL CALLBACK TileWindowsEnum (HMONITOR hmonitor, HDC hdc, LPRECT lprc, LPARAM lparam)
WORD TileWindows (HWND hwndParent, UINT flags, CONST RECT *lpRect, UINT chwnd, CONST HWND *ahwnd)
void xxxMDIActivate (PWND pwnd, PWND pwndActivate)
void xxxMDINext (PWND pwndMDI, PWND pwnd, BOOL fPrevWindow)
HWND CreateMDIWindowA (LPCSTR pClassName, LPCSTR pWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hwndParent, HINSTANCE hModule, LPARAM lParam)
HWND CreateMDIWindowW (LPCWSTR pClassName, LPCWSTR pWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hwndParent, HINSTANCE hModule, LPARAM lParam)
void xxxMDIDestroy (PWND pwnd, HWND hwndVictim)
LRESULT MDIClientWndProcWorker (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, DWORD fAnsi)
LRESULT WINAPI MDIClientWndProcA (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT WINAPI MDIClientWndProcW (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT DefFrameProcWorker (HWND hwnd, HWND hwndMDI, UINT wMsg, WPARAM wParam, LPARAM lParam, BOOL fAnsi)
LRESULT WINAPI DefFrameProcW (HWND hwnd, HWND hwndMDIClient, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT WINAPI DefFrameProcA (HWND hwnd, HWND hwndMDIClient, UINT message, WPARAM wParam, LPARAM lParam)
void ChildMinMaxInfo (PWND pwnd, PMINMAXINFO pmmi)
void xxxChildResize (PWND pwnd, UINT wMode)
LRESULT DefMDIChildProcWorker (HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam, BOOL fAnsi)
LRESULT WINAPI DefMDIChildProcW (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT WINAPI DefMDIChildProcA (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
BOOL MDICompleteChildCreation (HWND hwndChild, HMENU hSysMenu, BOOL fVisible, BOOL fDisabled)
BOOL CreateMDIChild (PSHORTCREATE psc, LPMDICREATESTRUCT pmcs, DWORD dwExpWinVerAndFlags, HMENU *phSysMenu, PWND pwndParent)


Define Documentation

#define MAX_TITLE_LEN   160
 

Definition at line 18 of file mdiwin.c.

Referenced by xxxSetFrameTitle().

#define SBJ_BOTH   (SBJ_HORZ | SBJ_VERT)
 

Definition at line 183 of file mdiwin.c.

#define SBJ_HORZ   HAS_SBHORZ
 

Definition at line 181 of file mdiwin.c.

Referenced by CalcClientScrolling(), and ScrollMDIChildren().

#define SBJ_VERT   HAS_SBVERT
 

Definition at line 182 of file mdiwin.c.

Referenced by CalcClientScrolling(), and ScrollMDIChildren().

#define TITLE_EXTRA   5
 

Definition at line 17 of file mdiwin.c.

Referenced by xxxSetFrameTitle().


Typedef Documentation

typedef struct tagARRANGEWINDOWSDATA ARRANGEWINDOWSDATA
 

typedef struct tagARRANGEWINDOWSDATA * PARRANGEWINDOWSDATA
 

Referenced by CascadeWindowsEnum(), and TileWindowsEnum().


Function Documentation

WORD ArrangeWindows HWND  hwndParent,
UINT  flags,
CONST RECT *  lpRect,
UINT  chwnd,
CONST HWND *  ahwnd,
MONITORENUMPROC  lpfnEnum
 

Definition at line 711 of file mdiwin.c.

References _GetDesktopWindow(), BuildHwndList(), tagARRANGEWINDOWSDATA::chwnd, tagARRANGEWINDOWSDATA::chwndReal, FALSE, tagARRANGEWINDOWSDATA::flags, tagARRANGEWINDOWSDATA::fVerifyParent, GRC_MINWNDS, GRC_SCROLLS, tagARRANGEWINDOWSDATA::hdwp, HW, tagARRANGEWINDOWSDATA::lprcParent, NtUserArrangeIconicWindows, NtUserBeginDeferWindowPos, NtUserEndDeferWindowPosEx(), NtUserEnumDisplayMonitors(), NULL, tagARRANGEWINDOWSDATA::phwnd, tagARRANGEWINDOWSDATA::pwndDesktop, tagARRANGEWINDOWSDATA::pwndParent, tagWND::rcClient, REBASEPWND, SYSMET, TRUE, tagARRANGEWINDOWSDATA::uGRCFlags, UnmaximizeChildWindows(), UserLocalFree, and ValidateHwnd.

Referenced by CascadeWindows(), and TileWindows().

00718 { 00719 ARRANGEWINDOWSDATA awd; 00720 HWND * phwnd = NULL; 00721 00722 /* 00723 * Get parent window 00724 */ 00725 awd.pwndDesktop = _GetDesktopWindow(); 00726 if (!hwndParent) { 00727 hwndParent = HW(awd.pwndDesktop); 00728 awd.pwndParent = awd.pwndDesktop; 00729 } else { 00730 awd.pwndParent = ValidateHwnd(hwndParent); 00731 if (awd.pwndParent == NULL) { 00732 return 0; 00733 } 00734 } 00735 00736 UnmaximizeChildWindows(hwndParent); 00737 00738 /* 00739 * If the rect passed in contains the desktop window, 00740 * arrange the windows on the desktop 00741 */ 00742 if ( lpRect && 00743 awd.pwndParent == awd.pwndDesktop && 00744 lpRect->left <= awd.pwndDesktop->rcClient.left && 00745 lpRect->top <= awd.pwndDesktop->rcClient.top && 00746 lpRect->right >= awd.pwndDesktop->rcClient.right && 00747 lpRect->bottom >= awd.pwndDesktop->rcClient.bottom ) { 00748 00749 lpRect = NULL; 00750 } 00751 00752 /* 00753 * Arrange iconic windows if appropriate, and determine flags 00754 * for getting the client rectangle if no rect is given. 00755 */ 00756 if (lpRect == NULL) { 00757 if ( ( awd.pwndParent != awd.pwndDesktop || 00758 !(SYSMET(ARRANGE) & ARW_HIDE)) && 00759 NtUserArrangeIconicWindows(hwndParent) != 0) { 00760 00761 awd.uGRCFlags = GRC_SCROLLS | GRC_MINWNDS; 00762 } else { 00763 awd.uGRCFlags = GRC_SCROLLS; 00764 } 00765 } 00766 00767 /* 00768 * Get window list 00769 */ 00770 if (ahwnd == NULL) { 00771 HWND hwndChild; 00772 PWND pwndChild; 00773 00774 pwndChild = REBASEPWND(awd.pwndParent, spwndChild); 00775 hwndChild = HW(pwndChild); 00776 if ( hwndChild == NULL || 00777 (chwnd = BuildHwndList(NULL, hwndChild, FALSE, 0, &phwnd)) == 0) { 00778 return 0; 00779 } 00780 } 00781 00782 /* 00783 * Arrange windows 00784 */ 00785 awd.hdwp = NtUserBeginDeferWindowPos(chwnd); 00786 if (awd.hdwp == NULL) 00787 goto Done; 00788 00789 awd.flags = flags; 00790 awd.lprcParent = (LPRECT) lpRect; 00791 awd.chwnd = chwnd; 00792 awd.chwndReal = 0; 00793 awd.phwnd = ahwnd ? (HWND *) ahwnd : phwnd; 00794 awd.fVerifyParent = (ahwnd != NULL); 00795 00796 /* 00797 * If the parent is the desktop and a rectangle is not provided, 00798 * arrange the windows on each monitor. Otherwise, arrange the 00799 * windows once by calling the enumeration function directly. 00800 */ 00801 if (awd.pwndParent == awd.pwndDesktop && lpRect == NULL) { 00802 NtUserEnumDisplayMonitors(NULL, NULL, lpfnEnum, (LPARAM) &awd); 00803 } else { 00804 (*lpfnEnum)(NULL, NULL, NULL, (LPARAM) &awd); 00805 } 00806 00807 /* Make this arrangement asynchronous so we don't hang */ 00808 if (awd.hdwp != NULL) { 00809 NtUserEndDeferWindowPosEx(awd.hdwp, TRUE); 00810 } 00811 00812 Done: 00813 if (phwnd) { 00814 UserLocalFree(phwnd); 00815 } 00816 00817 return (awd.hdwp != NULL) ? awd.chwndReal : 0; 00818 }

void ByteOutsetRect LPRECT  lprc  ) 
 

Definition at line 185 of file mdiwin.c.

References FAR.

Referenced by CalcClientScrolling().

00186 { 00187 int FAR *pi; 00188 int i; 00189 00190 for (i = 0, pi = (int FAR *) lprc; i < 4; i++, pi++) { 00191 if (*pi > 0) 00192 *pi += 7; 00193 else if (*pi < 0) 00194 *pi -= 7; 00195 00196 *pi /= 8; 00197 } 00198 }

void CalcClientScrolling HWND  hwnd,
UINT  sbj,
BOOL  fIgnoreMin
 

Definition at line 200 of file mdiwin.c.

References BOOL, BYTE, ByteOutsetRect(), CheckLock, ClearWindowState(), CopyRect, EqualRect, FALSE, FNID_DESKTOP, GETFNID, NtUserRedrawFrame, NtUserSetScrollInfo(), NULL, OffsetRect(), tagWND::rcClient, tagWND::rcWindow, REBASEPWND, SBJ_HORZ, SBJ_VERT, SetRectEmpty, SetWindowState(), SYSMET, TestWF, TRUE, UnionRect(), ValidateHwnd, WFHSCROLL, WFMAXIMIZED, WFMINIMIZED, WFVISIBLE, and WFVSCROLL.

Referenced by MDIClientWndProcWorker(), and ScrollMDIChildren().

00201 { 00202 PWND pwnd; 00203 RECT rcScroll; 00204 RECT rcClient; 00205 RECT rcRange; 00206 RECT rcT; 00207 PWND pwndT; 00208 BOOL fVert; 00209 BOOL fHorz; 00210 BYTE fHadVert, fHadHorz; 00211 BOOL fCheckVert; 00212 BOOL fCheckHorz; 00213 BOOL fNeedScrolls; 00214 SCROLLINFO si; 00215 00216 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 00217 return; 00218 } 00219 CheckLock(pwnd); 00220 00221 UserAssert(GETFNID(pwnd) != FNID_DESKTOP); 00222 00223 // do nothing if the parent is iconic. This way, we don't add invisible 00224 // scrollbars which will paint and unpaint when restoring... 00225 if (TestWF(pwnd, WFMINIMIZED)) 00226 return; 00227 00228 fVert = FALSE; 00229 fHorz = FALSE; 00230 fNeedScrolls=FALSE; 00231 00232 fCheckHorz = (sbj & SBJ_HORZ); 00233 fCheckVert = (sbj & SBJ_VERT); 00234 00235 // find client area without scroll bars 00236 CopyRect(&rcClient, &pwnd->rcClient); 00237 00238 fHadVert = TestWF(pwnd, WFVSCROLL); 00239 if (fCheckVert && fHadVert) 00240 rcClient.right += SYSMET(CXVSCROLL); 00241 00242 fHadHorz = TestWF(pwnd, WFHSCROLL); 00243 if (fCheckHorz && fHadHorz) 00244 rcClient.bottom += SYSMET(CYHSCROLL); 00245 00246 // find the rectangle that bounds all visible child windows 00247 SetRectEmpty(&rcScroll); 00248 00249 for (pwndT = REBASEPWND(pwnd, spwndChild); pwndT; 00250 pwndT = REBASEPWND(pwndT, spwndNext)) { 00251 if (fIgnoreMin && TestWF(pwndT, WFMINIMIZED)) 00252 continue; 00253 00254 if (TestWF(pwndT,WFVISIBLE)) { 00255 if (TestWF(pwndT, WFMAXIMIZED)) { 00256 fNeedScrolls = FALSE; 00257 break; 00258 } 00259 00260 /* 00261 * add this window to the area that has to be visible 00262 */ 00263 UnionRect(&rcScroll, &rcScroll, &pwndT->rcWindow); 00264 00265 /* 00266 * add scroll bars if its not contained in the 00267 * client area 00268 */ 00269 UnionRect(&rcT, &rcClient, &pwndT->rcWindow); 00270 if (!EqualRect(&rcClient, &rcT)) { 00271 fNeedScrolls = TRUE; 00272 } 00273 } 00274 } 00275 00276 SetRectEmpty(&rcRange); 00277 00278 // offset rectangles such that rcClient's top & left are both 0 00279 // making rcClient's right & bottom be the page size 00280 OffsetRect(&rcScroll, -rcClient.left, -rcClient.top); 00281 OffsetRect(&rcClient, -rcClient.left, -rcClient.top); 00282 00283 if (!fNeedScrolls) 00284 rcClient.bottom = rcClient.right = 0; 00285 else do 00286 { 00287 /* 00288 * the range is the union of the parent client with all of its 00289 * children 00290 */ 00291 CopyRect(&rcT, &rcRange); 00292 UnionRect(&rcRange, &rcScroll, &rcClient); 00293 00294 if (fCheckVert) { 00295 // subtract off space for the vertical scroll if we need it 00296 if (((rcRange.bottom - rcRange.top) > rcClient.bottom) && !fVert) { 00297 fVert = TRUE; 00298 rcClient.right -= SYSMET(CXVSCROLL); 00299 } 00300 } 00301 00302 if (fCheckHorz) { 00303 // subtract off space for the horizontal scroll if we need it 00304 if (((rcRange.right - rcRange.left) > rcClient.right) && !fHorz) { 00305 fHorz = TRUE; 00306 rcClient.bottom -= SYSMET(CYHSCROLL); 00307 } 00308 } 00309 } 00310 while (!EqualRect(&rcRange, &rcT)); 00311 00312 if (fNeedScrolls) { 00313 // HACK of death beginning 00314 if (rcRange.right == rcClient.right) 00315 rcRange.right -= 8; 00316 00317 if (rcRange.bottom == rcClient.bottom) 00318 rcRange.bottom -= 8; 00319 // HACK of death ending 00320 } 00321 00322 if (fCheckVert) { 00323 00324 /* 00325 * check to see if we are changing the presence of the vertical 00326 * scrollbar 00327 */ 00328 if ((rcRange.bottom - rcRange.top) <= rcClient.bottom) { 00329 ClearWindowState(pwnd, WFVSCROLL); 00330 } else { 00331 SetWindowState(pwnd, WFVSCROLL); 00332 } 00333 } 00334 00335 if (fCheckHorz) { 00336 00337 /* 00338 * same for horizontal scroll 00339 */ 00340 if ((rcRange.right - rcRange.left) <= rcClient.right) { 00341 ClearWindowState(pwnd, WFHSCROLL); 00342 } else { 00343 SetWindowState(pwnd, WFHSCROLL); 00344 } 00345 } 00346 00347 if (fNeedScrolls) { 00348 ByteOutsetRect(&rcClient); 00349 ByteOutsetRect(&rcRange); 00350 } 00351 00352 si.cbSize = sizeof(SCROLLINFO); 00353 si.fMask = SIF_ALL; 00354 si.nPos = 0; 00355 00356 si.nMin = rcRange.left; 00357 si.nMax = rcRange.right; 00358 si.nPage = rcClient.right; 00359 00360 NtUserSetScrollInfo(hwnd, SB_HORZ, &si, FALSE); 00361 00362 si.nMin = rcRange.top; 00363 si.nMax = rcRange.bottom; 00364 si.nPage = rcClient.bottom; 00365 00366 NtUserSetScrollInfo(hwnd, SB_VERT, &si, FALSE); 00367 00368 if ((fHadVert != TestWF(pwnd, WFVSCROLL)) || 00369 (fHadHorz != TestWF(pwnd, WFHSCROLL))) 00370 NtUserRedrawFrame(hwnd); 00371 }

WORD CascadeWindows HWND  hwndParent,
UINT  flags,
CONST RECT *  lpRect,
UINT  chwnd,
CONST HWND *  ahwnd
 

Definition at line 1061 of file mdiwin.c.

References ArrangeWindows(), and CascadeWindowsEnum().

Referenced by CascadeChildWindows(), and MDIClientWndProcWorker().

01067 { 01068 return ArrangeWindows(hwndParent, flags, lpRect, chwnd, ahwnd, CascadeWindowsEnum); 01069 }

BOOL CALLBACK CascadeWindowsEnum HMONITOR  hmonitor,
HDC  hdc,
LPRECT  lprc,
LPARAM  lparam
 

Definition at line 927 of file mdiwin.c.

References BOOL, BuildHwndList(), tagARRANGEWINDOWSDATA::chwnd, tagARRANGEWINDOWSDATA::chwndReal, DWORD, FALSE, tagARRANGEWINDOWSDATA::flags, tagARRANGEWINDOWSDATA::fVerifyParent, GetCascadeWindowPos(), GetParentArrangeRect(), tagARRANGEWINDOWSDATA::hdwp, HWq, NtUserDeferWindowPos(), NULL, PARRANGEWINDOWSDATA, tagARRANGEWINDOWSDATA::phwnd, tagARRANGEWINDOWSDATA::pwndDesktop, tagARRANGEWINDOWSDATA::pwndParent, REBASEPWND, TRUE, UserLocalAlloc, UserLocalFree, VALIDATEHMONITOR, and ValidatePositionableWindow().

Referenced by CascadeWindows().

00932 { 00933 PARRANGEWINDOWSDATA pawd = (PARRANGEWINDOWSDATA)lparam; 00934 PMONITOR pMonitor = hmonitor ? VALIDATEHMONITOR(hmonitor) : NULL; 00935 RECT rcParent; 00936 int i; 00937 int chwndReal = 0; 00938 RECT rc; 00939 HWND * phwnd, * phwndCopy; 00940 BOOL fRet = TRUE; 00941 00942 UNREFERENCED_PARAMETER(hdc); 00943 UNREFERENCED_PARAMETER(lprc); 00944 00945 /* 00946 * Get the parent rectangle if none is given. 00947 */ 00948 GetParentArrangeRect(pawd, pMonitor, &rcParent); 00949 00950 /* 00951 * New for NT5: MDITILE_ZORDER (for the SHELL guys) 00952 * Sort pawd->phwnd by z-order 00953 */ 00954 if (pawd->flags & MDITILE_ZORDER) { 00955 PWND pwndChild; 00956 HWND * phwndFullList, * phwndNext, * phwndSort, * phwndSearch; 00957 int chwndFullList, chwndSort, chwndSearch; 00958 /* 00959 * Make a copy to leave their array alone (it's supposed to be const) 00960 */ 00961 phwndCopy = UserLocalAlloc(0, pawd->chwnd * sizeof(HWND)); 00962 if (phwndCopy == NULL) { 00963 return FALSE; 00964 } 00965 RtlCopyMemory(phwndCopy, pawd->phwnd, pawd->chwnd * sizeof(HWND)); 00966 /* 00967 * Get the sibblings Z-Ordered list. 00968 */ 00969 pwndChild = REBASEPWND(pawd->pwndParent, spwndChild); 00970 if (pwndChild == NULL) { 00971 fRet = FALSE; 00972 goto CleanUp; 00973 } 00974 chwndFullList = BuildHwndList(NULL, HWq(pwndChild), FALSE, 0, &phwndFullList); 00975 if (chwndFullList == 0) { 00976 fRet = FALSE; 00977 goto CleanUp; 00978 } 00979 /* 00980 * Loop through the Z-Ordered list looking for the windows in the array 00981 */ 00982 for (phwndNext = phwndFullList, chwndSort = pawd->chwnd, phwndSort = phwndCopy; 00983 (chwndFullList > 0) && (chwndSort > 1); 00984 chwndFullList--, phwndNext++) { 00985 00986 for (chwndSearch = chwndSort, phwndSearch = phwndSort; 00987 chwndSearch > 0; 00988 chwndSearch--, phwndSearch++) { 00989 /* 00990 * If it found a window, move it after the last sorted window. 00991 */ 00992 if (*phwndNext == *phwndSearch) { 00993 HWND hwndFirst = *phwndSort; 00994 *phwndSort = *phwndSearch; 00995 *phwndSearch = hwndFirst; 00996 phwndSort++; 00997 chwndSort--; 00998 break; 00999 } 01000 } 01001 } 01002 UserLocalFree(phwndFullList); 01003 } else { /* if (pawd->flags & MDITILE_ZORDER) */ 01004 phwndCopy = pawd->phwnd; 01005 } 01006 01007 /* 01008 * Arrange the windows in the list, preserving z-order. 01009 */ 01010 for (i = pawd->chwnd, phwnd = phwndCopy + i - 1; --i >= 0; phwnd--) { 01011 HWND hwndChild; 01012 PWND pwndChild = NULL; 01013 DWORD dwSWPFlags; 01014 01015 hwndChild = *phwnd; 01016 pwndChild = ValidatePositionableWindow( 01017 hwndChild, 01018 pawd->fVerifyParent ? pawd->pwndParent : NULL, 01019 pawd->pwndDesktop, 01020 pawd->flags, 01021 pMonitor, 01022 &dwSWPFlags); 01023 01024 if (!pwndChild) 01025 continue; 01026 01027 GetCascadeWindowPos(&rcParent, chwndReal, &rc); 01028 01029 pawd->hdwp = NtUserDeferWindowPos( 01030 pawd->hdwp, 01031 hwndChild, 01032 HWND_TOP, 01033 rc.left, 01034 rc.top, 01035 rc.right, 01036 rc.bottom, 01037 dwSWPFlags); 01038 01039 chwndReal++; 01040 pawd->chwndReal++; 01041 } 01042 01043 CleanUp: 01044 if (pawd->flags & MDITILE_ZORDER) { 01045 UserLocalFree(phwndCopy); 01046 } 01047 01048 return fRet && (pawd->hdwp != NULL); 01049 }

void ChildMinMaxInfo PWND  pwnd,
PMINMAXINFO  pmmi
 

Definition at line 2380 of file mdiwin.c.

References _AdjustWindowRectEx(), _ScreenToClient(), CopyRect, FALSE, FNID_DESKTOP, GETFNID, tagWND::rcClient, REBASEPWND, and TestWF.

Referenced by DefMDIChildProcWorker().

02383 { 02384 PWND pwndParent = REBASEPWND(pwnd, spwndParent); 02385 RECT rc; 02386 #ifdef USE_MIRRORING 02387 int SaveLeft; 02388 #endif 02389 UserAssert(GETFNID(pwnd) != FNID_DESKTOP); 02390 02391 CopyRect(&rc, &pwndParent->rcClient); 02392 _ScreenToClient(pwndParent, (LPPOINT)&rc.left); 02393 _ScreenToClient(pwndParent, (LPPOINT)&rc.right); 02394 02395 #ifdef USE_MIRRORING 02396 /* 02397 * Swap the left and right if pwnd is a mirrored window. 02398 */ 02399 if (TestWF(pwnd,WEFLAYOUTRTL)) { 02400 SaveLeft = rc.left; 02401 rc.left = rc.right; 02402 rc.right = SaveLeft; 02403 } 02404 #endif 02405 02406 _AdjustWindowRectEx(&rc, pwnd->style, FALSE, pwnd->ExStyle); 02407 02408 /* 02409 * Position... 02410 */ 02411 pmmi->ptMaxPosition.x = rc.left; 02412 pmmi->ptMaxPosition.y = rc.top; 02413 pmmi->ptMaxSize.x = rc.right - rc.left; 02414 pmmi->ptMaxSize.y = rc.bottom - rc.top; 02415 }

BOOL CreateMDIChild PSHORTCREATE  psc,
LPMDICREATESTRUCT  pmcs,
DWORD  dwExpWinVerAndFlags,
HMENU *  phSysMenu,
PWND  pwndParent
 

Definition at line 2794 of file mdiwin.c.

References BOOL, CHILDSYSMENU, CKIDS, tagSHORTCREATE::cx, tagSHORTCREATE::cy, FALSE, FIRST, tagSHORTCREATE::hMenu, IsWindow(), L, MAXED, MDICheckCascadeRect(), NtUserMinMaximize(), NULL, PSHORTCREATE, SendMessage(), tagSHORTCREATE::style, TRUE, VER40, WS_MDIALLOWED, WS_MDISTYLE, tagSHORTCREATE::x, xxxLoadSysMenu(), and tagSHORTCREATE::y.

Referenced by _CreateWindowEx().

02800 { 02801 BOOL fVisible; 02802 RECT rcT; 02803 HMENU hSysMenu = NULL; 02804 HWND hwndPrevMaxed; 02805 PMDI pmdi; 02806 02807 /* 02808 * Get a pointer to the MDI structure 02809 */ 02810 pmdi = ((PMDIWND)(pwndParent))->pmdi; 02811 02812 pmcs->style = psc->style; 02813 02814 // Mask off ignored style bits and add required ones. 02815 psc->style |= (WS_CHILD | WS_CLIPSIBLINGS); 02816 if (!(pwndParent->style & MDIS_ALLCHILDSTYLES)) 02817 { 02818 psc->style &= WS_MDIALLOWED; 02819 psc->style |= (WS_MDISTYLE | WS_VISIBLE); 02820 } 02821 else if (psc->style & WS_POPUP) 02822 { 02823 RIPMSG0(RIP_ERROR, "CreateWindowEx: WS_POPUP not allowed on MDI children"); 02824 if (LOWORD(dwExpWinVerAndFlags) >= VER40) 02825 return FALSE; 02826 } 02827 02828 fVisible = ((psc->style & WS_VISIBLE) != 0L); 02829 02830 // 02831 // Save ORIGINAL parameters in MDICREATESTRUCT. This is for 02832 // compatibility with old WM_MDICREATE. 02833 // 02834 pmcs->x = rcT.left = psc->x; 02835 pmcs->y = rcT.top = psc->y; 02836 pmcs->cx = rcT.right = psc->cx; 02837 pmcs->cy = rcT.bottom = psc->cy; 02838 02839 MDICheckCascadeRect(pwndParent, &rcT); 02840 02841 // 02842 // Setup creation coords 02843 // 02844 psc->x = rcT.left; 02845 psc->y = rcT.top; 02846 psc->cx = rcT.right; 02847 psc->cy = rcT.bottom; 02848 02849 // Load the system menu 02850 if (psc->style & WS_SYSMENU) { 02851 hSysMenu = xxxLoadSysMenu(CHILDSYSMENU); 02852 if (hSysMenu == NULL) { 02853 return FALSE; 02854 } 02855 } 02856 02857 02858 // The window got created ok: now restore the current maximized window 02859 // so we can maximize ourself in its place. 02860 hwndPrevMaxed = MAXED(pmdi); 02861 if (fVisible && IsWindow(hwndPrevMaxed)) 02862 { 02863 if (psc->style & WS_MAXIMIZE) 02864 SendMessage(hwndPrevMaxed, WM_SETREDRAW, (WPARAM)FALSE, 0L); 02865 02866 // we could nuke the hwndPrevMaxed during the SendMessage32 02867 // so recheck just in case, B#11122, [t-arthb] 02868 02869 if ( IsWindow(hwndPrevMaxed) ) 02870 { 02871 NtUserMinMaximize(hwndPrevMaxed, SW_SHOWNORMAL, TRUE); 02872 02873 if ( psc->style & WS_MAXIMIZE ) 02874 SendMessage(hwndPrevMaxed, WM_SETREDRAW, (WPARAM)TRUE, 0L); 02875 } 02876 02877 } 02878 02879 // Set the proper Child Window ID for this MDI child. 02880 psc->hMenu = (HMENU)UIntToPtr( (FIRST(pmdi) + CKIDS(pmdi)) ); 02881 02882 *phSysMenu = hSysMenu; 02883 02884 return TRUE; 02885 }

HWND CreateMDIWindowA LPCSTR  pClassName,
LPCSTR  pWindowName,
DWORD  dwStyle,
int  x,
int  y,
int  nWidth,
int  nHeight,
HWND  hwndParent,
HINSTANCE  hModule,
LPARAM  lParam
 

Definition at line 1495 of file mdiwin.c.

References LPVOID, NULL, and WS_EX_MDICHILD.

01506 { 01507 return CreateWindowExA(WS_EX_MDICHILD, pClassName, pWindowName, 01508 dwStyle, x, y, nWidth, nHeight, 01509 hwndParent, NULL, hModule, (LPVOID)lParam); 01510 }

HWND CreateMDIWindowW LPCWSTR  pClassName,
LPCWSTR  pWindowName,
DWORD  dwStyle,
int  x,
int  y,
int  nWidth,
int  nHeight,
HWND  hwndParent,
HINSTANCE  hModule,
LPARAM  lParam
 

Definition at line 1514 of file mdiwin.c.

References LPVOID, NULL, and WS_EX_MDICHILD.

01525 { 01526 return CreateWindowExW(WS_EX_MDICHILD, pClassName, pWindowName, 01527 dwStyle, x, y, nWidth, nHeight, 01528 hwndParent, NULL, hModule, (LPVOID)lParam); 01529 }

LRESULT WINAPI DefFrameProcA HWND  hwnd,
HWND  hwndMDIClient,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 2361 of file mdiwin.c.

References DefFrameProcWorker(), and TRUE.

02367 { 02368 return DefFrameProcWorker(hwnd, hwndMDIClient, message, wParam, 02369 lParam, TRUE); 02370 }

LRESULT WINAPI DefFrameProcW HWND  hwnd,
HWND  hwndMDIClient,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 2350 of file mdiwin.c.

References DefFrameProcWorker(), and FALSE.

02356 { 02357 return DefFrameProcWorker(hwnd, hwndMDIClient, message, wParam, lParam, 02358 FALSE); 02359 }

LRESULT DefFrameProcWorker HWND  hwnd,
HWND  hwndMDI,
UINT  wMsg,
WPARAM  wParam,
LPARAM  lParam,
BOOL  fAnsi
 

Definition at line 2101 of file mdiwin.c.

References ACTIVE, BOOL, CheckLock, CKIDS, ClearWindowState(), CopyInflateRect(), DefWindowProcWorker(), DialogBoxParamA(), DialogBoxParamW(), FALSE, FindPwndChild(), FIRST, GetWindowBorders(), GetWindowPlacement, hmodUser, HW, HWq, IDD_MDI_ACTIVATE, L, LOBYTE, MAXED, MAXITEMS, MDIActivateDlgProcA(), MDIActivateDlgProcW(), NtUserGetSystemMenu(), NtUserMoveWindow(), NtUserSetFocus(), NtUserSetSysMenu, NULL, PostMessage(), REBASE, RevalidateHmenu, SendMessage(), SetWindowState(), tagWND::spmenuSys, SYSMET, TestWF, ThreadLock, ThreadUnlock, TRUE, UINT, UserLocalFree, ValidateHwnd, WFBORDERMASK, WFCAPTION, WFMAXIMIZED, WFMINBOX, WFMINIMIZED, WFSYSMENU, xxxMNCanClose(), and xxxSetFrameTitle().

Referenced by DefFrameProcA(), and DefFrameProcW().

02108 { 02109 PWND pwnd; 02110 PWND pwndMDI; 02111 PMDI pmdi; 02112 TL tlpwndT; 02113 HWND hwndT; 02114 PWND pwndT; 02115 PMDINEXTMENU pmnm; 02116 WINDOWPLACEMENT wp; 02117 02118 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 02119 return (0L); 02120 } 02121 CheckLock(pwnd); 02122 02123 if (hwndMDI == NULL) { 02124 goto CallDWP; 02125 } 02126 02127 if ((pwndMDI = ValidateHwnd(hwndMDI)) == NULL) { 02128 return (0L); 02129 } 02130 CheckLock(pwndMDI); 02131 02132 /* 02133 * Get a pointer to the MDI structure 02134 */ 02135 pmdi = ((PMDIWND)pwndMDI)->pmdi; 02136 02137 switch (wMsg) { 02138 02139 /* 02140 * If there is a maximized child window, add it's window text... 02141 */ 02142 case WM_SETTEXT: { 02143 LPWSTR lpwsz = NULL; 02144 02145 if (fAnsi && lParam) { 02146 if (!MBToWCS((LPSTR)lParam, -1, &lpwsz, -1, TRUE)) 02147 return 0; 02148 lParam = (LPARAM)lpwsz; 02149 } 02150 xxxSetFrameTitle(pwnd, pwndMDI, (LPWSTR)lParam); 02151 02152 if (lpwsz) 02153 UserLocalFree(lpwsz); 02154 break; 02155 } 02156 case WM_NCACTIVATE: 02157 SendMessage(hwndMDI, WM_NCACTIVATE, wParam, lParam); 02158 goto CallDWP; 02159 02160 case WM_COMMAND: 02161 if ((UINT)LOWORD(wParam) == (FIRST(pmdi) + MAXITEMS -1)) { 02162 02163 /* 02164 * selected the More... item 02165 */ 02166 if (fAnsi) { 02167 wParam = DialogBoxParamA(hmodUser, 02168 MAKEINTRESOURCEA(IDD_MDI_ACTIVATE), 02169 hwnd, 02170 MDIActivateDlgProcA, 02171 (LPARAM)pwndMDI); 02172 } else { 02173 wParam = DialogBoxParamW(hmodUser, 02174 MAKEINTRESOURCEW(IDD_MDI_ACTIVATE), 02175 hwnd, 02176 MDIActivateDlgProcW, 02177 (LPARAM)pwndMDI); 02178 } 02179 if ((int)wParam >= 0) { 02180 wParam += FIRST(pmdi); 02181 goto ActivateTheChild; 02182 } 02183 } else if (((UINT)LOWORD(wParam) >= FIRST(pmdi)) && 02184 ((UINT)LOWORD(wParam) < FIRST(pmdi) + CKIDS(pmdi))) { 02185 ActivateTheChild: 02186 pwndT = FindPwndChild(pwndMDI, (UINT)LOWORD(wParam)); 02187 ThreadLock(pwndT, &tlpwndT); 02188 02189 SendMessage(hwndMDI, WM_MDIACTIVATE, (WPARAM)HW(pwndT), 0L); 02190 02191 /* 02192 * if minimized, restore it. 02193 */ 02194 if (pwndT != NULL && TestWF(pwndT, WFMINIMIZED)) 02195 // 02196 // Fix for B#1510. Don't restore directly. Send child 02197 // a restore message. 02198 // 02199 SendMessage(HWq(pwndT), WM_SYSCOMMAND, (WPARAM)SC_RESTORE, 0L); 02200 ThreadUnlock(&tlpwndT); 02201 break; 02202 } 02203 02204 switch (wParam & 0xFFF0) { 02205 02206 /* 02207 * System menu commands on a maxed mdi child 02208 */ 02209 case SC_SIZE: 02210 case SC_MOVE: 02211 case SC_RESTORE: 02212 case SC_CLOSE: 02213 case SC_NEXTWINDOW: 02214 case SC_PREVWINDOW: 02215 case SC_MINIMIZE: 02216 case SC_MAXIMIZE: 02217 hwndT = MAXED(pmdi); 02218 if (hwndT != NULL) { 02219 PWND pwndT = ValidateHwnd(hwndT); 02220 if (pwndT == NULL) 02221 break; 02222 if ((wParam & 0xFFF0) == SC_CLOSE) { 02223 /* 02224 * Since the window is maxed, we've cleared WFSYSMENU (see 02225 * MDIAddSysMenu). We need to set it back here so GetSysMenuHandle 02226 * will do the right thing for _MNCanClose. 02227 */ 02228 BOOL fCanClose; 02229 UserAssert(!TestWF(pwndT, WFSYSMENU) && (pwndT->spmenuSys != NULL)); 02230 SetWindowState(pwndT, WFSYSMENU); 02231 fCanClose = xxxMNCanClose(pwndT); 02232 ClearWindowState(pwndT, WFSYSMENU); 02233 if (!fCanClose) { 02234 break; 02235 } 02236 } else if (((wParam & 0xFFF0) == SC_MINIMIZE) && !TestWF(pwndT, WFMINBOX)) { 02237 break; 02238 } 02239 02240 return SendMessage(hwndT, WM_SYSCOMMAND, wParam, lParam); 02241 } 02242 } 02243 goto CallDWP; 02244 02245 case WM_SIZE: 02246 if (wParam != SIZEICONIC) { 02247 NtUserMoveWindow(hwndMDI, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE); 02248 } else { 02249 wp.length = sizeof(WINDOWPLACEMENT); 02250 if (GetWindowPlacement(hwnd, &wp)) { 02251 RECT rcT; 02252 int clB; 02253 02254 /* 02255 * If frame is iconic, size mdi win to be size of restored 02256 * frame's client area. Thus mdi children etc created in here 02257 * use the proper mdiclient size. 02258 */ 02259 clB = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, TRUE); 02260 02261 CopyInflateRect(&rcT, &wp.rcNormalPosition, 02262 -clB*SYSMET(CXBORDER), -clB*SYSMET(CYBORDER)); 02263 02264 if (TestWF(pwnd, WFBORDERMASK) == LOBYTE(WFCAPTION)) 02265 rcT.top += SYSMET(CYCAPTION); 02266 rcT.top += SYSMET(CYMENU); 02267 02268 NtUserMoveWindow(hwndMDI, 0, 0, rcT.right-rcT.left, 02269 rcT.bottom-rcT.top, TRUE); 02270 } 02271 } 02272 goto CallDWP; 02273 02274 case WM_SETFOCUS: 02275 NtUserSetFocus(hwndMDI); 02276 break; 02277 02278 case WM_NEXTMENU: 02279 if (TestWF(pwnd, WFSYSMENU) && !TestWF(pwnd, WFMINIMIZED) && 02280 ACTIVE(pmdi) && !MAXED(pmdi)) 02281 { 02282 PMENU pmenuIn; 02283 /* 02284 * Go to child system menu by wrapping to the left from 02285 * the first popup in the menu bar or to the right from 02286 * the frame sysmenu. 02287 */ 02288 pmnm = (PMDINEXTMENU)lParam; 02289 pmenuIn = RevalidateHmenu(pmnm->hmenuIn); 02290 02291 if (pmenuIn && ((wParam == VK_LEFT && pmenuIn == REBASE(pwnd, spmenu)) || 02292 (wParam == VK_RIGHT && pmnm->hmenuIn == 02293 NtUserGetSystemMenu(hwnd, FALSE)))) { 02294 02295 HMENU hmenu; 02296 PWND pwndActive; 02297 02298 // 02299 // Make sure the window is still valid 02300 // 02301 if ((pwndActive = ValidateHwnd(ACTIVE(pmdi))) == NULL) { 02302 return 0; 02303 } 02304 02305 // 02306 // Make sure the child's system menu items are updated 02307 // (i.e. the ones are enabled/disabled) 02308 // 02309 if (!TestWF(pwndActive,WFMAXIMIZED)) { 02310 NtUserSetSysMenu(ACTIVE(pmdi)); 02311 } 02312 02313 hmenu = NtUserGetSystemMenu(ACTIVE(pmdi), FALSE); 02314 pmnm->hmenuNext = hmenu; 02315 pmnm->hwndNext = ACTIVE(pmdi); 02316 02317 return TRUE; 02318 } 02319 } 02320 02321 /* 02322 * default behaviour 02323 */ 02324 return 0L; 02325 02326 case WM_MENUCHAR: 02327 if (!TestWF(pwnd, WFMINIMIZED) && LOWORD(wParam) == TEXT('-')) { 02328 if (MAXED(pmdi)) 02329 return MAKELONG(0, 2); 02330 else if (ACTIVE(pmdi)) { 02331 PostMessage(ACTIVE(pmdi), WM_SYSCOMMAND, 02332 SC_KEYMENU, MAKELONG(TEXT('-'), 0)); 02333 return MAKELONG(0, 1); 02334 } 02335 } 02336 02337 /* 02338 ** FALL THRU ** 02339 */ 02340 02341 default: 02342 CallDWP: 02343 return DefWindowProcWorker(pwnd, wMsg, wParam, lParam, fAnsi); 02344 } 02345 02346 return 0L; 02347 }

LRESULT WINAPI DefMDIChildProcA HWND  hwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 2726 of file mdiwin.c.

References DefMDIChildProcWorker(), and TRUE.

02731 { 02732 return DefMDIChildProcWorker(hwnd, message, wParam, lParam, TRUE); 02733 }

LRESULT WINAPI DefMDIChildProcW HWND  hwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 2717 of file mdiwin.c.

References DefMDIChildProcWorker(), and FALSE.

02722 { 02723 return DefMDIChildProcWorker(hwnd, message, wParam, lParam, FALSE); 02724 }

LRESULT DefMDIChildProcWorker HWND  hwnd,
UINT  wMsg,
WPARAM  wParam,
LPARAM  lParam,
BOOL  fAnsi
 

Definition at line 2531 of file mdiwin.c.

References ACTIVE, CheckLock, ChildMinMaxInfo(), DefWindowProcWorker(), DIFFWOWHANDLE, DWORD, FALSE, FNID_MDICLIENT, GETFNID, GetMenu(), GetParent(), HW, hWnd, L, MAXED, ModifyMenuItem(), NtUserGetSystemMenu(), NULL, PostMessage(), REBASEPWND, RecalculateScrollRanges(), SAMEWOWHANDLE, SendMessage(), tagWND::spmenu, TestWF, ThreadLock, ThreadLockAlways, ThreadUnlock, TRUE, UINT, ValidateHwnd, WFMAXIMIZED, WINDOW, xxxChildResize(), xxxMDIActivate(), and xxxSetFrameTitle().

Referenced by DefMDIChildProcA(), and DefMDIChildProcW().

02537 { 02538 PWND pwnd; 02539 PWND pwndParent; 02540 PMDI pmdi; 02541 PMDINEXTMENU pmnm; 02542 HWND hwndT; 02543 PWND pwndT; 02544 TL tlpwndT; 02545 TL tlpwndParent; 02546 LRESULT lRet; 02547 02548 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 02549 return (0L); 02550 } 02551 02552 CheckLock(pwnd); 02553 02554 /* 02555 * Check to see if this is a real mdi child window 02556 */ 02557 pwndParent = REBASEPWND(pwnd, spwndParent); 02558 if (!pwndParent || GETFNID(pwndParent) != FNID_MDICLIENT) { 02559 RIPERR0(ERROR_NON_MDICHILD_WINDOW, RIP_VERBOSE, ""); 02560 return DefWindowProcWorker(pwnd, wMsg, wParam, lParam, fAnsi); 02561 } 02562 02563 /* 02564 * Get a pointer to the MDI structure, if it still exists 02565 */ 02566 pmdi = ((PMDIWND)pwndParent)->pmdi; 02567 if ((ULONG_PTR)pmdi == (ULONG_PTR)-1) { 02568 goto CallDWP; 02569 } 02570 02571 switch (wMsg) { 02572 case WM_SETFOCUS: 02573 if (DIFFWOWHANDLE(hwnd, ACTIVE(pmdi))) { 02574 ThreadLockAlways(pwndParent, &tlpwndParent); 02575 xxxMDIActivate(pwndParent, pwnd); 02576 ThreadUnlock(&tlpwndParent); 02577 } 02578 goto CallDWP; 02579 02580 case WM_NEXTMENU: 02581 02582 /* 02583 * wrap to the frame menu bar, either left to the system menu, 02584 * or right to the frame menu bar. 02585 */ 02586 pmnm = (PMDINEXTMENU)lParam; 02587 pwndT = REBASEPWND(pwndParent, spwndParent); 02588 pmnm->hwndNext = HW(pwndT); 02589 pmnm->hmenuNext = (wParam == VK_LEFT) ? 02590 NtUserGetSystemMenu(pmnm->hwndNext, FALSE) : 02591 GetMenu(pmnm->hwndNext); 02592 return TRUE; 02593 #if 0 02594 hWnd->hwndParent->hwndParent 02595 return (LONG)(((wParam == VK_LEFT) ? 02596 NtUserGetSystemMenu(HW(pwndT), FALSE): 02597 pwndT->spmenu) 02598 ); 02599 // return MAKELONG(NtUserGetSystemMenu(ACTIVE(pwndMDI), FALSE), 02600 // ACTIVE(pwndMDI)); 02601 #endif 02602 case WM_CLOSE: 02603 hwndT = GetParent(hwnd); 02604 if (hwndT != NULL) { 02605 SendMessage(hwndT, WM_MDIDESTROY, (WPARAM)hwnd, 0L); 02606 } 02607 break; 02608 02609 case WM_MENUCHAR: 02610 PostMessage(GetParent(GetParent(hwnd)), WM_SYSCOMMAND, 02611 (DWORD)SC_KEYMENU, (LONG)LOWORD(wParam)); 02612 return 0x10000; 02613 02614 case WM_SETTEXT: 02615 DefWindowProcWorker(pwnd, wMsg, wParam, lParam, fAnsi); 02616 if (WINDOW(pmdi)) 02617 ModifyMenuItem(pwnd); 02618 02619 if (TestWF(pwnd, WFMAXIMIZED)) { 02620 02621 /* 02622 * Add the child's window text to the frame since it is 02623 * maximized. But just redraw the caption so pass a 3L. 02624 */ 02625 pwndT = REBASEPWND(pwndParent, spwndParent); 02626 ThreadLock(pwndT, &tlpwndT); 02627 ThreadLock(pwndParent, &tlpwndParent); 02628 xxxSetFrameTitle(pwndT, pwndParent, (LPWSTR)3L); 02629 ThreadUnlock(&tlpwndParent); 02630 ThreadUnlock(&tlpwndT); 02631 } 02632 break; 02633 02634 case WM_GETMINMAXINFO: 02635 ChildMinMaxInfo(pwnd, (PMINMAXINFO)lParam); 02636 break; 02637 02638 case WM_SIZE: 02639 xxxChildResize(pwnd, (UINT)wParam); 02640 goto CallDWP; 02641 02642 case WM_MOVE: 02643 if (!TestWF(pwnd, WFMAXIMIZED)) 02644 RecalculateScrollRanges(pwndParent, FALSE); 02645 goto CallDWP; 02646 02647 case WM_CHILDACTIVATE: 02648 ThreadLock(pwndParent, &tlpwndParent); 02649 xxxMDIActivate(pwndParent, pwnd); 02650 ThreadUnlock(&tlpwndParent); 02651 break; 02652 02653 case WM_SYSCOMMAND: 02654 switch (wParam & 0xFFF0) { 02655 case SC_NEXTWINDOW: 02656 case SC_PREVWINDOW: 02657 hwndT = GetParent(hwnd); 02658 SendMessage(hwndT, WM_MDINEXT, (WPARAM)hwnd, 02659 (DWORD)((wParam & 0xFFF0) == SC_PREVWINDOW)); 02660 break; 02661 02662 case SC_SIZE: 02663 case SC_MOVE: 02664 if (SAMEWOWHANDLE(hwnd, MAXED(pmdi))) { 02665 02666 /* 02667 * If a maxed child gets a size or move message, blow it 02668 * off. 02669 */ 02670 break; 02671 } else 02672 goto CallDWP; 02673 02674 case SC_MAXIMIZE: 02675 if (SAMEWOWHANDLE(hwnd, MAXED(pmdi))) { 02676 02677 /* 02678 * If a maxed child gets a maximize message, forward it 02679 * to the frame. Useful if the maximized child has a 02680 * size box so that clicking on it then maximizes the 02681 * parent. 02682 */ 02683 pwndT = REBASEPWND(pwndParent, spwndParent); 02684 ThreadLock(pwndT, &tlpwndT); 02685 lRet = SendMessage(HW(pwndT), 02686 WM_SYSCOMMAND, SC_MAXIMIZE, lParam); 02687 ThreadUnlock(&tlpwndT); 02688 return lRet; 02689 } 02690 02691 /* 02692 * else fall through 02693 */ 02694 02695 default: 02696 goto CallDWP; 02697 } 02698 break; 02699 02700 default: 02701 CallDWP: 02702 return DefWindowProcWorker(pwnd, wMsg, wParam, lParam, fAnsi); 02703 } 02704 02705 return 0L; 02706 }

void GetCascadeWindowPos LPCRECT  prcClient,
int  iWindow,
LPRECT  lprc
 

Definition at line 505 of file mdiwin.c.

References SYSMET.

Referenced by CascadeWindowsEnum(), and MDICheckCascadeRect().

00509 { 00510 int cStack; 00511 int xStep, yStep; 00512 int dxClient, dyClient; 00513 00514 /* 00515 * Compute the width and breadth of the situation. 00516 */ 00517 dxClient = prcClient->right - prcClient->left; 00518 UserAssert(dxClient >= 0); 00519 dyClient = prcClient->bottom - prcClient->top; 00520 UserAssert(dyClient >= 0); 00521 00522 /* 00523 * Compute the width and breadth of the window steps. 00524 */ 00525 xStep = SYSMET(CXSIZEFRAME) + SYSMET(CXSIZE); 00526 yStep = SYSMET(CYSIZEFRAME) + SYSMET(CYSIZE); 00527 00528 /* 00529 * How many windows per stack? 00530 */ 00531 cStack = dyClient / (3 * yStep); 00532 00533 lprc->right = dxClient - (cStack * xStep); 00534 lprc->bottom = dyClient - (cStack * yStep); 00535 00536 /* 00537 * HACK!: Mod by cStack+1 and make sure no div-by-zero 00538 * exception happens. 00539 */ 00540 if (++cStack <= 0) { 00541 cStack = 1; 00542 } 00543 00544 lprc->left = prcClient->left + (iWindow % cStack) * xStep; 00545 lprc->top = prcClient->top + (iWindow % cStack) * yStep; 00546 }

void GetParentArrangeRect PARRANGEWINDOWSDATA  pawd,
PMONITOR  pMonitor,
LPRECT  lprc
 

Definition at line 833 of file mdiwin.c.

References GetPrimaryMonitor(), GetRealClientRect(), GRC_MINWNDS, tagARRANGEWINDOWSDATA::lprcParent, tagARRANGEWINDOWSDATA::pwndParent, tagARRANGEWINDOWSDATA::uGRCFlags, and UINT.

Referenced by CascadeWindowsEnum(), and TileWindowsEnum().

00834 { 00835 UINT uGRCFlags; 00836 00837 if (pawd->lprcParent) { 00838 *lprc = *pawd->lprcParent; 00839 } else { 00840 uGRCFlags = pawd->uGRCFlags; 00841 00842 /* 00843 * If icons are shown on the desktop, then they are always 00844 * shown on the primary monitor. So remove the GRC_MINWNDS 00845 * flag for monitors other than the primary. 00846 */ 00847 if (pMonitor && pMonitor != GetPrimaryMonitor()) { 00848 uGRCFlags &= ~GRC_MINWNDS; 00849 } 00850 00851 GetRealClientRect( 00852 pawd->pwndParent, lprc, uGRCFlags, pMonitor); 00853 } 00854 }

void MDICheckCascadeRect PWND  pwndClient,
LPRECT  lprc
 

Definition at line 557 of file mdiwin.c.

References CW2_USEDEFAULT, GetCascadeWindowPos(), GetRect(), GRECT_CLIENT, GRECT_CLIENTCOORDS, and ITILELEVEL.

Referenced by CreateMDIChild().

00560 { 00561 PMDI pmdi; 00562 RECT rc, rcClient; 00563 int iWindow; 00564 00565 /* 00566 * Get a pointer to the MDI structure 00567 */ 00568 pmdi = ((PMDIWND)pwndClient)->pmdi; 00569 00570 iWindow = ITILELEVEL(pmdi); 00571 00572 GetRect(pwndClient, &rcClient, GRECT_CLIENT | GRECT_CLIENTCOORDS); 00573 GetCascadeWindowPos(&rcClient, iWindow, &rc); 00574 00575 if ((lprc->right == CW_USEDEFAULT || lprc->right == CW2_USEDEFAULT) || 00576 !(lprc->right)) { 00577 lprc->right = rc.right; 00578 } 00579 00580 if ((lprc->bottom == CW_USEDEFAULT || lprc->bottom == CW2_USEDEFAULT) || 00581 !(lprc->bottom)) { 00582 lprc->bottom = rc.bottom; 00583 } 00584 00585 if (lprc->left == CW_USEDEFAULT || lprc->left == CW2_USEDEFAULT) { 00586 lprc->left = rc.left; 00587 lprc->top = rc.top; 00588 } 00589 }

LRESULT WINAPI MDIClientWndProcA HWND  hwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 2063 of file mdiwin.c.

References MDIClientWndProcWorker(), NULL, TRUE, and ValidateHwnd.

Referenced by ClientThreadSetup().

02068 { 02069 PWND pwnd; 02070 02071 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 02072 return 0; 02073 } 02074 02075 return MDIClientWndProcWorker(pwnd, message, wParam, lParam, TRUE); 02076 }

LRESULT WINAPI MDIClientWndProcW HWND  hwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 2078 of file mdiwin.c.

References FALSE, MDIClientWndProcWorker(), NULL, and ValidateHwnd.

Referenced by ClientThreadSetup(), and RW_RegisterControls().

02083 { 02084 PWND pwnd; 02085 02086 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 02087 return 0; 02088 } 02089 02090 return MDIClientWndProcWorker(pwnd, message, wParam, lParam, FALSE); 02091 }

LRESULT MDIClientWndProcWorker PWND  pwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam,
DWORD  fAnsi
 

Definition at line 1657 of file mdiwin.c.

References _AdjustWindowRectEx(), _DefSetText(), ACTIVE, BOOL, CalcClientScrolling(), CALCSCROLL, CascadeWindows(), CheckLock, CKIDS, ClearWindowState(), DefWindowProcWorker(), DWORD, FALSE, FIRST, FNID_CLEANEDUP_BIT, FNID_MDICLIENT, GetMenuItemCount(), GWLP_MDIDATA, HAS_SBHORZ, HAS_SBVERT, HTITLE, HW, HWq, IsIconic(), IsMenu(), L, MAXED, MAXITEMS, MDI, MDIRemoveSysMenu(), MDISetMenu(), NtUserArrangeIconicWindows, NtUserChildWindowFromPointEx(), NtUserDeleteMenu(), NtUserGetSystemMenu(), NtUserMoveWindow(), NtUserSetFocus(), NtUserSetWindowFNID(), NtUserSetWindowLongPtr, NtUserSetWindowPos(), NtUserShowScrollBar(), NtUserShowWindow(), NtUserUpdateClientRect, NULL, PtoH, tagWND::rcClient, REBASE, REBASEPWND, RecalculateScrollRanges(), SAMEWOWHANDLE, SCROLL, SCROLLCOUNT, ScrollMDIChildren(), SCROLLSUPPRESS, SendMessage(), TestWF, TextAlloc(), ThreadLock, ThreadLockAlways, ThreadUnlock, TileWindows(), TRUE, UINT, Unlock, UserLocalAlloc, UserLocalFree, VALIDATECLASSANDSIZE, ValidateHwnd, WFHSCROLL, WFMAXBOX, WFMAXIMIZED, WFVSCROLL, WFWIN40COMPAT, WINDOW, WS_EX_MDICHILD, tagMDI::wScroll, xxxMDIDestroy(), xxxMDINext(), and xxxSetFrameTitle().

Referenced by ClientThreadSetup(), MDIClientWndProcA(), and MDIClientWndProcW().

01663 { 01664 HWND hwnd = HWq(pwnd); 01665 HWND hwndT; 01666 PWND pwndT; 01667 TL tlpwndT; 01668 PMDI pmdi; 01669 PWND pwndParent; 01670 01671 CheckLock(pwnd); 01672 01673 VALIDATECLASSANDSIZE(pwnd, FNID_MDICLIENT); 01674 01675 /* 01676 * Get the pmdi for the given window now since we will use it a lot in 01677 * various handlers. This was stored using SetWindowLong(hwnd,4,pmdi) when 01678 * we initially created the MDI client window. 01679 */ 01680 pmdi = ((PMDIWND)pwnd)->pmdi; 01681 01682 if (pmdi == NULL) { 01683 switch (message) { 01684 case WM_MDICREATE: 01685 case WM_MDIMAXIMIZE: 01686 case WM_PARENTNOTIFY: 01687 case WM_CREATE: 01688 /* 01689 * These messages are safe to call, even when pmdi has not already 01690 * been initialized. 01691 */ 01692 break; 01693 01694 default: 01695 /* 01696 * Any message that is not listed above is not safe to call when 01697 * pmdi has not been initialized. Instead, just directly call DWP. 01698 */ 01699 goto CallDWP; 01700 } 01701 } 01702 01703 switch (message) { 01704 case WM_NCACTIVATE: 01705 01706 /* 01707 * We are changing app activation. Fix the active child's caption. 01708 */ 01709 if (ACTIVE(pmdi) != NULL) { 01710 SendMessage(ACTIVE(pmdi), WM_NCACTIVATE, wParam, lParam); 01711 } 01712 goto CallDWP; 01713 01714 case WM_MDIGETACTIVE: 01715 if (lParam != 0) { 01716 *((LPBOOL)lParam) = (MAXED(pmdi) != NULL); 01717 } 01718 01719 return (LRESULT)ACTIVE(pmdi); 01720 01721 case WM_MDIACTIVATE: 01722 hwndT = (HWND)wParam; 01723 if ((pwndT = ValidateHwnd(hwndT)) == NULL) 01724 return 0; 01725 01726 if (SAMEWOWHANDLE(hwndT, ACTIVE(pmdi))) 01727 break; 01728 01729 NtUserSetWindowPos(hwndT, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 01730 break; 01731 01732 case WM_MDICASCADE: 01733 pmdi->wScroll |= SCROLLSUPPRESS; 01734 NtUserShowScrollBar(hwnd, SB_BOTH, FALSE); 01735 01736 /* 01737 * Unmaximize any maximized window. 01738 */ 01739 #ifdef NEVER // Not in Chicago -- FritzS 01740 if (MAXED(pmdi) != NULL) { 01741 NtUserShowWindow(MAXED(pmdi), SW_SHOWNORMAL); 01742 } 01743 #endif 01744 /* 01745 * Save success/failure code to return to app 01746 */ 01747 message = (UINT)CascadeWindows(hwnd, (UINT)wParam, NULL, 0, NULL); 01748 pmdi->wScroll &= ~SCROLLCOUNT; 01749 return (LONG)message; 01750 break; 01751 01752 case WM_VSCROLL: 01753 case WM_HSCROLL: 01754 pmdi->wScroll |= SCROLLSUPPRESS; 01755 ScrollMDIChildren(hwnd, (message == WM_VSCROLL) ? SB_VERT : SB_HORZ, 01756 LOWORD(wParam), (short)(HIWORD(wParam))); 01757 pmdi->wScroll &= ~SCROLLCOUNT; 01758 break; 01759 01760 case WM_MDICREATE: 01761 { 01762 LPMDICREATESTRUCTA lpMCSA = (LPMDICREATESTRUCTA)lParam; 01763 LPMDICREATESTRUCTW lpMCSW = (LPMDICREATESTRUCTW)lParam; 01764 DWORD exStyle = WS_EX_MDICHILD; 01765 01766 /* 01767 * inherit the right.to.leftness of the parent. 01768 */ 01769 exStyle |= (pwnd->ExStyle & (WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR)); 01770 01771 if (fAnsi) { 01772 hwndT = CreateWindowExA(exStyle, lpMCSA->szClass, lpMCSA->szTitle, 01773 lpMCSA->style, lpMCSA->x, lpMCSA->y, lpMCSA->cx, lpMCSA->cy, 01774 hwnd, NULL, lpMCSA->hOwner, (LPSTR)lpMCSA->lParam); 01775 } else { 01776 hwndT = CreateWindowExW(exStyle, lpMCSW->szClass, lpMCSW->szTitle, 01777 lpMCSW->style, lpMCSW->x, lpMCSW->y, lpMCSW->cx, lpMCSW->cy, 01778 hwnd, NULL, lpMCSW->hOwner, (LPWSTR)lpMCSW->lParam); 01779 } 01780 01781 return((LRESULT)hwndT); 01782 01783 } 01784 01785 case WM_MDIDESTROY: 01786 xxxMDIDestroy(pwnd, (HWND)wParam); 01787 break; 01788 01789 case WM_MDIMAXIMIZE: 01790 hwndT = (HWND)wParam; 01791 if ((pwndT = ValidateHwnd(hwndT)) == NULL) 01792 return 0; 01793 01794 // Only maximize children with a MAXBOX. However, this introduces 01795 // backwards-compatibility issues with VB apps (see#12211) 01796 // So, we do this only for WIN40COMPAT apps and beyond. 01797 // 01798 if ((TestWF(pwndT, WFMAXBOX)) || !(TestWF(pwndT, WFWIN40COMPAT))) { 01799 NtUserShowWindow(hwndT, SW_SHOWMAXIMIZED); 01800 } 01801 break; 01802 01803 case WM_MDIRESTORE: 01804 hwndT = (HWND)wParam; 01805 if ((pwndT = ValidateHwnd(hwndT)) == NULL) 01806 return 0; 01807 01808 NtUserShowWindow(hwndT, SW_SHOWNORMAL); 01809 break; 01810 01811 case WM_MDITILE: 01812 pmdi->wScroll |= SCROLLSUPPRESS; 01813 NtUserShowScrollBar(hwnd, SB_BOTH, FALSE); 01814 01815 /* 01816 * Unmaximize any maximized window. 01817 */ 01818 #ifdef NEVER //Not in Chicago 01819 if (MAXED(pmdi) != NULL) { 01820 NtUserShowWindow(MAXED(pmdi), SW_SHOWNORMAL); 01821 } 01822 #endif 01823 /* 01824 * Save success/failure code to return to app 01825 */ 01826 message = (UINT)TileWindows(hwnd, (UINT)wParam, NULL, 0, NULL); 01827 pmdi->wScroll &= ~SCROLLCOUNT; 01828 return (LONG)message; 01829 break; 01830 01831 case WM_MDIICONARRANGE: 01832 pmdi->wScroll |= SCROLLSUPPRESS; 01833 NtUserArrangeIconicWindows(hwnd); 01834 pmdi->wScroll &= ~SCROLLCOUNT; 01835 RecalculateScrollRanges(pwnd, TRUE); 01836 break; 01837 01838 case WM_MDINEXT: 01839 if (wParam) { 01840 hwndT = (HWND)wParam; 01841 } else { 01842 hwndT = ACTIVE(pmdi); 01843 } 01844 01845 if ((pwndT = ValidateHwnd(hwndT)) == NULL) { 01846 return 0; 01847 } 01848 01849 /* 01850 * If lParam is 1, do a prev window instead of a next window 01851 */ 01852 ThreadLockAlways(pwndT, &tlpwndT); 01853 xxxMDINext(pwnd, pwndT, (lParam == 0 ? 0 : 1)); 01854 ThreadUnlock(&tlpwndT); 01855 break; 01856 01857 case WM_MDIREFRESHMENU: 01858 return (LRESULT)MDISetMenu(pwnd, TRUE, NULL, NULL); 01859 01860 case WM_MDISETMENU: 01861 return (LRESULT)MDISetMenu(pwnd, FALSE, (HMENU)wParam, (HMENU)lParam); 01862 01863 case WM_PARENTNOTIFY: 01864 if (wParam == WM_LBUTTONDOWN) { 01865 HWND hwndChild; 01866 POINT pt; 01867 01868 #ifdef USE_MIRRORING 01869 if ((pwndT = ValidateHwnd(hwnd)) == NULL) 01870 return 0; 01871 #endif 01872 01873 /* 01874 * Activate this child and bring it to the top. 01875 */ 01876 pt.x = (int)MAKEPOINTS(lParam).x; 01877 pt.y = (int)MAKEPOINTS(lParam).y; 01878 01879 #ifdef USE_MIRRORING 01880 /* 01881 * Since pt is relative to the client MDI window, 01882 * then the points should be mirrored if the MDI 01883 * client window is mirrored so that Scrren Coord 01884 * calculations are done properly in NtUserChildWindowFromPointEx. 01885 * [samera] 01886 */ 01887 if (TestWF(pwndT,WEFLAYOUTRTL)) { 01888 pt.x = (pwndT->rcClient.right-pwndT->rcClient.left)-pt.x; 01889 } 01890 #endif 01891 01892 hwndChild = NtUserChildWindowFromPointEx(hwnd, pt, 01893 CWP_SKIPDISABLED | CWP_SKIPINVISIBLE); 01894 01895 if ((hwndChild) && (hwndChild != hwnd)) { 01896 01897 if (hwndChild != ACTIVE(pmdi)) { 01898 NtUserSetWindowPos(hwndChild, HWND_TOP, 0, 0, 0, 0, 01899 SWP_NOMOVE | SWP_NOSIZE); 01900 } 01901 } 01902 } 01903 break; 01904 01905 case WM_SETFOCUS: 01906 if (ACTIVE(pmdi) != NULL && !IsIconic(ACTIVE(pmdi))) { 01907 NtUserSetFocus(ACTIVE(pmdi)); 01908 } 01909 break; 01910 01911 case WM_SIZE: 01912 if (ACTIVE(pmdi) && (pwndT = ValidateHwnd(ACTIVE(pmdi))) && 01913 TestWF(pwndT, WFMAXIMIZED)) { 01914 01915 RECT rc; 01916 01917 rc.top = rc.left = 0; 01918 rc.right = (int)MAKEPOINTS(lParam).x; 01919 rc.bottom = (int)MAKEPOINTS(lParam).y; 01920 _AdjustWindowRectEx(&rc, pwndT->style, FALSE, 01921 pwndT->ExStyle); 01922 NtUserMoveWindow(ACTIVE(pmdi), rc.left, rc.top, 01923 rc.right - rc.left, rc.bottom - rc.top, TRUE); 01924 } else { 01925 RecalculateScrollRanges(pwnd, FALSE); 01926 } 01927 goto CallDWP; 01928 01929 case MM_CALCSCROLL: { 01930 01931 if (SCROLL(pmdi) & SCROLLCOUNT) 01932 break; 01933 01934 { 01935 WORD sbj = pmdi->wScroll & (HAS_SBVERT | HAS_SBHORZ); 01936 01937 if (sbj) 01938 { 01939 CalcClientScrolling(hwnd, sbj, (BOOL) wParam); 01940 01941 SCROLL(pmdi) &= ~CALCSCROLL; 01942 } 01943 } 01944 break; 01945 } 01946 01947 case WM_CREATE: { 01948 LPCLIENTCREATESTRUCT pccs = ((LPCREATESTRUCT)lParam)->lpCreateParams; 01949 01950 /* 01951 * Try to allocate space for the pmdi 01952 */ 01953 if ((pmdi = (PMDI)UserLocalAlloc(HEAP_ZERO_MEMORY, sizeof(MDI)))) { 01954 NtUserSetWindowLongPtr(hwnd, GWLP_MDIDATA, (LONG_PTR)pmdi, FALSE); 01955 } else { 01956 NtUserSetWindowFNID(hwnd, FNID_CLEANEDUP_BIT); 01957 break; 01958 } 01959 01960 pwndParent = REBASEPWND(pwnd, spwndParent); 01961 ACTIVE(pmdi) = NULL; 01962 MAXED(pmdi) = NULL; 01963 CKIDS(pmdi) = 0; 01964 WINDOW(pmdi) = pccs->hWindowMenu; 01965 01966 FIRST(pmdi) = pccs->idFirstChild; 01967 SCROLL(pmdi) = 0; 01968 HTITLE(pmdi) = TextAlloc(REBASE(pwndParent, strName.Buffer)); 01969 01970 _DefSetText(HW(pwndParent), NULL, FALSE); 01971 01972 ThreadLock(pwndParent, &tlpwndT); 01973 xxxSetFrameTitle(pwndParent, pwnd, (LPWSTR)2L); 01974 ThreadUnlock(&tlpwndT); 01975 01976 if (TestWF(pwnd, WFVSCROLL)) 01977 SCROLL(pmdi) |= HAS_SBVERT; 01978 if (TestWF(pwnd, WFHSCROLL)) 01979 SCROLL(pmdi) |= HAS_SBHORZ; 01980 if (SCROLL(pmdi)) { 01981 ClearWindowState(pwnd, WFVSCROLL | WFHSCROLL); 01982 } 01983 01984 /* 01985 * Set this dude's system menu. 01986 */ 01987 NtUserGetSystemMenu(HW(pwndParent), FALSE); 01988 01989 /* 01990 * make sure we have the correct window client area if scrolls are 01991 * removed... hack to take care of small progman bug 01992 */ 01993 if (SCROLL(pmdi)) { 01994 NtUserUpdateClientRect(hwnd); 01995 } 01996 break; 01997 } 01998 01999 case WM_DESTROY: 02000 case WM_FINALDESTROY: 02001 if (MAXED(pmdi)) { 02002 PWND pwndParent; 02003 PMENU pmenu; 02004 02005 pwndParent = REBASEPWND(pwnd, spwndParent); 02006 pmenu = REBASE(pwndParent, spmenu); 02007 MDIRemoveSysMenu(PtoH(pmenu), MAXED(pmdi)); 02008 } 02009 02010 /* 02011 * delete the title 02012 */ 02013 if (HTITLE(pmdi)) { 02014 UserLocalFree(HTITLE(pmdi)); 02015 HTITLE(pmdi) = NULL; 02016 } 02017 02018 /* 02019 * Delete the menu items of the child windows in the frame. 02020 * Chances are, this is called by destroying the frame, but 02021 * one never knows, does one? 02022 * 02023 * Increase CKIDS by 1 after checking to delete the separator 02024 */ 02025 if (IsMenu(WINDOW(pmdi)) && CKIDS(pmdi)++) { 02026 UINT iPosition; 02027 02028 if (CKIDS(pmdi) > MAXITEMS + 1) 02029 CKIDS(pmdi) = MAXITEMS + 1; 02030 02031 iPosition = GetMenuItemCount(WINDOW(pmdi)); 02032 while (CKIDS(pmdi)--) { 02033 NtUserDeleteMenu(WINDOW(pmdi), --iPosition, MF_BYPOSITION); 02034 } 02035 } 02036 02037 /* 02038 * Unlock those objects that are used by the MDI structure. 02039 */ 02040 Unlock(&MAXED(pmdi)); 02041 Unlock(&ACTIVE(pmdi)); 02042 Unlock(&WINDOW(pmdi)); 02043 02044 /* 02045 * Free the MDI structure 02046 */ 02047 UserLocalFree(pmdi); 02048 NtUserSetWindowFNID(hwnd, FNID_CLEANEDUP_BIT); 02049 02050 break; 02051 02052 default: 02053 CallDWP: 02054 return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi); 02055 } 02056 return 0L; 02057 }

BOOL MDICompleteChildCreation HWND  hwndChild,
HMENU  hSysMenu,
BOOL  fVisible,
BOOL  fDisabled
 

Definition at line 2735 of file mdiwin.c.

References ACTIVE, BOOL, CKIDS, FALSE, HW, HWq, ITILELEVEL, L, MAXITEMS, MDIAddSysMenu(), NtUserDestroyMenu(), NtUserRedrawFrame, NtUserSetSystemMenu(), NtUserSetWindowPos(), NtUserShowWindow(), PtoH, REBASE, REBASEPWND, SendMessage(), tagWND::spmenuSys, TestWF, TRUE, ValidateHwnd, WFMAXIMIZED, and WFMINIMIZED.

Referenced by _CreateWindowEx().

02735 { 02736 PWND pwndChild; 02737 PWND pwndClient; 02738 HWND hwndClient; 02739 BOOL fHasOwnSysMenu; 02740 PMDI pmdi; 02741 02742 pwndChild = ValidateHwnd(hwndChild); 02743 pwndClient = REBASEPWND(pwndChild,spwndParent); 02744 hwndClient = HWq(pwndClient); 02745 02746 fHasOwnSysMenu = (pwndChild->spmenuSys) ? TRUE : FALSE; 02747 02748 pmdi = ((PMDIWND)(pwndClient))->pmdi; 02749 02750 CKIDS(pmdi)++; 02751 ITILELEVEL(pmdi)++; 02752 if (ITILELEVEL(pmdi) > 0x7ffe) 02753 ITILELEVEL(pmdi) = 0; 02754 02755 // Update "Window" menu if this new window should be on it 02756 if (fVisible && !fDisabled && (CKIDS(pmdi) <= MAXITEMS)) 02757 SendMessage(hwndClient, WM_MDIREFRESHMENU, 0, 0L); 02758 02759 // 02760 // Add the MDI System Menu. Catch the case of not being able to add a 02761 // system menu (EG, guy doesn't have WS_SYSMENU style), and delete the 02762 // menu to avoid buildup in USER's heap. 02763 // 02764 if (hSysMenu && (fHasOwnSysMenu || !NtUserSetSystemMenu(hwndChild, hSysMenu))) 02765 NtUserDestroyMenu(hSysMenu); 02766 02767 if (fVisible) 02768 { 02769 if (!TestWF(pwndChild, WFMINIMIZED) || !ACTIVE(pmdi)) 02770 { 02771 NtUserSetWindowPos(hwndChild, HWND_TOP, 0, 0, 0, 0, 02772 SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); 02773 02774 if (TestWF(pwndChild, WFMAXIMIZED) && !fHasOwnSysMenu) 02775 { 02776 PWND pwndParent = REBASEPWND(pwndClient, spwndParent); 02777 PMENU pmenu = REBASE(pwndParent, spmenu); 02778 MDIAddSysMenu(PtoH(pmenu), hwndChild); 02779 NtUserRedrawFrame(HW(pwndParent)); 02780 } 02781 } 02782 else 02783 { 02784 NtUserShowWindow(hwndChild, SW_SHOWMINNOACTIVE); 02785 } 02786 } 02787 02788 02789 return TRUE; 02790 }

void RecalculateScrollRanges PWND  pwndParent,
BOOL  fIgnoreMin
 

Definition at line 483 of file mdiwin.c.

References CALCSCROLL, HWq, L, PostMessage(), SCROLL, and SCROLLCOUNT.

Referenced by DefMDIChildProcWorker(), MDIClientWndProcWorker(), xxxChildResize(), and xxxMDIDestroy().

00486 { 00487 PMDI pmdi = ((PMDIWND)pwndParent)->pmdi; 00488 00489 if (!(SCROLL(pmdi) & (CALCSCROLL | SCROLLCOUNT))) { 00490 if (PostMessage(HWq(pwndParent), MM_CALCSCROLL, fIgnoreMin, 0L)) { 00491 SCROLL(pmdi) |= CALCSCROLL; 00492 } 00493 } 00494 }

VOID ScrollChildren HWND  hwnd,
UINT  wMsg,
DWORD  wParam
 

Definition at line 463 of file mdiwin.c.

References ScrollMDIChildren(), and VOID().

00467 { 00468 ScrollMDIChildren(hwnd, 00469 wMsg == WM_VSCROLL ? SB_VERT : SB_HORZ, 00470 LOWORD(wParam), 00471 (short)(HIWORD(wParam))); 00472 }

void ScrollMDIChildren HWND  hwnd,
int  nCtl,
UINT  wCmd,
int  iThumbPos
 

Definition at line 383 of file mdiwin.c.

References CalcClientScrolling(), FALSE, GetScrollInfo(), NtUserScrollWindowEx(), NULL, SBJ_HORZ, SBJ_VERT, SetScrollPos(), SYSMET, and TRUE.

Referenced by MDIClientWndProcWorker(), and ScrollChildren().

00388 { 00389 SCROLLINFO si; 00390 int wInc; 00391 int wNewPos; 00392 //SHORT sPos; 00393 int x, y; 00394 00395 wInc = (((nCtl == SB_VERT) ? SYSMET(CYSIZE) : SYSMET(CXSIZE)) + 7) / 8; 00396 00397 si.cbSize = sizeof(SCROLLINFO); 00398 si.fMask = SIF_ALL; 00399 GetScrollInfo(hwnd, nCtl, &si); 00400 00401 si.nPage--; 00402 si.nMax -= si.nPage; 00403 00404 switch (wCmd) { 00405 case SB_BOTTOM: 00406 wNewPos = si.nMax; 00407 break; 00408 case SB_TOP: 00409 wNewPos = si.nMin; 00410 break; 00411 case SB_LINEDOWN: 00412 wNewPos = si.nPos + wInc; 00413 break; 00414 case SB_LINEUP: 00415 wNewPos = si.nPos - wInc; 00416 break; 00417 case SB_PAGEDOWN: 00418 wNewPos = si.nPos + si.nPage; 00419 break; 00420 case SB_PAGEUP: 00421 wNewPos = si.nPos - si.nPage; 00422 break; 00423 case SB_THUMBPOSITION: 00424 00425 wNewPos = iThumbPos; 00426 break; 00427 case SB_ENDSCROLL: 00428 CalcClientScrolling(hwnd, (nCtl == SB_VERT) ? SBJ_VERT : SBJ_HORZ, FALSE); 00429 00430 /* 00431 ** FALL THRU ** 00432 */ 00433 default: 00434 return; 00435 } 00436 00437 if (wNewPos < si.nMin) 00438 wNewPos = si.nMin; 00439 else if (wNewPos > si.nMax) 00440 wNewPos = si.nMax; 00441 00442 SetScrollPos(hwnd, nCtl, wNewPos, TRUE); 00443 00444 // the "* 8" is because we need to scroll in bytes. The scrollbar 00445 // increments for MDI are bytes (this is due to the fact that we need to 00446 // not upset the brush origin of the app workspace brush that is used to 00447 // fill the MDI background) 00448 00449 x = (si.nPos - wNewPos) * 8; 00450 00451 if (nCtl == SB_VERT) { 00452 y = x; 00453 x = 0; 00454 } else 00455 // x is already set properly for this case 00456 y = 0; 00457 00458 NtUserScrollWindowEx(hwnd, x, y, NULL, NULL, NULL, NULL, 00459 SW_SCROLLWINDOW | SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN); 00460 }

WORD TileWindows HWND  hwndParent,
UINT  flags,
CONST RECT *  lpRect,
UINT  chwnd,
CONST HWND *  ahwnd
 

Definition at line 1217 of file mdiwin.c.

References ArrangeWindows(), and TileWindowsEnum().

Referenced by MDIClientWndProcWorker(), and TileChildWindows().

01223 { 01224 return ArrangeWindows(hwndParent, flags, lpRect, chwnd, ahwnd, TileWindowsEnum); 01225 }

BOOL CALLBACK TileWindowsEnum HMONITOR  hmonitor,
HDC  hdc,
LPRECT  lprc,
LPARAM  lparam
 

Definition at line 1072 of file mdiwin.c.

References tagARRANGEWINDOWSDATA::chwnd, tagARRANGEWINDOWSDATA::chwndReal, DWORD, FALSE, tagARRANGEWINDOWSDATA::flags, tagARRANGEWINDOWSDATA::fVerifyParent, GetParentArrangeRect(), tagARRANGEWINDOWSDATA::hdwp, NtUserDeferWindowPos(), NULL, PARRANGEWINDOWSDATA, tagARRANGEWINDOWSDATA::phwnd, tagARRANGEWINDOWSDATA::pwndDesktop, tagARRANGEWINDOWSDATA::pwndParent, TRUE, VALIDATEHMONITOR, and ValidatePositionableWindow().

Referenced by TileWindows().

01077 { 01078 PARRANGEWINDOWSDATA pawd = (PARRANGEWINDOWSDATA)lparam; 01079 PMONITOR pMonitor = hmonitor ? VALIDATEHMONITOR(hmonitor) : NULL; 01080 RECT rcParent; 01081 int ihwnd; 01082 int chwndReal; 01083 int square; 01084 int iCol, iRow; 01085 int cCol, cRow; 01086 int cRem; 01087 int dx, dy; 01088 int xRes, yRes; 01089 01090 UNREFERENCED_PARAMETER(hdc); 01091 UNREFERENCED_PARAMETER(lprc); 01092 01093 /* 01094 * Get the parent rectangle if none is given. 01095 */ 01096 GetParentArrangeRect(pawd, pMonitor, &rcParent); 01097 01098 /* 01099 * Now, figure out how many REAL windows we have. 01100 */ 01101 chwndReal = 0; 01102 for (ihwnd = pawd->chwnd; --ihwnd >= 0;) { 01103 if (ValidatePositionableWindow( 01104 pawd->phwnd[ihwnd], 01105 pawd->fVerifyParent ? pawd->pwndParent : NULL, 01106 pawd->pwndDesktop, 01107 pawd->flags, 01108 pMonitor, 01109 NULL)) { 01110 01111 chwndReal++; 01112 } 01113 } 01114 01115 if (chwndReal == 0) 01116 return TRUE; 01117 01118 xRes = rcParent.right - rcParent.left; 01119 yRes = rcParent.bottom - rcParent.top; 01120 if (xRes <= 0 || yRes <= 0) 01121 return TRUE; 01122 01123 /* 01124 * Compute nearest least square 01125 */ 01126 for (square = 2; square * square <= chwndReal; square++) { 01127 ; 01128 } 01129 01130 if (pawd->flags & MDITILE_HORIZONTAL) { 01131 cCol = square - 1; 01132 cRow = chwndReal / cCol; 01133 cRem = chwndReal % cCol; 01134 } else { 01135 cRow = square - 1; 01136 cCol = chwndReal / cRow; 01137 cRem = chwndReal % cRow; 01138 } 01139 01140 chwndReal = 0; 01141 ihwnd = -1; 01142 for (iCol = 0; iCol < cCol; iCol++) { 01143 /* 01144 * Add one extra row to handle the remainders. 01145 */ 01146 if (cCol - iCol <= cRem) { 01147 cRow++; 01148 } 01149 01150 for (iRow = 0; iRow < cRow; iRow++) { 01151 HWND hwndChild; 01152 PWND pwndChild; 01153 DWORD dwSWPFlags; 01154 01155 dx = xRes / cCol; 01156 dy = yRes / cRow; 01157 01158 NextWindow: 01159 /* 01160 * Skip bogus and nonpositionable windows 01161 */ 01162 ihwnd++; 01163 if (ihwnd >= pawd->chwnd) 01164 return TRUE; 01165 01166 hwndChild = pawd->phwnd[ihwnd]; 01167 pwndChild = ValidatePositionableWindow( 01168 hwndChild, 01169 pawd->fVerifyParent ? pawd->pwndParent : NULL, 01170 pawd->pwndDesktop, 01171 pawd->flags, 01172 pMonitor, 01173 &dwSWPFlags); 01174 01175 if (!pwndChild) 01176 goto NextWindow; 01177 01178 /* 01179 * Move, size the window 01180 */ 01181 pawd->hdwp = NtUserDeferWindowPos( 01182 pawd->hdwp, 01183 hwndChild, 01184 HWND_TOP, 01185 rcParent.left + iCol*dx, 01186 rcParent.top + iRow*dy, 01187 dx, 01188 dy, 01189 dwSWPFlags); 01190 01191 if (pawd->hdwp == NULL) 01192 return FALSE; 01193 01194 chwndReal++; 01195 pawd->chwndReal++; 01196 } 01197 01198 if (cCol - iCol <= cRem) { 01199 cRow--; 01200 cRem--; 01201 } 01202 } 01203 01204 return TRUE; 01205 }

BOOL TranslateMDISysAccel HWND  hwnd,
LPMSG  lpMsg
 

Definition at line 96 of file mdiwin.c.

References ACTIVE, BOOL, CheckLock, FALSE, FNID_MDICLIENT, GETFNID, GetKeyState(), IsWindowEnabled(), NULL, SendMessage(), TRUE, and ValidateHwndNoRip().

Referenced by WinMain().

00099 { 00100 PWND pwnd; 00101 PMDI pmdi; 00102 int event; 00103 00104 /* 00105 * Is this a message we care about? 00106 */ 00107 if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN) { 00108 return FALSE; 00109 } 00110 00111 /* 00112 * This is called within a message loop. If the window gets destroyed, 00113 * there still may be other messages in the queue that get returned 00114 * after the window is destroyed. The app will call TranslateAccelerator() 00115 * on every one of these, causing RIPs.... Make it nice so it just 00116 * returns FALSE. 00117 */ 00118 if ((pwnd = ValidateHwndNoRip(hwnd)) == NULL) { 00119 RIPERR0(ERROR_INVALID_WINDOW_HANDLE, RIP_VERBOSE, ""); 00120 return FALSE; 00121 } 00122 00123 CheckLock(pwnd); 00124 00125 /* 00126 * Make sure this is really an MDIClient window. Harvard Graphics 2.0 00127 * calls this function with a different window class and caused us 00128 * to get an access violation. 00129 */ 00130 if (GETFNID(pwnd) != FNID_MDICLIENT) { 00131 RIPMSG0(RIP_WARNING, "Window not of MDIClient class"); 00132 return FALSE; 00133 } 00134 00135 /* 00136 * Get a pointer to the MDI structure 00137 */ 00138 pmdi = ((PMDIWND)pwnd)->pmdi; 00139 00140 if (!ACTIVE(pmdi)) 00141 return FALSE; 00142 00143 if (!IsWindowEnabled(ACTIVE(pmdi))) 00144 return FALSE; 00145 00146 switch (lpMsg->wParam) { 00147 case VK_F4: 00148 event = SC_CLOSE; 00149 break; 00150 case VK_F6: 00151 case VK_TAB: 00152 if (GetKeyState(VK_SHIFT) < 0) 00153 event = SC_PREVWINDOW; 00154 else 00155 event = SC_NEXTWINDOW; 00156 break; 00157 default: 00158 return FALSE; 00159 } 00160 00161 /* 00162 * All of these have the control key down 00163 */ 00164 if (GetKeyState(VK_CONTROL) >= 0) 00165 return FALSE; 00166 00167 if (GetKeyState(VK_MENU) < 0) 00168 return FALSE; 00169 00170 SendMessage(ACTIVE(pmdi), WM_SYSCOMMAND, event, MAKELONG(lpMsg->wParam, 0)); 00171 00172 return TRUE; 00173 }

BOOL UnmaximizeChildWindows HWND  hwndParent  ) 
 

Definition at line 603 of file mdiwin.c.

References BOOL, BuildHwndList(), FALSE, GetDesktopWindow(), GetWindow(), NtUserGetForegroundWindow(), NtUserLockWindowUpdate(), NtUserSetWindowPos(), NtUserShowWindow(), NtUserShowWindowAsync(), NULL, RedrawWindow, TestWF, TRUE, UINT, UserLocalFree, ValidateHwnd, WFMAXIMIZED, and WFVISIBLE.

Referenced by ArrangeWindows().

00605 { 00606 HWND hwndMove; 00607 PWND pwndMove; 00608 BOOL fFoundOne = FALSE; 00609 BOOL fAsync; 00610 UINT chwnd; 00611 HWND *phwndList; 00612 HWND *phwnd; 00613 HWND hwndChild = GetWindow(hwndParent, GW_CHILD); 00614 00615 /* 00616 * Get the hwnd list. It is returned in a block of memory 00617 * allocated with LocalAlloc. 00618 */ 00619 if (hwndChild == NULL || 00620 (chwnd = BuildHwndList(NULL, GetWindow(hwndParent, GW_CHILD), 00621 FALSE, 0, &phwndList)) == 0) { 00622 return FALSE; 00623 } 00624 00625 fAsync = (hwndParent == GetDesktopWindow()); 00626 00627 for (phwnd = phwndList; chwnd > 0; chwnd--, phwnd++) { 00628 if ((hwndMove = *phwnd) == NULL) 00629 continue; 00630 00631 if ((pwndMove = ValidateHwnd(hwndMove)) == NULL) 00632 continue; 00633 00634 // Not in Chicago -- FritzS 00635 // if (pwndMove->spwndOwner != NULL) 00636 // continue; 00637 00638 if (TestWF(pwndMove, WFMAXIMIZED) && TestWF(pwndMove, WFVISIBLE)) { 00639 // 00640 // If we haven't done it yet, lock the screen to prevent sending 00641 // paints for a cleaner update. 00642 // 00643 if (!fFoundOne && fAsync) 00644 NtUserLockWindowUpdate(hwndParent); 00645 00646 fFoundOne = TRUE; 00647 00648 if (fAsync) 00649 NtUserShowWindowAsync(hwndMove, SW_SHOWNOACTIVATE); 00650 else 00651 NtUserShowWindow(hwndMove, SW_SHOWNORMAL); 00652 } 00653 } 00654 00655 UserLocalFree(phwndList); 00656 00657 if (fFoundOne && fAsync) { 00658 00659 HWND hwndActive = NtUserGetForegroundWindow(); 00660 if (hwndActive != NULL) { 00661 00662 /* 00663 * Hack! Since the above showwindows cause zorder changes, we want 00664 * the active window to be in front. This makes sure... 00665 */ 00666 NtUserSetWindowPos(hwndActive, HWND_TOP, 0, 0, 0, 0, 00667 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS); 00668 00669 } 00670 NtUserLockWindowUpdate(NULL); 00671 RedrawWindow(hwndParent, NULL, NULL, 00672 RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE | RDW_FRAME); 00673 } 00674 00675 return fFoundOne; 00676 }

PWND ValidatePositionableWindow HWND  hwndChild,
PWND  pwndParent,
PWND  pwndDesktop,
DWORD  dwMDIFlags,
PMONITOR  pMonitor,
DWORD pdwSWPFlags
 

Definition at line 869 of file mdiwin.c.

References _MonitorFromWindow(), NULL, REBASEPWND, TestWF, ValidateHwnd, WEFTOOLWINDOW, WEFTOPMOST, WFCPRESENT, WFDISABLED, WFMINIMIZED, WFSIZEBOX, and WFVISIBLE.

Referenced by CascadeWindowsEnum(), and TileWindowsEnum().

00876 { 00877 PWND pwndChild; 00878 00879 pwndChild = ValidateHwnd(hwndChild); 00880 if (pwndChild) { 00881 if (pwndParent && REBASEPWND(pwndChild, spwndParent) != pwndParent) { 00882 RIPMSG0(RIP_WARNING, "Cascade/Tile Windows: Windows in list must have same parent"); 00883 } else if ( 00884 /* 00885 * mikesch - removed the maximized check since the call 00886 * to restore maximized windows in unmaximizechildwindows occurs 00887 * asynchronously now. 00888 */ 00889 TestWF(pwndChild, WFVISIBLE) && 00890 TestWF(pwndChild, WFCPRESENT) && 00891 !TestWF(pwndChild, WFMINIMIZED) && 00892 !TestWF(pwndChild, WEFTOPMOST) && 00893 (!(dwMDIFlags & MDITILE_SKIPDISABLED) || !TestWF(pwndChild, WFDISABLED)) && 00894 !TestWF(pwndChild, WEFTOOLWINDOW) && 00895 ((pMonitor) ? 00896 (pMonitor == _MonitorFromWindow(pwndChild, MONITOR_DEFAULTTONULL)) : 00897 (pwndParent != pwndDesktop || _MonitorFromWindow(pwndChild, MONITOR_DEFAULTTONULL)))) { 00898 00899 if (pdwSWPFlags) { 00900 *pdwSWPFlags = SWP_NOACTIVATE | SWP_NOCOPYBITS; 00901 if (!TestWF(pwndChild, WFSIZEBOX)) { 00902 *pdwSWPFlags |= SWP_NOSIZE; 00903 } 00904 if (!(dwMDIFlags & MDITILE_ZORDER)) { 00905 *pdwSWPFlags |= SWP_NOZORDER; 00906 } 00907 } 00908 return pwndChild; 00909 } 00910 } 00911 00912 return NULL; 00913 }

void xxxChildResize PWND  pwnd,
UINT  wMode
 

Definition at line 2425 of file mdiwin.c.

References CheckLock, FALSE, HWq, IsChild(), L, Lock, MAXED, MDIAddSysMenu(), MDIRemoveSysMenu(), NtUserMinMaximize(), NtUserQueryWindow(), NtUserSetSysMenu, NULL, OTHERMAXING, PtoH, REBASE, REBASEPWND, RecalculateScrollRanges(), SCROLL, SCROLLCOUNT, SendMessage(), tagWND::spwndOwner, SW_MDIRESTORE, TestWF, ThreadLock, ThreadLockAlways, ThreadUnlock, TRUE, Unlock, WFVISIBLE, wMode, tagMDI::wScroll, and xxxSetFrameTitle().

Referenced by DefMDIChildProcWorker().

02428 { 02429 PWND pwndT; 02430 PWND pwndMDI = REBASEPWND(pwnd, spwndParent); 02431 PWND pwndFrame = REBASEPWND(pwndMDI, spwndParent); 02432 HWND hwndOldActive; 02433 PMDI pmdi; 02434 HWND hwndActive; 02435 TL tlpwndMDI; 02436 TL tlpwndFrame; 02437 TL tlpwndT; 02438 PMENU pmenu; 02439 HWND hwnd = HWq(pwnd); 02440 02441 CheckLock(pwnd); 02442 02443 NtUserSetSysMenu(hwnd); 02444 02445 ThreadLock(pwndMDI, &tlpwndMDI); 02446 ThreadLock(pwndFrame, &tlpwndFrame); 02447 02448 /* 02449 * Get a pointer to the MDI structure 02450 */ 02451 pmdi = ((PMDIWND)pwndMDI)->pmdi; 02452 pmenu = REBASE(pwndFrame, spmenu); 02453 02454 if (MAXED(pmdi) == hwnd && wMode != SIZEFULLSCREEN) { 02455 /* 02456 * Restoring the current maximized window... 02457 * Remove the system menu from the Frame window. 02458 */ 02459 if (!(SCROLL(pmdi) & OTHERMAXING)) { 02460 Unlock(&MAXED(pmdi)); 02461 MDIRemoveSysMenu(PtoH(pmenu), hwnd); 02462 Unlock(&MAXED(pmdi)); 02463 xxxSetFrameTitle(pwndFrame, pwndMDI, (LPWSTR)1L); 02464 } 02465 } 02466 02467 if (wMode == SIZEFULLSCREEN) { 02468 02469 /* 02470 * Already maximized? 02471 */ 02472 if (hwnd == MAXED(pmdi)) 02473 goto Exit; 02474 02475 /* 02476 * Maximizing this window... 02477 */ 02478 02479 pmdi->wScroll |= OTHERMAXING | SCROLLCOUNT; 02480 02481 if (hwndOldActive = MAXED(pmdi)) { 02482 SendMessage(hwndOldActive, WM_SETREDRAW, FALSE, 0L); 02483 MDIRemoveSysMenu(PtoH(pmenu), hwndOldActive); 02484 NtUserMinMaximize(hwndOldActive, SW_MDIRESTORE, FALSE); 02485 SendMessage(hwndOldActive, WM_SETREDRAW, TRUE, 0L); 02486 } 02487 02488 Lock(&MAXED(pmdi), hwnd); 02489 02490 /* 02491 * Add the system menu to the Frame window. 02492 */ 02493 MDIAddSysMenu(PtoH(pmenu), hwnd); 02494 xxxSetFrameTitle(pwndFrame, pwndMDI, (LPWSTR)1L); 02495 02496 pmdi->wScroll &= ~(OTHERMAXING | SCROLLCOUNT); 02497 } 02498 02499 if (wMode == SIZEICONIC) { 02500 for (pwndT = REBASEPWND(pwndMDI, spwndChild); pwndT; 02501 pwndT = REBASEPWND(pwndT, spwndNext)) { 02502 if (!pwndT->spwndOwner && TestWF(pwndT, WFVISIBLE)) 02503 break; 02504 } 02505 02506 hwndActive = NtUserQueryWindow(hwnd, WindowActiveWindow); 02507 if ((pwndT != NULL) && (hwndActive != NULL) && 02508 IsChild(hwndActive, HWq(pwndMDI))) { 02509 ThreadLockAlways(pwndT, &tlpwndT); 02510 SendMessage(HWq(pwndT), WM_CHILDACTIVATE, 0, 0L); 02511 ThreadUnlock(&tlpwndT); 02512 } 02513 } 02514 02515 if (!(SCROLL(pmdi) & SCROLLCOUNT)) 02516 RecalculateScrollRanges(pwndMDI, FALSE); 02517 02518 Exit: 02519 ThreadUnlock(&tlpwndFrame); 02520 ThreadUnlock(&tlpwndMDI); 02521 }

void xxxMDIActivate PWND  pwnd,
PWND  pwndActivate
 

Definition at line 1237 of file mdiwin.c.

References ACTIVE, BOOL, CheckLock, CheckMenuItem(), FALSE, FindPwndChild(), FIRST, HW, HWq, L, Lock, MAXED, MAXITEMS, ModifyMenuItem(), NtUserCallHwndParam(), NtUserQueryWindow(), NtUserSetFocus(), NtUserSetWindowPos(), NtUserShowWindow(), NULL, REBASEPWND, SendMessage(), SetWindowLongPtr(), tagWND::spmenu, TestWF, ThreadLock, ThreadUnlock, TRUE, UINT, ValidateHwnd, WFDISABLED, WFFRAMEON, WFMAXBOX, WFNOANIMATE, WFWIN31COMPAT, WFWIN40COMPAT, and WINDOW.

Referenced by DefMDIChildProcWorker(), and xxxMDIDestroy().

01240 { 01241 HWND hwndOld; 01242 PWND pwndOld; 01243 01244 PMDI pmdi; 01245 BOOL fShowActivate; 01246 UINT nID; 01247 TL tlpwnd; 01248 TL tlpwndOld; 01249 PWND pwndT; 01250 HWND hwnd = HWq(pwnd); 01251 HWND hwndActivate = HW(pwndActivate); 01252 01253 CheckLock(pwnd); 01254 CheckLock(pwndActivate); 01255 01256 /* 01257 * Get a pointer to the MDI structure 01258 */ 01259 pmdi = ((PMDIWND)pwnd)->pmdi; 01260 01261 if (ACTIVE(pmdi) == hwndActivate) 01262 return; 01263 01264 if ((pwndActivate != NULL) && (TestWF(pwndActivate, WFDISABLED))) { 01265 /* 01266 * Don't even try activating disabled or invisible windows. 01267 */ 01268 return; 01269 } 01270 01271 pwndT = REBASEPWND(pwnd, spwndParent); 01272 fShowActivate = (HW(pwndT) == 01273 NtUserQueryWindow(hwnd, WindowActiveWindow)); 01274 01275 hwndOld = ACTIVE(pmdi); 01276 if (hwndOld && (pwndOld = ValidateHwnd(hwndOld)) == NULL) { 01277 hwndOld = NULL; 01278 } 01279 ThreadLock(pwndOld, &tlpwndOld); 01280 01281 if (hwndOld) { 01282 01283 /* 01284 * Attempt to deactivate the MDI child window. 01285 * The MDI child window can fail deactivation by returning FALSE. 01286 * But this only applies if the MDI frame is the active window 01287 * and the app is a 3.1 app or later 01288 */ 01289 if (!SendMessage(hwndOld, WM_NCACTIVATE, FALSE, 0L) && fShowActivate) { 01290 if (TestWF(pwndOld, WFWIN31COMPAT)) 01291 goto UnlockOld; 01292 } 01293 01294 if (!TestWF(pwndOld, WFWIN31COMPAT) && TestWF(pwndOld, WFFRAMEON)) { 01295 01296 /* 01297 * Error: Quicken for Windows is sort of bogus. They try to fail 01298 * the WM_NCACTIVATE of their newly created window by not passing 01299 * it to DefWindowProc. Bug 6412. WM_NCACTIVATE sets/unsets the 01300 * WFFRAMEON bit if passed to DWP so we can double check things 01301 * here. 01302 */ 01303 goto UnlockOld; 01304 } 01305 01306 SendMessage(hwndOld, WM_MDIACTIVATE, (WPARAM)hwndOld, (LPARAM)hwndActivate); 01307 01308 /* 01309 * Uncheck the old window menu entry. 01310 */ 01311 if (WINDOW(pmdi)) 01312 CheckMenuItem(WINDOW(pmdi), PtrToUlong(pwndOld->spmenu), 01313 MF_BYCOMMAND | MF_UNCHECKED); 01314 } 01315 01316 // 01317 // Handle switching to a new (or NO) maximized window. If NO window is 01318 // to become maximized, because we're activating NULL or the window to 01319 // become active doesn't have a WS_MAXIMIZEBOX, restore the old one to 01320 // it's normal size to clean up the MDI maximized menubar mess 01321 // 01322 if (MAXED(pmdi) && MAXED(pmdi) != hwndActivate) { 01323 HWND hwndMax; 01324 int iShowCode; 01325 01326 // The MAXBOX check is a new thing for 4.0 dudes; it breaks 3.x apps. 01327 // See comment in the WM_MDIMAXIMIZE handling. 01328 01329 if (pwndActivate && (TestWF(pwndActivate, WFMAXBOX) || !TestWF(pwndActivate, WFWIN40COMPAT))) { 01330 hwndMax = hwndActivate; 01331 iShowCode = SW_SHOWMAXIMIZED; 01332 Lock(&ACTIVE(pmdi), hwndMax); 01333 } else { 01334 hwndMax = MAXED(pmdi); 01335 iShowCode = SW_SHOWNORMAL; 01336 } 01337 01338 // overload WFFULLSCREEN bit -- useless for child windows anyways 01339 // use it to indicate to min/max code to not animate size change. 01340 01341 // NO -- no bit overloading, damn it. FritzS 01342 NtUserCallHwndParam(hwndMax, WFNOANIMATE, SFI_SETWINDOWSTATE); 01343 NtUserShowWindow(hwndMax, iShowCode); 01344 NtUserCallHwndParam(hwndMax, WFNOANIMATE, SFI_CLEARWINDOWSTATE); 01345 } 01346 01347 Lock(&ACTIVE(pmdi), hwndActivate); 01348 01349 /* 01350 * We may be removing the activation entirely... 01351 */ 01352 if (!pwndActivate) { 01353 if (fShowActivate) 01354 NtUserSetFocus(hwnd); 01355 goto UnlockOld; 01356 } 01357 01358 if (WINDOW(pmdi)) { 01359 01360 /* 01361 * Check the new window menu entry. 01362 */ 01363 nID = GetWindowID(ACTIVE(pmdi)); 01364 if (nID - FIRST(pmdi) < (MAXITEMS - 1)) { 01365 CheckMenuItem(WINDOW(pmdi), nID, MF_BYCOMMAND | MFS_CHECKED); 01366 } else { 01367 /* 01368 * the item is not in the menu at all! Swap it with number 9. 01369 */ 01370 PWND pwndOther = FindPwndChild(pwnd, (UINT)(FIRST(pmdi) + MAXITEMS - 2)); 01371 01372 SetWindowLongPtr(HW(pwndOther), GWLP_ID, PtrToLong(pwndActivate->spmenu)); 01373 SetWindowLongPtr(hwndActivate, GWLP_ID, FIRST(pmdi) + MAXITEMS - 2); 01374 01375 ModifyMenuItem(pwndActivate); 01376 } 01377 } 01378 01379 /* 01380 * Bring the window to the top. 01381 */ 01382 NtUserSetWindowPos(ACTIVE(pmdi), NULL, 0, 0, 0, 0, 01383 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 01384 01385 /* 01386 * Update the Caption bar. Don't muck with styles for 3.1. 01387 */ 01388 if (fShowActivate) { 01389 SendMessage(ACTIVE(pmdi), WM_NCACTIVATE, TRUE, 0L); 01390 01391 ThreadLock(pwnd, &tlpwnd); 01392 01393 if (hwnd == NtUserQueryWindow(hwnd, WindowFocusWindow)) 01394 SendMessage(hwnd, WM_SETFOCUS, (WPARAM)hwnd, 0); 01395 else 01396 NtUserSetFocus(hwnd); 01397 01398 ThreadUnlock(&tlpwnd); 01399 } 01400 01401 /* 01402 * Notify the new active window of his activation. 01403 */ 01404 SendMessage(ACTIVE(pmdi), WM_MDIACTIVATE, (WPARAM)hwndOld, 01405 (LPARAM)hwndActivate); 01406 01407 UnlockOld: 01408 ThreadUnlock(&tlpwndOld); 01409 }

void xxxMDIDestroy PWND  pwnd,
HWND  hwndVictim
 

Definition at line 1540 of file mdiwin.c.

References ACTIVE, CheckLock, CKIDS, FALSE, FIRST, HWq, L, MAXED, MDIRemoveSysMenu(), NtUserDestroyWindow(), NtUserRedrawFrame, NtUserShowWindow(), NULL, PtoH, REBASE, REBASEPWND, RecalculateScrollRanges(), SAMEWOWHANDLE, SendMessage(), ShiftMenuIDs(), tagWND::spmenu, tagWND::spwndOwner, TestWF, ThreadLock, ThreadUnlock, UINT, Unlock, ValidateHwnd, WFVISIBLE, xxxMDIActivate(), xxxMDINext(), and xxxSetFrameTitle().

Referenced by MDIClientWndProcWorker().

01543 { 01544 PWND pwndVictim; 01545 TL tlpwndParent; 01546 PMDI pmdi; 01547 PWND pwndParent; 01548 HWND hwnd; 01549 01550 CheckLock(pwnd); 01551 01552 if ((pwndVictim = ValidateHwnd(hwndVictim)) == NULL) { 01553 return; 01554 } 01555 CheckLock(pwndVictim); 01556 01557 /* 01558 * Get a pointer to the MDI structure 01559 */ 01560 pmdi = ((PMDIWND)pwnd)->pmdi; 01561 01562 #ifdef NEVER 01563 // don't do this validation - because it sometimes doesn't work! If an 01564 // app passed in idFirstChild (through CLIENTCREATESTRUCT) as -1, this 01565 // code fails because it treats the id comparisons as unsigned compares. 01566 // Change them to signed compares and it still doesn't work. That is because 01567 // when ShiftMenuIDs() is called, you'll shift mdi windows out of the signed 01568 // comparison range and this check won't allow them to be destroyed. This 01569 // is straight win3.1 code. 01570 // 01571 /* 01572 * Validate that this is one of the mdi children we are keeping track 01573 * of. If it isn't don't destroy it because it'll get mdi id tracking 01574 * code all screwed up. 01575 */ 01576 if (((UINT)pwndVictim->spmenu) < FIRST(pmdi) || 01577 ((UINT)pwndVictim->spmenu) >= (UINT)(FIRST(pmdi) + CKIDS(pmdi)) || 01578 pwndVictim->spwndOwner != NULL) { 01579 RIPERR0(ERROR_NON_MDICHILD_WINDOW, RIP_VERBOSE, ""); 01580 return; 01581 } 01582 #endif 01583 01584 ShiftMenuIDs(pwnd, pwndVictim); 01585 01586 /* 01587 * First Activate another window. 01588 */ 01589 if (SAMEWOWHANDLE(hwndVictim, ACTIVE(pmdi))) { 01590 xxxMDINext(pwnd, pwndVictim, FALSE); 01591 01592 /* 01593 * Destroying only child? 01594 */ 01595 if (SAMEWOWHANDLE(hwndVictim, ACTIVE(pmdi))) { 01596 NtUserShowWindow(hwndVictim, SW_HIDE); 01597 01598 /* 01599 * If the window is maximized, we need to remove his sys menu 01600 * now otherwise it may get deleted twice. Once when the child 01601 * is destroyed and once when the frame is destroyed. 01602 */ 01603 if (MAXED(pmdi)) { 01604 pwndParent = REBASEPWND(pwnd, spwndParent); 01605 MDIRemoveSysMenu(PtoH(REBASE(pwndParent,spmenu)), MAXED(pmdi)); 01606 Unlock(&MAXED(pmdi)); 01607 ThreadLock(pwndParent, &tlpwndParent); 01608 xxxSetFrameTitle(pwndParent, pwnd, (LPWSTR)1L); 01609 01610 /* 01611 * Redraw frame so menu bar shows the removed sys menu stuff 01612 */ 01613 if (TestWF(pwndParent, WFVISIBLE)) 01614 NtUserRedrawFrame(HWq(pwndParent)); 01615 ThreadUnlock(&tlpwndParent); 01616 } 01617 xxxMDIActivate(pwnd, NULL); 01618 } 01619 } 01620 01621 /* 01622 * Don't ever let this go negative or we'll get caught in long loops. 01623 */ 01624 CKIDS(pmdi)--; 01625 if ((int)CKIDS(pmdi) < 0) 01626 CKIDS(pmdi) = 0; 01627 01628 hwnd = HWq(pwnd); 01629 SendMessage(hwnd, WM_MDIREFRESHMENU, 0L, 0L); 01630 01631 /* 01632 * Destroy the window. 01633 */ 01634 NtUserDestroyWindow(hwndVictim); 01635 01636 01637 /* 01638 * During the DestroyWindow the parent may also have been deleted 01639 * Remove revalidate if we get client side locking 01640 */ 01641 if (ValidateHwnd(hwnd) == NULL) 01642 return; 01643 01644 /* 01645 * Deleting a window can change the scroll ranges. 01646 */ 01647 RecalculateScrollRanges(pwnd, FALSE); 01648 }

void xxxMDINext PWND  pwndMDI,
PWND  pwnd,
BOOL  fPrevWindow
 

Definition at line 1420 of file mdiwin.c.

References _GetWindow(), BOOL, CheckLock, FALSE, HW, HWq, MAXED, NtUserBeginDeferWindowPos, NtUserDeferWindowPos(), NtUserEndDeferWindowPosEx(), NtUserSetVisible, NtUserShowWindow(), REBASEPWND, SV_CLRFTRUEVIS, SV_UNSET, TestWF, TRUE, WFDISABLED, and WFVISIBLE.

Referenced by MDIClientWndProcWorker(), and xxxMDIDestroy().

01424 { 01425 PMDI pmdi; 01426 PWND pwndNextGuy; 01427 HDWP hdwp; 01428 BOOL fHack = FALSE; 01429 01430 CheckLock(pwndMDI); 01431 CheckLock(pwnd); 01432 01433 /* 01434 * Get a pointer to the MDI structure 01435 */ 01436 pmdi = ((PMDIWND)pwndMDI)->pmdi; 01437 01438 pwndNextGuy = pwnd; 01439 01440 while (TRUE) { 01441 if (fPrevWindow) 01442 pwndNextGuy = _GetWindow(pwndNextGuy, GW_HWNDPREV); 01443 else 01444 pwndNextGuy = REBASEPWND(pwndNextGuy, spwndNext); 01445 01446 if (!pwndNextGuy) { 01447 if (fPrevWindow) { 01448 pwndNextGuy = _GetWindow(pwnd, GW_HWNDLAST); 01449 } else { 01450 pwndNextGuy = REBASEPWND(pwndMDI, spwndChild); 01451 } 01452 } 01453 01454 if (pwndNextGuy == pwnd) 01455 return; 01456 01457 01458 // 01459 // Ignore hidden and disabled windows. 01460 // 01461 if (TestWF(pwndNextGuy, WFVISIBLE) && !TestWF(pwndNextGuy, WFDISABLED)) 01462 break; 01463 } 01464 01465 if (MAXED(pmdi)) { 01466 NtUserSetVisible(HWq(pwndMDI), SV_UNSET | SV_CLRFTRUEVIS); 01467 fHack = TRUE; 01468 } 01469 01470 hdwp = NtUserBeginDeferWindowPos(2); 01471 01472 /* 01473 * activate the new window (first, in case of maximized windows) 01474 */ 01475 hdwp = NtUserDeferWindowPos(hdwp, HW(pwndNextGuy), HWND_TOP, 0, 0, 0, 0, 01476 SWP_NOMOVE | SWP_NOSIZE); 01477 01478 // LATER 30-Mar-1992 mikeke 01479 // this used to be _GetWindow(pwndMDI->spwndChild, GW_HWNDLAST) 01480 // instead of HWND_BOTTOM 01481 if (hdwp && !fPrevWindow && (pwnd != pwndNextGuy)) 01482 hdwp = NtUserDeferWindowPos(hdwp, HW(pwnd), 01483 HWND_BOTTOM, 0, 0, 0, 0, 01484 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE ); 01485 01486 NtUserEndDeferWindowPosEx(hdwp, FALSE); 01487 01488 if (fHack) { 01489 NtUserShowWindow(HWq(pwndMDI), SW_SHOW); 01490 } 01491 }

void xxxSetFrameTitle PWND  pwndFrame,
PWND  pwndMDI,
LPWSTR  lpch
 

Definition at line 32 of file mdiwin.c.

References _DefSetText(), CheckLock, FALSE, HTITLE, HW, IS_PTR, L, _LARGE_UNICODE_STRING::Length, MAX_TITLE_LEN, MAXED, NtUserRedrawFrame, NtUserRedrawFrameAndHook, NtUserRedrawTitle, NULL, REBASE, RtlInitLargeUnicodeString(), tagWND::strName, TextAlloc(), TextCopy(), TITLE_EXTRA, UINT, UserLocalFree, and ValidateHwnd.

Referenced by DefFrameProcWorker(), DefMDIChildProcWorker(), MDIClientWndProcWorker(), xxxChildResize(), and xxxMDIDestroy().

00036 { 00037 PWND pwnd; 00038 PMDI pmdi; 00039 WCHAR sz[MAX_TITLE_LEN]; 00040 HWND hwndFrame = HW(pwndFrame); 00041 00042 CheckLock(pwndFrame); 00043 CheckLock(pwndMDI); 00044 00045 /* 00046 * Get a pointer to the MDI structure 00047 */ 00048 pmdi = ((PMDIWND)pwndMDI)->pmdi; 00049 00050 if (IS_PTR(lpch) || lpch == NULL) { 00051 if (HTITLE(pmdi)) { 00052 UserLocalFree(HTITLE(pmdi)); 00053 } 00054 HTITLE(pmdi) = TextAlloc(lpch); 00055 } 00056 00057 if (HTITLE(pmdi)) { 00058 LARGE_UNICODE_STRING str; 00059 int cch; 00060 00061 RtlInitLargeUnicodeString(&str, HTITLE(pmdi), (UINT)-1); 00062 TextCopy(&str, sz, sizeof(sz)/sizeof(WCHAR)); 00063 00064 if (MAXED(pmdi) && (pwnd = ValidateHwnd(MAXED(pmdi))) && pwnd->strName.Length) { 00065 00066 cch = MAX_TITLE_LEN - ((str.Length / sizeof(WCHAR)) + TITLE_EXTRA); 00067 if (cch > 0) { 00068 wcscat(sz, TEXT(" - [")); 00069 wcsncat(sz, REBASE(pwnd, strName.Buffer), cch - 1); 00070 wcscat(sz, TEXT("]")); 00071 } 00072 } 00073 } else { 00074 sz[0] = 0; 00075 } 00076 00077 _DefSetText(hwndFrame, sz, FALSE); 00078 00079 if (lpch == (LPWSTR)1L) 00080 NtUserRedrawFrameAndHook(hwndFrame); 00081 00082 else if (lpch != (LPWSTR)2L) { 00083 if (!NtUserRedrawTitle(hwndFrame, DC_TEXT)) 00084 NtUserRedrawFrame(hwndFrame); 00085 } 00086 }


Generated on Sat May 15 19:44:36 2004 for test by doxygen 1.3.7