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

mdimenu.c

Go to the documentation of this file.
00001 /***************************************************************************\ 00002 * 00003 * MDIMENU.C - 00004 * 00005 * Copyright (c) 1985 - 1999, Microsoft Corporation 00006 * 00007 * MDI "Window" Menu Support 00008 * 00009 * History 00010 * 11-14-90 MikeHar Ported from windows 00011 * 14-Feb-1991 mikeke Added Revalidation code 00012 /****************************************************************************/ 00013 00014 #include "precomp.h" 00015 #pragma hdrstop 00016 00017 /***************************************************************************\ 00018 * FindPwndChild 00019 * 00020 * History: 00021 * 11-14-90 MikeHar Ported from windows 00022 \***************************************************************************/ 00023 00024 PWND FindPwndChild( 00025 PWND pwndMDI, 00026 UINT wChildID) 00027 { 00028 PWND pwndT; 00029 00030 for (pwndT = REBASEPWND(pwndMDI, spwndChild); 00031 pwndT && (pwndT->spwndOwner || PtrToUlong(pwndT->spmenu) != wChildID); 00032 pwndT = REBASEPWND(pwndT, spwndNext)) 00033 ; 00034 00035 return pwndT; 00036 } 00037 00038 00039 /***************************************************************************\ 00040 * MakeMenuItem 00041 * 00042 * History: 00043 * 11-14-90 MikeHar Ported from windows 00044 * 4-16-91 Win31 Merge 00045 \***************************************************************************/ 00046 00047 int MakeMenuItem( 00048 LPWSTR lpOut, 00049 PWND pwnd) 00050 { 00051 PMDI pmdi; 00052 DWORD rgParm; 00053 int cch = 0; 00054 WCHAR string[160]; 00055 LPWSTR lpstr; 00056 int i = 0; 00057 00058 /* 00059 * Get a pointer to the MDI structure 00060 */ 00061 pmdi = ((PMDIWND)(REBASEPWND(pwnd, spwndParent)))->pmdi; 00062 00063 *lpOut = 0; 00064 00065 rgParm = PtrToUlong(pwnd->spmenu) - (DWORD)FIRST(pmdi) + 1; 00066 00067 if (pwnd->strName.Length) { 00068 lpstr = REBASEALWAYS(pwnd, strName.Buffer); 00069 00070 /* 00071 * Search for an & in the title string and duplicate it so that we don't 00072 * get bogus accelerators. 00073 */ 00074 while (*lpstr && i < ((sizeof(string) / sizeof(WCHAR)) - 1)) { 00075 string[i] = *lpstr; 00076 i++; 00077 if (*lpstr == TEXT('&')) 00078 string[i++] = TEXT('&'); 00079 00080 lpstr++; 00081 } 00082 00083 string[i] = 0; 00084 cch = wsprintfW(lpOut, L"&%d %ws", rgParm, string); 00085 00086 } else { 00087 00088 /* 00089 * Handle the case of MDI children without any window title text. 00090 */ 00091 cch = wsprintfW(lpOut, L"&%d ", rgParm); 00092 } 00093 00094 return cch; 00095 } 00096 00097 /***************************************************************************\ 00098 * ModifyMenuItem 00099 * 00100 * History: 00101 * 11-14-90 MikeHar Ported from windows 00102 \***************************************************************************/ 00103 00104 void ModifyMenuItem( 00105 PWND pwnd) 00106 { 00107 PMDI pmdi; 00108 WCHAR sz[200]; 00109 MENUITEMINFO mii; 00110 PWND pwndParent; 00111 PMENU pmenu; 00112 00113 /* 00114 * Get a pointer to the MDI structure 00115 */ 00116 pwndParent = REBASEPWND(pwnd, spwndParent); 00117 pmdi = ((PMDIWND)pwndParent)->pmdi; 00118 00119 if (PtrToUlong(pwnd->spmenu) > FIRST(pmdi) + (UINT)8) 00120 return; 00121 00122 mii.cbSize = sizeof(MENUITEMINFO); 00123 mii.fMask = MIIM_STRING; 00124 mii.dwTypeData = sz; 00125 00126 /* 00127 * Parent is MDI Client. 00128 */ 00129 MakeMenuItem(sz, pwnd); 00130 00131 /* 00132 * Changing the active child? Check it. 00133 */ 00134 if (HWq(pwnd) == ACTIVE(pmdi)) { 00135 mii.fMask |= MIIM_STATE; 00136 mii.fState = MFS_CHECKED; 00137 } 00138 00139 pwndParent = REBASEPWND(pwndParent, spwndParent); 00140 00141 if (pwndParent->spmenu) { 00142 00143 /* 00144 * Bug# 21566. If spmenu is NULL we used to fail 00145 * because REBASEALWAYS is trying to get the kernel 00146 * address of NULL based on pwndParent 00147 */ 00148 pmenu = REBASEALWAYS(pwndParent, spmenu); 00149 /* 00150 * Internal call to SetMenuItemInfo 00151 */ 00152 ThunkedMenuItemInfo(PtoH(pmenu), PtrToUlong(pwnd->spmenu), FALSE, FALSE, &mii, FALSE); 00153 } 00154 } 00155 00156 /***************************************************************************\ 00157 * MDIAddSysMenu 00158 * 00159 * Insert the MDI child's system menu onto the existing Menu. 00160 * 00161 * History: 00162 * 11-14-90 MikeHar Ported from windows 00163 \***************************************************************************/ 00164 00165 BOOL MDIAddSysMenu( 00166 HMENU hMenuFrame, 00167 HWND hwndChild) 00168 { 00169 PWND pwndChild; 00170 MENUITEMINFO mii; 00171 PMENU pMenuChild; 00172 00173 00174 // LATER -- look at passing pwndChild in -- FritzS 00175 00176 UserAssert(IsWindow(hwndChild)); 00177 pwndChild = ValidateHwnd(hwndChild); 00178 if (!hMenuFrame || !pwndChild || !pwndChild->spmenuSys) { 00179 return FALSE; 00180 } 00181 00182 /* 00183 * We don't need the pMenuChild pointer but the handle. However, if you 00184 * do PtoH(_GetSubMenu()), you end up calling the function twice 00185 */ 00186 pMenuChild = _GetSubMenu (REBASEALWAYS(pwndChild, spmenuSys), 0); 00187 if (!pMenuChild) { 00188 return FALSE; 00189 } 00190 00191 // Add MDI system button as first menu item 00192 mii.cbSize = sizeof(MENUITEMINFO); 00193 mii.fMask = MIIM_SUBMENU | MIIM_DATA | MIIM_BITMAP; // Add MIIM_DATA because of hack described below 00194 mii.hSubMenu = PtoH(pMenuChild); 00195 // Fritzs -- this won't work. 00196 // mii.dwTypeData = (LPSTR) MAKELONG(MENUHBM_SYSTEM, GetWindowSmIcon(hwndChild)); 00197 mii.hbmpItem = HBMMENU_SYSTEM; 00198 // FritzS -- so, we sneak the icon into ItemData 00199 mii.dwItemData = (ULONG_PTR)hwndChild; 00200 00201 if (!InternalInsertMenuItem(hMenuFrame, 0, TRUE, &mii)) 00202 return FALSE; 00203 00204 // TimeLine 6.1 gets confused by the extra Min/Close buttons, 00205 // don't add them if WFOLDUI 00206 00207 mii.fMask = MIIM_ID | MIIM_FTYPE | MIIM_BITMAP; 00208 mii.fType = MFT_RIGHTJUSTIFY; 00209 00210 pwndChild = ValidateHwnd(hwndChild); 00211 if (!pwndChild) { 00212 NtUserRemoveMenu(hMenuFrame, 0, MF_BYPOSITION); 00213 return FALSE; 00214 } 00215 00216 00217 if (!TestWF(pwndChild, WFOLDUI)) 00218 { 00219 // Add Minimize button as last menu item 00220 mii.hbmpItem = (TestWF(pwndChild, WFMINBOX) ? HBMMENU_MBAR_MINIMIZE : HBMMENU_MBAR_MINIMIZE_D); 00221 mii.wID = SC_MINIMIZE; 00222 00223 if (!InternalInsertMenuItem(hMenuFrame, MFMWFP_NOITEM, TRUE, &mii)) 00224 { 00225 NtUserRemoveMenu(hMenuFrame, 0, MF_BYPOSITION); 00226 return FALSE; 00227 } 00228 mii.fType &= ~MFT_RIGHTJUSTIFY; 00229 } 00230 00231 // Add Restore button as last menu item 00232 mii.hbmpItem = HBMMENU_MBAR_RESTORE; 00233 mii.wID = SC_RESTORE; 00234 00235 if (!InternalInsertMenuItem(hMenuFrame, MFMWFP_NOITEM, TRUE, &mii)) { 00236 // BOGUS -- we gotta remove the MINIMIZE button too 00237 NtUserRemoveMenu(hMenuFrame, 0, MF_BYPOSITION); 00238 return FALSE; 00239 } 00240 00241 pwndChild = ValidateHwnd(hwndChild); 00242 if (!pwndChild) { 00243 NtUserRemoveMenu(hMenuFrame, 0, MF_BYPOSITION); 00244 return FALSE; 00245 } 00246 00247 if (!TestWF(pwndChild, WFOLDUI)) 00248 { 00249 // Add Close button as last menu item 00250 mii.hbmpItem = (xxxMNCanClose(pwndChild) ? HBMMENU_MBAR_CLOSE : HBMMENU_MBAR_CLOSE_D); 00251 mii.wID = SC_CLOSE; 00252 00253 if (!InternalInsertMenuItem(hMenuFrame, MFMWFP_NOITEM, TRUE, &mii)) 00254 { 00255 // BOGUS -- we gotta remove the MINIMIZE and RESTORE buttons too 00256 NtUserRemoveMenu(hMenuFrame, 0, MF_BYPOSITION); 00257 return FALSE; 00258 } 00259 } 00260 00261 /* 00262 * Set the menu items to proper state since we just maximized it. Note 00263 * setsysmenu doesn't work if we've cleared the sysmenu bit so do it now... 00264 */ 00265 NtUserSetSysMenu(hwndChild); 00266 00267 /* 00268 * This is so that if the user brings up the child sysmenu, it's sure 00269 * to be that in the frame menu bar... 00270 */ 00271 ClearWindowState(pwndChild, WFSYSMENU); 00272 00273 /* 00274 * Make sure that the child's frame is redrawn to reflect the removed 00275 * system menu. 00276 */ 00277 NtUserRedrawFrame(hwndChild); 00278 00279 return TRUE; 00280 } 00281 00282 /***************************************************************************\ 00283 * MDIRemoveSysMenu 00284 * 00285 * History: 00286 * 11-14-90 MikeHar Ported from windows 00287 \***************************************************************************/ 00288 00289 BOOL MDIRemoveSysMenu( 00290 HMENU hMenuFrame, 00291 HWND hwndChild) 00292 { 00293 int iLastItem; 00294 UINT iLastCmd; 00295 PWND pwndChild; 00296 00297 // LATER -- look at passing pwndChild in -- FritzS 00298 00299 if (hMenuFrame == NULL) 00300 return FALSE; 00301 00302 pwndChild = ValidateHwnd(hwndChild); 00303 00304 if (pwndChild == NULL) 00305 return FALSE; 00306 00307 iLastItem = GetMenuItemCount(hMenuFrame) - 1; 00308 iLastCmd = TestWF(pwndChild, WFOLDUI) ? SC_RESTORE : SC_CLOSE; 00309 00310 if ((UINT) GetMenuItemID(hMenuFrame, iLastItem) != iLastCmd) 00311 return FALSE; 00312 00313 /* 00314 * Enable the sysmenu in the child window. 00315 */ 00316 SetWindowState(pwndChild, WFSYSMENU); 00317 00318 /* 00319 * Take the child sysmenu popup out of the frame menu. 00320 */ 00321 NtUserRemoveMenu(hMenuFrame, 0, MF_BYPOSITION); 00322 00323 /* 00324 * Delete the restore button from the menu bar. 00325 */ 00326 NtUserDeleteMenu(hMenuFrame, iLastItem - 1, MF_BYPOSITION); 00327 00328 pwndChild = ValidateHwnd(hwndChild); 00329 if (pwndChild == NULL) 00330 return FALSE; 00331 00332 if (!TestWF(pwndChild, WFOLDUI)) { 00333 NtUserDeleteMenu(hMenuFrame, iLastItem - 2, MF_BYPOSITION); 00334 NtUserDeleteMenu(hMenuFrame, iLastItem - 3, MF_BYPOSITION); 00335 } 00336 00337 /* 00338 * Make sure that the child's frame is redrawn to reflect the added 00339 * system menu. 00340 */ 00341 NtUserRedrawFrame(hwndChild); 00342 00343 return TRUE; 00344 } 00345 00346 /***************************************************************************\ 00347 * AppendToWindowsMenu 00348 * 00349 * Add the title of the MDI child window 'hwndChild' to the bottom of the 00350 * "Window" menu (or add the "More Windows ..." item) if there's room. 00351 * 00352 * MDI Child # Add 00353 * ------------- -------------------- 00354 * < MAXITEMS Child # and Title 00355 * = MAXITEMS "More Windows ..." 00356 * > MAXITEMS nothing 00357 * 00358 * History: 00359 * 17-Mar-1992 mikeke from win31 00360 \***************************************************************************/ 00361 00362 BOOL FAR PASCAL AppendToWindowsMenu( 00363 PWND pwndMDI, 00364 PWND pwndChild) 00365 { 00366 PMDI pmdi; 00367 WCHAR szMenuItem[165]; 00368 int item; 00369 MENUITEMINFO mii; 00370 00371 /* 00372 * Get a pointer to the MDI structure 00373 */ 00374 pmdi = ((PMDIWND)pwndMDI)->pmdi; 00375 00376 item = PtrToUlong(pwndChild->spmenu) - FIRST(pmdi); 00377 00378 if (WINDOW(pmdi) && (item < MAXITEMS)) { 00379 mii.cbSize = sizeof(MENUITEMINFO); 00380 if (!item) { 00381 00382 /* 00383 * Add separator before first item 00384 */ 00385 mii.fMask = MIIM_FTYPE; 00386 mii.fType = MFT_SEPARATOR; 00387 if (!InternalInsertMenuItem(WINDOW(pmdi), MFMWFP_NOITEM, TRUE, &mii)) 00388 return FALSE; 00389 } 00390 00391 if (item == (MAXITEMS - 1)) 00392 LoadString(hmodUser, STR_MOREWINDOWS, szMenuItem, 00393 sizeof(szMenuItem) / sizeof(WCHAR)); 00394 else 00395 MakeMenuItem(szMenuItem, pwndChild); 00396 00397 mii.fMask = MIIM_ID | MIIM_STRING; 00398 mii.wID = PtrToUlong(pwndChild->spmenu); 00399 mii.dwTypeData = szMenuItem; 00400 mii.cch = (UINT)-1; 00401 if (!InternalInsertMenuItem(WINDOW(pmdi), MFMWFP_NOITEM, TRUE, &mii)) 00402 return FALSE; 00403 } 00404 return TRUE; 00405 } 00406 00407 /***************************************************************************\ 00408 * SwitchWindowsMenus 00409 * 00410 * Switch the "Window" menu in the frame menu bar 'hMenu' from 00411 * 'hOldWindow' to 'hNewWindow' 00412 * 00413 * History: 00414 * 17-Mar-1992 mikeke from win31 00415 \***************************************************************************/ 00416 00417 BOOL SwitchWindowsMenus( 00418 HMENU hmenu, 00419 HMENU hOldWindow, 00420 HMENU hNewWindow) 00421 { 00422 int i; 00423 HMENU hsubMenu; 00424 WCHAR szMenuName[128]; 00425 MENUITEMINFO mii; 00426 00427 if (hOldWindow == hNewWindow) 00428 return TRUE; 00429 00430 mii.cbSize = sizeof(MENUITEMINFO); 00431 00432 /* 00433 * Determine position of old "Window" menu 00434 */ 00435 for (i = 0; hsubMenu = GetSubMenu(hmenu, i); i++) { 00436 if (hsubMenu == hOldWindow) 00437 { 00438 // Extract the name of the old menu to use it for the new menu 00439 mii.fMask = MIIM_STRING; 00440 mii.dwTypeData = szMenuName; 00441 mii.cch = sizeof(szMenuName)/sizeof(WCHAR); 00442 GetMenuItemInfoInternalW(hmenu, i, TRUE, &mii); 00443 // Out with the old, in with the new 00444 if (!NtUserRemoveMenu(hmenu, i, MF_BYPOSITION)) 00445 return(FALSE); 00446 00447 mii.fMask |= MIIM_SUBMENU; 00448 mii.hSubMenu = hNewWindow; 00449 return(InternalInsertMenuItem(hmenu, i, TRUE, &mii)); 00450 } 00451 } 00452 00453 return(FALSE); 00454 } 00455 00456 /***************************************************************************\ 00457 * ShiftMenuIDs 00458 * 00459 * Shift the id's of the MDI child windows of the MDI client window 'hWnd' 00460 * down by 1 (id--) starting with the child window 'hwndVictim' -- moving 00461 * 'hwndVictim' to the end of the list 00462 * 00463 * History: 00464 * 17-Mar-1992 mikeke from win31 00465 \***************************************************************************/ 00466 00467 void ShiftMenuIDs( 00468 PWND pwnd, 00469 PWND pwndVictim) 00470 { 00471 PMDI pmdi; 00472 PWND pwndChild; 00473 PWND pwndParent; 00474 /* 00475 * Get a pointer to the MDI structure 00476 */ 00477 pmdi = ((PMDIWND)pwnd)->pmdi; 00478 00479 pwndParent = REBASEPWND(pwndVictim, spwndParent); 00480 pwndChild = REBASEPWND(pwndParent, spwndChild); 00481 00482 while (pwndChild) { 00483 if (!pwndChild->spwndOwner && (pwndChild->spmenu > pwndVictim->spmenu)) { 00484 SetWindowLongPtr(HWq(pwndChild), GWLP_ID, PtrToUlong(pwndChild->spmenu) - 1); 00485 } 00486 pwndChild = REBASEPWND(pwndChild, spwndNext); 00487 } 00488 00489 SetWindowLongPtr(HWq(pwndVictim), GWLP_ID, FIRST(pmdi) + CKIDS(pmdi) - 1); 00490 } 00491 00492 /***************************************************************************\ 00493 * MDISetMenu 00494 * 00495 * History: 00496 * 11-14-90 MikeHar Ported from windows 00497 \***************************************************************************/ 00498 00499 HMENU MDISetMenu( 00500 PWND pwndMDI, 00501 BOOL fRefresh, 00502 HMENU hNewSys, 00503 HMENU hNewWindow) 00504 { 00505 int i; 00506 int iFirst; 00507 int item; 00508 PMDI pmdi; 00509 PWND pwndParent; 00510 HMENU hOldSys; 00511 HMENU hOldWindow; 00512 PWND pwndChild; 00513 00514 /* 00515 * Get a pointer to the MDI structure 00516 */ 00517 pmdi = ((PMDIWND)pwndMDI)->pmdi; 00518 00519 /* 00520 * Save the old values 00521 */ 00522 pwndParent = REBASEPWND(pwndMDI, spwndParent); 00523 hOldSys = GetMenu(HW(pwndParent)); 00524 hOldWindow = WINDOW(pmdi); 00525 00526 if (fRefresh) { 00527 hNewSys = hOldSys; 00528 hNewWindow = hOldWindow; 00529 } 00530 00531 /* 00532 * Change the Frame Menu. 00533 */ 00534 if (hNewSys && (hNewSys != hOldSys)) { 00535 if (MAXED(pmdi)) 00536 MDIRemoveSysMenu(hOldSys, MAXED(pmdi)); 00537 00538 NtUserSetMenu(HW(pwndParent), hNewSys, FALSE); 00539 00540 if (MAXED(pmdi)) 00541 MDIAddSysMenu(hNewSys, MAXED(pmdi)); 00542 } else 00543 hNewSys = hOldSys; 00544 00545 /* 00546 * Now update the Window menu. 00547 */ 00548 if (fRefresh || (hOldWindow != hNewWindow)) { 00549 iFirst = FIRST(pmdi); 00550 00551 if (hOldWindow) { 00552 int cItems = GetMenuItemCount(hOldWindow); 00553 00554 for (i = cItems - 1; i >= 0; i--) { 00555 if (GetMenuState(hOldWindow, i, MF_BYPOSITION) & MF_SEPARATOR) 00556 break; 00557 } 00558 if ((i >= 0) && (GetMenuItemID(hOldWindow, i + 1) == (UINT)iFirst)) { 00559 int idTrim = i; 00560 00561 for (i = idTrim; i < cItems; i++) 00562 NtUserDeleteMenu(hOldWindow, idTrim, MF_BYPOSITION); 00563 } 00564 } 00565 00566 Lock(&WINDOW(pmdi), hNewWindow); 00567 00568 if (hNewWindow != NULL) { 00569 00570 /* 00571 * Add the list of child windows to the new window 00572 */ 00573 for (i = 0, item = 0; ((UINT)i < CKIDS(pmdi)) && (item < MAXITEMS); 00574 i++) { 00575 pwndChild = FindPwndChild(pwndMDI, iFirst + item); 00576 if (pwndChild != NULL) { 00577 if ((!TestWF(pwndChild, WFVISIBLE) && 00578 (LOWORD(pwndMDI->style) & 0x0001)) || 00579 TestWF(pwndChild, WFDISABLED)) { 00580 ShiftMenuIDs(pwndMDI, pwndChild); 00581 } else { 00582 AppendToWindowsMenu(pwndMDI, pwndChild); 00583 item++; 00584 } 00585 } 00586 } 00587 00588 /* 00589 * Add checkmark by the active child's menu item 00590 */ 00591 if (ACTIVE(pmdi)) 00592 CheckMenuItem(hNewWindow, (WORD)GetWindowID(ACTIVE(pmdi)), 00593 MF_BYCOMMAND | MF_CHECKED); 00594 } 00595 00596 /* 00597 * Out with the old, in with the new 00598 */ 00599 SwitchWindowsMenus(hNewSys, hOldWindow, hNewWindow); 00600 } 00601 return hOldSys; 00602 } 00603 00604 /***************************************************************************\ 00605 * xxxInitActivateDlg 00606 * 00607 * History: 00608 * 11-14-90 MikeHar Ported from windows 00609 \***************************************************************************/ 00610 00611 void xxxInitActivateDlg( 00612 HWND hwnd, 00613 PWND pwndMDI) 00614 { 00615 PMDI pmdi; 00616 UINT wKid; 00617 HWND hwndT; 00618 PWND pwndT; 00619 WCHAR szTitle[CCHTITLEMAX]; 00620 TL tlpwndT; 00621 SIZE Size; 00622 HDC hDC; 00623 DWORD width = 0; 00624 00625 CheckLock(pwndMDI); 00626 00627 /* 00628 * Get a pointer to the MDI structure 00629 */ 00630 pmdi = ((PMDIWND)pwndMDI)->pmdi; 00631 00632 hDC = NtUserGetDC(hwnd); 00633 00634 /* 00635 * Insert the list of titles. 00636 * Note the wKid-th item in the listbox has ID wKid+FIRST(pwnd), so that 00637 * the listbox is in creation order (like the menu). This is also 00638 * helpful when we go to select one... 00639 */ 00640 00641 for (wKid = 0; wKid < CKIDS(pmdi); wKid++) { 00642 pwndT = FindPwndChild(pwndMDI, (UINT)(wKid + FIRST(pmdi))); 00643 00644 if (pwndT && TestWF(pwndT, WFVISIBLE) && !TestWF(pwndT, WFDISABLED)) { 00645 ThreadLockAlways(pwndT, &tlpwndT); 00646 GetWindowText(HWq(pwndT), szTitle, CCHTITLEMAX); 00647 SendDlgItemMessage(hwnd, 100, LB_ADDSTRING, 0, (LPARAM)szTitle); 00648 GetTextExtentPoint(hDC, szTitle, lstrlen(szTitle), &Size); 00649 if (Size.cx > (LONG)width) { 00650 width = Size.cx; 00651 } 00652 ThreadUnlock(&tlpwndT); 00653 } 00654 } 00655 00656 /* 00657 * Select the currently active window. 00658 */ 00659 SendDlgItemMessage(hwnd, 100, LB_SETTOPINDEX, MAXITEMS - 1, 0L); 00660 SendDlgItemMessage(hwnd, 100, LB_SETCURSEL, MAXITEMS - 1, 0L); 00661 00662 /* 00663 * Set the horizontal extent of the list box to the longest window title. 00664 */ 00665 SendDlgItemMessage(hwnd, 100, LB_SETHORIZONTALEXTENT, width, 0L); 00666 NtUserReleaseDC(hwnd, hDC); 00667 00668 /* 00669 * Set the focus to the listbox. 00670 */ 00671 hwndT = GetDlgItem(hwnd, 100); 00672 NtUserSetFocus(hwndT); 00673 } 00674 00675 /***************************************************************************\ 00676 * MDIActivateDlgSize 00677 * 00678 * The minimum allowed size and the previous one are saved as properties 00679 * of the parent window. 00680 * 00681 * History: 00682 * Oct 97 MCostea Created 00683 \***************************************************************************/ 00684 00685 VOID MDIActivateDlgSize(HWND hwnd, int width, int height) 00686 { 00687 PMDIACTIVATEPOS pPos; 00688 PWND pwnd, pwndList, pwndButtonLeft, pwndButtonRight; 00689 HDWP hdwp; 00690 int deltaX, deltaY; 00691 00692 pPos = (PMDIACTIVATEPOS)GetProp(GetParent(hwnd), MAKEINTATOM(atomMDIActivateProp)); 00693 if (pPos == NULL) { 00694 return; 00695 } 00696 00697 /* 00698 * Retrieve the children 00699 */ 00700 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 00701 return; 00702 } 00703 pwndList = REBASEPWND(pwnd, spwndChild); 00704 pwndButtonLeft = REBASEPWND(pwndList, spwndNext); 00705 pwndButtonRight = REBASEPWND(pwndButtonLeft, spwndNext); 00706 00707 UserAssert(GETFNID(pwndList) == FNID_LISTBOX); 00708 UserAssert(GETFNID(pwndButtonLeft) == FNID_BUTTON); 00709 UserAssert(GETFNID(pwndButtonRight) == FNID_BUTTON); 00710 UserAssert(pwndButtonRight->rcWindow.left > pwndButtonLeft->rcWindow.left); 00711 00712 deltaX = width - pPos->cx; 00713 deltaY = height - pPos->cy; 00714 00715 pPos->cx = width; 00716 pPos->cy = height; 00717 00718 /* 00719 * Move/resize the child windows accordingly 00720 */ 00721 hdwp = NtUserBeginDeferWindowPos(3); 00722 00723 if (hdwp) 00724 { 00725 hdwp = NtUserDeferWindowPos( hdwp, 00726 PtoH(pwndList), 00727 NULL, 00728 0, 00729 0, 00730 deltaX + pwndList->rcWindow.right - pwndList->rcWindow.left, 00731 deltaY + pwndList->rcWindow.bottom - pwndList->rcWindow.top, 00732 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE ); 00733 00734 if (hdwp) 00735 { 00736 hdwp = NtUserDeferWindowPos(hdwp, 00737 PtoH(pwndButtonLeft), 00738 NULL, 00739 pwndButtonLeft->rcWindow.left - pwnd->rcClient.left, 00740 deltaY + pwndButtonLeft->rcWindow.top - pwnd->rcClient.top, 00741 0, 00742 0, 00743 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); 00744 00745 00746 if (hdwp) 00747 { 00748 hdwp = NtUserDeferWindowPos( hdwp, 00749 PtoH(pwndButtonRight), 00750 NULL, 00751 pwndButtonRight->rcWindow.left - pwnd->rcClient.left, 00752 deltaY + pwndButtonRight->rcWindow.top - pwnd->rcClient.top, 00753 0, 00754 0, 00755 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); 00756 } 00757 00758 } 00759 if (hdwp) { 00760 NtUserEndDeferWindowPosEx(hdwp, FALSE); 00761 } 00762 } 00763 } 00764 00765 /***************************************************************************\ 00766 * MDIActivateDlgInit 00767 * 00768 * The minimum allowed size and the previous one are saved as properties 00769 * of the parent window. 00770 * 00771 * History: 00772 * Oct 97 MCostea Created 00773 \***************************************************************************/ 00774 00775 VOID MDIActivateDlgInit(HWND hwnd, LPARAM lParam) 00776 { 00777 PMDIACTIVATEPOS pPos; 00778 HWND hwndParent; 00779 RECT rc; 00780 00781 xxxInitActivateDlg(hwnd, (PWND)lParam); 00782 00783 hwndParent = GetParent(hwnd); 00784 /* 00785 * Preserve the previous size of the dialog, if any 00786 */ 00787 if (atomMDIActivateProp == 0) { 00788 00789 atomMDIActivateProp = AddAtomW(MDIACTIVATE_PROP_NAME); 00790 UserAssert(atomMDIActivateProp); 00791 } 00792 00793 GetWindowRect(hwnd, &rc); 00794 00795 pPos = (PMDIACTIVATEPOS)GetProp(hwndParent, MAKEINTATOM(atomMDIActivateProp)); 00796 /* 00797 * If the dialog was used before, retrieve it's size 00798 */ 00799 if (pPos != NULL) { 00800 00801 int cxBorder, cyBorder, cx, cy; 00802 00803 /* 00804 * The stored size and the ones in WM_SIZE are client window coordinates 00805 * Need to adjust them for NtUserSetWindowPos and WM_INITDIALOG 00806 */ 00807 cxBorder = rc.right - rc.left; 00808 cyBorder = rc.bottom - rc.top; 00809 GetClientRect(hwnd, &rc); 00810 cxBorder -= rc.right - rc.left; 00811 cyBorder -= rc.bottom - rc.top; 00812 00813 NtUserSetWindowPos(hwnd, NULL, 0, 0, 00814 pPos->cx + cxBorder, 00815 pPos->cy + cyBorder, 00816 SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER 00817 | SWP_NOSENDCHANGING | SWP_NOREDRAW); 00818 cx = pPos->cx; 00819 cy = pPos->cy; 00820 pPos->cx = pPos->cxMin - cxBorder; 00821 pPos->cy = pPos->cyMin - cyBorder; 00822 MDIActivateDlgSize(hwnd, cx, cy); 00823 00824 } else { 00825 /* 00826 * 00827 */ 00828 pPos = UserLocalAlloc(0, sizeof(MDIACTIVATEPOS)); 00829 if (pPos == NULL) { 00830 return; 00831 } 00832 pPos->cxMin = rc.right - rc.left; 00833 pPos->cyMin = rc.bottom - rc.top; 00834 00835 GetClientRect(hwnd, &rc); 00836 pPos->cx = rc.right - rc.left; 00837 pPos->cy = rc.bottom - rc.top; 00838 SetProp(hwndParent, MAKEINTATOM(atomMDIActivateProp), (HANDLE)pPos); 00839 } 00840 } 00841 00842 /***************************************************************************\ 00843 * MDIActivateDlgProc 00844 * 00845 * History: 00846 * 11-14-90 MikeHar Ported from windows 00847 \***************************************************************************/ 00848 00849 INT_PTR MDIActivateDlgProcWorker( 00850 HWND hwnd, 00851 UINT wMsg, 00852 WPARAM wParam, 00853 LPARAM lParam) 00854 { 00855 int i; 00856 00857 switch (wMsg) { 00858 00859 case WM_INITDIALOG: 00860 /* 00861 * NOTE: Code above uses DialogBoxParam, passing pwndMDI in the low 00862 * word of the parameter... 00863 */ 00864 MDIActivateDlgInit(hwnd, lParam); 00865 return FALSE; 00866 00867 case WM_COMMAND: 00868 i = -2; 00869 00870 switch (LOWORD(wParam)) { 00871 00872 /* 00873 * Listbox doubleclicks act like OK... 00874 */ 00875 case 100: 00876 if (HIWORD(wParam) != LBN_DBLCLK) 00877 break; 00878 00879 /* 00880 ** FALL THRU ** 00881 */ 00882 case IDOK: 00883 i = (UINT)SendDlgItemMessage(hwnd, 100, LB_GETCURSEL, 0, 0L); 00884 00885 /* 00886 ** FALL THRU ** 00887 */ 00888 case IDCANCEL: 00889 EndDialog(hwnd, i); 00890 break; 00891 default: 00892 return FALSE; 00893 } 00894 break; 00895 00896 case WM_SIZE: 00897 MDIActivateDlgSize(hwnd, LOWORD(lParam), HIWORD(lParam)); 00898 return FALSE; 00899 00900 case WM_GETMINMAXINFO: 00901 { 00902 PMDIACTIVATEPOS pPos; 00903 00904 if (pPos = (PMDIACTIVATEPOS)GetProp(GetParent(hwnd), MAKEINTATOM(atomMDIActivateProp))) { 00905 ((LPMINMAXINFO)lParam)->ptMinTrackSize.x = pPos->cxMin; 00906 ((LPMINMAXINFO)lParam)->ptMinTrackSize.y = pPos->cyMin; 00907 } 00908 return FALSE; 00909 } 00910 00911 default: 00912 return FALSE; 00913 } 00914 return TRUE; 00915 } 00916 00917 INT_PTR WINAPI MDIActivateDlgProcA( 00918 HWND hwnd, 00919 UINT message, 00920 WPARAM wParam, 00921 LPARAM lParam) 00922 { 00923 return MDIActivateDlgProcWorker(hwnd, message, wParam, lParam); 00924 } 00925 00926 INT_PTR WINAPI MDIActivateDlgProcW( 00927 HWND hwnd, 00928 UINT message, 00929 WPARAM wParam, 00930 LPARAM lParam) 00931 { 00932 return MDIActivateDlgProcWorker(hwnd, message, wParam, lParam); 00933 }

Generated on Sat May 15 19:40:42 2004 for test by doxygen 1.3.7