00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <os2win.h>
00021 #include <win.h>
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <stdarg.h>
00026 #include <assert.h>
00027 #include <misc.h>
00028 #include <heapstring.h>
00029 #include <win32wnd.h>
00030 #include <win32wmdiclient.h>
00031 #include <win32wmdichild.h>
00032 #include <spy.h>
00033 #include "wndmsg.h"
00034 #include <oslibwin.h>
00035 #include <oslibutil.h>
00036 #include <oslibgdi.h>
00037 #include <oslibres.h>
00038 #include "oslibdos.h"
00039 #include "syscolor.h"
00040 #include "win32wndhandle.h"
00041
00042 #define DBG_LOCALLOG DBG_win32wmdichild
00043 #include "dbglocal.h"
00044
00045
00046
00047 Win32MDIChildWindow::Win32MDIChildWindow(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL fUnicode)
00048 : Win32BaseWindow()
00049 {
00050 isUnicode = fUnicode;
00051 CreateWindowExA(lpCreateStructA, classAtom);
00052 }
00053
00054
00055 Win32MDIChildWindow::~Win32MDIChildWindow()
00056 {
00057 }
00058
00059
00060 BOOL Win32MDIChildWindow::isMDIChild()
00061 {
00062 return TRUE;
00063 }
00064
00065
00066 LRESULT Win32MDIChildWindow::DefMDIChildProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
00067 {
00068 Win32MDIClientWindow *client = (Win32MDIClientWindow *)getParent();
00069
00070 switch (Msg)
00071 {
00072 case WM_SETTEXT:
00073 DefWindowProcA(Msg, wParam, lParam);
00074 menuModifyItem();
00075 if( client->getMaximizedChild() == getWindowHandle() )
00076 client->updateFrameText(MDI_REPAINTFRAME, NULL);
00077 return 0;
00078
00079 case WM_GETMINMAXINFO:
00080 {
00081 childGetMinMaxInfo((MINMAXINFO *)lParam);
00082 return 0;
00083 }
00084
00085 case WM_MENUCHAR:
00086
00087 PostMessageA(client->getWindowHandle(), WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)LOWORD(wParam) );
00088 return 0x00010000L;
00089
00090 case WM_CLOSE:
00091 client->SendMessageA(WM_MDIDESTROY,(WPARAM)getWindowHandle(), 0L);
00092 return 0;
00093
00094 case WM_SETFOCUS:
00095 if(client->getActiveChild() != getWindowHandle() )
00096 client->childActivate(this);
00097 break;
00098
00099 case WM_CHILDACTIVATE:
00100 client->childActivate(this);
00101 return 0;
00102
00103 case WM_NCPAINT:
00104 break;
00105
00106 case WM_SYSCOMMAND:
00107 switch( wParam )
00108 {
00109 case SC_MOVE:
00110 if( client->getMaximizedChild() == getWindowHandle())
00111 {
00112 return 0;
00113 }
00114 break;
00115 case SC_RESTORE:
00116 case SC_MINIMIZE:
00117 setStyle(getStyle() | WS_SYSMENU);
00118 break;
00119
00120 case SC_MAXIMIZE:
00121 if( client->getMaximizedChild() == getWindowHandle())
00122 {
00123 return client->SendMessageA(Msg, wParam, lParam);
00124 }
00125 setStyle(getStyle() & ~WS_SYSMENU);
00126 break;
00127
00128 case SC_NEXTWINDOW:
00129 client->SendMessageA(WM_MDINEXT, 0, 0);
00130 return 0;
00131
00132 case SC_PREVWINDOW:
00133 client->SendMessageA(WM_MDINEXT, 0, 0);
00134 return 0;
00135 }
00136 break;
00137
00138 case WM_SETVISIBLE:
00139 if( client->getMaximizedChild()) {
00140 client->setMdiFlags(client->getMdiFlags() & ~MDIF_NEEDUPDATE);
00141 }
00142 else client->postUpdate(SB_BOTH+1);
00143 break;
00144
00145 case WM_SIZE:
00146
00147 if( client->getActiveChild() == getWindowHandle() && wParam != SIZE_MAXIMIZED )
00148 {
00149 client->setMaximizedChild(NULL);
00150 client->restoreFrameMenu(getWindowHandle());
00151 client->updateFrameText(MDI_REPAINTFRAME, NULL );
00152 }
00153
00154 if( wParam == SIZE_MAXIMIZED )
00155 {
00156 HWND maxChild = client->getMaximizedChild();
00157
00158 if( maxChild == getWindowHandle() ) break;
00159
00160 if( maxChild)
00161 {
00162 ::SendMessageA(maxChild, WM_SETREDRAW, FALSE, 0L );
00163 client->restoreFrameMenu(maxChild);
00164 ::ShowWindow(maxChild, SW_SHOWNOACTIVATE);
00165
00166 ::SendMessageA(maxChild, WM_SETREDRAW, TRUE, 0L );
00167 }
00168
00169 client->setMaximizedChild(getWindowHandle());
00170 client->setActiveChild(getWindowHandle());
00171
00172 client->augmentFrameMenu(getWindowHandle());
00173
00174 client->updateFrameText(MDI_REPAINTFRAME, NULL );
00175 }
00176
00177 if( wParam == SIZE_MINIMIZED )
00178 {
00179 Win32MDIChildWindow *switchTo = client->getWindow(this, TRUE, WS_MINIMIZE);
00180
00181 if( switchTo )
00182 switchTo->SendMessageA(WM_CHILDACTIVATE, 0, 0L);
00183 }
00184
00185 client->postUpdate(SB_BOTH+1);
00186 break;
00187
00188 #if 0
00189 case WM_NEXTMENU:
00190 if( wParam == VK_LEFT )
00191 {
00192 return MAKELONG( GetSubMenu(clientWnd->parent->hSysMenu, 0),
00193 clientWnd->parent->hwndSelf );
00194 goto END;
00195 }
00196 if( wParam == VK_RIGHT )
00197 {
00198 retvalue = MAKELONG( clientWnd->parent->wIDmenu,
00199 clientWnd->parent->hwndSelf );
00200 goto END;
00201 }
00202 #endif
00203 case WM_SYSCHAR:
00204 if (wParam == '-')
00205 {
00206 SendInternalMessageA(WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)(DWORD)VK_SPACE);
00207 return 0;
00208 }
00209 }
00210 return DefWindowProcA(Msg, wParam, lParam);
00211 }
00212
00213
00214 LRESULT Win32MDIChildWindow::DefMDIChildProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
00215 {
00216 Win32MDIClientWindow *client = (Win32MDIClientWindow *)getParent();
00217
00218 switch (Msg)
00219 {
00220 case WM_SETTEXT:
00221 DefWindowProcW(Msg, wParam, lParam);
00222 menuModifyItem();
00223 if( client->getMaximizedChild() == getWindowHandle() )
00224 client->updateFrameText(MDI_REPAINTFRAME, NULL );
00225
00226 return 0;
00227
00228 case WM_GETMINMAXINFO:
00229 case WM_MENUCHAR:
00230 case WM_CLOSE:
00231 case WM_SETFOCUS:
00232 case WM_CHILDACTIVATE:
00233 case WM_NCPAINT:
00234 case WM_SYSCOMMAND:
00235 case WM_SETVISIBLE:
00236 case WM_SIZE:
00237 case WM_NEXTMENU:
00238 return DefMDIChildProcA(Msg, wParam, lParam );
00239
00240 case WM_SYSCHAR:
00241 if (wParam == '-')
00242 {
00243 SendInternalMessageW(WM_SYSCOMMAND, SC_KEYMENU, (LPARAM)(DWORD)VK_SPACE);
00244 return 0;
00245 }
00246 break;
00247 }
00248 return DefWindowProcW(Msg, wParam, lParam);
00249 }
00250
00251
00252
00253 HWND Win32MDIChildWindow::createChild(Win32MDIClientWindow *client, LPMDICREATESTRUCTA cs )
00254 {
00255 POINT pos[2];
00256 DWORD style = cs->style | (WS_CHILD | WS_CLIPSIBLINGS);
00257 WORD wIDmenu = client->getFirstChildId() + client->getNrOfChildren();
00258 char lpstrDef[]="junk!";
00259 Win32MDIChildWindow *newchild;
00260 HWND maximizedChild;
00261 CREATESTRUCTA createstruct;
00262 ATOM classAtom;
00263 char tmpClassA[20] = "";
00264 WCHAR tmpClassW[20];
00265 LPSTR className;
00266
00267 dprintf(("Win32MDIChildWindow::createChild %i,%i - dim %i,%i, style %08x\n",
00268 cs->x, cs->y, cs->cx, cs->cy, (unsigned)cs->style));
00269
00270
00271 calcDefaultChildPos(client, client->incTotalCreated()-1, pos, 0);
00272
00273 if (cs->cx == CW_USEDEFAULT || !cs->cx) cs->cx = pos[1].x;
00274 if (cs->cy == CW_USEDEFAULT || !cs->cy) cs->cy = pos[1].y;
00275
00276 if( cs->x == CW_USEDEFAULT )
00277 {
00278 cs->x = pos[0].x;
00279 cs->y = pos[0].y;
00280 }
00281
00282
00283 if( style & WS_VISIBLE && client->getMaximizedChild() )
00284 {
00285 if( style & WS_MAXIMIZE )
00286 client->SendMessageA(WM_SETREDRAW, FALSE, 0L );
00287
00288 maximizedChild = client->getMaximizedChild();
00289
00290 ::ShowWindow(maximizedChild, SW_SHOWNOACTIVATE );
00291
00292 if( style & WS_MAXIMIZE )
00293 client->SendMessageA(WM_SETREDRAW, TRUE, 0L );
00294 }
00295
00296
00297 if(client->getMDIMenu())
00298 AppendMenuA(client->getMDIMenu(), MF_STRING ,wIDmenu, lpstrDef );
00299
00300 client->incNrActiveChildren();
00301
00302
00303 if( !(client->getStyle() & MDIS_ALLCHILDSTYLES) )
00304 {
00305 dprintf(("Fixing MDI window style! %x -> %x", style, style | WS_VISIBLE | WS_OVERLAPPEDWINDOW));
00306 style &= (WS_CHILD | WS_CLIPSIBLINGS | WS_MINIMIZE | WS_MAXIMIZE |
00307 WS_CLIPCHILDREN | WS_DISABLED | WS_VSCROLL | WS_HSCROLL );
00308 style |= (WS_VISIBLE | WS_OVERLAPPEDWINDOW);
00309 }
00310
00311 createstruct.lpszName = cs->szTitle;
00312 createstruct.style = style;
00313 createstruct.dwExStyle = 0;
00314 createstruct.x = cs->x;
00315 createstruct.y = cs->y;
00316 createstruct.cx = cs->cx;
00317 createstruct.cy = cs->cy;
00318 createstruct.hInstance = cs->hOwner;
00319 createstruct.hMenu = wIDmenu;
00320 createstruct.hwndParent= client->getWindowHandle();
00321 createstruct.lpCreateParams = (LPVOID)cs;
00322
00323 className = (LPSTR)cs->szClass;
00324
00325 classAtom = GlobalFindAtomA(cs->szClass);
00326 if(classAtom == 0)
00327 {
00328 if (!HIWORD(cs->szClass))
00329 {
00330 sprintf(tmpClassA,"#%d", (int) className);
00331 classAtom = GlobalFindAtomA(tmpClassA);
00332 className = tmpClassA;
00333 }
00334 if (!classAtom)
00335 {
00336 if (!HIWORD(cs->szClass)) {
00337 dprintf(("createChild: bad class name %04x\n", LOWORD(className)));
00338 }
00339 else dprintf(("createChild: bad class name '%s'\n", tmpClassA ));
00340
00341 SetLastError(ERROR_INVALID_PARAMETER);
00342 return 0;
00343 }
00344 }
00345 createstruct.lpszClass = className;
00346
00347 newchild = new Win32MDIChildWindow(&createstruct, classAtom, FALSE);
00348
00349 if(newchild && GetLastError() == 0)
00350 {
00351
00352 newchild->setExStyle(newchild->getExStyle() | WS_EX_MDICHILD);
00353
00354 newchild->menuModifyItem();
00355
00356 if( newchild->getStyle() & WS_MINIMIZE && client->getActiveChild()) {
00357 newchild->ShowWindow(SW_SHOWMINNOACTIVE);
00358 }
00359 else
00360 {
00361
00362
00363
00364
00365
00366 int showflag = newchild->getStyle() & WS_VISIBLE;
00367
00368
00369
00370 newchild->setStyle(newchild->getStyle() & ~WS_VISIBLE);
00371
00372 if(showflag){
00373 dprintf(("newchild->SetWindowPos active window %x", GetActiveWindow()));
00374 newchild->SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE );
00375 dprintf(("newchild->SetWindowPos active window %x", GetActiveWindow()));
00376
00377
00378
00379
00380
00381 if((newchild->getStyle() & WS_MAXIMIZE) && !client->getMaximizedChild() )
00382 {
00383 client->setMaximizedChild(newchild->getWindowHandle());
00384
00385 client->augmentFrameMenu(newchild->getWindowHandle());
00386
00387 client->updateFrameText(MDI_REPAINTFRAME, NULL );
00388 }
00389 }
00390 else
00391
00392 newchild->SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE );
00393
00394 }
00395 }
00396 else
00397 {
00398 client->decNrActiveChildren();
00399 if(client->getMDIMenu()) {
00400 DeleteMenu(client->getMDIMenu(), wIDmenu,MF_BYCOMMAND);
00401 }
00402
00403 maximizedChild = client->getMaximizedChild();
00404 if( ::IsWindow(maximizedChild) )
00405 ::ShowWindow(maximizedChild, SW_SHOWMAXIMIZED);
00406
00407 dprintf(("MDI child creation failed!!"));
00408 return 0;
00409 }
00410 return newchild->getWindowHandle();
00411 }
00412
00413
00414
00415 BOOL Win32MDIChildWindow::menuModifyItem()
00416 {
00417 Win32MDIClientWindow *client = (Win32MDIClientWindow *)getParent();
00418 char buffer[128];
00419 UINT id = getWindowId()-client->getFirstChildId()+1;
00420 UINT n = sprintf(buffer,(id > 9) ? "%d":"&%d ",id);
00421 BOOL bRet = 0;
00422
00423 if( !client->getMDIMenu() )
00424 {
00425 return FALSE;
00426 }
00427
00428 if (getWindowNameA()) lstrcpynA(buffer + n, getWindowNameA(), sizeof(buffer) - n );
00429
00430 n = GetMenuState(client->getMDIMenu(), getWindowId() ,MF_BYCOMMAND);
00431 bRet = ModifyMenuA(client->getMDIMenu() , getWindowId(),
00432 MF_BYCOMMAND | MF_STRING, getWindowId(), buffer );
00433 CheckMenuItem(client->getMDIMenu(), getWindowId() , n & MF_CHECKED);
00434
00435 return bRet;
00436 }
00437
00438
00439
00440
00441 BOOL Win32MDIChildWindow::menuDeleteItem()
00442 {
00443 Win32MDIClientWindow *client = (Win32MDIClientWindow *)getParent();
00444 char buffer[128];
00445 UINT index = 0,id,n;
00446 BOOL retvalue;
00447
00448 if( !client->getNrOfChildren() ||
00449 !client->getMDIMenu())
00450 {
00451 return FALSE;
00452 }
00453
00454 id = getWindowId();
00455 DeleteMenu(client->getMDIMenu(),id,MF_BYCOMMAND);
00456
00457
00458
00459
00460 lock();
00461 for( index = id+1; index <= client->getNrOfChildren() +
00462 client->getFirstChildId(); index++ )
00463 {
00464 Win32MDIChildWindow *tmpWnd = (Win32MDIChildWindow *)GetWindowFromHandle(client->getChildByID(index));
00465 if( !tmpWnd )
00466 {
00467 dprintf(("no window for id=%i\n",index));
00468 continue;
00469 }
00470
00471
00472 tmpWnd->setWindowId(tmpWnd->getWindowId()-1);
00473
00474 n = sprintf(buffer, "%d ",index - client->getFirstChildId());
00475 if (tmpWnd->getWindowNameA())
00476 lstrcpynA(buffer + n, tmpWnd->getWindowNameA(), sizeof(buffer) - n );
00477
00478 RELEASE_WNDOBJ(tmpWnd);
00479
00480 unlock();
00481
00482 ModifyMenuA(client->getMDIMenu(), index ,MF_BYCOMMAND | MF_STRING,
00483 index - 1 , buffer );
00484 lock();
00485 }
00486 unlock();
00487 return TRUE;
00488 }
00489
00490
00491
00492
00493
00494 void Win32MDIChildWindow::calcDefaultChildPos(Win32MDIClientWindow *client, WORD n, LPPOINT lpPos, INT delta)
00495 {
00496 INT nstagger;
00497 RECT rect;
00498 INT spacing = GetSystemMetrics(SM_CYCAPTION) +
00499 GetSystemMetrics(SM_CYFRAME) - 1;
00500
00501 client->getClientRect(&rect);
00502 if( rect.bottom - rect.top - delta >= spacing )
00503 rect.bottom -= delta;
00504
00505 nstagger = (rect.bottom - rect.top)/(3 * spacing);
00506 lpPos[1].x = (rect.right - rect.left - nstagger * spacing);
00507 lpPos[1].y = (rect.bottom - rect.top - nstagger * spacing);
00508 lpPos[0].x = lpPos[0].y = spacing * (n%(nstagger+1));
00509 }
00510
00511
00512
00513
00514
00515
00516
00517 void Win32MDIChildWindow::childGetMinMaxInfo(MINMAXINFO* lpMinMax )
00518 {
00519 Win32MDIClientWindow *client = (Win32MDIClientWindow *)getParent();
00520 RECT rect;
00521
00522 if(client == NULL) {
00523 dprintf(("Win32MDIChildWindow::childGetMinMaxInfo:: client == NULL!!"));
00524 return;
00525 }
00526
00527 client->getClientRect(&rect);
00528 if(client->getParent() == NULL) {
00529 dprintf(("Win32MDIChildWindow::childGetMinMaxInfo:: client parent == NULL!!"));
00530 return;
00531 }
00532
00533
00534
00535 AdjustWindowRectEx( &rect, getStyle(), 0, getExStyle());
00536
00537 lpMinMax->ptMaxSize.x = rect.right -= rect.left;
00538 lpMinMax->ptMaxSize.y = rect.bottom -= rect.top;
00539
00540 lpMinMax->ptMaxPosition.x = rect.left;
00541 lpMinMax->ptMaxPosition.y = rect.top;
00542 }
00543
00544
00545
00546