00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #include <stdlib.h>
00070 #include <stdio.h>
00071 #include <string.h>
00072 #include <math.h>
00073
00074 #include "windef.h"
00075 #include "winbase.h"
00076 #include "wingdi.h"
00077 #include "winuser.h"
00078 #include "wine/unicode.h"
00079 #include "win.h"
00080 #include "heap.h"
00081 #include "controls.h"
00082 #include "user.h"
00083 #ifndef __WIN32OS2__
00084 #include "nonclient.h"
00085 #include "struct32.h"
00086 #endif
00087 #include "debugtools.h"
00088 #include "dlgs.h"
00089
00090 #ifdef __WIN32OS2__
00091 #include <heapstring.h>
00092 #define WIN_GetFullHandle(a) a
00093 #endif
00094
00095 DEFAULT_DEBUG_CHANNEL(mdi);
00096
00097 #ifdef __WIN32OS2__
00098 #include "mdi.h"
00099 #include <win32wmisc.h>
00100 #else
00101 #define MDI_MAXLISTLENGTH 0x40
00102 #define MDI_MAXTITLELENGTH 0xa1
00103
00104 #define MDI_NOFRAMEREPAINT 0
00105 #define MDI_REPAINTFRAMENOW 1
00106 #define MDI_REPAINTFRAME 2
00107
00108 #define WM_MDICALCCHILDSCROLL 0x10ac
00109
00110
00111 #define MDI_MOREWINDOWSLIMIT 9
00112
00113 #define MDI_IDC_LISTBOX 100
00114 #define MDI_IDS_MOREWINDOWS 13
00115
00116 #define MDIF_NEEDUPDATE 0x0001
00117
00118 typedef struct
00119 {
00120 UINT nActiveChildren;
00121 HWND hwndChildMaximized;
00122 HWND hwndActiveChild;
00123 HMENU hWindowMenu;
00124 UINT idFirstChild;
00125 LPWSTR frameTitle;
00126 UINT nTotalCreated;
00127 UINT mdiFlags;
00128 UINT sbRecalc;
00129 } MDICLIENTINFO;
00130 #endif
00131
00132 static HBITMAP hBmpClose = 0;
00133 static HBITMAP hBmpRestore = 0;
00134
00135
00136 static void MDI_UpdateFrameText( HWND, HWND, BOOL, LPCWSTR);
00137 static BOOL MDI_AugmentFrameMenu( HWND, HWND );
00138 static BOOL MDI_RestoreFrameMenu( HWND, HWND );
00139 static LONG MDI_ChildActivate( HWND, HWND );
00140
00141 static HWND MDI_MoreWindowsDialog(HWND);
00142 static void MDI_SwapMenuItems(HWND, UINT, UINT);
00143 #ifdef __WIN32OS2__
00144 LRESULT WINAPI MDIClientWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
00145 LRESULT WINAPI MDIClientWndProcW( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
00146 #else
00147 static LRESULT WINAPI MDIClientWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
00148 static LRESULT WINAPI MDIClientWndProcW( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
00149 #endif
00150
00151
00152
00153
00154
00155 static HWND MDI_GetChildByID(HWND hwnd, UINT id)
00156 {
00157 HWND ret;
00158 HWND *win_array;
00159 int i;
00160
00161 if (!(win_array = WIN_ListChildren( hwnd ))) return 0;
00162 for (i = 0; win_array[i]; i++)
00163 {
00164 if (GetWindowLongA( win_array[i], GWL_ID ) == id) break;
00165 }
00166 ret = win_array[i];
00167 HeapFree( GetProcessHeap(), 0, win_array );
00168 return ret;
00169 }
00170
00171 static void MDI_PostUpdate(HWND hwnd, MDICLIENTINFO* ci, WORD recalc)
00172 {
00173 if( !(ci->mdiFlags & MDIF_NEEDUPDATE) )
00174 {
00175 ci->mdiFlags |= MDIF_NEEDUPDATE;
00176 PostMessageA( hwnd, WM_MDICALCCHILDSCROLL, 0, 0);
00177 }
00178 ci->sbRecalc = recalc;
00179 }
00180
00181
00182 #ifndef __WIN32OS2__
00183
00184
00185
00186 const struct builtin_class_descr MDICLIENT_builtin_class =
00187 {
00188 "MDIClient",
00189 CS_GLOBALCLASS,
00190 MDIClientWndProcA,
00191 MDIClientWndProcW,
00192 sizeof(MDICLIENTINFO),
00193 IDC_ARROWA,
00194 COLOR_APPWORKSPACE+1
00195 };
00196
00197 static MDICLIENTINFO *get_client_info( HWND client )
00198 {
00199 MDICLIENTINFO *ret = NULL;
00200 WND *win = WIN_FindWndPtr( client );
00201 if (win)
00202 {
00203 if (win->cbWndExtra < sizeof(MDICLIENTINFO)) WARN( "%x is not an MDI client\n", client );
00204 else ret = (MDICLIENTINFO *)win->wExtra;
00205 WIN_ReleaseWndPtr( win );
00206 }
00207 return ret;
00208 }
00209
00210 #endif
00211
00212
00213
00214
00215 static void MDI_MenuModifyItem( HWND client, HWND hWndChild )
00216 {
00217 MDICLIENTINFO *clientInfo = get_client_info( client );
00218 WCHAR buffer[128];
00219 UINT n, id;
00220
00221 if (!clientInfo || !clientInfo->hWindowMenu) return;
00222
00223 id = GetWindowLongA( hWndChild, GWL_ID );
00224 if (id >= clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT) return;
00225 buffer[0] = '&';
00226 buffer[1] = '1' + id - clientInfo->idFirstChild;
00227 buffer[2] = ' ';
00228 GetWindowTextW( hWndChild, buffer + 3, sizeof(buffer)/sizeof(WCHAR) - 3 );
00229
00230 n = GetMenuState(clientInfo->hWindowMenu, id, MF_BYCOMMAND);
00231 ModifyMenuW(clientInfo->hWindowMenu, id, MF_BYCOMMAND | MF_STRING, id, buffer );
00232 CheckMenuItem(clientInfo->hWindowMenu, id, n & MF_CHECKED);
00233 }
00234
00235
00236
00237
00238 static BOOL MDI_MenuDeleteItem( HWND client, HWND hWndChild )
00239 {
00240 WCHAR buffer[128];
00241 static const WCHAR format[] = {'&','%','d',' ',0};
00242 MDICLIENTINFO *clientInfo = get_client_info( client );
00243 UINT index = 0,id,n;
00244
00245 if( !clientInfo->nActiveChildren || !clientInfo->hWindowMenu )
00246 return FALSE;
00247
00248 id = GetWindowLongA( hWndChild, GWL_ID );
00249 DeleteMenu(clientInfo->hWindowMenu,id,MF_BYCOMMAND);
00250
00251
00252
00253
00254 for( index = id+1; index <= clientInfo->nActiveChildren +
00255 clientInfo->idFirstChild; index++ )
00256 {
00257 HWND hwnd = MDI_GetChildByID(client,index);
00258 if (!hwnd)
00259 {
00260 TRACE("no window for id=%i\n",index);
00261 continue;
00262 }
00263
00264
00265 SetWindowLongW( hwnd, GWL_ID, GetWindowLongW( hwnd, GWL_ID ) - 1 );
00266
00267 n = wsprintfW(buffer, format ,index - clientInfo->idFirstChild);
00268 GetWindowTextW( hwnd, buffer + n, sizeof(buffer)/sizeof(WCHAR) - n );
00269
00270
00271
00272
00273 if (index <= clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT)
00274 ModifyMenuW(clientInfo->hWindowMenu ,index ,MF_BYCOMMAND | MF_STRING,
00275 index - 1 , buffer );
00276 }
00277
00278
00279
00280 if (clientInfo->nActiveChildren - 1 > MDI_MOREWINDOWSLIMIT)
00281 {
00282 WCHAR szTmp[50];
00283 LoadStringW(GetModuleHandleA("USER32"), MDI_IDS_MOREWINDOWS, szTmp, sizeof(szTmp)/sizeof(szTmp[0]));
00284 AppendMenuW(clientInfo->hWindowMenu, MF_STRING, clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT, szTmp);
00285 }
00286 return TRUE;
00287 }
00288
00289
00290
00291
00292
00293
00294 static HWND MDI_GetWindow(MDICLIENTINFO *clientInfo, HWND hWnd, BOOL bNext,
00295 DWORD dwStyleMask )
00296 {
00297 int i;
00298 HWND *list;
00299 HWND last = 0;
00300
00301 dwStyleMask |= WS_DISABLED | WS_VISIBLE;
00302 if( !hWnd ) hWnd = clientInfo->hwndActiveChild;
00303
00304 if (!(list = WIN_ListChildren( GetParent(hWnd) ))) return 0;
00305 i = 0;
00306
00307 while (list[i] && list[i] != hWnd) i++;
00308 if (list[i]) i++;
00309
00310 for ( ; list[i]; i++)
00311 {
00312 if (GetWindow( list[i], GW_OWNER )) continue;
00313 if ((GetWindowLongW( list[i], GWL_STYLE ) & dwStyleMask) != WS_VISIBLE) continue;
00314 last = list[i];
00315 if (bNext) goto found;
00316 }
00317
00318 for (i = 0; list[i] && list[i] != hWnd; i++)
00319 {
00320 if (GetWindow( list[i], GW_OWNER )) continue;
00321 if ((GetWindowLongW( list[i], GWL_STYLE ) & dwStyleMask) != WS_VISIBLE) continue;
00322 last = list[i];
00323 if (bNext) goto found;
00324 }
00325 found:
00326 HeapFree( GetProcessHeap(), 0, list );
00327 return last;
00328 }
00329
00330
00331
00332
00333
00334
00335 static void MDI_CalcDefaultChildPos( HWND hwnd, WORD n, LPPOINT lpPos, INT delta)
00336 {
00337 INT nstagger;
00338 RECT rect;
00339 INT spacing = GetSystemMetrics(SM_CYCAPTION) +
00340 GetSystemMetrics(SM_CYFRAME) - 1;
00341
00342 GetClientRect( hwnd, &rect );
00343 if( rect.bottom - rect.top - delta >= spacing )
00344 rect.bottom -= delta;
00345
00346 nstagger = (rect.bottom - rect.top)/(3 * spacing);
00347 lpPos[1].x = (rect.right - rect.left - nstagger * spacing);
00348 lpPos[1].y = (rect.bottom - rect.top - nstagger * spacing);
00349 lpPos[0].x = lpPos[0].y = spacing * (n%(nstagger+1));
00350 }
00351
00352
00353
00354
00355 static LRESULT MDISetMenu( HWND hwnd, HMENU hmenuFrame,
00356 HMENU hmenuWindow)
00357 {
00358 MDICLIENTINFO *ci;
00359 HWND hwndFrame = GetParent(hwnd);
00360 HMENU oldFrameMenu = GetMenu(hwndFrame);
00361
00362 TRACE("%04x %04x %04x\n",
00363 hwnd, hmenuFrame, hmenuWindow);
00364
00365 if (hmenuFrame && !IsMenu(hmenuFrame))
00366 {
00367 WARN("hmenuFrame is not a menu handle\n");
00368 return 0L;
00369 }
00370
00371 if (hmenuWindow && !IsMenu(hmenuWindow))
00372 {
00373 WARN("hmenuWindow is not a menu handle\n");
00374 return 0L;
00375 }
00376
00377 if (!(ci = get_client_info( hwnd ))) return 0;
00378
00379 if( ci->hwndChildMaximized && hmenuFrame && hmenuFrame!=oldFrameMenu )
00380 MDI_RestoreFrameMenu( GetParent(hwnd), ci->hwndChildMaximized );
00381
00382 if( hmenuWindow && ci->hWindowMenu && hmenuWindow!=ci->hWindowMenu )
00383 {
00384
00385
00386
00387 INT i = GetMenuItemCount(ci->hWindowMenu) - 1;
00388 INT pos = GetMenuItemCount(hmenuWindow) + 1;
00389
00390 AppendMenuA( hmenuWindow, MF_SEPARATOR, 0, NULL);
00391
00392 if( ci->nActiveChildren )
00393 {
00394 INT j;
00395 LPWSTR buffer = NULL;
00396 MENUITEMINFOW mii;
00397 INT nbWindowsMenuItems;
00398
00399 if (ci->nActiveChildren <= MDI_MOREWINDOWSLIMIT)
00400 nbWindowsMenuItems = ci->nActiveChildren;
00401 else
00402 nbWindowsMenuItems = MDI_MOREWINDOWSLIMIT + 1;
00403
00404 j = i - nbWindowsMenuItems + 1;
00405
00406 for( ; i >= j ; i-- )
00407 {
00408 memset(&mii, 0, sizeof(mii));
00409 mii.cbSize = sizeof(mii);
00410 mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE
00411 | MIIM_SUBMENU | MIIM_TYPE | MIIM_BITMAP;
00412
00413 GetMenuItemInfoW(ci->hWindowMenu, i, TRUE, &mii);
00414 if(mii.cch) {
00415 mii.cch++;
00416 buffer = HeapAlloc(GetProcessHeap(), 0,
00417 mii.cch * sizeof(WCHAR));
00418 mii.dwTypeData = buffer;
00419 GetMenuItemInfoW(ci->hWindowMenu, i, TRUE, &mii);
00420 }
00421 DeleteMenu(ci->hWindowMenu, i, MF_BYPOSITION);
00422 InsertMenuItemW(hmenuWindow, pos, TRUE, &mii);
00423 if(buffer) {
00424 HeapFree(GetProcessHeap(), 0, buffer);
00425 buffer = NULL;
00426 }
00427 }
00428 }
00429
00430
00431 DeleteMenu(ci->hWindowMenu, i, MF_BYPOSITION);
00432
00433 ci->hWindowMenu = hmenuWindow;
00434 }
00435
00436 if (hmenuFrame)
00437 {
00438 SetMenu(hwndFrame, hmenuFrame);
00439 if( hmenuFrame!=oldFrameMenu )
00440 {
00441 if( ci->hwndChildMaximized )
00442 MDI_AugmentFrameMenu( GetParent(hwnd), ci->hwndChildMaximized );
00443 return oldFrameMenu;
00444 }
00445 }
00446 else
00447 {
00448 HMENU menu = GetMenu( GetParent(hwnd) );
00449 INT nItems = GetMenuItemCount(menu) - 1;
00450 UINT iId = GetMenuItemID(menu,nItems) ;
00451
00452 if( !(iId == SC_RESTORE || iId == SC_CLOSE) )
00453 {
00454
00455
00456
00457
00458
00459
00460 if( ci->hwndChildMaximized )
00461 MDI_AugmentFrameMenu( GetParent(hwnd), ci->hwndChildMaximized );
00462 }
00463 }
00464 return 0;
00465 }
00466
00467
00468
00469
00470 static LRESULT MDIRefreshMenu( HWND hwnd, HMENU hmenuFrame,
00471 HMENU hmenuWindow)
00472 {
00473 HWND hwndFrame = GetParent(hwnd);
00474 HMENU oldFrameMenu = GetMenu(hwndFrame);
00475
00476 TRACE("%04x %04x %04x\n",
00477 hwnd, hmenuFrame, hmenuWindow);
00478
00479 FIXME("partially function stub\n");
00480
00481 return oldFrameMenu;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491 static HWND MDICreateChild( HWND parent, MDICLIENTINFO *ci,
00492 LPMDICREATESTRUCTA cs, BOOL unicode )
00493 {
00494 POINT pos[2];
00495 DWORD style = cs->style | (WS_CHILD | WS_CLIPSIBLINGS);
00496 HWND hwnd, hwndMax = 0;
00497 UINT wIDmenu = ci->idFirstChild + ci->nActiveChildren;
00498 #ifndef __WIN32OS2__
00499 WND *wndParent;
00500 #endif
00501 static const WCHAR lpstrDef[] = {'j','u','n','k','!',0};
00502
00503 TRACE("origin %i,%i - dim %i,%i, style %08lx\n",
00504 cs->x, cs->y, cs->cx, cs->cy, cs->style);
00505
00506 MDI_CalcDefaultChildPos(parent, ci->nTotalCreated++, pos, 0);
00507
00508 if (cs->cx == CW_USEDEFAULT || !cs->cx) cs->cx = pos[1].x;
00509 if (cs->cy == CW_USEDEFAULT || !cs->cy) cs->cy = pos[1].y;
00510
00511 if( cs->x == CW_USEDEFAULT )
00512 {
00513 cs->x = pos[0].x;
00514 cs->y = pos[0].y;
00515 }
00516
00517
00518 if( (style & WS_VISIBLE) && ci->hwndChildMaximized )
00519 {
00520 TRACE("Restoring current maximized child %04x\n", ci->hwndChildMaximized);
00521 if( style & WS_MAXIMIZE )
00522 SendMessageW(parent, WM_SETREDRAW, FALSE, 0L);
00523 hwndMax = ci->hwndChildMaximized;
00524 ShowWindow( hwndMax, SW_SHOWNOACTIVATE );
00525 if( style & WS_MAXIMIZE )
00526 SendMessageW(parent, WM_SETREDRAW, TRUE, 0L);
00527 }
00528
00529 if (ci->nActiveChildren <= MDI_MOREWINDOWSLIMIT)
00530
00531 if (ci->hWindowMenu != 0)
00532 AppendMenuW(ci->hWindowMenu, MF_STRING, wIDmenu, lpstrDef);
00533
00534 ci->nActiveChildren++;
00535
00536
00537 #ifdef __WIN32OS2__
00538 if( !(GetWindowLongA(parent, GWL_STYLE) & MDIS_ALLCHILDSTYLES) )
00539 #else
00540 wndParent = WIN_FindWndPtr( parent );
00541 if( !(wndParent->dwStyle & MDIS_ALLCHILDSTYLES) )
00542 #endif
00543 {
00544 TRACE("MDIS_ALLCHILDSTYLES is missing, fixing window style\n");
00545 style &= (WS_CHILD | WS_CLIPSIBLINGS | WS_MINIMIZE | WS_MAXIMIZE |
00546 WS_CLIPCHILDREN | WS_DISABLED | WS_VSCROLL | WS_HSCROLL );
00547 style |= (WS_VISIBLE | WS_OVERLAPPEDWINDOW);
00548 }
00549
00550 #ifndef __WIN32OS2__
00551 if( wndParent->flags & WIN_ISWIN32 )
00552 {
00553 WIN_ReleaseWndPtr( wndParent );
00554 #endif
00555 if(unicode)
00556 {
00557 MDICREATESTRUCTW *csW = (MDICREATESTRUCTW *)cs;
00558 hwnd = CreateWindowW( csW->szClass, csW->szTitle, style,
00559 csW->x, csW->y, csW->cx, csW->cy, parent,
00560 (HMENU)wIDmenu, csW->hOwner, csW );
00561 }
00562 else
00563 hwnd = CreateWindowA( cs->szClass, cs->szTitle, style,
00564 cs->x, cs->y, cs->cx, cs->cy, parent,
00565 (HMENU)wIDmenu, cs->hOwner, cs );
00566 #ifndef __WIN32OS2__
00567 }
00568 else
00569 {
00570 MDICREATESTRUCT16 *cs16;
00571 LPSTR title, cls;
00572
00573 WIN_ReleaseWndPtr( wndParent );
00574 cs16 = SEGPTR_NEW(MDICREATESTRUCT16);
00575 STRUCT32_MDICREATESTRUCT32Ato16( cs, cs16 );
00576 title = SEGPTR_STRDUP( cs->szTitle );
00577 cls = SEGPTR_STRDUP( cs->szClass );
00578 cs16->szTitle = SEGPTR_GET(title);
00579 cs16->szClass = SEGPTR_GET(cls);
00580
00581 hwnd = CreateWindow16( cs->szClass, cs->szTitle, style,
00582 cs16->x, cs16->y, cs16->cx, cs16->cy, parent,
00583 (HMENU)wIDmenu, cs16->hOwner,
00584 (LPVOID)SEGPTR_GET(cs16) );
00585 SEGPTR_FREE( title );
00586 SEGPTR_FREE( cls );
00587 SEGPTR_FREE( cs16 );
00588 }
00589 #endif
00590
00591
00592 if (hwnd)
00593 {
00594
00595 SetWindowLongW( hwnd, GWL_EXSTYLE, GetWindowLongW( hwnd, GWL_EXSTYLE ) | WS_EX_MDICHILD );
00596
00597
00598
00599
00600 if (ci->nActiveChildren > MDI_MOREWINDOWSLIMIT)
00601 MDI_SwapMenuItems( parent, GetWindowLongW( hwnd, GWL_ID ),
00602 ci->idFirstChild + MDI_MOREWINDOWSLIMIT - 1);
00603
00604 MDI_MenuModifyItem(parent, hwnd);
00605
00606
00607
00608
00609 if (ci->nActiveChildren == MDI_MOREWINDOWSLIMIT + 1)
00610 {
00611 WCHAR szTmp[50];
00612 LoadStringW(GetModuleHandleA("USER32"), MDI_IDS_MOREWINDOWS, szTmp, sizeof(szTmp)/sizeof(szTmp[0]));
00613
00614 ModifyMenuW(ci->hWindowMenu,
00615 ci->idFirstChild + MDI_MOREWINDOWSLIMIT,
00616 MF_BYCOMMAND | MF_STRING,
00617 ci->idFirstChild + MDI_MOREWINDOWSLIMIT,
00618 szTmp);
00619 }
00620
00621 if( IsIconic(hwnd) && ci->hwndActiveChild )
00622 {
00623 TRACE("Minimizing created MDI child %04x\n", hwnd);
00624 ShowWindow( hwnd, SW_SHOWMINNOACTIVE );
00625 }
00626 else
00627 {
00628
00629
00630
00631
00632
00633 if (IsWindowVisible(hwnd)) ShowWindow(hwnd, SW_SHOW);
00634 }
00635 TRACE("created child - %04x\n",hwnd);
00636 }
00637 else
00638 {
00639 ci->nActiveChildren--;
00640 DeleteMenu(ci->hWindowMenu,wIDmenu,MF_BYCOMMAND);
00641 if( IsWindow(hwndMax) )
00642 ShowWindow(hwndMax, SW_SHOWMAXIMIZED);
00643 }
00644
00645 return hwnd;
00646 }
00647
00648
00649
00650
00651
00652
00653
00654 static void MDI_ChildGetMinMaxInfo( HWND client, HWND hwnd, MINMAXINFO* lpMinMax )
00655 {
00656 RECT rect;
00657
00658 GetClientRect( client, &rect );
00659 AdjustWindowRectEx( &rect, GetWindowLongW( hwnd, GWL_STYLE ),
00660 0, GetWindowLongW( hwnd, GWL_EXSTYLE ));
00661
00662 lpMinMax->ptMaxSize.x = rect.right -= rect.left;
00663 lpMinMax->ptMaxSize.y = rect.bottom -= rect.top;
00664
00665 lpMinMax->ptMaxPosition.x = rect.left;
00666 lpMinMax->ptMaxPosition.y = rect.top;
00667
00668 TRACE("max rect (%i,%i - %i, %i)\n",
00669 rect.left,rect.top,rect.right,rect.bottom);
00670 }
00671
00672
00673
00674
00675
00676
00677
00678 static void MDI_SwitchActiveChild( HWND clientHwnd, HWND childHwnd,
00679 BOOL bNextWindow )
00680 {
00681 HWND hwndTo = 0;
00682 HWND hwndPrev = 0;
00683 MDICLIENTINFO *ci = get_client_info( clientHwnd );
00684
00685 hwndTo = MDI_GetWindow(ci, childHwnd, bNextWindow, 0);
00686
00687 TRACE("from %04x, to %04x\n",childHwnd,hwndTo);
00688
00689 if ( !hwndTo ) return;
00690
00691 hwndPrev = ci->hwndActiveChild;
00692
00693 if ( hwndTo != hwndPrev )
00694 {
00695 SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0,
00696 SWP_NOMOVE | SWP_NOSIZE );
00697
00698 if( bNextWindow && hwndPrev )
00699 SetWindowPos( hwndPrev, HWND_BOTTOM, 0, 0, 0, 0,
00700 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
00701 }
00702 }
00703
00704
00705
00706
00707
00708 static LRESULT MDIDestroyChild( HWND parent, MDICLIENTINFO *ci,
00709 HWND child, BOOL flagDestroy )
00710 {
00711 if( child == ci->hwndActiveChild )
00712 {
00713 MDI_SwitchActiveChild(parent, child, TRUE);
00714
00715 if( child == ci->hwndActiveChild )
00716 {
00717 ShowWindow( child, SW_HIDE);
00718 if( child == ci->hwndChildMaximized )
00719 {
00720 HWND frame = GetParent(parent);
00721 MDI_RestoreFrameMenu( frame, child );
00722 ci->hwndChildMaximized = 0;
00723 MDI_UpdateFrameText( frame, parent, TRUE, NULL);
00724 }
00725
00726 MDI_ChildActivate(parent, 0);
00727 }
00728 }
00729
00730 MDI_MenuDeleteItem(parent, child);
00731
00732 ci->nActiveChildren--;
00733
00734 TRACE("child destroyed - %04x\n",child);
00735
00736 if (flagDestroy)
00737 {
00738 MDI_PostUpdate(GetParent(child), ci, SB_BOTH+1);
00739 DestroyWindow(child);
00740 }
00741 return 0;
00742 }
00743
00744
00745
00746
00747
00748
00749
00750 static LONG MDI_ChildActivate( HWND client, HWND child )
00751 {
00752 MDICLIENTINFO *clientInfo = get_client_info( client );
00753 HWND prevActiveWnd = clientInfo->hwndActiveChild;
00754 BOOL isActiveFrameWnd;
00755
00756 #ifdef __WIN32OS2__
00757 if (!IsWindowEnabled( child )) {
00758 clientInfo->hwndActiveChild = 0;
00759 return 0;
00760 }
00761 #else
00762 if (!IsWindowEnabled( child )) return 0;
00763 #endif
00764
00765
00766
00767 if (clientInfo->hwndActiveChild == child) return 0;
00768
00769 TRACE("%04x\n", child);
00770
00771 isActiveFrameWnd = (GetActiveWindow() == GetParent(client));
00772
00773
00774 if(prevActiveWnd)
00775 {
00776 SetWindowLongA( prevActiveWnd, GWL_STYLE,
00777 GetWindowLongA( prevActiveWnd, GWL_STYLE ) | WS_SYSMENU );
00778 SendMessageA( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
00779 SendMessageA( prevActiveWnd, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child);
00780
00781 if( clientInfo->hWindowMenu )
00782 {
00783 UINT prevID = GetWindowLongA( prevActiveWnd, GWL_ID );
00784
00785 if (prevID - clientInfo->idFirstChild < MDI_MOREWINDOWSLIMIT)
00786 CheckMenuItem( clientInfo->hWindowMenu, prevID, 0);
00787 else
00788 CheckMenuItem( clientInfo->hWindowMenu,
00789 clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT - 1, 0);
00790 }
00791 }
00792
00793
00794 if (clientInfo->hwndChildMaximized && clientInfo->hwndChildMaximized != child)
00795 {
00796 if( child )
00797 {
00798 clientInfo->hwndActiveChild = child;
00799 ShowWindow( child, SW_SHOWMAXIMIZED);
00800 }
00801 else ShowWindow( clientInfo->hwndActiveChild, SW_SHOWNORMAL );
00802 }
00803
00804 clientInfo->hwndActiveChild = child;
00805
00806
00807 if( !child )
00808 {
00809 if( isActiveFrameWnd )
00810 SetFocus( client );
00811 return 0;
00812 }
00813
00814
00815 if( clientInfo->hWindowMenu )
00816 {
00817 UINT id = GetWindowLongA( child, GWL_ID );
00818
00819 if (id >= clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT)
00820 {
00821 MDI_SwapMenuItems( GetParent(child),
00822 id, clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT - 1);
00823 id = clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT - 1;
00824 MDI_MenuModifyItem( GetParent(child), child );
00825 }
00826
00827 CheckMenuItem(clientInfo->hWindowMenu, id, MF_CHECKED);
00828 }
00829
00830 SetWindowPos( child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
00831
00832 if( isActiveFrameWnd )
00833 {
00834 SendMessageA( child, WM_NCACTIVATE, TRUE, 0L);
00835 if( GetFocus() == client )
00836 SendMessageA( client, WM_SETFOCUS, (WPARAM)client, 0L );
00837 else
00838 SetFocus( client );
00839 }
00840 SendMessageA( child, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child );
00841 return TRUE;
00842 }
00843
00844
00845
00846
00847
00848
00849 static HBITMAP CreateMDIMenuBitmap(void)
00850 {
00851 HDC hDCSrc = CreateCompatibleDC(0);
00852 HDC hDCDest = CreateCompatibleDC(hDCSrc);
00853 HBITMAP hbClose = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE) );
00854 HBITMAP hbCopy;
00855 HBITMAP hobjSrc, hobjDest;
00856
00857 hobjSrc = SelectObject(hDCSrc, hbClose);
00858 hbCopy = CreateCompatibleBitmap(hDCSrc,GetSystemMetrics(SM_CXSIZE),GetSystemMetrics(SM_CYSIZE));
00859 hobjDest = SelectObject(hDCDest, hbCopy);
00860
00861 BitBlt(hDCDest, 0, 0, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
00862 hDCSrc, GetSystemMetrics(SM_CXSIZE), 0, SRCCOPY);
00863
00864 SelectObject(hDCSrc, hobjSrc);
00865 DeleteObject(hbClose);
00866 DeleteDC(hDCSrc);
00867
00868 hobjSrc = SelectObject( hDCDest, GetStockObject(BLACK_PEN) );
00869
00870 MoveToEx( hDCDest, GetSystemMetrics(SM_CXSIZE) - 1, 0, NULL );
00871 LineTo( hDCDest, GetSystemMetrics(SM_CXSIZE) - 1, GetSystemMetrics(SM_CYSIZE) - 1);
00872
00873 SelectObject(hDCDest, hobjSrc );
00874 SelectObject(hDCDest, hobjDest);
00875 DeleteDC(hDCDest);
00876
00877 return hbCopy;
00878 }
00879
00880
00881
00882
00883 static LONG MDICascade( HWND client, MDICLIENTINFO *ci )
00884 {
00885 HWND *win_array;
00886 BOOL has_icons = FALSE;
00887 int i, total;
00888
00889 if (ci->hwndChildMaximized)
00890 SendMessageA( client, WM_MDIRESTORE,
00891 (WPARAM)ci->hwndChildMaximized, 0);
00892
00893 if (ci->nActiveChildren == 0) return 0;
00894
00895 if (!(win_array = WIN_ListChildren( client ))) return 0;
00896
00897
00898 for (i = total = 0; win_array[i]; i++)
00899 {
00900 if (!IsWindowVisible( win_array[i] )) continue;
00901 if (GetWindow( win_array[i], GW_OWNER )) continue;
00902 if (IsIconic( win_array[i] ))
00903 {
00904 has_icons = TRUE;
00905 continue;
00906 }
00907 win_array[total++] = win_array[i];
00908 }
00909 win_array[total] = 0;
00910
00911 if (total)
00912 {
00913 INT delta = 0, n = 0, i;
00914 POINT pos[2];
00915 if (has_icons) delta = GetSystemMetrics(SM_CYICONSPACING) + GetSystemMetrics(SM_CYICON);
00916
00917
00918 for (i = total - 1; i >= 0; i--)
00919 {
00920 TRACE("move %04x to (%ld,%ld) size [%ld,%ld]\n",
00921 win_array[i], pos[0].x, pos[0].y, pos[1].x, pos[1].y);
00922
00923 MDI_CalcDefaultChildPos(client, n++, pos, delta);
00924 SetWindowPos( win_array[i], 0, pos[0].x, pos[0].y, pos[1].x, pos[1].y,
00925 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
00926 }
00927 }
00928 HeapFree( GetProcessHeap(), 0, win_array );
00929
00930 if (has_icons) ArrangeIconicWindows( client );
00931 return 0;
00932 }
00933
00934
00935
00936
00937 static void MDITile( HWND client, MDICLIENTINFO *ci, WPARAM wParam )
00938 {
00939 HWND *win_array;
00940 int i, total;
00941 BOOL has_icons = FALSE;
00942
00943 if (ci->hwndChildMaximized)
00944 SendMessageA( client, WM_MDIRESTORE, (WPARAM)ci->hwndChildMaximized, 0);
00945
00946 if (ci->nActiveChildren == 0) return;
00947
00948 if (!(win_array = WIN_ListChildren( client ))) return;
00949
00950
00951 for (i = total = 0; win_array[i]; i++)
00952 {
00953 if (!IsWindowVisible( win_array[i] )) continue;
00954 if (GetWindow( win_array[i], GW_OWNER )) continue;
00955 if (IsIconic( win_array[i] ))
00956 {
00957 has_icons = TRUE;
00958 continue;
00959 }
00960 if ((wParam & MDITILE_SKIPDISABLED) && !IsWindowEnabled( win_array[i] )) continue;
00961 win_array[total++] = win_array[i];
00962 }
00963 win_array[total] = 0;
00964
00965 TRACE("%u windows to tile\n", total);
00966
00967 if (total)
00968 {
00969 HWND *pWnd = win_array;
00970 RECT rect;
00971 int x, y, xsize, ysize;
00972 int rows, columns, r, c, i;
00973
00974 GetClientRect(client,&rect);
00975 rows = (int) sqrt((double)total);
00976 columns = total / rows;
00977
00978 if( wParam & MDITILE_HORIZONTAL )
00979 {
00980 i = rows;
00981 rows = columns;
00982 columns = i;
00983 }
00984
00985 if (has_icons)
00986 {
00987 y = rect.bottom - 2 * GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON);
00988 rect.bottom = ( y - GetSystemMetrics(SM_CYICON) < rect.top )? rect.bottom: y;
00989 }
00990
00991 ysize = rect.bottom / rows;
00992 xsize = rect.right / columns;
00993
00994 for (x = i = 0, c = 1; c <= columns && *pWnd; c++)
00995 {
00996 if (c == columns)
00997 {
00998 rows = total - i;
00999 ysize = rect.bottom / rows;
01000 }
01001
01002 y = 0;
01003 for (r = 1; r <= rows && *pWnd; r++, i++)
01004 {
01005 SetWindowPos(*pWnd, 0, x, y, xsize, ysize,
01006 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
01007 y += ysize;
01008 pWnd++;
01009 }
01010 x += xsize;
01011 }
01012 }
01013 HeapFree( GetProcessHeap(), 0, win_array );
01014 if (has_icons) ArrangeIconicWindows( client );
01015 }
01016
01017
01018
01019
01020
01021
01022
01023 static BOOL MDI_AugmentFrameMenu( HWND frame, HWND hChild )
01024 {
01025 HMENU menu = GetMenu( frame );
01026 #ifndef __WIN32OS2__
01027 WND* child = WIN_FindWndPtr(hChild);
01028 #endif
01029 HMENU hSysPopup = 0;
01030 HBITMAP hSysMenuBitmap = 0;
01031
01032 TRACE("frame %04x,child %04x\n",frame,hChild);
01033
01034 #ifdef __WIN32OS2__
01035 if( !menu || !getSysMenu(hChild) )
01036 {
01037 return 0;
01038 }
01039 #else
01040 if( !menu || !child->hSysMenu )
01041 {
01042 WIN_ReleaseWndPtr(child);
01043 return 0;
01044 }
01045 WIN_ReleaseWndPtr(child);
01046 #endif
01047
01048
01049
01050 if (!(hSysPopup = LoadMenuA(GetModuleHandleA("USER32"), "SYSMENU")))
01051 return 0;
01052
01053 AppendMenuA(menu,MF_HELP | MF_BITMAP,
01054 SC_MINIMIZE, (LPSTR)(DWORD)HBMMENU_MBAR_MINIMIZE ) ;
01055 AppendMenuA(menu,MF_HELP | MF_BITMAP,
01056 SC_RESTORE, (LPSTR)(DWORD)HBMMENU_MBAR_RESTORE );
01057
01058
01059
01060 #ifndef __WIN32OS2__
01061 if(TWEAK_WineLook > WIN31_LOOK)
01062 #endif
01063 {
01064 HICON hIcon = GetClassLongA(hChild, GCL_HICONSM);
01065 if (!hIcon)
01066 hIcon = GetClassLongA(hChild, GCL_HICON);
01067 if (hIcon)
01068 {
01069 HDC hMemDC;
01070 HBITMAP hBitmap, hOldBitmap;
01071 HBRUSH hBrush;
01072 HDC hdc = GetDC(hChild);
01073
01074 if (hdc)
01075 {
01076 int cx, cy;
01077 cx = GetSystemMetrics(SM_CXSMICON);
01078 cy = GetSystemMetrics(SM_CYSMICON);
01079 hMemDC = CreateCompatibleDC(hdc);
01080 hBitmap = CreateCompatibleBitmap(hdc, cx, cy);
01081 hOldBitmap = SelectObject(hMemDC, hBitmap);
01082 SetMapMode(hMemDC, MM_TEXT);
01083 hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU));
01084 DrawIconEx(hMemDC, 0, 0, hIcon, cx, cy, 0, hBrush, DI_NORMAL);
01085 SelectObject (hMemDC, hOldBitmap);
01086 DeleteObject(hBrush);
01087 DeleteDC(hMemDC);
01088 ReleaseDC(hChild, hdc);
01089 hSysMenuBitmap = hBitmap;
01090 }
01091 }
01092 }
01093 #ifndef __WIN32OS2__
01094 else
01095 hSysMenuBitmap = hBmpClose;
01096 #endif
01097
01098 if( !InsertMenuA(menu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP,
01099 hSysPopup, (LPSTR)(DWORD)hSysMenuBitmap))
01100 {
01101 TRACE("not inserted\n");
01102 DestroyMenu(hSysPopup);
01103 return 0;
01104 }
01105
01106
01107 #ifndef __WIN32OS2__
01108 if(TWEAK_WineLook > WIN31_LOOK)
01109 {
01110 #endif
01111 AppendMenuA(menu,MF_HELP | MF_BITMAP,
01112 SC_CLOSE, (LPSTR)(DWORD)HBMMENU_MBAR_CLOSE );
01113 #ifndef __WIN32OS2__
01114 }
01115 #endif
01116
01117 EnableMenuItem(hSysPopup, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
01118 EnableMenuItem(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
01119 EnableMenuItem(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
01120 SetMenuDefaultItem(hSysPopup, SC_CLOSE, FALSE);
01121
01122
01123 DrawMenuBar(frame);
01124
01125 return 1;
01126 }
01127
01128
01129
01130
01131 static BOOL MDI_RestoreFrameMenu( HWND frame, HWND hChild )
01132 {
01133 MENUITEMINFOW menuInfo;
01134 HMENU menu = GetMenu( frame );
01135 INT nItems = GetMenuItemCount(menu) - 1;
01136 UINT iId = GetMenuItemID(menu,nItems) ;
01137
01138 TRACE("frame %04x,child %04x,nIt=%d,iId=%d\n",frame,hChild,nItems,iId);
01139
01140 if(!(iId == SC_RESTORE || iId == SC_CLOSE) )
01141 return 0;
01142
01143
01144
01145
01146
01147 memset(&menuInfo, 0, sizeof(menuInfo));
01148 menuInfo.cbSize = sizeof(menuInfo);
01149 menuInfo.fMask = MIIM_DATA | MIIM_TYPE;
01150
01151 GetMenuItemInfoW(menu,
01152 0,
01153 TRUE,
01154 &menuInfo);
01155
01156 RemoveMenu(menu,0,MF_BYPOSITION);
01157
01158 if ( (menuInfo.fType & MFT_BITMAP) &&
01159 (LOWORD(menuInfo.dwTypeData)!=0) &&
01160 (LOWORD(menuInfo.dwTypeData)!=hBmpClose) )
01161 {
01162 DeleteObject((HBITMAP)LOWORD(menuInfo.dwTypeData));
01163 }
01164
01165 #ifndef __WIN32OS2__
01166 if(TWEAK_WineLook > WIN31_LOOK)
01167 {
01168 #endif
01169
01170 DeleteMenu(menu,GetMenuItemCount(menu) - 1,MF_BYPOSITION);
01171 #ifndef __WIN32OS2__
01172 }
01173 #endif
01174
01175 DeleteMenu(menu,GetMenuItemCount(menu) - 1,MF_BYPOSITION);
01176
01177 DeleteMenu(menu,GetMenuItemCount(menu) - 1,MF_BYPOSITION);
01178
01179 DrawMenuBar(frame);
01180
01181 return 1;
01182 }
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192 static void MDI_UpdateFrameText( HWND frame, HWND hClient,
01193 BOOL repaint, LPCWSTR lpTitle )
01194 {
01195 WCHAR lpBuffer[MDI_MAXTITLELENGTH+1];
01196 MDICLIENTINFO *ci = get_client_info( hClient );
01197
01198 TRACE("repaint %i, frameText %s\n", repaint, debugstr_w(lpTitle));
01199
01200 if (!ci) return;
01201
01202 if (!lpTitle && !ci->frameTitle)
01203 {
01204 GetWindowTextW( frame, lpBuffer, sizeof(lpBuffer)/sizeof(WCHAR) );
01205 lpTitle = lpBuffer;
01206 }
01207
01208
01209 if (lpTitle)
01210 {
01211 if (ci->frameTitle) HeapFree( GetProcessHeap(), 0, ci->frameTitle );
01212 if ((ci->frameTitle = HeapAlloc( GetProcessHeap(), 0, (strlenW(lpTitle)+1)*sizeof(WCHAR))))
01213 strcpyW( ci->frameTitle, lpTitle );
01214 }
01215
01216 if (ci->frameTitle)
01217 {
01218 if (ci->hwndChildMaximized)
01219 {
01220
01221
01222 static const WCHAR lpBracket[] = {' ','-',' ','[',0};
01223 static const WCHAR lpBracket2[] = {']',0};
01224 int i_frame_text_length = strlenW(ci->frameTitle);
01225
01226 lstrcpynW( lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH);
01227
01228 if( i_frame_text_length + 6 < MDI_MAXTITLELENGTH )
01229 {
01230 strcatW( lpBuffer, lpBracket );
01231 if (GetWindowTextW( ci->hwndChildMaximized, lpBuffer + i_frame_text_length + 4,
01232 MDI_MAXTITLELENGTH - i_frame_text_length - 5 ))
01233 strcatW( lpBuffer, lpBracket2 );
01234 else
01235 lpBuffer[i_frame_text_length] = 0;
01236 }
01237 }
01238 else
01239 {
01240 lstrcpynW(lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH+1 );
01241 }
01242 }
01243 else
01244 lpBuffer[0] = '\0';
01245
01246 DefWindowProcW( frame, WM_SETTEXT, 0, (LPARAM)lpBuffer );
01247 if( repaint == MDI_REPAINTFRAME)
01248 SetWindowPos( frame, 0,0,0,0,0, SWP_FRAMECHANGED |
01249 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
01250 }
01251
01252
01253
01254
01255
01256
01257
01258
01259 static LRESULT MDIClientWndProc_common( HWND hwnd, UINT message,
01260 WPARAM wParam, LPARAM lParam, BOOL unicode )
01261 {
01262 MDICLIENTINFO *ci;
01263
01264 if (!(ci = get_client_info( hwnd ))) return 0;
01265
01266 switch (message)
01267 {
01268 case WM_CREATE:
01269 {
01270 RECT rect;
01271
01272
01273 LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam;
01274 #ifndef __WIN32OS2__
01275 WND *wndPtr = WIN_FindWndPtr( hwnd );
01276
01277
01278
01279
01280 if( wndPtr->flags & WIN_ISWIN32 )
01281 {
01282 #endif
01283 #define ccs ((LPCLIENTCREATESTRUCT)cs->lpCreateParams)
01284 ci->hWindowMenu = ccs->hWindowMenu;
01285 ci->idFirstChild = ccs->idFirstChild;
01286 #undef ccs
01287 #ifndef __WIN32OS2__
01288 }
01289 else
01290 {
01291 LPCLIENTCREATESTRUCT16 ccs = MapSL((SEGPTR)cs->lpCreateParams);
01292 ci->hWindowMenu = ccs->hWindowMenu;
01293 ci->idFirstChild = ccs->idFirstChild;
01294 }
01295 WIN_ReleaseWndPtr( wndPtr );
01296 #endif
01297
01298 ci->hwndChildMaximized = 0;
01299 ci->nActiveChildren = 0;
01300 ci->nTotalCreated = 0;
01301 ci->frameTitle = NULL;
01302 ci->mdiFlags = 0;
01303 SetWindowLongW( hwnd, GWL_STYLE, GetWindowLongW(hwnd,GWL_STYLE) | WS_CLIPCHILDREN );
01304
01305 if (!hBmpClose)
01306 {
01307 hBmpClose = CreateMDIMenuBitmap();
01308 hBmpRestore = LoadBitmapW( 0, MAKEINTRESOURCEW(OBM_RESTORE) );
01309 }
01310
01311 if (ci->hWindowMenu != 0)
01312 AppendMenuW( ci->hWindowMenu, MF_SEPARATOR, 0, NULL );
01313
01314 GetClientRect( GetParent(hwnd), &rect);
01315 MoveWindow( hwnd, 0, 0, rect.right, rect.bottom, FALSE );
01316
01317 MDI_UpdateFrameText( GetParent(hwnd), hwnd, MDI_NOFRAMEREPAINT, NULL);
01318
01319 TRACE("Client created - hwnd = %04x, idFirst = %u\n",
01320 hwnd, ci->idFirstChild );
01321 return 0;
01322 }
01323
01324 case WM_DESTROY:
01325 {
01326 INT nItems;
01327 if( ci->hwndChildMaximized )
01328 MDI_RestoreFrameMenu( GetParent(hwnd), ci->hwndChildMaximized);
01329 if((ci->hWindowMenu != 0) &&
01330 (nItems = GetMenuItemCount(ci->hWindowMenu)) > 0)
01331 {
01332 ci->idFirstChild = nItems - 1;
01333 ci->nActiveChildren++;
01334 while( ci->nActiveChildren-- )
01335 DeleteMenu(ci->hWindowMenu,MF_BYPOSITION,ci->idFirstChild--);
01336 }
01337 if (ci->frameTitle) HeapFree( GetProcessHeap(), 0, ci->frameTitle );
01338 return 0;
01339 }
01340
01341 case WM_MDIACTIVATE:
01342 if( ci->hwndActiveChild != (HWND)wParam )
01343 SetWindowPos((HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
01344 return 0;
01345
01346 case WM_MDICASCADE:
01347 return MDICascade(hwnd, ci);
01348
01349 case WM_MDICREATE:
01350 if (lParam) return MDICreateChild( hwnd, ci,
01351 (MDICREATESTRUCTA *)lParam, unicode );
01352 else return 0;
01353
01354 case WM_MDIDESTROY:
01355 return MDIDestroyChild( hwnd, ci, WIN_GetFullHandle( (HWND)wParam ), TRUE );
01356
01357 case WM_MDIGETACTIVE:
01358 if (lParam) *(BOOL *)lParam = (ci->hwndChildMaximized != 0);
01359 return ci->hwndActiveChild;
01360
01361 case WM_MDIICONARRANGE:
01362 ci->mdiFlags |= MDIF_NEEDUPDATE;
01363 ArrangeIconicWindows( hwnd );
01364 ci->sbRecalc = SB_BOTH+1;
01365 SendMessageW( hwnd, WM_MDICALCCHILDSCROLL, 0, 0 );
01366 return 0;
01367
01368 case WM_MDIMAXIMIZE:
01369 ShowWindow( (HWND)wParam, SW_MAXIMIZE );
01370 return 0;
01371
01372 case WM_MDINEXT:
01373 MDI_SwitchActiveChild( hwnd, WIN_GetFullHandle( (HWND)wParam ), !lParam );
01374 break;
01375
01376 case WM_MDIRESTORE:
01377 SendMessageW( (HWND)wParam, WM_SYSCOMMAND, SC_RESTORE, 0);
01378 return 0;
01379
01380 case WM_MDISETMENU:
01381 return MDISetMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
01382
01383 case WM_MDIREFRESHMENU:
01384 return MDIRefreshMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
01385
01386 case WM_MDITILE:
01387 ci->mdiFlags |= MDIF_NEEDUPDATE;
01388 ShowScrollBar( hwnd, SB_BOTH, FALSE );
01389 MDITile( hwnd, ci, wParam );
01390 ci->mdiFlags &= ~MDIF_NEEDUPDATE;
01391 return 0;
01392
01393 case WM_VSCROLL:
01394 case WM_HSCROLL:
01395 ci->mdiFlags |= MDIF_NEEDUPDATE;
01396 ScrollChildren( hwnd, message, wParam, lParam );
01397 ci->mdiFlags &= ~MDIF_NEEDUPDATE;
01398 return 0;
01399
01400 case WM_SETFOCUS:
01401 if (ci->hwndActiveChild && !IsIconic( ci->hwndActiveChild ))
01402 SetFocus( ci->hwndActiveChild );
01403 return 0;
01404
01405 case WM_NCACTIVATE:
01406 if( ci->hwndActiveChild )
01407 SendMessageW(ci->hwndActiveChild, message, wParam, lParam);
01408 break;
01409
01410 case WM_PARENTNOTIFY:
01411 if (LOWORD(wParam) == WM_LBUTTONDOWN)
01412 {
01413 HWND child;
01414 POINT pt;
01415 pt.x = SLOWORD(lParam);
01416 pt.y = SHIWORD(lParam);
01417 child = ChildWindowFromPoint(hwnd, pt);
01418
01419 TRACE("notification from %04x (%li,%li)\n",child,pt.x,pt.y);
01420
01421 if( child && child != hwnd && child != ci->hwndActiveChild )
01422 SetWindowPos(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
01423 }
01424 return 0;
01425
01426 case WM_SIZE:
01427 if( IsWindow(ci->hwndChildMaximized) )
01428 {
01429 RECT rect;
01430
01431 rect.left = 0;
01432 rect.top = 0;
01433 rect.right = LOWORD(lParam);
01434 rect.bottom = HIWORD(lParam);
01435
01436 AdjustWindowRectEx(&rect, GetWindowLongA(ci->hwndChildMaximized,GWL_STYLE),
01437 0, GetWindowLongA(ci->hwndChildMaximized,GWL_EXSTYLE) );
01438 MoveWindow(ci->hwndChildMaximized, rect.left, rect.top,
01439 rect.right - rect.left, rect.bottom - rect.top, 1);
01440 }
01441 else
01442 MDI_PostUpdate(hwnd, ci, SB_BOTH+1);
01443
01444 break;
01445
01446 case WM_MDICALCCHILDSCROLL:
01447 if( (ci->mdiFlags & MDIF_NEEDUPDATE) && ci->sbRecalc )
01448 {
01449 CalcChildScroll(hwnd, ci->sbRecalc-1);
01450 ci->sbRecalc = 0;
01451 ci->mdiFlags &= ~MDIF_NEEDUPDATE;
01452 }
01453 return 0;
01454 }
01455 return unicode ? DefWindowProcW( hwnd, message, wParam, lParam ) :
01456 DefWindowProcA( hwnd, message, wParam, lParam );
01457 }
01458
01459
01460
01461
01462 #ifdef __WIN32OS2__
01463 LRESULT WINAPI MDIClientWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
01464 #else
01465 static LRESULT WINAPI MDIClientWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
01466 #endif
01467 {
01468 if (!IsWindow(hwnd)) return 0;
01469 return MDIClientWndProc_common( hwnd, message, wParam, lParam, FALSE );
01470 }
01471
01472
01473
01474
01475 static LRESULT WINAPI MDIClientWndProcW( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
01476 {
01477 if (!IsWindow(hwnd)) return 0;
01478 return MDIClientWndProc_common( hwnd, message, wParam, lParam, TRUE );
01479 }
01480
01481 #ifndef __WIN32OS2__
01482
01483
01484
01485 LRESULT WINAPI DefFrameProc16( HWND16 hwnd, HWND16 hwndMDIClient,
01486 UINT16 message, WPARAM16 wParam, LPARAM lParam )
01487 {
01488 switch (message)
01489 {
01490 case WM_SETTEXT:
01491 return DefFrameProcA( hwnd, hwndMDIClient, message, wParam, (LPARAM)MapSL(lParam) );
01492
01493 case WM_COMMAND:
01494 case WM_NCACTIVATE:
01495 case WM_SETFOCUS:
01496 case WM_SIZE:
01497 return DefFrameProcW( hwnd, hwndMDIClient, message, wParam, lParam );
01498
01499 case WM_NEXTMENU:
01500 {
01501 MDINEXTMENU next_menu;
01502 DefFrameProcW( hwnd, hwndMDIClient, message, wParam, (LPARAM)&next_menu );
01503 return MAKELONG( next_menu.hmenuNext, next_menu.hwndNext );
01504 }
01505 default:
01506 return DefWindowProc16(hwnd, message, wParam, lParam);
01507 }
01508 }
01509 #endif
01510
01511
01512
01513
01514 LRESULT WINAPI DefFrameProcA( HWND hwnd, HWND hwndMDIClient,
01515 UINT message, WPARAM wParam, LPARAM lParam)
01516 {
01517 if (hwndMDIClient)
01518 {
01519 switch (message)
01520 {
01521 case WM_SETTEXT:
01522 {
01523 LPWSTR text = HEAP_strdupAtoW( GetProcessHeap(), 0, (LPSTR)lParam );
01524 MDI_UpdateFrameText(hwnd, hwndMDIClient, MDI_REPAINTFRAME, text );
01525 HeapFree( GetProcessHeap(), 0, text );
01526 }
01527 return 1;
01528
01529 case WM_COMMAND:
01530 case WM_NCACTIVATE:
01531 case WM_NEXTMENU:
01532 case WM_SETFOCUS:
01533 case WM_SIZE:
01534 return DefFrameProcW( hwnd, hwndMDIClient, message, wParam, lParam );
01535 }
01536 }
01537 return DefWindowProcA(hwnd, message, wParam, lParam);
01538 }
01539
01540
01541
01542
01543
01544 LRESULT WINAPI DefFrameProcW( HWND hwnd, HWND hwndMDIClient,
01545 UINT message, WPARAM wParam, LPARAM lParam)
01546 {
01547 MDICLIENTINFO *ci = get_client_info( hwndMDIClient );
01548
01549 if (ci)
01550 {
01551 switch (message)
01552 {
01553 case WM_COMMAND:
01554 {
01555 WORD id = LOWORD(wParam);
01556
01557 if (id < ci->idFirstChild || id >= ci->idFirstChild + ci->nActiveChildren)
01558 {
01559 if( (id - 0xf000) & 0xf00f ) break;
01560 if( !ci->hwndChildMaximized ) break;
01561 switch( id )
01562 {
01563 case SC_SIZE:
01564 case SC_MOVE:
01565 case SC_MINIMIZE:
01566 case SC_MAXIMIZE:
01567 case SC_NEXTWINDOW:
01568 case SC_PREVWINDOW:
01569 case SC_CLOSE:
01570 case SC_RESTORE:
01571 return SendMessageW( ci->hwndChildMaximized, WM_SYSCOMMAND,
01572 wParam, lParam);
01573 }
01574 }
01575 else
01576 {
01577 HWND childHwnd;
01578 if (id - ci->idFirstChild == MDI_MOREWINDOWSLIMIT)
01579
01580 childHwnd = MDI_MoreWindowsDialog(hwndMDIClient);
01581 else
01582
01583 childHwnd = MDI_GetChildByID(hwndMDIClient,id);
01584
01585 if( childHwnd )
01586 SendMessageW( hwndMDIClient, WM_MDIACTIVATE, (WPARAM)childHwnd, 0 );
01587 }
01588 }
01589 break;
01590
01591 case WM_NCACTIVATE:
01592 SendMessageW(hwndMDIClient, message, wParam, lParam);
01593 break;
01594
01595 case WM_SETTEXT:
01596 MDI_UpdateFrameText(hwnd, hwndMDIClient, MDI_REPAINTFRAME, (LPWSTR)lParam );
01597 return 1;
01598
01599 case WM_SETFOCUS:
01600 SetFocus(hwndMDIClient);
01601 break;
01602
01603 case WM_SIZE:
01604 MoveWindow(hwndMDIClient, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
01605 break;
01606
01607 case WM_NEXTMENU:
01608 {
01609 MDINEXTMENU *next_menu = (MDINEXTMENU *)lParam;
01610
01611 if (!IsIconic(hwnd) && ci->hwndActiveChild && !ci->hwndChildMaximized)
01612 {
01613
01614
01615 #ifdef __WIN32OS2__
01616 if( (wParam == VK_LEFT && GetMenu(hwnd) == next_menu->hmenuIn) ||
01617 (wParam == VK_RIGHT && GetSubMenu(getSysMenu(hwnd), 0) == next_menu->hmenuIn) )
01618 {
01619 next_menu->hmenuNext = GetSubMenu(getSysMenu(ci->hwndActiveChild), 0);
01620 next_menu->hwndNext = ci->hwndActiveChild;
01621 }
01622 #else
01623
01624 WND *wndPtr = WIN_FindWndPtr(hwnd);
01625
01626 if( (wParam == VK_LEFT && GetMenu(hwnd) == next_menu->hmenuIn) ||
01627 (wParam == VK_RIGHT && GetSubMenu(wndPtr->hSysMenu, 0) == next_menu->hmenuIn) )
01628 {
01629 WIN_ReleaseWndPtr(wndPtr);
01630 wndPtr = WIN_FindWndPtr(ci->hwndActiveChild);
01631 next_menu->hmenuNext = GetSubMenu(wndPtr->hSysMenu, 0);
01632 next_menu->hwndNext = ci->hwndActiveChild;
01633 WIN_ReleaseWndPtr(wndPtr);
01634 }
01635 #endif
01636 }
01637 return 0;
01638 }
01639 }
01640 }
01641
01642 return DefWindowProcW( hwnd, message, wParam, lParam );
01643 }
01644
01645
01646 #ifndef __WIN32OS2__
01647
01648
01649
01650 LRESULT WINAPI DefMDIChildProc16( HWND16 hwnd, UINT16 message,
01651 WPARAM16 wParam, LPARAM lParam )
01652 {
01653 switch (message)
01654 {
01655 case WM_SETTEXT:
01656 return DefMDIChildProcA( WIN_Handle32(hwnd), message, wParam, (LPARAM)MapSL(lParam) );
01657 case WM_MENUCHAR:
01658 case WM_CLOSE:
01659 case WM_SETFOCUS:
01660 case WM_CHILDACTIVATE:
01661 case WM_SYSCOMMAND:
01662 case WM_SETVISIBLE:
01663 case WM_SIZE:
01664 case WM_SYSCHAR:
01665 return DefMDIChildProcW( WIN_Handle32(hwnd), message, wParam, lParam );
01666 case WM_GETMINMAXINFO:
01667 {
01668 MINMAXINFO16 *mmi16 = (MINMAXINFO16 *)MapSL(lParam);
01669 MINMAXINFO mmi;
01670 STRUCT32_MINMAXINFO16to32( mmi16, &mmi );
01671 DefMDIChildProcW( WIN_Handle32(hwnd), message, wParam, (LPARAM)&mmi );
01672 STRUCT32_MINMAXINFO32to16( &mmi, mmi16 );
01673 return 0;
01674 }
01675 case WM_NEXTMENU:
01676 {
01677 MDINEXTMENU next_menu;
01678 DefMDIChildProcW( WIN_Handle32(hwnd), message, wParam, (LPARAM)&next_menu );
01679 return MAKELONG( next_menu.hmenuNext, next_menu.hwndNext );
01680 }
01681 default:
01682 return DefWindowProc16(hwnd, message, wParam, lParam);
01683 }
01684 }
01685 #endif
01686
01687
01688
01689
01690 LRESULT WINAPI DefMDIChildProcA( HWND hwnd, UINT message,
01691 WPARAM wParam, LPARAM lParam )
01692 {
01693 HWND client = GetParent(hwnd);
01694 MDICLIENTINFO *ci = get_client_info( client );
01695
01696 hwnd = WIN_GetFullHandle( hwnd );
01697 if (!ci) return DefWindowProcA( hwnd, message, wParam, lParam );
01698
01699 switch (message)
01700 {
01701 case WM_SETTEXT:
01702 DefWindowProcA(hwnd, message, wParam, lParam);
01703 MDI_MenuModifyItem( client, hwnd );
01704 if( ci->hwndChildMaximized == hwnd )
01705 MDI_UpdateFrameText( GetParent(client), client, MDI_REPAINTFRAME, NULL );
01706 return 1;
01707
01708 case WM_GETMINMAXINFO:
01709 case WM_MENUCHAR:
01710 case WM_CLOSE:
01711 case WM_SETFOCUS:
01712 case WM_CHILDACTIVATE:
01713 case WM_SYSCOMMAND:
01714 case WM_SETVISIBLE:
01715 case WM_SIZE:
01716 case WM_NEXTMENU:
01717 case WM_SYSCHAR:
01718 return DefMDIChildProcW( hwnd, message, wParam, lParam );
01719 }
01720 return DefWindowProcA(hwnd, message, wParam, lParam);
01721 }
01722
01723
01724
01725
01726
01727 LRESULT WINAPI DefMDIChildProcW( HWND hwnd, UINT message,
01728 WPARAM wParam, LPARAM lParam )
01729 {
01730 HWND client = GetParent(hwnd);
01731 MDICLIENTINFO *ci = get_client_info( client );
01732
01733 hwnd = WIN_GetFullHandle( hwnd );
01734 if (!ci) return DefWindowProcW( hwnd, message, wParam, lParam );
01735
01736 switch (message)
01737 {
01738 case WM_SETTEXT:
01739 DefWindowProcW(hwnd, message, wParam, lParam);
01740 MDI_MenuModifyItem( client, hwnd );
01741 if( ci->hwndChildMaximized == hwnd )
01742 MDI_UpdateFrameText( GetParent(client), client, MDI_REPAINTFRAME, NULL );
01743 return 1;
01744
01745 case WM_GETMINMAXINFO:
01746 MDI_ChildGetMinMaxInfo( client, hwnd, (MINMAXINFO *)lParam );
01747 return 0;
01748
01749 case WM_MENUCHAR:
01750 return 0x00010000;
01751
01752 case WM_CLOSE:
01753 SendMessageW( client, WM_MDIDESTROY, (WPARAM)hwnd, 0 );
01754 return 0;
01755
01756 case WM_SETFOCUS:
01757 if (ci->hwndActiveChild != hwnd) MDI_ChildActivate( client, hwnd );
01758 break;
01759
01760 case WM_CHILDACTIVATE:
01761 MDI_ChildActivate( client, hwnd );
01762 return 0;
01763
01764 case WM_SYSCOMMAND:
01765 switch( wParam )
01766 {
01767 case SC_MOVE:
01768 if( ci->hwndChildMaximized == hwnd) return 0;
01769 break;
01770 case SC_RESTORE:
01771 case SC_MINIMIZE:
01772 SetWindowLongA( hwnd, GWL_STYLE,
01773 GetWindowLongA( hwnd, GWL_STYLE ) | WS_SYSMENU );
01774 break;
01775 case SC_MAXIMIZE:
01776 if (ci->hwndChildMaximized == hwnd)
01777 return SendMessageW( GetParent(client), message, wParam, lParam);
01778 SetWindowLongW( hwnd, GWL_STYLE,
01779 GetWindowLongW( hwnd, GWL_STYLE ) & ~WS_SYSMENU );
01780 break;
01781 case SC_NEXTWINDOW:
01782 SendMessageW( client, WM_MDINEXT, 0, 0);
01783 return 0;
01784 case SC_PREVWINDOW:
01785 SendMessageW( client, WM_MDINEXT, 0, 1);
01786 return 0;
01787 }
01788 break;
01789
01790 case WM_SETVISIBLE:
01791 if( ci->hwndChildMaximized) ci->mdiFlags &= ~MDIF_NEEDUPDATE;
01792 else MDI_PostUpdate(client, ci, SB_BOTH+1);
01793 break;
01794
01795 case WM_SIZE:
01796 if( ci->hwndActiveChild == hwnd && wParam != SIZE_MAXIMIZED )
01797 {
01798 ci->hwndChildMaximized = 0;
01799 MDI_RestoreFrameMenu( GetParent(client), hwnd );
01800 MDI_UpdateFrameText( GetParent(client), client, MDI_REPAINTFRAME, NULL );
01801 }
01802
01803 if( wParam == SIZE_MAXIMIZED )
01804 {
01805 HWND hMaxChild = ci->hwndChildMaximized;
01806
01807 if( hMaxChild == hwnd ) break;
01808 if( hMaxChild)
01809 {
01810 SendMessageW( hMaxChild, WM_SETREDRAW, FALSE, 0 );
01811 MDI_RestoreFrameMenu( GetParent(client), hMaxChild );
01812 ShowWindow( hMaxChild, SW_SHOWNOACTIVATE );
01813 SendMessageW( hMaxChild, WM_SETREDRAW, TRUE, 0 );
01814 }
01815 TRACE("maximizing child %04x\n", hwnd );
01816
01817
01818 ci->hwndChildMaximized = hwnd;
01819
01820
01821 MDI_ChildActivate( client, hwnd );
01822 MDI_AugmentFrameMenu( GetParent(client), hwnd );
01823 MDI_UpdateFrameText( GetParent(client), client, MDI_REPAINTFRAME, NULL );
01824 }
01825
01826 if( wParam == SIZE_MINIMIZED )
01827 {
01828 HWND switchTo = MDI_GetWindow(ci, hwnd, TRUE, WS_MINIMIZE);
01829
01830 if (switchTo) SendMessageW( switchTo, WM_CHILDACTIVATE, 0, 0);
01831 }
01832 MDI_PostUpdate(client, ci, SB_BOTH+1);
01833 break;
01834
01835 case WM_NEXTMENU:
01836 {
01837 MDINEXTMENU *next_menu = (MDINEXTMENU *)lParam;
01838 HWND parent = GetParent(client);
01839
01840 if( wParam == VK_LEFT )
01841 {
01842 #ifdef __WIN32OS2__
01843 next_menu->hmenuNext = GetSubMenu( getSysMenu(parent), 0 );
01844 #else
01845 WND *wndPtr = WIN_FindWndPtr( parent );
01846 next_menu->hmenuNext = GetSubMenu( wndPtr->hSysMenu, 0 );
01847 WIN_ReleaseWndPtr( wndPtr );
01848 #endif
01849 }
01850 if( wParam == VK_RIGHT )
01851 {
01852 next_menu->hmenuNext = GetMenu(parent);
01853 }
01854 next_menu->hwndNext = parent;
01855 return 0;
01856 }
01857
01858 case WM_SYSCHAR:
01859 if (wParam == '-')
01860 {
01861 SendMessageW( hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (DWORD)VK_SPACE);
01862 return 0;
01863 }
01864 break;
01865 }
01866 return DefWindowProcW(hwnd, message, wParam, lParam);
01867 }
01868
01869
01870
01871
01872
01873
01874
01875
01876 HWND WINAPI CreateMDIWindowA(
01877 LPCSTR lpClassName,
01878 LPCSTR lpWindowName,
01879 DWORD dwStyle,
01880 INT X,
01881 INT Y,
01882 INT nWidth,
01883 INT nHeight,
01884 HWND hWndParent,
01885 HINSTANCE hInstance,
01886 LPARAM lParam)
01887 {
01888 MDICLIENTINFO *pCi = get_client_info( hWndParent );
01889 MDICREATESTRUCTA cs;
01890
01891 TRACE("(%s,%s,%ld,%d,%d,%d,%d,%x,%d,%ld)\n",
01892 debugstr_a(lpClassName),debugstr_a(lpWindowName),dwStyle,X,Y,
01893 nWidth,nHeight,hWndParent,hInstance,lParam);
01894
01895 if (!pCi)
01896 {
01897 ERR("bad hwnd for MDI-client: %04x\n", hWndParent);
01898 return 0;
01899 }
01900 cs.szClass=lpClassName;
01901 cs.szTitle=lpWindowName;
01902 cs.hOwner=hInstance;
01903 cs.x=X;
01904 cs.y=Y;
01905 cs.cx=nWidth;
01906 cs.cy=nHeight;
01907 cs.style=dwStyle;
01908 cs.lParam=lParam;
01909
01910 return MDICreateChild(hWndParent, pCi, &cs, FALSE);
01911 }
01912
01913
01914
01915
01916
01917
01918
01919
01920 HWND WINAPI CreateMDIWindowW(
01921 LPCWSTR lpClassName,
01922 LPCWSTR lpWindowName,
01923 DWORD dwStyle,
01924 INT X,
01925 INT Y,
01926 INT nWidth,
01927 INT nHeight,
01928 HWND hWndParent,
01929 HINSTANCE hInstance,
01930 LPARAM lParam)
01931 {
01932 MDICLIENTINFO *pCi = get_client_info( hWndParent );
01933 MDICREATESTRUCTW cs;
01934
01935 TRACE("(%s,%s,%ld,%d,%d,%d,%d,%x,%d,%ld)\n",
01936 debugstr_w(lpClassName), debugstr_w(lpWindowName), dwStyle, X, Y,
01937 nWidth, nHeight, hWndParent, hInstance, lParam);
01938
01939 if (!pCi)
01940 {
01941 ERR("bad hwnd for MDI-client: %04x\n", hWndParent);
01942 return 0;
01943 }
01944 cs.szClass = lpClassName;
01945 cs.szTitle = lpWindowName;
01946 cs.hOwner = hInstance;
01947 cs.x = X;
01948 cs.y = Y;
01949 cs.cx = nWidth;
01950 cs.cy = nHeight;
01951 cs.style = dwStyle;
01952 cs.lParam = lParam;
01953
01954 return MDICreateChild(hWndParent, pCi, (MDICREATESTRUCTA *)&cs, TRUE);
01955 }
01956
01957 #ifndef __WIN32OS2__
01958
01959
01960
01961 BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
01962 {
01963 if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
01964 {
01965 MSG msg32;
01966 msg32.hwnd = msg->hwnd;
01967 msg32.message = msg->message;
01968 msg32.wParam = msg->wParam;
01969 msg32.lParam = msg->lParam;
01970
01971 return TranslateMDISysAccel(hwndClient, &msg32);
01972 }
01973 return 0;
01974 }
01975 #endif
01976
01977
01978
01979
01980 BOOL WINAPI TranslateMDISysAccel( HWND hwndClient, LPMSG msg )
01981 {
01982 if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
01983 {
01984 MDICLIENTINFO *ci = get_client_info( hwndClient );
01985 WPARAM wParam = 0;
01986
01987 if (!ci || !IsWindowEnabled(ci->hwndActiveChild)) return 0;
01988
01989
01990
01991 if( (GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_MENU) & 0x8000))
01992 {
01993 switch( msg->wParam )
01994 {
01995 case VK_F6:
01996 case VK_TAB:
01997 wParam = ( GetKeyState(VK_SHIFT) & 0x8000 ) ? SC_NEXTWINDOW : SC_PREVWINDOW;
01998 break;
01999 case VK_F4:
02000 case VK_RBUTTON:
02001 wParam = SC_CLOSE;
02002 break;
02003 default:
02004 return 0;
02005 }
02006 TRACE("wParam = %04x\n", wParam);
02007 SendMessageW(ci->hwndActiveChild, WM_SYSCOMMAND, wParam, (LPARAM)msg->wParam);
02008 return 1;
02009 }
02010 }
02011 return 0;
02012 }
02013
02014 #ifndef __WIN32OS2__
02015
02016
02017
02018 void WINAPI CalcChildScroll16( HWND16 hwnd, WORD scroll )
02019 {
02020 return CalcChildScroll( hwnd, scroll );
02021 }
02022 #endif
02023
02024
02025
02026
02027 void WINAPI CalcChildScroll( HWND hwnd, INT scroll )
02028 {
02029 SCROLLINFO info;
02030 RECT childRect, clientRect;
02031 INT vmin, vmax, hmin, hmax, vpos, hpos;
02032 HWND *list;
02033
02034 GetClientRect( hwnd, &clientRect );
02035 SetRectEmpty( &childRect );
02036
02037 if ((list = WIN_ListChildren( hwnd )))
02038 {
02039 int i;
02040 for (i = 0; list[i]; i++)
02041 {
02042 DWORD style = GetWindowLongW( list[i], GWL_STYLE );
02043 if (style & WS_MAXIMIZE)
02044 {
02045 HeapFree( GetProcessHeap(), 0, list );
02046 ShowScrollBar( hwnd, SB_BOTH, FALSE );
02047 return;
02048 }
02049 if (style & WS_VISIBLE)
02050 {
02051 #ifdef __WIN32OS2__
02052 RECT rect;
02053 GetWindowRectParent(list[i], &rect);
02054 UnionRect( &childRect, &rect, &childRect );
02055 #else
02056 WND *pWnd = WIN_FindWndPtr( list[i] );
02057 UnionRect( &childRect, &pWnd->rectWindow, &childRect );
02058 WIN_ReleaseWndPtr( pWnd );
02059 #endif
02060 }
02061 }
02062 HeapFree( GetProcessHeap(), 0, list );
02063 }
02064 UnionRect( &childRect, &clientRect, &childRect );
02065
02066 hmin = childRect.left;
02067 hmax = childRect.right - clientRect.right;
02068 hpos = clientRect.left - childRect.left;
02069 vmin = childRect.top;
02070 vmax = childRect.bottom - clientRect.bottom;
02071 vpos = clientRect.top - childRect.top;
02072
02073 switch( scroll )
02074 {
02075 case SB_HORZ:
02076 vpos = hpos; vmin = hmin; vmax = hmax;
02077 case SB_VERT:
02078 info.cbSize = sizeof(info);
02079 info.nMax = vmax; info.nMin = vmin; info.nPos = vpos;
02080 info.fMask = SIF_POS | SIF_RANGE;
02081 SetScrollInfo(hwnd, scroll, &info, TRUE);
02082 break;
02083 case SB_BOTH:
02084 SCROLL_SetNCSbState( hwnd, vmin, vmax, vpos,
02085 hmin, hmax, hpos);
02086 }
02087 }
02088
02089
02090 #ifndef __WIN32OS2__
02091
02092
02093
02094 void WINAPI ScrollChildren16(HWND16 hWnd, UINT16 uMsg, WPARAM16 wParam, LPARAM lParam)
02095 {
02096 ScrollChildren( hWnd, uMsg, wParam, lParam );
02097 }
02098 #endif
02099
02100
02101
02102
02103 void WINAPI ScrollChildren(HWND hWnd, UINT uMsg, WPARAM wParam,
02104 LPARAM lParam)
02105 {
02106 INT newPos = -1;
02107 INT curPos, length, minPos, maxPos, shift;
02108 RECT rect;
02109
02110 GetClientRect( hWnd, &rect );
02111
02112 switch(uMsg)
02113 {
02114 case WM_HSCROLL:
02115 GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos);
02116 curPos = GetScrollPos(hWnd,SB_HORZ);
02117 length = (rect.right - rect.left) / 2;
02118 shift = GetSystemMetrics(SM_CYHSCROLL);
02119 break;
02120 case WM_VSCROLL:
02121 GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos);
02122 curPos = GetScrollPos(hWnd,SB_VERT);
02123 length = (rect.bottom - rect.top) / 2;
02124 shift = GetSystemMetrics(SM_CXVSCROLL);
02125 break;
02126 default:
02127 return;
02128 }
02129
02130 switch( wParam )
02131 {
02132 case SB_LINEUP:
02133 newPos = curPos - shift;
02134 break;
02135 case SB_LINEDOWN:
02136 newPos = curPos + shift;
02137 break;
02138 case SB_PAGEUP:
02139 newPos = curPos - length;
02140 break;
02141 case SB_PAGEDOWN:
02142 newPos = curPos + length;
02143 break;
02144
02145 case SB_THUMBPOSITION:
02146 newPos = LOWORD(lParam);
02147 break;
02148
02149 case SB_THUMBTRACK:
02150 return;
02151
02152 case SB_TOP:
02153 newPos = minPos;
02154 break;
02155 case SB_BOTTOM:
02156 newPos = maxPos;
02157 break;
02158 case SB_ENDSCROLL:
02159 CalcChildScroll(hWnd,(uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ);
02160 return;
02161 }
02162
02163 if( newPos > maxPos )
02164 newPos = maxPos;
02165 else
02166 if( newPos < minPos )
02167 newPos = minPos;
02168
02169 SetScrollPos(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
02170
02171 if( uMsg == WM_VSCROLL )
02172 ScrollWindowEx(hWnd ,0 ,curPos - newPos, NULL, NULL, 0, NULL,
02173 SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
02174 else
02175 ScrollWindowEx(hWnd ,curPos - newPos, 0, NULL, NULL, 0, NULL,
02176 SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
02177 }
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187 WORD WINAPI
02188 CascadeWindows (HWND hwndParent, UINT wFlags, const LPRECT lpRect,
02189 UINT cKids, const HWND *lpKids)
02190 {
02191 FIXME("(0x%08x,0x%08x,...,%u,...): stub\n",
02192 hwndParent, wFlags, cKids);
02193
02194 return 0;
02195 }
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205 WORD WINAPI
02206 TileWindows (HWND hwndParent, UINT wFlags, const LPRECT lpRect,
02207 UINT cKids, const HWND *lpKids)
02208 {
02209 FIXME("(0x%08x,0x%08x,...,%u,...): stub\n",
02210 hwndParent, wFlags, cKids);
02211
02212 return 0;
02213 }
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228 static BOOL WINAPI MDI_MoreWindowsDlgProc (HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
02229 {
02230 switch (iMsg)
02231 {
02232 case WM_INITDIALOG:
02233 {
02234 UINT widest = 0;
02235 UINT length;
02236 UINT i;
02237 MDICLIENTINFO *ci = get_client_info( (HWND)lParam );
02238 HWND hListBox = GetDlgItem(hDlg, MDI_IDC_LISTBOX);
02239 HWND *list, *sorted_list;
02240
02241 if (!(list = WIN_ListChildren( (HWND)lParam ))) return TRUE;
02242 if (!(sorted_list = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
02243 sizeof(HWND) * ci->nActiveChildren )))
02244 {
02245 HeapFree( GetProcessHeap(), 0, list );
02246 return FALSE;
02247 }
02248
02249
02250 for (i = 0; list[i]; i++)
02251 {
02252 UINT id = GetWindowLongW( list[i], GWL_ID ) - ci->idFirstChild;
02253 if (id < ci->nActiveChildren) sorted_list[id] = list[i];
02254 }
02255 HeapFree( GetProcessHeap(), 0, list );
02256
02257 for (i = 0; i < ci->nActiveChildren; i++)
02258 {
02259 WCHAR buffer[128];
02260
02261 if (!GetWindowTextW( sorted_list[i], buffer, sizeof(buffer)/sizeof(WCHAR) ))
02262 continue;
02263 SendMessageW(hListBox, LB_ADDSTRING, 0, (LPARAM)buffer );
02264 SendMessageW(hListBox, LB_SETITEMDATA, i, (LPARAM)sorted_list[i] );
02265 length = strlenW(buffer);
02266 if (length > widest)
02267 widest = length;
02268 }
02269
02270 SendMessageW(hListBox, LB_SETHORIZONTALEXTENT, widest * 6, 0);
02271
02272
02273 SendMessageW(hListBox, LB_SETCURSEL, MDI_MOREWINDOWSLIMIT, 0);
02274 return TRUE;
02275 }
02276
02277 case WM_COMMAND:
02278 switch (LOWORD(wParam))
02279 {
02280 default:
02281 if (HIWORD(wParam) != LBN_DBLCLK) break;
02282
02283 case IDOK:
02284 {
02285
02286
02287
02288 HWND hListBox = GetDlgItem(hDlg, MDI_IDC_LISTBOX);
02289 UINT index = SendMessageW(hListBox, LB_GETCURSEL, 0, 0);
02290 HWND hwnd = SendMessageW(hListBox, LB_GETITEMDATA, index, 0);
02291
02292 EndDialog(hDlg, hwnd);
02293 return TRUE;
02294 }
02295 case IDCANCEL:
02296 EndDialog(hDlg, 0);
02297 return TRUE;
02298 }
02299 break;
02300 }
02301 return FALSE;
02302 }
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315 static HWND MDI_MoreWindowsDialog(HWND hwnd)
02316 {
02317 LPCVOID template;
02318 HRSRC hRes;
02319 HANDLE hDlgTmpl;
02320
02321 hRes = FindResourceA(GetModuleHandleA("USER32"), "MDI_MOREWINDOWS", RT_DIALOGA);
02322
02323 if (hRes == 0)
02324 return 0;
02325
02326 hDlgTmpl = LoadResource(GetModuleHandleA("USER32"), hRes );
02327
02328 if (hDlgTmpl == 0)
02329 return 0;
02330
02331 template = LockResource( hDlgTmpl );
02332
02333 if (template == 0)
02334 return 0;
02335
02336 return (HWND) DialogBoxIndirectParamA(GetModuleHandleA("USER32"),
02337 (LPDLGTEMPLATEA) template,
02338 hwnd, MDI_MoreWindowsDlgProc, (LPARAM) hwnd);
02339 }
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351 static void MDI_SwapMenuItems(HWND parent, UINT pos1, UINT pos2)
02352 {
02353 HWND *list;
02354 int i;
02355
02356 if (!(list = WIN_ListChildren( parent ))) return;
02357 for (i = 0; list[i]; i++)
02358 {
02359 UINT id = GetWindowLongW( list[i], GWL_ID );
02360 if (id == pos1) SetWindowLongW( list[i], GWL_ID, pos2 );
02361 else if (id == pos2) SetWindowLongW( list[i], GWL_ID, pos1 );
02362 }
02363 HeapFree( GetProcessHeap(), 0, list );
02364 }
02365
02366 #ifdef __WIN32OS2__
02367
02368 #define MDICLIENTCLASSNAMEA "MDICLIENT"
02369 #define MDICLIENTCLASSNAMEW L"MDICLIENT"
02370
02371
02372
02373 BOOL MDICLIENT_Register()
02374 {
02375 WNDCLASSA wndClass;
02376
02377
02378
02379
02380 ZeroMemory(&wndClass,sizeof(WNDCLASSA));
02381 wndClass.style = CS_GLOBALCLASS;
02382 wndClass.lpfnWndProc = (WNDPROC)MDIClientWndProcA;
02383 wndClass.cbClsExtra = 0;
02384 wndClass.cbWndExtra = 0;
02385 wndClass.hCursor = LoadCursorA(0,IDC_ARROWA);;
02386 wndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
02387 wndClass.lpszClassName = MDICLIENTCLASSNAMEA;
02388
02389 return RegisterClassA(&wndClass);
02390 }
02391
02392
02393 BOOL MDICLIENT_Unregister()
02394 {
02395 if (GlobalFindAtomA(MDICLIENTCLASSNAMEA))
02396 return UnregisterClassA(MDICLIENTCLASSNAMEA,(HINSTANCE)NULL);
02397 else return FALSE;
02398 }
02399
02400
02401 #endif