Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1 | /* MDI.C |
| 2 | * |
| 3 | * Copyright 1994, Bob Amstadt |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 4 | * 1995,1996 Alex Korobka |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 5 | * |
| 6 | * This file contains routines to support MDI features. |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 7 | * |
| 8 | * Notes: Windows keeps ID of MDI menu item in the wIDenu field |
| 9 | * of corresponding MDI child. |
| 10 | * |
| 11 | * Basic child activation routine is MDI_ChildActivate and |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 12 | * SetWindowPos(childHwnd,...) implicitly calls it if SWP_NOACTIVATE |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 13 | * is not used. |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 14 | * |
| 15 | * To fix: |
| 16 | * Sticky client crollbars |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 17 | */ |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 18 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 19 | #include <stdlib.h> |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 20 | #include <string.h> |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 21 | #include <stdio.h> |
Alexandre Julliard | 490a27e | 1994-06-08 13:57:50 +0000 | [diff] [blame] | 22 | #include <math.h> |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 23 | #include "xmalloc.h" |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 24 | #include "windows.h" |
| 25 | #include "win.h" |
Alexandre Julliard | 1850655 | 1995-01-24 16:21:01 +0000 | [diff] [blame] | 26 | #include "nonclient.h" |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 27 | #include "mdi.h" |
| 28 | #include "user.h" |
Alexandre Julliard | 234bc24 | 1994-12-10 13:02:28 +0000 | [diff] [blame] | 29 | #include "menu.h" |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 30 | #include "stackframe.h" |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 31 | #include "sysmetrics.h" |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 32 | #include "stddebug.h" |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 33 | #include "debug.h" |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 34 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 35 | void MDI_UpdateFrameText(WND *, HWND, BOOL, LPCSTR); |
| 36 | BOOL MDI_AugmentFrameMenu(MDICLIENTINFO*, WND *, HWND); |
| 37 | BOOL MDI_RestoreFrameMenu(WND *, HWND); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 38 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 39 | void ScrollChildren(HWND , UINT , WPARAM , LPARAM ); |
| 40 | void CalcChildScroll(HWND, WORD); |
| 41 | |
| 42 | /* ----------------- declarations ----------------- */ |
| 43 | |
| 44 | static LONG MDI_ChildActivate(WND* ,HWND ); |
| 45 | |
| 46 | /* -------- Miscellaneous service functions ---------- |
| 47 | * |
| 48 | * MDI_GetChildByID |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 49 | */ |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 50 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 51 | static HWND MDI_GetChildByID(WND* wndPtr,int id) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 52 | { |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 53 | for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next) |
| 54 | if (wndPtr->wIDmenu == id) return wndPtr->hwndSelf; |
| 55 | return 0; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 56 | } |
| 57 | |
Alexandre Julliard | e2991ea | 1995-07-29 13:09:43 +0000 | [diff] [blame] | 58 | /********************************************************************** |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 59 | * MDI_MenuAppendItem |
| 60 | */ |
Alexandre Julliard | d7d4fdf | 1995-12-26 15:05:24 +0000 | [diff] [blame] | 61 | #ifdef SUPERFLUOUS_FUNCTIONS |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 62 | static BOOL MDI_MenuAppendItem(WND *clientWnd, HWND hWndChild) |
| 63 | { |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 64 | char buffer[128]; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 65 | MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra; |
| 66 | WND *wndPtr = WIN_FindWndPtr(hWndChild); |
| 67 | LPSTR lpWndText = (LPSTR) USER_HEAP_LIN_ADDR(wndPtr->hText); |
| 68 | int n = sprintf(buffer, "%d ", |
| 69 | clientInfo->nActiveChildren); |
| 70 | |
| 71 | if( !clientInfo->hWindowMenu ) return 0; |
| 72 | |
| 73 | if( lpWndText ) |
| 74 | strncpy(buffer + n, lpWndText, sizeof(buffer) - n - 1); |
| 75 | return AppendMenu(clientInfo->hWindowMenu,MF_STRING, |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 76 | wndPtr->wIDmenu, MAKE_SEGPTR(buffer) ); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 77 | } |
Alexandre Julliard | d7d4fdf | 1995-12-26 15:05:24 +0000 | [diff] [blame] | 78 | #endif |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 79 | |
| 80 | /********************************************************************** |
| 81 | * MDI_MenuModifyItem |
| 82 | */ |
| 83 | static BOOL MDI_MenuModifyItem(WND* clientWnd, HWND hWndChild ) |
| 84 | { |
| 85 | char buffer[128]; |
| 86 | MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra; |
| 87 | WND *wndPtr = WIN_FindWndPtr(hWndChild); |
| 88 | LPSTR lpWndText = (LPSTR) USER_HEAP_LIN_ADDR(wndPtr->hText); |
| 89 | UINT n = sprintf(buffer, "%d ", |
| 90 | wndPtr->wIDmenu - clientInfo->idFirstChild + 1); |
| 91 | BOOL bRet = 0; |
| 92 | |
| 93 | if( !clientInfo->hWindowMenu ) return 0; |
| 94 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 95 | if( lpWndText ) lstrcpyn(buffer + n, lpWndText, sizeof(buffer) - n ); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 96 | |
| 97 | n = GetMenuState(clientInfo->hWindowMenu,wndPtr->wIDmenu ,MF_BYCOMMAND); |
| 98 | bRet = ModifyMenu(clientInfo->hWindowMenu , wndPtr->wIDmenu , |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 99 | MF_BYCOMMAND | MF_STRING, wndPtr->wIDmenu , |
| 100 | MAKE_SEGPTR(buffer) ); |
| 101 | CheckMenuItem(clientInfo->hWindowMenu ,wndPtr->wIDmenu , n & MF_CHECKED); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 102 | return bRet; |
| 103 | } |
| 104 | |
| 105 | /********************************************************************** |
| 106 | * MDI_MenuDeleteItem |
| 107 | */ |
| 108 | static BOOL MDI_MenuDeleteItem(WND* clientWnd, HWND hWndChild ) |
| 109 | { |
| 110 | char buffer[128]; |
| 111 | MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra; |
| 112 | WND *wndPtr = WIN_FindWndPtr(hWndChild); |
| 113 | LPSTR lpWndText; |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 114 | UINT index = 0,id,n; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 115 | |
| 116 | if( !clientInfo->nActiveChildren || |
| 117 | !clientInfo->hWindowMenu ) return 0; |
| 118 | |
| 119 | id = wndPtr->wIDmenu; |
| 120 | DeleteMenu(clientInfo->hWindowMenu,id,MF_BYCOMMAND); |
| 121 | |
| 122 | /* walk the rest of MDI children to prevent gaps in the id |
| 123 | * sequence and in the menu child list |
| 124 | */ |
| 125 | |
| 126 | for( index = id+1; index <= clientInfo->nActiveChildren + |
| 127 | clientInfo->idFirstChild; index++ ) |
| 128 | { |
| 129 | wndPtr = WIN_FindWndPtr(MDI_GetChildByID(clientWnd,index)); |
| 130 | if( !wndPtr ) |
| 131 | { |
| 132 | dprintf_mdi(stddeb,"MDIMenuDeleteItem: no window for id=%i\n",index); |
| 133 | continue; |
| 134 | } |
| 135 | |
| 136 | /* set correct id */ |
| 137 | wndPtr->wIDmenu--; |
| 138 | |
| 139 | n = sprintf(buffer, "%d ",index - clientInfo->idFirstChild); |
| 140 | lpWndText = (LPSTR) USER_HEAP_LIN_ADDR(wndPtr->hText); |
| 141 | |
| 142 | if( lpWndText ) |
| 143 | strncpy(buffer + n, lpWndText, sizeof(buffer) - n - 1); |
| 144 | |
| 145 | /* change menu */ |
| 146 | ModifyMenu(clientInfo->hWindowMenu ,index ,MF_BYCOMMAND | MF_STRING, |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 147 | index - 1 , MAKE_SEGPTR(buffer) ); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 148 | } |
| 149 | return 1; |
| 150 | } |
| 151 | |
| 152 | /********************************************************************** |
| 153 | * MDI_GetWindow |
| 154 | * |
| 155 | * returns "activateable" child or zero |
| 156 | */ |
| 157 | HWND MDI_GetWindow(WND *clientWnd, HWND hWnd, WORD wTo ) |
| 158 | { |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 159 | MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra; |
| 160 | WND *wndPtr, *pWnd, *pWndLast; |
| 161 | |
| 162 | if( !hWnd ) hWnd = clientInfo->hwndActiveChild; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 163 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 164 | if( !(wndPtr = WIN_FindWndPtr(hWnd)) ) return 0; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 165 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 166 | pWnd = wndPtr; |
| 167 | pWndLast = NULL; |
| 168 | for (;;) |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 169 | { |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 170 | pWnd = pWnd->next; |
| 171 | if (!pWnd) pWnd = wndPtr->parent->child; |
| 172 | if (pWnd == wndPtr) /* not found */ |
| 173 | { |
| 174 | if (!wTo || !pWndLast) return 0; |
| 175 | break; |
| 176 | } |
Alexandre Julliard | c981d0b | 1996-03-31 16:40:13 +0000 | [diff] [blame^] | 177 | |
| 178 | /* we are not interested in owned popups */ |
| 179 | if ( !pWnd->owner && |
| 180 | (pWnd->dwStyle & WS_VISIBLE) && |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 181 | !(pWnd->dwStyle & WS_DISABLED)) /* found one */ |
| 182 | { |
| 183 | pWndLast = pWnd; |
| 184 | if (!wTo) break; |
| 185 | } |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 186 | } |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 187 | return pWndLast ? pWndLast->hwndSelf : 0; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 188 | } |
| 189 | |
| 190 | |
| 191 | /********************************************************************** |
Alexandre Julliard | e2991ea | 1995-07-29 13:09:43 +0000 | [diff] [blame] | 192 | * MDISetMenu |
Alexandre Julliard | e2991ea | 1995-07-29 13:09:43 +0000 | [diff] [blame] | 193 | */ |
| 194 | HMENU MDISetMenu(HWND hwnd, BOOL fRefresh, HMENU hmenuFrame, HMENU hmenuWindow) |
| 195 | { |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 196 | WND *w = WIN_FindWndPtr(hwnd); |
| 197 | MDICLIENTINFO *ci; |
| 198 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 199 | dprintf_mdi(stddeb, "WM_MDISETMENU: %04x %04x %04x %04x\n", |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 200 | hwnd, fRefresh, hmenuFrame, hmenuWindow); |
| 201 | |
| 202 | ci = (MDICLIENTINFO *) w->wExtra; |
| 203 | |
| 204 | if (!fRefresh) |
| 205 | { |
Alexandre Julliard | e2991ea | 1995-07-29 13:09:43 +0000 | [diff] [blame] | 206 | HWND hwndFrame = GetParent(hwnd); |
| 207 | HMENU oldFrameMenu = GetMenu(hwndFrame); |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 208 | |
| 209 | if( ci->flagChildMaximized && hmenuFrame && hmenuFrame!=oldFrameMenu ) |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 210 | MDI_RestoreFrameMenu(w->parent, ci->flagChildMaximized ); |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 211 | |
| 212 | if( hmenuWindow && hmenuWindow!=ci->hWindowMenu ) |
| 213 | { |
| 214 | /* delete menu items from ci->hWindowMenu |
| 215 | * and add them to hmenuWindow */ |
| 216 | |
| 217 | INT i = GetMenuItemCount(ci->hWindowMenu) - 1; |
| 218 | INT pos = GetMenuItemCount(hmenuWindow) + 1; |
| 219 | |
| 220 | AppendMenu(hmenuWindow,MF_SEPARATOR,0,(SEGPTR)0); |
| 221 | |
| 222 | if( ci->nActiveChildren ) |
| 223 | { |
| 224 | INT j = i - ci->nActiveChildren + 1; |
| 225 | char buffer[100]; |
| 226 | UINT id,state; |
| 227 | |
| 228 | for( ; i >= j ; i-- ) |
| 229 | { |
| 230 | id = GetMenuItemID(ci->hWindowMenu,i ); |
| 231 | state = GetMenuState(ci->hWindowMenu,i,MF_BYPOSITION); |
| 232 | |
| 233 | GetMenuString(ci->hWindowMenu, i, buffer, 100, MF_BYPOSITION); |
| 234 | |
| 235 | DeleteMenu(ci->hWindowMenu, i , MF_BYPOSITION); |
| 236 | InsertMenu(hmenuWindow, pos, MF_BYPOSITION | MF_STRING, |
| 237 | id, MAKE_SEGPTR(buffer)); |
| 238 | CheckMenuItem(hmenuWindow ,pos , MF_BYPOSITION | (state & MF_CHECKED)); |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | /* remove separator */ |
| 243 | DeleteMenu(ci->hWindowMenu, i, MF_BYPOSITION); |
| 244 | |
| 245 | ci->hWindowMenu = hmenuWindow; |
| 246 | } |
| 247 | |
| 248 | if( hmenuFrame && hmenuFrame!=oldFrameMenu) |
| 249 | { |
| 250 | SetMenu(hwndFrame, hmenuFrame); |
| 251 | if( ci->flagChildMaximized ) |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 252 | MDI_AugmentFrameMenu(ci, w->parent, ci->flagChildMaximized ); |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 253 | return oldFrameMenu; |
| 254 | } |
| 255 | |
| 256 | } |
Alexandre Julliard | e2991ea | 1995-07-29 13:09:43 +0000 | [diff] [blame] | 257 | return 0; |
| 258 | } |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 259 | |
| 260 | /********************************************************************** |
| 261 | * MDIIconArrange |
| 262 | */ |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 263 | WORD MDIIconArrange(HWND parent) |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 264 | { |
| 265 | return ArrangeIconicWindows(parent); /* Any reason why the */ |
| 266 | /* existing icon arrange */ |
| 267 | /* can't be used here? */ |
| 268 | /* -DRP */ |
| 269 | } |
| 270 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 271 | |
| 272 | /* ------------------ MDI child window functions ---------------------- */ |
| 273 | |
| 274 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 275 | /********************************************************************** |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 276 | * MDICreateChild |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 277 | */ |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 278 | HWND MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPARAM lParam ) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 279 | { |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 280 | MDICREATESTRUCT *cs = (MDICREATESTRUCT *)PTR_SEG_TO_LIN(lParam); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 281 | HWND hwnd; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 282 | WORD wIDmenu = ci->idFirstChild + ci->nActiveChildren; |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 283 | int spacing; |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 284 | char* lpstrDef="junk!"; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 285 | |
| 286 | /* |
| 287 | * Create child window |
| 288 | */ |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 289 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 290 | cs->style &= (WS_MINIMIZE | WS_MAXIMIZE | WS_HSCROLL | WS_VSCROLL); |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 291 | |
| 292 | /* The child windows should probably */ |
| 293 | /* stagger, shouldn't they? -DRP */ |
| 294 | spacing = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME); |
| 295 | cs->x = ci->nActiveChildren * spacing; |
| 296 | cs->y = ci->nActiveChildren * spacing; |
| 297 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 298 | /* this menu is needed to set a check mark in MDI_ChildActivate */ |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 299 | AppendMenu(ci->hWindowMenu ,MF_STRING ,wIDmenu, MAKE_SEGPTR(lpstrDef) ); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 300 | |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 301 | ci->nActiveChildren++; |
| 302 | |
Alexandre Julliard | ff8331e | 1995-09-18 11:19:54 +0000 | [diff] [blame] | 303 | hwnd = CreateWindow( cs->szClass, cs->szTitle, |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 304 | WS_CHILD | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS | |
| 305 | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU | |
| 306 | WS_THICKFRAME | WS_VISIBLE | cs->style, |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 307 | cs->x, cs->y, cs->cx, cs->cy, parent, |
Alexandre Julliard | d7d4fdf | 1995-12-26 15:05:24 +0000 | [diff] [blame] | 308 | (HMENU)(DWORD)(WORD)wIDmenu, w->hInstance, |
| 309 | (SEGPTR)lParam); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 310 | |
| 311 | if (hwnd) |
| 312 | { |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 313 | MDI_MenuModifyItem(w ,hwnd); |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 314 | dprintf_mdi(stddeb, "MDICreateChild: created child - %04x\n",hwnd); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 315 | } |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 316 | else |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 317 | { |
| 318 | ci->nActiveChildren--; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 319 | DeleteMenu(ci->hWindowMenu,wIDmenu,MF_BYCOMMAND); |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 320 | } |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 321 | |
| 322 | return hwnd; |
| 323 | } |
| 324 | |
| 325 | /********************************************************************** |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 326 | * MDI_ChildGetMinMaxInfo |
| 327 | * |
| 328 | */ |
| 329 | void MDI_ChildGetMinMaxInfo(WND* clientWnd, HWND hwnd, MINMAXINFO* lpMinMax ) |
| 330 | { |
| 331 | WND* childWnd = WIN_FindWndPtr(hwnd); |
| 332 | RECT rect = clientWnd->rectClient; |
| 333 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 334 | MapWindowPoints(clientWnd->parent->hwndSelf, |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 335 | ((MDICLIENTINFO*)clientWnd->wExtra)->self, (LPPOINT)&rect, 2); |
| 336 | AdjustWindowRectEx(&rect, childWnd->dwStyle, 0, childWnd->dwExStyle); |
| 337 | |
| 338 | lpMinMax->ptMaxSize.x = rect.right -= rect.left; |
| 339 | lpMinMax->ptMaxSize.y = rect.bottom -= rect.top; |
| 340 | |
| 341 | lpMinMax->ptMaxPosition.x = rect.left; |
| 342 | lpMinMax->ptMaxPosition.y = rect.top; |
| 343 | } |
| 344 | |
| 345 | /********************************************************************** |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 346 | * MDI_SwitchActiveChild |
| 347 | * |
| 348 | * Notes: SetWindowPos sends WM_CHILDACTIVATE to the child window that is |
| 349 | * being activated |
| 350 | * |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 351 | * wTo is basically lParam of WM_MDINEXT message or explicit |
| 352 | * window handle |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 353 | */ |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 354 | void MDI_SwitchActiveChild(HWND clientHwnd, HWND childHwnd, BOOL wTo ) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 355 | { |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 356 | WND *w = WIN_FindWndPtr(clientHwnd); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 357 | HWND hwndTo = 0; |
| 358 | HWND hwndPrev = 0; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 359 | MDICLIENTINFO *ci; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 360 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 361 | hwndTo = MDI_GetWindow(w,childHwnd,(WORD)wTo); |
| 362 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 363 | ci = (MDICLIENTINFO *) w->wExtra; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 364 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 365 | dprintf_mdi(stddeb, "MDI_SwitchActiveChild: from %04x, to %04x\n",childHwnd,hwndTo); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 366 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 367 | if ( !hwndTo ) return; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 368 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 369 | hwndPrev = ci->hwndActiveChild; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 370 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 371 | if ( hwndTo != hwndPrev ) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 372 | { |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 373 | BOOL bSA = 0; |
| 374 | |
| 375 | if( ci->flagChildMaximized ) |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 376 | { |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 377 | bSA = 1; |
| 378 | w->dwStyle &= ~WS_VISIBLE; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 379 | } |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 380 | |
| 381 | SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, |
| 382 | SWP_NOMOVE | SWP_NOSIZE ); |
| 383 | if( !wTo && hwndPrev ) |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 384 | { |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 385 | SetWindowPos( hwndPrev, HWND_BOTTOM, 0, 0, 0, 0, |
| 386 | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 387 | } |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 388 | |
| 389 | if( bSA ) |
| 390 | ShowWindow( clientHwnd, SW_SHOW ); |
| 391 | } |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 392 | } |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 393 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 394 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 395 | /********************************************************************** |
| 396 | * MDIDestroyChild |
| 397 | */ |
| 398 | HWND MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent, |
| 399 | HWND child, BOOL flagDestroy) |
| 400 | { |
| 401 | WND *childPtr = WIN_FindWndPtr(child); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 402 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 403 | if( childPtr ) |
| 404 | { |
| 405 | if( child == ci->hwndActiveChild ) |
| 406 | { |
| 407 | MDI_SwitchActiveChild(parent,child,0); |
| 408 | |
| 409 | if( child == ci->hwndActiveChild ) |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 410 | { |
| 411 | ShowWindow( child, SW_HIDE); |
| 412 | if( child == ci->flagChildMaximized ) |
| 413 | { |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 414 | MDI_RestoreFrameMenu(w_parent->parent, child); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 415 | ci->flagChildMaximized = 0; |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 416 | MDI_UpdateFrameText(w_parent->parent,parent,TRUE,NULL); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 417 | } |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 418 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 419 | MDI_ChildActivate(w_parent,0); |
| 420 | } |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 421 | MDI_MenuDeleteItem(w_parent, child); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 422 | } |
| 423 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 424 | ci->nActiveChildren--; |
| 425 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 426 | dprintf_mdi(stddeb,"MDIDestroyChild: child destroyed - %04x\n",child); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 427 | |
| 428 | if (flagDestroy) |
| 429 | { |
| 430 | DestroyWindow(child); |
| 431 | PostMessage(parent,WM_MDICALCCHILDSCROLL,0,0L); |
| 432 | ci->sbRecalc |= (SB_BOTH+1); |
| 433 | } |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 434 | } |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 435 | |
| 436 | return 0; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 437 | } |
| 438 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 439 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 440 | /********************************************************************** |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 441 | * MDI_ChildActivate |
| 442 | * |
| 443 | * Note: hWndChild is NULL when last child is being destroyed |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 444 | */ |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 445 | LONG MDI_ChildActivate(WND *clientPtr, HWND hWndChild) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 446 | { |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 447 | MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientPtr->wExtra; |
| 448 | HWND prevActiveWnd = clientInfo->hwndActiveChild; |
| 449 | WND *wndPtr = WIN_FindWndPtr( hWndChild ); |
| 450 | WND *wndPrev = WIN_FindWndPtr( prevActiveWnd ); |
| 451 | BOOL isActiveFrameWnd = 0; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 452 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 453 | if( hWndChild == prevActiveWnd ) return 0L; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 454 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 455 | if( wndPtr ) |
| 456 | if( wndPtr->dwStyle & WS_DISABLED ) return 0L; |
| 457 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 458 | dprintf_mdi(stddeb,"MDI_ChildActivate: %04x\n", hWndChild); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 459 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 460 | if( GetActiveWindow() == clientPtr->parent->hwndSelf ) |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 461 | isActiveFrameWnd = TRUE; |
| 462 | |
| 463 | /* deactivate prev. active child */ |
| 464 | if( wndPrev ) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 465 | { |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 466 | SendMessage( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L ); |
Alexandre Julliard | d7d4fdf | 1995-12-26 15:05:24 +0000 | [diff] [blame] | 467 | #ifdef WINELIB32 |
| 468 | SendMessage( prevActiveWnd, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, |
| 469 | (LPARAM)hWndChild); |
| 470 | #else |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 471 | SendMessage( prevActiveWnd, WM_MDIACTIVATE, FALSE, |
| 472 | MAKELONG(hWndChild,prevActiveWnd)); |
Alexandre Julliard | d7d4fdf | 1995-12-26 15:05:24 +0000 | [diff] [blame] | 473 | #endif |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 474 | /* uncheck menu item */ |
| 475 | if( clientInfo->hWindowMenu ) |
| 476 | CheckMenuItem( clientInfo->hWindowMenu, |
| 477 | wndPrev->wIDmenu, 0); |
| 478 | } |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 479 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 480 | /* set appearance */ |
| 481 | if( clientInfo->flagChildMaximized ) |
| 482 | if( clientInfo->flagChildMaximized != hWndChild ) |
| 483 | if( hWndChild ) |
| 484 | { |
| 485 | clientInfo->hwndActiveChild = hWndChild; |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 486 | ShowWindow( hWndChild, SW_SHOWMAXIMIZED); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 487 | } |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 488 | else |
| 489 | ShowWindow( clientInfo->hwndActiveChild, |
| 490 | SW_SHOWNORMAL ); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 491 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 492 | clientInfo->hwndActiveChild = hWndChild; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 493 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 494 | /* check if we have any children left */ |
| 495 | if( !hWndChild ) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 496 | { |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 497 | if( isActiveFrameWnd ) |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 498 | SetFocus( clientInfo->self ); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 499 | return 0; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 500 | } |
| 501 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 502 | /* check menu item */ |
| 503 | if( clientInfo->hWindowMenu ) |
| 504 | CheckMenuItem( clientInfo->hWindowMenu, |
| 505 | wndPtr->wIDmenu, MF_CHECKED); |
| 506 | |
| 507 | /* bring active child to the top */ |
| 508 | SetWindowPos( hWndChild, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); |
| 509 | |
| 510 | if( isActiveFrameWnd ) |
| 511 | { |
| 512 | SendMessage( hWndChild, WM_NCACTIVATE, TRUE, 0L); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 513 | if( GetFocus() == clientInfo->self ) |
| 514 | SendMessage( clientInfo->self, WM_SETFOCUS, |
| 515 | (WPARAM)clientInfo->self, 0L ); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 516 | else |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 517 | SetFocus( clientInfo->self ); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 518 | } |
| 519 | |
Alexandre Julliard | d7d4fdf | 1995-12-26 15:05:24 +0000 | [diff] [blame] | 520 | #ifdef WINELIB32 |
| 521 | SendMessage( hWndChild, WM_MDIACTIVATE, (WPARAM)hWndChild, |
| 522 | (LPARAM)prevActiveWnd ); |
| 523 | #else |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 524 | SendMessage( hWndChild, WM_MDIACTIVATE, TRUE, |
| 525 | MAKELONG(prevActiveWnd,hWndChild) ); |
Alexandre Julliard | d7d4fdf | 1995-12-26 15:05:24 +0000 | [diff] [blame] | 526 | #endif |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 527 | |
| 528 | return 1; |
| 529 | } |
| 530 | |
| 531 | /********************************************************************** |
| 532 | * MDI_BuildWCL |
| 533 | * |
| 534 | * iTotal returns number of children available for tiling or cascading |
| 535 | */ |
| 536 | MDIWCL* MDI_BuildWCL(WND* clientWnd, int* iTotal) |
| 537 | { |
| 538 | MDIWCL *listTop,*listNext; |
| 539 | WND *childWnd; |
| 540 | |
| 541 | if (!(listTop = (MDIWCL*)malloc( sizeof(MDIWCL) ))) return NULL; |
| 542 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 543 | listTop->hChild = clientWnd->child ? clientWnd->child->hwndSelf : 0; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 544 | listTop->prev = NULL; |
| 545 | *iTotal = 1; |
| 546 | |
| 547 | /* build linked list from top child to bottom */ |
| 548 | |
| 549 | childWnd = WIN_FindWndPtr( listTop->hChild ); |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 550 | while( childWnd && childWnd->next ) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 551 | { |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 552 | listNext = (MDIWCL*)xmalloc(sizeof(MDIWCL)); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 553 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 554 | if( (childWnd->dwStyle & WS_DISABLED) || |
| 555 | (childWnd->dwStyle & WS_MINIMIZE) || |
| 556 | !(childWnd->dwStyle & WS_VISIBLE) ) |
| 557 | { |
| 558 | listTop->hChild = 0; |
| 559 | (*iTotal)--; |
| 560 | } |
| 561 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 562 | listNext->hChild = childWnd->next->hwndSelf; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 563 | listNext->prev = listTop; |
| 564 | listTop = listNext; |
| 565 | (*iTotal)++; |
| 566 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 567 | childWnd = childWnd->next; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 568 | } |
| 569 | |
| 570 | if( (childWnd->dwStyle & WS_DISABLED) || |
| 571 | (childWnd->dwStyle & WS_MINIMIZE) || |
| 572 | !(childWnd->dwStyle & WS_VISIBLE) ) |
| 573 | { |
| 574 | listTop->hChild = 0; |
| 575 | (*iTotal)--; |
| 576 | } |
| 577 | |
| 578 | return listTop; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 579 | } |
| 580 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 581 | |
| 582 | /* -------------------- MDI client window functions ------------------- */ |
| 583 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 584 | /********************************************************************** |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 585 | * CreateMDIMenuBitmap |
| 586 | */ |
| 587 | HBITMAP CreateMDIMenuBitmap(void) |
| 588 | { |
| 589 | HDC hDCSrc = CreateCompatibleDC(0); |
| 590 | HDC hDCDest = CreateCompatibleDC(hDCSrc); |
| 591 | HBITMAP hbClose = LoadBitmap(0, MAKEINTRESOURCE(OBM_CLOSE) ); |
| 592 | HBITMAP hbCopy,hb_src,hb_dest; |
| 593 | |
| 594 | hb_src = SelectObject(hDCSrc,hbClose); |
| 595 | hbCopy = CreateCompatibleBitmap(hDCSrc,SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE); |
| 596 | hb_dest = SelectObject(hDCDest,hbCopy); |
| 597 | |
| 598 | BitBlt(hDCDest, 0, 0, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE, |
| 599 | hDCSrc, SYSMETRICS_CXSIZE, 0, SRCCOPY); |
| 600 | |
| 601 | SelectObject(hDCSrc,hb_src); |
| 602 | SelectObject(hDCDest,hb_dest); |
| 603 | |
| 604 | DeleteObject(hbClose); |
| 605 | |
| 606 | DeleteDC(hDCDest); |
| 607 | DeleteDC(hDCSrc); |
| 608 | |
| 609 | return hbCopy; |
| 610 | } |
| 611 | |
| 612 | /********************************************************************** |
| 613 | * MDICascade |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 614 | */ |
| 615 | LONG MDICascade(HWND parent, MDICLIENTINFO *ci) |
| 616 | { |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 617 | WND *clientWnd; |
| 618 | MDIWCL *listTop,*listPrev; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 619 | RECT rect; |
| 620 | int spacing, xsize, ysize; |
| 621 | int x, y; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 622 | int iToPosition = 0; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 623 | |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 624 | if (ci->flagChildMaximized) |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 625 | ShowWindow( ci->flagChildMaximized, SW_NORMAL); |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 626 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 627 | if (ci->nActiveChildren == 0) return 0; |
Alexandre Julliard | 7cbe657 | 1995-01-09 18:21:16 +0000 | [diff] [blame] | 628 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 629 | GetClientRect(parent, &rect); |
| 630 | spacing = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME); |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 631 | ysize = rect.bottom - 8 * spacing; |
| 632 | xsize = rect.right - 8 * spacing; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 633 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 634 | dprintf_mdi(stddeb, "MDICascade: Client wnd at (%d,%d) - (%d,%d), spacing %d\n", |
| 635 | rect.left, rect.top, rect.right, rect.bottom, spacing); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 636 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 637 | clientWnd = WIN_FindWndPtr( parent ); |
| 638 | |
| 639 | listTop = MDI_BuildWCL(clientWnd,&iToPosition); |
| 640 | |
| 641 | if( !listTop ) return 0; |
| 642 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 643 | x = 0; |
| 644 | y = 0; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 645 | |
| 646 | /* walk list and move windows */ |
| 647 | while ( listTop ) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 648 | { |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 649 | dprintf_mdi(stddeb, "MDICascade: move %04x to (%d,%d) size [%d,%d]\n", |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 650 | listTop->hChild, x, y, xsize, ysize); |
| 651 | |
| 652 | if( listTop->hChild ) |
| 653 | { |
| 654 | SetWindowPos(listTop->hChild, 0, x, y, xsize, ysize, |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 655 | SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER); |
| 656 | |
| 657 | x += spacing; |
| 658 | y += spacing; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 659 | } |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 660 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 661 | listPrev = listTop->prev; |
| 662 | free(listTop); |
| 663 | listTop = listPrev; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 664 | } |
| 665 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 666 | if( iToPosition < ci->nActiveChildren ) |
| 667 | ArrangeIconicWindows( parent ); |
| 668 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 669 | return 0; |
| 670 | } |
| 671 | |
| 672 | /********************************************************************** |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 673 | * MDITile |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 674 | * |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 675 | */ |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 676 | LONG MDITile(HWND parent, MDICLIENTINFO *ci,WORD wParam) |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 677 | { |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 678 | WND *wndClient = WIN_FindWndPtr(parent); |
| 679 | MDIWCL *listTop,*listPrev; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 680 | RECT rect; |
| 681 | int xsize, ysize; |
| 682 | int x, y; |
| 683 | int rows, columns; |
| 684 | int r, c; |
| 685 | int i; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 686 | int iToPosition = 0; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 687 | |
| 688 | if (ci->flagChildMaximized) |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 689 | ShowWindow(ci->flagChildMaximized, SW_NORMAL); |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 690 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 691 | if (ci->nActiveChildren == 0) return 0; |
| 692 | |
| 693 | listTop = MDI_BuildWCL(wndClient, &iToPosition); |
| 694 | |
| 695 | dprintf_mdi(stddeb,"MDITile: %i windows to tile\n",iToPosition); |
| 696 | |
| 697 | if( !listTop ) return 0; |
Alexandre Julliard | 7cbe657 | 1995-01-09 18:21:16 +0000 | [diff] [blame] | 698 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 699 | /* tile children */ |
| 700 | if ( iToPosition ) |
| 701 | { |
Alexandre Julliard | d7d4fdf | 1995-12-26 15:05:24 +0000 | [diff] [blame] | 702 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 703 | GetClientRect(parent, &rect); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 704 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 705 | rows = (int) sqrt((double) iToPosition); |
| 706 | columns = iToPosition / rows; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 707 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 708 | if (wParam == MDITILE_HORIZONTAL) /* version >= 3.1 */ |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 709 | { |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 710 | i=rows; |
| 711 | rows=columns; /* exchange r and c */ |
| 712 | columns=i; |
| 713 | } |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 714 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 715 | /* hack */ |
| 716 | if( iToPosition != ci->nActiveChildren) |
| 717 | { |
| 718 | y = rect.bottom - 2 * SYSMETRICS_CYICONSPACING - SYSMETRICS_CYICON; |
| 719 | rect.bottom = ( y - SYSMETRICS_CYICON < rect.top )? rect.bottom: y; |
| 720 | } |
| 721 | |
| 722 | ysize = rect.bottom / rows; |
| 723 | xsize = rect.right / columns; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 724 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 725 | x = 0; |
| 726 | i = 0; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 727 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 728 | for (c = 1; c <= columns; c++) |
| 729 | { |
| 730 | if (c == columns) |
| 731 | { |
| 732 | rows = iToPosition - i; |
| 733 | ysize = rect.bottom / rows; |
| 734 | } |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 735 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 736 | y = 0; |
| 737 | for (r = 1; r <= rows; r++, i++) |
| 738 | { |
| 739 | /* shouldn't happen but... */ |
| 740 | if( !listTop ) |
| 741 | break; |
| 742 | |
| 743 | if( listTop->hChild ) |
| 744 | { |
| 745 | SetWindowPos(listTop->hChild, 0, x, y, xsize, ysize, |
| 746 | SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER); |
| 747 | y += ysize; |
| 748 | } |
| 749 | listPrev = listTop->prev; |
| 750 | free(listTop); |
| 751 | listTop = listPrev; |
| 752 | } |
| 753 | x += xsize; |
| 754 | } |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 755 | } |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 756 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 757 | /* free the rest if any */ |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 758 | while( listTop ) |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 759 | { |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 760 | listPrev = listTop->prev; |
| 761 | free(listTop); |
| 762 | listTop = listPrev; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 763 | } |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 764 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 765 | if (iToPosition < ci->nActiveChildren ) |
| 766 | ArrangeIconicWindows( parent ); |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 767 | |
Alexandre Julliard | 1850655 | 1995-01-24 16:21:01 +0000 | [diff] [blame] | 768 | return 0; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 769 | } |
| 770 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 771 | /* ----------------------- Frame window ---------------------------- */ |
| 772 | |
| 773 | |
| 774 | /********************************************************************** |
| 775 | * MDI_AugmentFrameMenu |
| 776 | */ |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 777 | BOOL MDI_AugmentFrameMenu(MDICLIENTINFO* ci, WND *frame, HWND hChild) |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 778 | { |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 779 | WND* child = WIN_FindWndPtr(hChild); |
| 780 | HMENU hSysPopup = 0; |
| 781 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 782 | dprintf_mdi(stddeb,"MDI_AugmentFrameMenu: frame %p,child %04x\n",frame,hChild); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 783 | |
| 784 | if( !frame->wIDmenu || !child->hSysMenu ) return 0; |
| 785 | |
| 786 | hSysPopup = GetSystemMenu(hChild,FALSE); |
| 787 | |
Alexandre Julliard | c981d0b | 1996-03-31 16:40:13 +0000 | [diff] [blame^] | 788 | dprintf_mdi(stddeb,"\t\tgot popup %04x\n in sysmenu %04x",hSysPopup,child->hSysMenu); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 789 | |
| 790 | if( !InsertMenu(frame->wIDmenu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP, |
| 791 | hSysPopup, (SEGPTR)(DWORD)ci->obmClose) ) |
| 792 | return 0; |
| 793 | |
| 794 | if( !AppendMenu(frame->wIDmenu,MF_HELP | MF_BITMAP, |
| 795 | SC_RESTORE, (SEGPTR)(DWORD)ci->obmRestore) ) |
| 796 | { |
| 797 | RemoveMenu(frame->wIDmenu,0,MF_BYPOSITION); |
| 798 | return 0; |
| 799 | } |
| 800 | |
Alexandre Julliard | c981d0b | 1996-03-31 16:40:13 +0000 | [diff] [blame^] | 801 | /* FIXME: add a call to function that sets sysmenu items according |
| 802 | * to the window state. WS_MAXIMIZE -> no SC_SIZE, etc... |
| 803 | */ |
| 804 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 805 | EnableMenuItem(hSysPopup, SC_SIZE, MF_BYCOMMAND | MF_GRAYED); |
| 806 | EnableMenuItem(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED); |
| 807 | EnableMenuItem(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED); |
| 808 | |
| 809 | child->dwStyle &= ~WS_SYSMENU; |
| 810 | |
| 811 | /* redraw frame */ |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 812 | SetWindowPos(frame->hwndSelf, 0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 813 | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER ); |
| 814 | |
| 815 | return 1; |
| 816 | } |
| 817 | |
| 818 | /********************************************************************** |
| 819 | * MDI_RestoreFrameMenu |
| 820 | */ |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 821 | BOOL MDI_RestoreFrameMenu( WND *frameWnd, HWND hChild) |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 822 | { |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 823 | WND* child = WIN_FindWndPtr(hChild); |
| 824 | INT nItems = GetMenuItemCount(frameWnd->wIDmenu) - 1; |
| 825 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 826 | dprintf_mdi(stddeb,"MDI_RestoreFrameMenu: for child %04x\n",hChild); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 827 | |
| 828 | if( GetMenuItemID(frameWnd->wIDmenu,nItems) != SC_RESTORE ) |
| 829 | return 0; |
| 830 | |
| 831 | child->dwStyle |= WS_SYSMENU; |
| 832 | |
Alexandre Julliard | c981d0b | 1996-03-31 16:40:13 +0000 | [diff] [blame^] | 833 | /* FIXME: add a call to function that sets sysmenu items according |
| 834 | * to the window state. WS_MAXIMIZE -> no SC_SIZE, etc... |
| 835 | */ |
| 836 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 837 | RemoveMenu(frameWnd->wIDmenu,0,MF_BYPOSITION); |
| 838 | DeleteMenu(frameWnd->wIDmenu,nItems-1,MF_BYPOSITION); |
| 839 | |
| 840 | /* redraw frame */ |
| 841 | SetWindowPos(hChild, 0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | |
| 842 | SWP_NOACTIVATE | SWP_NOZORDER ); |
| 843 | return 1; |
| 844 | } |
| 845 | |
| 846 | /********************************************************************** |
| 847 | * MDI_UpdateFrameText |
| 848 | * |
| 849 | * used when child window is maximized/restored |
| 850 | * |
| 851 | * Note: lpTitle can be NULL |
| 852 | */ |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 853 | void MDI_UpdateFrameText(WND *frameWnd, HWND hClient, BOOL repaint, LPCSTR lpTitle) |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 854 | { |
| 855 | char lpBuffer[MDI_MAXTITLELENGTH+1]; |
| 856 | LPSTR lpText = NULL; |
| 857 | WND* clientWnd = WIN_FindWndPtr(hClient); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 858 | |
| 859 | MDICLIENTINFO *ci = (MDICLIENTINFO *) clientWnd->wExtra; |
| 860 | |
| 861 | dprintf_mdi(stddeb, "MDI: repaint %i, frameText %s\n", repaint, (lpTitle)?lpTitle:"NULL"); |
| 862 | |
| 863 | /* store new "default" title if lpTitle is not NULL */ |
| 864 | if( lpTitle ) |
| 865 | { |
| 866 | if( ci->hFrameTitle ) |
| 867 | USER_HEAP_FREE( ci->hFrameTitle ); |
| 868 | ci->hFrameTitle = USER_HEAP_ALLOC( strlen(lpTitle) + 1 ); |
| 869 | lpText = (LPSTR) USER_HEAP_LIN_ADDR( ci->hFrameTitle ); |
| 870 | strcpy( lpText, lpTitle ); |
| 871 | } |
| 872 | else |
| 873 | lpText = (LPSTR) USER_HEAP_LIN_ADDR(ci->hFrameTitle); |
| 874 | |
| 875 | if( ci->hFrameTitle ) |
| 876 | { |
| 877 | WND* childWnd = WIN_FindWndPtr( ci->flagChildMaximized ); |
| 878 | |
| 879 | if( childWnd && childWnd->hText ) |
| 880 | { |
| 881 | /* combine frame title and child title if possible */ |
| 882 | |
| 883 | LPCSTR lpBracket = " - ["; |
| 884 | LPCSTR lpChildText = (LPCSTR) USER_HEAP_LIN_ADDR( childWnd->hText ); |
| 885 | |
| 886 | int i_frame_text_length = strlen(lpText); |
| 887 | int i_child_text_length = strlen(lpChildText); |
| 888 | |
| 889 | strncpy( lpBuffer, lpText, MDI_MAXTITLELENGTH); |
| 890 | lpBuffer[MDI_MAXTITLELENGTH] = '\0'; |
| 891 | |
| 892 | if( i_frame_text_length + 5 < MDI_MAXTITLELENGTH ) |
| 893 | { |
| 894 | strcat( lpBuffer, lpBracket ); |
| 895 | |
| 896 | if( i_frame_text_length + i_child_text_length + 5 < MDI_MAXTITLELENGTH ) |
| 897 | { |
| 898 | strcat( lpBuffer, lpChildText ); |
| 899 | *(short*)(lpBuffer + i_frame_text_length + i_child_text_length + 4) = (short)']'; |
| 900 | } |
| 901 | else |
| 902 | { |
| 903 | memcpy( lpBuffer + i_frame_text_length + 4, |
| 904 | lpChildText, |
| 905 | MDI_MAXTITLELENGTH - i_frame_text_length - 4); |
| 906 | *(short*)(lpBuffer + MDI_MAXTITLELENGTH - 1) = (short)']'; |
| 907 | } |
| 908 | } |
| 909 | } |
| 910 | else |
| 911 | { |
| 912 | strncpy(lpBuffer, lpText, MDI_MAXTITLELENGTH ); |
| 913 | lpBuffer[MDI_MAXTITLELENGTH]='\0'; |
| 914 | } |
| 915 | } |
| 916 | else |
| 917 | lpBuffer[0] = '\0'; |
| 918 | |
| 919 | if( frameWnd->hText ) |
| 920 | USER_HEAP_FREE( frameWnd->hText ); |
| 921 | |
| 922 | frameWnd->hText = USER_HEAP_ALLOC( strlen(lpBuffer) + 1 ); |
| 923 | lpText = (LPSTR) USER_HEAP_LIN_ADDR( frameWnd->hText ); |
| 924 | strcpy( lpText, lpBuffer ); |
| 925 | |
| 926 | if( frameWnd->window ) |
| 927 | XStoreName( display, frameWnd->window, lpBuffer ); |
| 928 | |
| 929 | if( repaint == MDI_REPAINTFRAME) |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 930 | SetWindowPos(frameWnd->hwndSelf, 0,0,0,0,0, SWP_FRAMECHANGED | |
| 931 | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER ); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 932 | } |
| 933 | |
| 934 | |
| 935 | /* ----------------------------- Interface ---------------------------- */ |
| 936 | |
| 937 | |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 938 | /********************************************************************** |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 939 | * MDIClientWndProc |
| 940 | * |
| 941 | * This function is the handler for all MDI requests. |
| 942 | */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 943 | LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 944 | { |
| 945 | LPCREATESTRUCT cs; |
| 946 | LPCLIENTCREATESTRUCT ccs; |
| 947 | MDICLIENTINFO *ci; |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 948 | RECT rect; |
| 949 | WND *w = WIN_FindWndPtr(hwnd); |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 950 | WND *frameWnd = w->parent; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 951 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 952 | ci = (MDICLIENTINFO *) w->wExtra; |
| 953 | |
| 954 | switch (message) |
| 955 | { |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 956 | case WM_CREATE: |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 957 | cs = (LPCREATESTRUCT) PTR_SEG_TO_LIN(lParam); |
| 958 | ccs = (LPCLIENTCREATESTRUCT) PTR_SEG_TO_LIN(cs->lpCreateParams); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 959 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 960 | ci->hWindowMenu = ccs->hWindowMenu; |
| 961 | ci->idFirstChild = ccs->idFirstChild; |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 962 | ci->flagChildMaximized = 0; |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 963 | ci->nActiveChildren = 0; |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 964 | ci->hFrameTitle = frameWnd->hText; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 965 | ci->sbStop = 0; |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 966 | ci->self = hwnd; |
| 967 | ci->obmClose = CreateMDIMenuBitmap(); |
| 968 | ci->obmRestore = LoadBitmap(0, MAKEINTRESOURCE(OBM_RESTORE)); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 969 | w->dwStyle |= WS_CLIPCHILDREN; |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 970 | frameWnd->hText = 0; /* will be restored in UpdateFrameText */ |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 971 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 972 | MDI_UpdateFrameText( frameWnd, hwnd, MDI_NOFRAMEREPAINT, NULL); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 973 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 974 | AppendMenu(ccs->hWindowMenu,MF_SEPARATOR,0,(SEGPTR)0); |
| 975 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 976 | GetClientRect(frameWnd->hwndSelf, &rect); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 977 | NC_HandleNCCalcSize(hwnd, (NCCALCSIZE_PARAMS*) &rect); |
| 978 | w->rectClient = rect; |
| 979 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 980 | dprintf_mdi(stddeb,"MDI: Client created - hwnd = %04x, idFirst = %u\n",hwnd,ci->idFirstChild); |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 981 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 982 | return 0; |
| 983 | |
| 984 | case WM_DESTROY: |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 985 | if( ci->flagChildMaximized ) MDI_RestoreFrameMenu(w, frameWnd->hwndSelf); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 986 | |
| 987 | if(ci->obmClose) DeleteObject(ci->obmClose); |
| 988 | if(ci->obmRestore) DeleteObject(ci->obmRestore); |
| 989 | |
| 990 | ci->idFirstChild = GetMenuItemCount(ci->hWindowMenu) - 1; |
| 991 | ci->nActiveChildren++; /* to delete a separator */ |
| 992 | |
| 993 | while( ci->nActiveChildren-- ) |
| 994 | DeleteMenu(ci->hWindowMenu,MF_BYPOSITION,ci->idFirstChild--); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 995 | |
| 996 | return 0; |
| 997 | |
| 998 | case WM_MDIACTIVATE: |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 999 | if( ci->hwndActiveChild != (HWND)wParam ) |
| 1000 | SetWindowPos((HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE ); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1001 | return 0; |
| 1002 | |
| 1003 | case WM_MDICASCADE: |
| 1004 | return MDICascade(hwnd, ci); |
| 1005 | |
| 1006 | case WM_MDICREATE: |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1007 | return (LONG)MDICreateChild(w, ci, hwnd, lParam ); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1008 | |
| 1009 | case WM_MDIDESTROY: |
Alexandre Julliard | d7d4fdf | 1995-12-26 15:05:24 +0000 | [diff] [blame] | 1010 | return (LONG)MDIDestroyChild(w, ci, hwnd, (HWND)wParam, TRUE); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1011 | |
| 1012 | case WM_MDIGETACTIVE: |
| 1013 | return ((LONG) ci->hwndActiveChild | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1014 | ((LONG) (ci->flagChildMaximized>0) << 16)); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1015 | |
| 1016 | case WM_MDIICONARRANGE: |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1017 | ci->sbStop = TRUE; |
| 1018 | MDIIconArrange(hwnd); |
| 1019 | ci->sbStop = FALSE; |
| 1020 | SendMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L); |
| 1021 | return 0; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1022 | |
| 1023 | case WM_MDIMAXIMIZE: |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1024 | ShowWindow((HWND)wParam, SW_MAXIMIZE); |
| 1025 | return 0; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1026 | |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 1027 | case WM_MDINEXT: |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1028 | MDI_SwitchActiveChild(hwnd, (HWND)wParam, (lParam)?1:0); |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 1029 | break; |
| 1030 | |
| 1031 | case WM_MDIRESTORE: |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1032 | ShowWindow( (HWND)wParam, SW_NORMAL); |
| 1033 | return 0; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 1034 | |
| 1035 | case WM_MDISETMENU: |
Alexandre Julliard | d7d4fdf | 1995-12-26 15:05:24 +0000 | [diff] [blame] | 1036 | #ifdef WINELIB32 |
| 1037 | return (LRESULT)MDISetMenu(hwnd, FALSE, (HMENU)wParam, (HMENU)lParam); |
| 1038 | #else |
| 1039 | return (LRESULT)MDISetMenu(hwnd, wParam, LOWORD(lParam), HIWORD(lParam)); |
| 1040 | #endif |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 1041 | |
| 1042 | case WM_MDITILE: |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1043 | ci->sbStop = TRUE; |
| 1044 | ShowScrollBar(hwnd,SB_BOTH,FALSE); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1045 | MDITile(hwnd, ci,wParam); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1046 | ci->sbStop = FALSE; |
| 1047 | return 0; |
| 1048 | |
| 1049 | case WM_VSCROLL: |
| 1050 | case WM_HSCROLL: |
| 1051 | ci->sbStop = TRUE; |
| 1052 | ScrollChildren(hwnd,message,wParam,lParam); |
| 1053 | ci->sbStop = FALSE; |
| 1054 | return 0; |
| 1055 | |
| 1056 | case WM_SETFOCUS: |
| 1057 | if( ci->hwndActiveChild ) |
| 1058 | { |
| 1059 | w = WIN_FindWndPtr( ci->hwndActiveChild ); |
| 1060 | if( !(w->dwStyle & WS_MINIMIZE) ) |
| 1061 | SetFocus( ci->hwndActiveChild ); |
| 1062 | } |
| 1063 | return 0; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 1064 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1065 | case WM_NCACTIVATE: |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1066 | if( ci->hwndActiveChild ) |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1067 | SendMessage(ci->hwndActiveChild, message, wParam, lParam); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1068 | break; |
| 1069 | |
| 1070 | case WM_PARENTNOTIFY: |
Alexandre Julliard | c981d0b | 1996-03-31 16:40:13 +0000 | [diff] [blame^] | 1071 | if( wParam == WM_LBUTTONDOWN ) |
| 1072 | { |
| 1073 | LPPOINT lppt = (LPPOINT)(void*)(&lParam); |
| 1074 | HWND child = ChildWindowFromPoint(hwnd, *lppt); |
| 1075 | |
| 1076 | dprintf_mdi(stddeb,"MDIClient: notification from %04x (%i,%i)\n",child,lppt->x,lppt->y); |
| 1077 | |
| 1078 | if( child && child != hwnd ) |
| 1079 | { |
| 1080 | WND* wnd = WIN_FindWndPtr( child ); |
| 1081 | |
| 1082 | /* if we got owned popup */ |
| 1083 | if( wnd->owner ) child = wnd->owner->hwndSelf; |
| 1084 | |
| 1085 | if( child != ci->hwndActiveChild ) |
| 1086 | SetWindowPos(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE ); |
| 1087 | } |
| 1088 | } |
| 1089 | return 0; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 1090 | |
| 1091 | case WM_SIZE: |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1092 | if( ci->flagChildMaximized ) |
| 1093 | { |
| 1094 | WND* child = WIN_FindWndPtr(ci->flagChildMaximized); |
| 1095 | RECT rect = { 0, 0, LOWORD(lParam), HIWORD(lParam) }; |
| 1096 | |
| 1097 | AdjustWindowRectEx(&rect, child->dwStyle, 0, child->dwExStyle); |
| 1098 | MoveWindow(ci->flagChildMaximized, rect.left, rect.top, |
| 1099 | rect.right - rect.left, rect.bottom - rect.top, 1); |
| 1100 | } |
| 1101 | else |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1102 | { |
| 1103 | PostMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L); |
| 1104 | ci->sbRecalc |= (SB_BOTH+1); |
| 1105 | } |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1106 | break; |
| 1107 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1108 | case WM_MDICALCCHILDSCROLL: |
| 1109 | if( !ci->sbStop ) |
| 1110 | if( ci->sbRecalc ) |
| 1111 | { |
| 1112 | CalcChildScroll(hwnd, ci->sbRecalc-1); |
| 1113 | ci->sbRecalc = 0; |
| 1114 | } |
| 1115 | return 0; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1116 | } |
| 1117 | |
| 1118 | return DefWindowProc(hwnd, message, wParam, lParam); |
| 1119 | } |
| 1120 | |
| 1121 | /********************************************************************** |
| 1122 | * DefFrameProc (USER.445) |
| 1123 | * |
| 1124 | */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1125 | LRESULT DefFrameProc(HWND hwnd, HWND hwndMDIClient, UINT message, |
| 1126 | WPARAM wParam, LPARAM lParam) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1127 | { |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1128 | HWND childHwnd; |
| 1129 | MDICLIENTINFO* ci; |
| 1130 | WND* wndPtr; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1131 | |
Alexandre Julliard | 7cc9c0c | 1994-06-15 15:45:11 +0000 | [diff] [blame] | 1132 | if (hwndMDIClient) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1133 | { |
Alexandre Julliard | 7cc9c0c | 1994-06-15 15:45:11 +0000 | [diff] [blame] | 1134 | switch (message) |
| 1135 | { |
| 1136 | case WM_COMMAND: |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1137 | wndPtr = WIN_FindWndPtr(hwndMDIClient); |
| 1138 | ci = (MDICLIENTINFO*)wndPtr->wExtra; |
| 1139 | |
| 1140 | /* check for possible system command codes */ |
| 1141 | |
| 1142 | if( wParam < ci->idFirstChild || |
| 1143 | wParam >= ci->idFirstChild + ci->nActiveChildren ) |
| 1144 | { |
| 1145 | if( (wParam - 0xF000) & 0xF00F ) break; |
| 1146 | switch( wParam ) |
| 1147 | { |
| 1148 | case SC_SIZE: |
| 1149 | case SC_MOVE: |
| 1150 | case SC_MINIMIZE: |
| 1151 | case SC_MAXIMIZE: |
| 1152 | case SC_NEXTWINDOW: |
| 1153 | case SC_PREVWINDOW: |
| 1154 | case SC_CLOSE: |
| 1155 | case SC_RESTORE: |
| 1156 | if( ci->flagChildMaximized ) |
| 1157 | return SendMessage( ci->flagChildMaximized, WM_SYSCOMMAND, |
| 1158 | wParam, lParam); |
| 1159 | } |
| 1160 | } |
| 1161 | else |
| 1162 | { |
| 1163 | childHwnd = MDI_GetChildByID( WIN_FindWndPtr(hwndMDIClient), |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1164 | wParam ); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1165 | if( childHwnd ) |
| 1166 | SendMessage(hwndMDIClient, WM_MDIACTIVATE, (WPARAM)childHwnd , 0L); |
| 1167 | } |
Alexandre Julliard | 7cc9c0c | 1994-06-15 15:45:11 +0000 | [diff] [blame] | 1168 | break; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 1169 | |
Alexandre Julliard | 7cc9c0c | 1994-06-15 15:45:11 +0000 | [diff] [blame] | 1170 | case WM_NCACTIVATE: |
| 1171 | SendMessage(hwndMDIClient, message, wParam, lParam); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1172 | break; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1173 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1174 | case WM_SETTEXT: |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 1175 | MDI_UpdateFrameText(WIN_FindWndPtr(hwnd), hwndMDIClient, |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1176 | MDI_REPAINTFRAME, |
| 1177 | (LPCSTR)PTR_SEG_TO_LIN(lParam)); |
| 1178 | return 0; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1179 | |
Alexandre Julliard | 7cc9c0c | 1994-06-15 15:45:11 +0000 | [diff] [blame] | 1180 | case WM_SETFOCUS: |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1181 | SetFocus(hwndMDIClient); |
Alexandre Julliard | 7cc9c0c | 1994-06-15 15:45:11 +0000 | [diff] [blame] | 1182 | break; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1183 | |
Alexandre Julliard | 7cc9c0c | 1994-06-15 15:45:11 +0000 | [diff] [blame] | 1184 | case WM_SIZE: |
| 1185 | MoveWindow(hwndMDIClient, 0, 0, |
| 1186 | LOWORD(lParam), HIWORD(lParam), TRUE); |
| 1187 | break; |
| 1188 | } |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1189 | } |
| 1190 | |
| 1191 | return DefWindowProc(hwnd, message, wParam, lParam); |
| 1192 | } |
| 1193 | |
| 1194 | /********************************************************************** |
| 1195 | * DefMDIChildProc (USER.447) |
| 1196 | * |
| 1197 | */ |
Alexandre Julliard | 0c126c7 | 1996-02-18 18:44:41 +0000 | [diff] [blame] | 1198 | LRESULT DefMDIChildProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1199 | { |
| 1200 | MDICLIENTINFO *ci; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1201 | WND *clientWnd; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1202 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1203 | clientWnd = WIN_FindWndPtr(GetParent(hwnd)); |
| 1204 | ci = (MDICLIENTINFO *) clientWnd->wExtra; |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1205 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1206 | switch (message) |
| 1207 | { |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1208 | case WM_SETTEXT: |
| 1209 | DefWindowProc(hwnd, message, wParam, lParam); |
| 1210 | MDI_MenuModifyItem(clientWnd,hwnd); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1211 | if( ci->flagChildMaximized == hwnd ) |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 1212 | MDI_UpdateFrameText( clientWnd->parent, ci->self, |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1213 | MDI_REPAINTFRAME, NULL ); |
Alexandre Julliard | 1850655 | 1995-01-24 16:21:01 +0000 | [diff] [blame] | 1214 | return 0; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 1215 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1216 | case WM_CLOSE: |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1217 | SendMessage(ci->self,WM_MDIDESTROY,(WPARAM)hwnd,0L); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1218 | return 0; |
| 1219 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1220 | case WM_SETFOCUS: |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1221 | if( ci->hwndActiveChild != hwnd ) |
| 1222 | MDI_ChildActivate(clientWnd, hwnd); |
| 1223 | break; |
| 1224 | |
| 1225 | case WM_CHILDACTIVATE: |
| 1226 | MDI_ChildActivate(clientWnd, hwnd); |
| 1227 | return 0; |
| 1228 | |
| 1229 | case WM_NCPAINT: |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 1230 | dprintf_mdi(stddeb,"DefMDIChildProc: WM_NCPAINT for %04x, active %04x\n", |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1231 | hwnd, ci->hwndActiveChild ); |
| 1232 | break; |
| 1233 | |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 1234 | case WM_SYSCOMMAND: |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1235 | switch( wParam ) |
| 1236 | { |
| 1237 | case SC_MOVE: |
| 1238 | if( ci->flagChildMaximized == hwnd) return 0; |
| 1239 | break; |
| 1240 | case SC_MAXIMIZE: |
| 1241 | if( ci->flagChildMaximized == hwnd) |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 1242 | return SendMessage( clientWnd->parent->hwndSelf, |
| 1243 | message, wParam, lParam); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1244 | break; |
| 1245 | case SC_NEXTWINDOW: |
| 1246 | SendMessage( ci->self, WM_MDINEXT, 0, 0); |
| 1247 | return 0; |
| 1248 | case SC_PREVWINDOW: |
| 1249 | SendMessage( ci->self, WM_MDINEXT, 0, 1); |
| 1250 | return 0; |
| 1251 | } |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 1252 | break; |
| 1253 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1254 | case WM_GETMINMAXINFO: |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1255 | MDI_ChildGetMinMaxInfo(clientWnd, hwnd, (MINMAXINFO*) PTR_SEG_TO_LIN(lParam)); |
| 1256 | return 0; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1257 | |
| 1258 | case WM_SETVISIBLE: |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1259 | if( !ci->sbStop && !ci->flagChildMaximized) |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1260 | { |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1261 | PostMessage(ci->self,WM_MDICALCCHILDSCROLL,0,0L); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1262 | ci->sbRecalc |= (SB_BOTH+1); |
| 1263 | } |
| 1264 | break; |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1265 | |
| 1266 | case WM_SIZE: |
| 1267 | /* do not change */ |
| 1268 | |
| 1269 | if( ci->hwndActiveChild == hwnd && wParam != SIZE_MAXIMIZED ) |
| 1270 | { |
| 1271 | ci->flagChildMaximized = 0; |
| 1272 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 1273 | MDI_RestoreFrameMenu( clientWnd->parent, hwnd); |
| 1274 | MDI_UpdateFrameText( clientWnd->parent, ci->self, |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1275 | MDI_REPAINTFRAME, NULL ); |
| 1276 | } |
| 1277 | |
| 1278 | if( wParam == SIZE_MAXIMIZED ) |
| 1279 | { |
| 1280 | HWND hMaxChild = ci->flagChildMaximized; |
| 1281 | |
| 1282 | if( hMaxChild == hwnd ) break; |
| 1283 | |
| 1284 | if( hMaxChild) |
| 1285 | { |
| 1286 | SendMessage( hMaxChild, WM_SETREDRAW, FALSE, 0L ); |
| 1287 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 1288 | MDI_RestoreFrameMenu( clientWnd->parent, hMaxChild); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1289 | ShowWindow( hMaxChild, SW_SHOWNOACTIVATE); |
| 1290 | |
| 1291 | SendMessage( hMaxChild, WM_SETREDRAW, TRUE, 0L ); |
| 1292 | } |
| 1293 | |
| 1294 | ci->flagChildMaximized = hwnd; /* !!! */ |
| 1295 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 1296 | MDI_AugmentFrameMenu( ci, clientWnd->parent, hwnd); |
| 1297 | MDI_UpdateFrameText( clientWnd->parent, ci->self, |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1298 | MDI_REPAINTFRAME, NULL ); |
| 1299 | } |
| 1300 | |
| 1301 | if( wParam == SIZE_MINIMIZED ) |
| 1302 | { |
| 1303 | HWND switchTo = MDI_GetWindow(clientWnd, hwnd, 0); |
| 1304 | |
| 1305 | if( switchTo ) |
| 1306 | SendMessage( switchTo, WM_CHILDACTIVATE, 0, 0L); |
| 1307 | } |
| 1308 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1309 | if( !ci->sbStop ) |
| 1310 | { |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1311 | PostMessage(ci->self,WM_MDICALCCHILDSCROLL,0,0L); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1312 | ci->sbRecalc |= (SB_BOTH+1); |
| 1313 | } |
| 1314 | break; |
| 1315 | |
| 1316 | case WM_MENUCHAR: |
Alexandre Julliard | c981d0b | 1996-03-31 16:40:13 +0000 | [diff] [blame^] | 1317 | |
| 1318 | /* MDI children don't have menus */ |
| 1319 | PostMessage( clientWnd->parent->hwndSelf, WM_SYSCOMMAND, |
| 1320 | (WPARAM)SC_KEYMENU, (LPARAM)wParam); |
| 1321 | return 0x00010000L; |
| 1322 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1323 | case WM_NEXTMENU: |
| 1324 | /* set current menu to child system menu */ |
| 1325 | |
| 1326 | break; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1327 | } |
| 1328 | |
| 1329 | return DefWindowProc(hwnd, message, wParam, lParam); |
| 1330 | } |
| 1331 | |
| 1332 | /********************************************************************** |
| 1333 | * TranslateMDISysAccel (USER.451) |
| 1334 | * |
| 1335 | */ |
| 1336 | BOOL TranslateMDISysAccel(HWND hwndClient, LPMSG msg) |
| 1337 | { |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1338 | WND* clientWnd = WIN_FindWndPtr( hwndClient); |
| 1339 | WND* wnd; |
| 1340 | MDICLIENTINFO *ci = NULL; |
| 1341 | WPARAM wParam = 0; |
| 1342 | |
| 1343 | if( (msg->message != WM_KEYDOWN && msg->message != WM_SYSKEYDOWN) || !clientWnd ) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1344 | return 0; |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1345 | |
| 1346 | ci = (MDICLIENTINFO*) clientWnd->wExtra; |
| 1347 | wnd = WIN_FindWndPtr(ci->hwndActiveChild); |
| 1348 | |
| 1349 | if( !wnd ) return 0; |
| 1350 | |
| 1351 | if( wnd->dwStyle & WS_DISABLED ) return 0; |
| 1352 | |
Alexandre Julliard | c981d0b | 1996-03-31 16:40:13 +0000 | [diff] [blame^] | 1353 | if ((GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_MENU) & 0x8000)) |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1354 | switch( msg->wParam ) |
| 1355 | { |
| 1356 | case VK_F6: |
| 1357 | case VK_SEPARATOR: |
Alexandre Julliard | c981d0b | 1996-03-31 16:40:13 +0000 | [diff] [blame^] | 1358 | wParam = ( GetKeyState(VK_SHIFT) & 0x8000 )? SC_NEXTWINDOW: SC_PREVWINDOW; |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1359 | break; |
| 1360 | case VK_RBUTTON: |
| 1361 | wParam = SC_CLOSE; |
Alexandre Julliard | c981d0b | 1996-03-31 16:40:13 +0000 | [diff] [blame^] | 1362 | break; |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1363 | default: |
| 1364 | return 0; |
| 1365 | } |
Alexandre Julliard | c981d0b | 1996-03-31 16:40:13 +0000 | [diff] [blame^] | 1366 | else |
| 1367 | return 0; |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1368 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 1369 | dprintf_mdi(stddeb,"TranslateMDISysAccel: wParam = %04x\n", wParam); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1370 | |
| 1371 | SendMessage(ci->hwndActiveChild,WM_SYSCOMMAND, wParam, (LPARAM)msg->wParam); |
| 1372 | return 1; |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 1373 | } |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 1374 | |
| 1375 | |
| 1376 | /*********************************************************************** |
| 1377 | * CalcChildScroll (USER.462) |
| 1378 | */ |
| 1379 | void CalcChildScroll( HWND hwnd, WORD scroll ) |
| 1380 | { |
| 1381 | RECT childRect, clientRect; |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 1382 | WND *pWnd; |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 1383 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 1384 | if (!(pWnd = WIN_FindWndPtr( hwnd ))) return; |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 1385 | GetClientRect( hwnd, &clientRect ); |
| 1386 | SetRectEmpty( &childRect ); |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 1387 | for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next) |
| 1388 | UnionRect( &childRect, &pWnd->rectWindow, &childRect ); |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 1389 | UnionRect( &childRect, &clientRect, &childRect ); |
| 1390 | |
| 1391 | if ((scroll == SB_HORZ) || (scroll == SB_BOTH)) |
| 1392 | { |
| 1393 | SetScrollRange( hwnd, SB_HORZ, childRect.left, |
| 1394 | childRect.right - clientRect.right, FALSE ); |
| 1395 | SetScrollPos( hwnd, SB_HORZ, clientRect.left - childRect.left, TRUE ); |
| 1396 | } |
| 1397 | if ((scroll == SB_VERT) || (scroll == SB_BOTH)) |
| 1398 | { |
| 1399 | SetScrollRange( hwnd, SB_VERT, childRect.top, |
| 1400 | childRect.bottom - clientRect.bottom, FALSE ); |
| 1401 | SetScrollPos( hwnd, SB_HORZ, clientRect.top - childRect.top, TRUE ); |
| 1402 | } |
| 1403 | } |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1404 | |
| 1405 | /*********************************************************************** |
| 1406 | * ScrollChildren (USER.463) |
| 1407 | */ |
| 1408 | void ScrollChildren(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
| 1409 | { |
| 1410 | WND *wndPtr = WIN_FindWndPtr(hWnd); |
Alexandre Julliard | d7d4fdf | 1995-12-26 15:05:24 +0000 | [diff] [blame] | 1411 | short newPos=-1; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1412 | short curPos; |
| 1413 | short length; |
Alexandre Julliard | d7d4fdf | 1995-12-26 15:05:24 +0000 | [diff] [blame] | 1414 | INT minPos; |
| 1415 | INT maxPos; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 1416 | short shift; |
| 1417 | |
| 1418 | if( !wndPtr ) return; |
| 1419 | |
| 1420 | if( uMsg == WM_HSCROLL ) |
| 1421 | { |
| 1422 | GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos); |
| 1423 | curPos = GetScrollPos(hWnd,SB_HORZ); |
| 1424 | length = (wndPtr->rectClient.right - wndPtr->rectClient.left)/2; |
| 1425 | shift = SYSMETRICS_CYHSCROLL; |
| 1426 | } |
| 1427 | else if( uMsg == WM_VSCROLL ) |
| 1428 | { |
| 1429 | GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos); |
| 1430 | curPos = GetScrollPos(hWnd,SB_VERT); |
| 1431 | length = (wndPtr->rectClient.bottom - wndPtr->rectClient.top)/2; |
| 1432 | shift = SYSMETRICS_CXVSCROLL; |
| 1433 | } |
| 1434 | else return; |
| 1435 | |
| 1436 | switch( wParam ) |
| 1437 | { |
| 1438 | case SB_LINEUP: |
| 1439 | newPos = curPos - shift; |
| 1440 | break; |
| 1441 | case SB_LINEDOWN: |
| 1442 | newPos = curPos + shift; |
| 1443 | break; |
| 1444 | case SB_PAGEUP: |
| 1445 | newPos = curPos - length; |
| 1446 | break; |
| 1447 | case SB_PAGEDOWN: |
| 1448 | newPos = curPos + length; |
| 1449 | break; |
| 1450 | |
| 1451 | case SB_THUMBPOSITION: |
| 1452 | newPos = LOWORD(lParam); |
| 1453 | break; |
| 1454 | |
| 1455 | case SB_THUMBTRACK: |
| 1456 | return; |
| 1457 | |
| 1458 | case SB_TOP: |
| 1459 | newPos = minPos; |
| 1460 | break; |
| 1461 | case SB_BOTTOM: |
| 1462 | newPos = maxPos; |
| 1463 | break; |
| 1464 | case SB_ENDSCROLL: |
| 1465 | CalcChildScroll(hWnd,(uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ); |
| 1466 | return; |
| 1467 | } |
| 1468 | |
| 1469 | if( newPos > maxPos ) |
| 1470 | newPos = maxPos; |
| 1471 | else if( newPos < minPos ) |
| 1472 | newPos = minPos; |
| 1473 | |
| 1474 | SetScrollPos(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE); |
| 1475 | |
| 1476 | if( uMsg == WM_VSCROLL ) |
| 1477 | ScrollWindow(hWnd ,0 ,curPos - newPos, NULL, NULL); |
| 1478 | else |
| 1479 | ScrollWindow(hWnd ,curPos - newPos, 0, NULL, NULL); |
| 1480 | } |
| 1481 | |