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

dlgmgr2.c File Reference

#include "precomp.h"

Go to the source code of this file.

Functions

void xxxRemoveDefaultButton (PWND pwndRoot, PWND pwndStart)
void xxxCheckDefPushButton (PWND pwndDlg, HWND hwndOldFocus, HWND hwndNewFocus)
BOOL IsDialogMessageA (HWND hwndDlg, LPMSG lpmsg)
BOOL IsDialogMessageW (HWND hwndDlg, LPMSG lpMsg)
PWND _FindDlgItem (PWND pwndParent, DWORD id)


Function Documentation

PWND _FindDlgItem PWND  pwndParent,
DWORD  id
 

Definition at line 749 of file dlgmgr2.c.

References _GetDlgItem(), _NextControl(), NULL, tagWND::spmenu, TestWF, and WFWIN40COMPAT.

Referenced by DefDlgProcWorker(), IsDialogMessageW(), and xxxCheckDefPushButton().

00750 { 00751 PWND pwndChild; 00752 PWND pwndOrig; 00753 00754 // QUICK TRY: 00755 pwndChild = _GetDlgItem(pwndParent, id); 00756 if (pwndChild || !TestWF(pwndParent, WFWIN40COMPAT)) 00757 return(pwndChild); 00758 00759 pwndOrig = _NextControl(pwndParent, NULL, CWP_SKIPINVISIBLE); 00760 if (pwndOrig == pwndParent) 00761 return(NULL); 00762 00763 pwndChild = pwndOrig; 00764 00765 // VerifyWindow(pwndChild); 00766 00767 do 00768 { 00769 if (PtrToUlong(pwndChild->spmenu) == id) 00770 return(pwndChild); 00771 00772 pwndChild = _NextControl(pwndParent, pwndChild, CWP_SKIPINVISIBLE); 00773 } 00774 while (pwndChild && (pwndChild != pwndOrig)); 00775 00776 return(NULL); 00777 }

BOOL IsDialogMessageA HWND  hwndDlg,
LPMSG  lpmsg
 

Definition at line 230 of file dlgmgr2.c.

References _IsChild(), BOOL, BUILD_DBCS_MESSAGE_TO_CLIENTW_FROM_CLIENTA, FALSE, GetParentDialog(), HWq, IS_DBCS_ENABLED, IsDialogMessageW(), NULL, RtlMBMessageWParamCharToWCS(), TestWF, ThreadLock, ThreadUnlock, TRUE, ValidateHwnd, ValidateHwndNoRip(), WEFCONTROLPARENT, and WFCHILD.

00233 { 00234 WPARAM wParamSaved = lpmsg->wParam; 00235 BOOL bRet; 00236 00237 switch (lpmsg->message) { 00238 #ifdef FE_SB // IsDialogMessageA() 00239 case WM_CHAR: 00240 case EM_SETPASSWORDCHAR: 00241 /* 00242 * BUILD_DBCS_MESSAGE_TO_CLIENTW_FROM_CLIENTA() macro will return TRUE 00243 * for DBCS leadbyte message everytime, then we check there is some 00244 * possibility the return value become FALSE, here. 00245 * 00246 * These code originally come from IsDialogMessageW(). 00247 */ 00248 if (IS_DBCS_ENABLED()) { 00249 PWND pwndDlg, pwnd; 00250 TL tlpwndDlg; 00251 BOOL fLockDlg = FALSE; 00252 00253 if ((pwndDlg = ValidateHwndNoRip(hwndDlg)) == NULL) { 00254 return FALSE; 00255 } 00256 00257 if (lpmsg->hwnd == NULL) { 00258 return FALSE; 00259 } 00260 00261 pwnd = ValidateHwnd(lpmsg->hwnd); 00262 // 00263 // THIS IS FOR MFC. 00264 // 00265 // This solves many problems with apps that use MFC but want to take 00266 // advantage of DS_CONTROL. MFC blindly passes in child dialogs sometimes 00267 // to IsDialogMessage, which can screw up tabbing etc. 00268 // 00269 if (TestWF(pwndDlg, WEFCONTROLPARENT) && TestWF(pwndDlg, WFCHILD)) { 00270 pwndDlg = GetParentDialog(pwndDlg); 00271 ThreadLock(pwndDlg, &tlpwndDlg); 00272 fLockDlg = TRUE; 00273 hwndDlg = HWq(pwndDlg); 00274 } 00275 00276 if (pwnd != pwndDlg && !_IsChild(pwndDlg, pwnd)) { 00277 if (fLockDlg) 00278 ThreadUnlock(&tlpwndDlg); 00279 return FALSE; 00280 } 00281 00282 /* 00283 * Build DBCS-aware message. 00284 */ 00285 BUILD_DBCS_MESSAGE_TO_CLIENTW_FROM_CLIENTA(lpmsg->message,lpmsg->wParam,TRUE); 00286 00287 /* 00288 * Fall through..... 00289 */ 00290 } 00291 #else 00292 case WM_CHAR: 00293 case EM_SETPASSWORDCHAR: 00294 #endif // FE_SB 00295 case WM_CHARTOITEM: 00296 case WM_DEADCHAR: 00297 case WM_SYSCHAR: 00298 case WM_SYSDEADCHAR: 00299 case WM_MENUCHAR: 00300 #ifdef FE_IME // IsDialogMessageA() 00301 case WM_IME_CHAR: 00302 case WM_IME_COMPOSITION: 00303 #endif // FE_IME 00304 00305 RtlMBMessageWParamCharToWCS(lpmsg->message, &lpmsg->wParam); 00306 } 00307 00308 bRet = IsDialogMessageW(hwndDlg, lpmsg); 00309 00310 /* 00311 * Restore the original ANSI char. 00312 */ 00313 lpmsg->wParam = wParamSaved; 00314 return bRet; 00315 }

BOOL IsDialogMessageW HWND  hwndDlg,
LPMSG  lpMsg
 

Definition at line 317 of file dlgmgr2.c.

References _FindDlgItem(), _GetNextDlgGroupItem(), _GetNextDlgTabItem(), _IsChild(), BFTYPEMASK, BOOL, BST_DONTCLICK, BUTTONSTATE, CallMsgFilter(), CheckLock, DefWindowProcWorker(), DispatchMessage(), DlgSetFocus(), DWORD, FALSE, FNID_BUTTON, GetClientInfo, GetDlgCtrlID(), GETFNID, GetFocus(), GetKeyState(), GetParentDialog(), HW, HWq, L, LOBYTE, MENUSYSMENU, MSGFLAG_WOW_RESERVED, NtUserMessageBeep, NULL, SendMessage(), SendMessageWorker(), SYS_ALTERNATE, TEST_KbdCuesPUSIF, TESTSYNCONLYMESSAGE, TestWF, ThreadLock, ThreadLockAlways, ThreadUnlock, TIF_16BIT, TranslateMessage(), TRUE, UINT, ValidateHwnd, ValidateHwndNoRip(), WEFCONTROLPARENT, WEFPUIACCELHIDDEN, WEFPUIFOCUSHIDDEN, WEFRTLREADING, WFCHILD, WFDISABLED, WFMINIMIZED, xxxCheckDefPushButton(), and xxxGotoNextMnem().

Referenced by IsDialogMessageA().

00320 { 00321 PWND pwndDlg; 00322 PWND pwnd; 00323 PWND pwnd2; 00324 HWND hwnd2; 00325 HWND hwndFocus; 00326 int iOK; 00327 BOOL fBack; 00328 UINT code; 00329 LONG lT; 00330 TL tlpwnd; 00331 TL tlpwndDlg; 00332 BOOL fLockDlg = FALSE; 00333 TL tlpwnd2; 00334 WORD langID; 00335 00336 langID = PRIMARYLANGID(LANGIDFROMLCID(GetUserDefaultLCID())); 00337 00338 if ((pwndDlg = ValidateHwndNoRip(hwndDlg)) == NULL) { 00339 return FALSE; 00340 } 00341 00342 CheckLock(pwndDlg); 00343 00344 /* 00345 * If this is a synchronous-only message (takes a pointer in wParam or 00346 * lParam), then don't allow this message to go through since those 00347 * parameters have not been thunked, and are pointing into outer-space 00348 * (which would case exceptions to occur). 00349 * 00350 * (This api is only called in the context of a message loop, and you 00351 * don't get synchronous-only messages in a message loop). 00352 */ 00353 if (TESTSYNCONLYMESSAGE(lpMsg->message, lpMsg->wParam)) { 00354 /* 00355 * Fail if 32 bit app is calling. 00356 */ 00357 if (!(GetClientInfo()->dwTIFlags & TIF_16BIT)) { 00358 RIPERR0(ERROR_MESSAGE_SYNC_ONLY, RIP_WARNING, "IsDialogMessage: must be sync only"); 00359 return FALSE; 00360 } 00361 00362 /* 00363 * For wow apps, allow it to go through (for compatibility). Change 00364 * the message id so our code doesn't understand the message - wow 00365 * will get the message and strip out this bit before dispatching 00366 * the message to the application. 00367 */ 00368 lpMsg->message |= MSGFLAG_WOW_RESERVED; 00369 } 00370 00371 if (CallMsgFilter(lpMsg, MSGF_DIALOGBOX)) 00372 return TRUE; 00373 00374 if (lpMsg->hwnd == NULL) { 00375 return FALSE; 00376 } 00377 00378 pwnd = ValidateHwnd(lpMsg->hwnd); 00379 // 00380 // THIS IS FOR MFC. 00381 // 00382 // This solves many problems with apps that use MFC but want to take 00383 // advantage of DS_CONTROL. MFC blindly passes in child dialogs sometimes 00384 // to IsDialogMessage, which can screw up tabbing etc. 00385 // 00386 if (TestWF(pwndDlg, WEFCONTROLPARENT) && TestWF(pwndDlg, WFCHILD)) { 00387 pwndDlg = GetParentDialog(pwndDlg); 00388 ThreadLock(pwndDlg, &tlpwndDlg); 00389 fLockDlg = TRUE; 00390 hwndDlg = HWq(pwndDlg); 00391 } 00392 00393 if (pwnd != pwndDlg && !_IsChild(pwndDlg, pwnd)) { 00394 if (fLockDlg) 00395 ThreadUnlock(&tlpwndDlg); 00396 return FALSE; 00397 } 00398 ThreadLock(pwnd, &tlpwnd); 00399 00400 fBack = FALSE; 00401 iOK = IDCANCEL; 00402 switch (lpMsg->message) { 00403 case WM_LBUTTONDOWN: 00404 00405 /* 00406 * Move the default button styles around on button clicks in the 00407 * same way as TABs. 00408 */ 00409 if ((pwnd != pwndDlg) && ((hwndFocus = GetFocus()) != NULL)) { 00410 xxxCheckDefPushButton(pwndDlg, hwndFocus, lpMsg->hwnd); 00411 } 00412 break; 00413 00414 case WM_SYSCHAR: 00415 00416 /* 00417 * If no control has focus, and Alt not down, then ignore. 00418 */ 00419 if ((GetFocus() == NULL) && (GetKeyState(VK_MENU) >= 0)) { 00420 if (lpMsg->wParam == VK_RETURN && TestWF(pwnd, WFMINIMIZED)) { 00421 00422 /* 00423 * If this is an iconic dialog box window and the user hits 00424 * return, send the message off to DefWindowProc so that it 00425 * can be restored. Especially useful for apps whose top 00426 * level window is a dialog box. 00427 */ 00428 goto CallDefWindowProcAndReturnTrue; 00429 } else { 00430 NtUserMessageBeep(0); 00431 } 00432 00433 ThreadUnlock(&tlpwnd); 00434 if (fLockDlg) 00435 ThreadUnlock(&tlpwndDlg); 00436 return TRUE; 00437 } 00438 00439 /* 00440 * If alt+menuchar, process as menu. 00441 */ 00442 if (lpMsg->wParam == MENUSYSMENU) { 00443 DefWindowProcWorker(pwndDlg, lpMsg->message, lpMsg->wParam, 00444 lpMsg->lParam, FALSE); 00445 ThreadUnlock(&tlpwnd); 00446 if (fLockDlg) 00447 ThreadUnlock(&tlpwndDlg); 00448 return TRUE; 00449 } 00450 00451 /* 00452 *** FALL THRU ** 00453 */ 00454 00455 case WM_CHAR: 00456 00457 /* 00458 * Ignore chars sent to the dialog box (rather than the control). 00459 */ 00460 if (pwnd == pwndDlg) { 00461 ThreadUnlock(&tlpwnd); 00462 if (fLockDlg) 00463 ThreadUnlock(&tlpwndDlg); 00464 return TRUE; 00465 } 00466 00467 code = (UINT)SendMessage(lpMsg->hwnd, WM_GETDLGCODE, lpMsg->wParam, 00468 (LPARAM)lpMsg); 00469 00470 /* 00471 * If the control wants to process the message, then don't check for 00472 * possible mnemonic key. 00473 */ 00474 if ((lpMsg->message == WM_CHAR) && (code & (DLGC_WANTCHARS | DLGC_WANTMESSAGE))) 00475 break; 00476 00477 /* If the control wants tabs, then don't let tab fall thru here 00478 */ 00479 if ((lpMsg->wParam == VK_TAB) && (code & DLGC_WANTTAB)) 00480 break; 00481 00482 00483 /* 00484 * HACK ALERT 00485 * 00486 * If ALT is held down (i.e., SYSCHARs), then ALWAYS do mnemonic 00487 * processing. If we do away with SYSCHARS, then we should 00488 * check key state of ALT instead. 00489 */ 00490 00491 /* 00492 * Space is not a valid mnemonic, but it IS the char that toggles 00493 * button states. Don't look for it as a mnemonic or we will 00494 * beep when it is typed.... 00495 */ 00496 if (lpMsg->wParam == VK_SPACE) { 00497 ThreadUnlock(&tlpwnd); 00498 if (fLockDlg) 00499 ThreadUnlock(&tlpwndDlg); 00500 return TRUE; 00501 } 00502 00503 if (!(pwnd2 = xxxGotoNextMnem(pwndDlg, pwnd, (WCHAR)lpMsg->wParam))) { 00504 00505 if (code & DLGC_WANTMESSAGE) 00506 break; 00507 00508 /* 00509 * No mnemonic could be found so we will send the sys char over 00510 * to xxxDefWindowProc so that any menu bar on the dialog box is 00511 * handled properly. 00512 */ 00513 if (lpMsg->message == WM_SYSCHAR) { 00514 CallDefWindowProcAndReturnTrue: 00515 DefWindowProcWorker(pwndDlg, lpMsg->message, lpMsg->wParam, 00516 lpMsg->lParam, FALSE); 00517 00518 ThreadUnlock(&tlpwnd); 00519 if (fLockDlg) 00520 ThreadUnlock(&tlpwndDlg); 00521 return TRUE; 00522 } 00523 NtUserMessageBeep(0); 00524 } else { 00525 00526 /* 00527 * pwnd2 is 1 if the mnemonic took us to a pushbutton. We 00528 * don't change the default button status here since doing this 00529 * doesn't change the focus. 00530 */ 00531 if (pwnd2 != (PWND)1) { 00532 ThreadLockAlways(pwnd2, &tlpwnd2); 00533 xxxCheckDefPushButton(pwndDlg, lpMsg->hwnd, HWq(pwnd2)); 00534 ThreadUnlock(&tlpwnd2); 00535 } 00536 } 00537 00538 ThreadUnlock(&tlpwnd); 00539 if (fLockDlg) 00540 ThreadUnlock(&tlpwndDlg); 00541 return TRUE; 00542 00543 case WM_SYSKEYDOWN: 00544 /* 00545 * If Alt is down, deal with keyboard cues 00546 */ 00547 if ((HIWORD(lpMsg->lParam) & SYS_ALTERNATE) && TEST_KbdCuesPUSIF) { 00548 if (TestWF(pwnd, WEFPUIFOCUSHIDDEN) || (TestWF(pwnd, WEFPUIACCELHIDDEN))) { 00549 SendMessageWorker(pwndDlg, WM_CHANGEUISTATE, 00550 MAKEWPARAM(UIS_CLEAR, UISF_HIDEACCEL | UISF_HIDEFOCUS), 0, FALSE); 00551 } 00552 } 00553 break; 00554 00555 case WM_KEYDOWN: 00556 code = (UINT)SendMessage(lpMsg->hwnd, WM_GETDLGCODE, lpMsg->wParam, 00557 (LPARAM)lpMsg); 00558 if (code & (DLGC_WANTALLKEYS | DLGC_WANTMESSAGE)) 00559 break; 00560 00561 switch (lpMsg->wParam) { 00562 case VK_TAB: 00563 if (code & DLGC_WANTTAB) 00564 break; 00565 pwnd2 = _GetNextDlgTabItem(pwndDlg, pwnd, 00566 (GetKeyState(VK_SHIFT) & 0x8000)); 00567 00568 if (TEST_KbdCuesPUSIF) { 00569 if (TestWF(pwnd, WEFPUIFOCUSHIDDEN)) { 00570 SendMessageWorker(pwndDlg, WM_CHANGEUISTATE, 00571 MAKEWPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 0, FALSE); 00572 } 00573 } 00574 00575 if (pwnd2 != NULL) { 00576 hwnd2 = HWq(pwnd2); 00577 ThreadLockAlways(pwnd2, &tlpwnd2); 00578 DlgSetFocus(hwnd2); 00579 xxxCheckDefPushButton(pwndDlg, lpMsg->hwnd, hwnd2); 00580 ThreadUnlock(&tlpwnd2); 00581 } 00582 ThreadUnlock(&tlpwnd); 00583 if (fLockDlg) 00584 ThreadUnlock(&tlpwndDlg); 00585 return TRUE; 00586 00587 /* 00588 * For Arabic and Hebrew locales the arrow keys are reversed. Also reverse them if 00589 * the dialog is RTL mirrored. 00590 */ 00591 case VK_LEFT: 00592 if ((((langID == LANG_ARABIC) || (langID == LANG_HEBREW)) && TestWF(pwndDlg,WEFRTLREADING)) 00593 #ifdef USE_MIRRORING 00594 ^ (!!TestWF(pwndDlg, WEFLAYOUTRTL)) 00595 #endif 00596 ) 00597 goto DoKeyStuff; 00598 case VK_UP: 00599 fBack = TRUE; 00600 goto DoKeyStuff; 00601 00602 /* 00603 *** FALL THRU ** 00604 */ 00605 case VK_RIGHT: 00606 if ((((langID == LANG_ARABIC) || (langID == LANG_HEBREW)) && TestWF(pwndDlg,WEFRTLREADING)) 00607 #ifdef USE_MIRRORING 00608 ^ (!!TestWF(pwndDlg, WEFLAYOUTRTL)) 00609 #endif 00610 ) 00611 fBack = TRUE; 00612 case VK_DOWN: 00613 DoKeyStuff: 00614 if (code & DLGC_WANTARROWS) 00615 break; 00616 00617 if (TEST_KbdCuesPUSIF) { 00618 if (TestWF(pwnd, WEFPUIFOCUSHIDDEN)) { 00619 SendMessageWorker(pwndDlg, WM_CHANGEUISTATE, 00620 MAKEWPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 0, FALSE); 00621 } 00622 } 00623 00624 pwnd2 = _GetNextDlgGroupItem(pwndDlg, pwnd, fBack); 00625 if (pwnd2 == NULL) { 00626 ThreadUnlock(&tlpwnd); 00627 if (fLockDlg) 00628 ThreadUnlock(&tlpwndDlg); 00629 return TRUE; 00630 } 00631 hwnd2 = HWq(pwnd2); 00632 ThreadLockAlways(pwnd2, &tlpwnd2); 00633 00634 code = (UINT)SendMessage(hwnd2, WM_GETDLGCODE, lpMsg->wParam, 00635 (LPARAM)lpMsg); 00636 00637 /* 00638 * We are just moving the focus rect around! So, do not send 00639 * BN_CLICK messages, when WM_SETFOCUSing. Fix for Bug 00640 * #4358. 00641 */ 00642 if (code & (DLGC_UNDEFPUSHBUTTON | DLGC_DEFPUSHBUTTON)) { 00643 PBUTN pbutn; 00644 BOOL fIsNTButton = (GETFNID(pwnd2) == FNID_BUTTON); 00645 if (fIsNTButton) { 00646 pbutn = ((PBUTNWND)pwnd2)->pbutn; 00647 BUTTONSTATE(pbutn) |= BST_DONTCLICK; 00648 } 00649 DlgSetFocus(hwnd2); 00650 if (fIsNTButton) { 00651 BUTTONSTATE(pbutn) &= ~BST_DONTCLICK; 00652 } 00653 xxxCheckDefPushButton(pwndDlg, lpMsg->hwnd, hwnd2); 00654 } else if (code & DLGC_RADIOBUTTON) { 00655 DlgSetFocus(hwnd2); 00656 xxxCheckDefPushButton(pwndDlg, lpMsg->hwnd, hwnd2); 00657 if (TestWF(pwnd2, BFTYPEMASK) == LOBYTE(BS_AUTORADIOBUTTON)) { 00658 00659 /* 00660 * So that auto radio buttons get clicked on 00661 */ 00662 if (!SendMessage(hwnd2, BM_GETCHECK, 0, 0L)) { 00663 SendMessage(hwnd2, BM_CLICK, TRUE, 0L); 00664 } 00665 } 00666 } else if (!(code & DLGC_STATIC)) { 00667 DlgSetFocus(hwnd2); 00668 xxxCheckDefPushButton(pwndDlg, lpMsg->hwnd, hwnd2); 00669 } 00670 ThreadUnlock(&tlpwnd2); 00671 ThreadUnlock(&tlpwnd); 00672 if (fLockDlg) 00673 ThreadUnlock(&tlpwndDlg); 00674 return TRUE; 00675 00676 case VK_EXECUTE: 00677 case VK_RETURN: 00678 00679 /* 00680 * Guy pressed return - if button with focus is 00681 * defpushbutton, return its ID. Otherwise, return id 00682 * of original defpushbutton. 00683 */ 00684 if (!(hwndFocus = GetFocus())) 00685 code = 0; 00686 else 00687 { 00688 code = (WORD)(DWORD)SendMessage(hwndFocus, WM_GETDLGCODE, 00689 0, 0L); 00690 } 00691 00692 if (code & DLGC_DEFPUSHBUTTON) 00693 { 00694 iOK = GetDlgCtrlID(hwndFocus); 00695 pwnd2 = ValidateHwnd(hwndFocus); 00696 goto HaveWindow; 00697 } 00698 else 00699 { 00700 lT = (LONG)SendMessage(hwndDlg, DM_GETDEFID, 0, 0L); 00701 iOK = MAKELONG( 00702 (HIWORD(lT)==DC_HASDEFID ? LOWORD(lT) : IDOK), 00703 0); 00704 } 00705 // FALL THRU 00706 00707 case VK_ESCAPE: 00708 case VK_CANCEL: 00709 00710 /* 00711 * Make sure button is not disabled. 00712 */ 00713 pwnd2 = _FindDlgItem(pwndDlg, iOK); 00714 HaveWindow: 00715 if (pwnd2 != NULL && TestWF(pwnd2, WFDISABLED)) { 00716 NtUserMessageBeep(0); 00717 } else { 00718 SendMessage(hwndDlg, WM_COMMAND, 00719 MAKELONG(iOK, BN_CLICKED), (LPARAM)HW(pwnd2)); 00720 } 00721 00722 ThreadUnlock(&tlpwnd); 00723 if (fLockDlg) 00724 ThreadUnlock(&tlpwndDlg); 00725 return TRUE; 00726 } 00727 break; 00728 } 00729 00730 ThreadUnlock(&tlpwnd); 00731 if (fLockDlg) 00732 ThreadUnlock(&tlpwndDlg); 00733 00734 TranslateMessage(lpMsg); 00735 DispatchMessage(lpMsg); 00736 00737 return TRUE; 00738 }

void xxxCheckDefPushButton PWND  pwndDlg,
HWND  hwndOldFocus,
HWND  hwndNewFocus
 

Definition at line 84 of file dlgmgr2.c.

References _FindDlgItem(), CheckLock, HW, HWq, L, NULL, SAMEWOWHANDLE, SendMessage(), tagWND::spmenu, TestWF, ThreadLockAlways, ThreadUnlock, TRUE, UINT, ValidateHwnd, WEFCONTROLPARENT, WFDISABLED, WFWIN40COMPAT, and xxxRemoveDefaultButton().

Referenced by DefDlgProcWorker(), InternalCreateDialog(), IsDialogMessageW(), and xxxRestoreDlgFocus().

00088 { 00089 PWND pwndNewFocus; 00090 PWND pwndOldFocus; 00091 TL tlpwndT; 00092 PWND pwndT; 00093 UINT codeNewFocus = 0; 00094 UINT styleT; 00095 LONG lT; 00096 int id; 00097 00098 if (hwndNewFocus) 00099 pwndNewFocus = ValidateHwnd(hwndNewFocus); 00100 else 00101 pwndNewFocus = NULL; 00102 00103 if (hwndOldFocus) 00104 pwndOldFocus = ValidateHwnd(hwndOldFocus); 00105 else 00106 pwndOldFocus = NULL; 00107 00108 CheckLock(pwndDlg); 00109 CheckLock(pwndNewFocus); 00110 CheckLock(pwndOldFocus); 00111 00112 if (pwndNewFocus) 00113 { 00114 // Do nothing if clicking on dialog background or recursive dialog 00115 // background. 00116 if (TestWF(pwndNewFocus, WEFCONTROLPARENT)) 00117 return; 00118 00119 codeNewFocus = (UINT)SendMessage(hwndNewFocus, WM_GETDLGCODE, 0, 0L); 00120 } 00121 00122 if (SAMEWOWHANDLE(hwndOldFocus, hwndNewFocus)) { 00123 // 00124 // NEW FOR 4.0: 00125 // 00126 // There is a very common frustrating scenario for ISVs who try to 00127 // set the default ID. Our dialog manager assumes that if a push 00128 // button has the focus, it is the default button also. As such 00129 // it passes in the focus window to this routine. If someone tries 00130 // to change the focus or set the def ID such that they reside with 00131 // two different push buttons, the double-default-push button case 00132 // will result shortly. 00133 // 00134 // As such, for 4.0 dialogs, we will go check the def ID and see if 00135 // is the same as hwndOldFocus' ID. If not, then we will find IT 00136 // and use that dude as hwndOldFocus 00137 // 00138 if (codeNewFocus & DLGC_UNDEFPUSHBUTTON) 00139 { 00140 if (TestWF(pwndDlg, WFWIN40COMPAT) && hwndOldFocus) 00141 { 00142 lT = (LONG)SendMessage(HWq(pwndDlg), DM_GETDEFID, 0, 0L); 00143 id = (HIWORD(lT) == DC_HASDEFID ? LOWORD(lT) : IDOK); 00144 lT = MAKELONG(id, 0); 00145 00146 if (lT != PtrToLong(pwndNewFocus->spmenu)) 00147 { 00148 if (pwndOldFocus = _FindDlgItem(pwndDlg, lT)) 00149 { 00150 hwndOldFocus = HW(pwndOldFocus); 00151 if (SendMessage(hwndOldFocus, WM_GETDLGCODE, 0, 0L) & DLGC_DEFPUSHBUTTON) 00152 { 00153 xxxRemoveDefaultButton(pwndDlg, pwndOldFocus); 00154 goto SetNewDefault; 00155 } 00156 } 00157 } 00158 } 00159 00160 SendMessage(hwndNewFocus, BM_SETSTYLE, BS_DEFPUSHBUTTON, (LONG)TRUE); 00161 } 00162 return; 00163 } 00164 00165 /* 00166 * If the focus is changing to or from a pushbutton, then remove the 00167 * default style from the current default button 00168 */ 00169 if ((hwndOldFocus != NULL && (SendMessage(hwndOldFocus, WM_GETDLGCODE, 00170 0, 0) & (DLGC_DEFPUSHBUTTON | DLGC_UNDEFPUSHBUTTON))) || 00171 (hwndNewFocus != NULL && 00172 (codeNewFocus & (DLGC_DEFPUSHBUTTON | DLGC_UNDEFPUSHBUTTON)))) { 00173 xxxRemoveDefaultButton(pwndDlg, pwndNewFocus); 00174 } 00175 00176 SetNewDefault: 00177 /* 00178 * If moving to a button, make that button the default. 00179 */ 00180 if (codeNewFocus & DLGC_UNDEFPUSHBUTTON) { 00181 SendMessage(hwndNewFocus, BM_SETSTYLE, BS_DEFPUSHBUTTON, (LONG)TRUE); 00182 } else { 00183 00184 /* 00185 * Otherwise, make sure the original default button is default 00186 * and no others. 00187 */ 00188 00189 /* 00190 * Get the original default button handle 00191 */ 00192 lT = (LONG)SendMessage(HWq(pwndDlg), DM_GETDEFID, 0, 0L); 00193 id = (HIWORD(lT) == DC_HASDEFID ? LOWORD(lT) : IDOK); 00194 pwndT = _FindDlgItem(pwndDlg, id); 00195 00196 if (pwndT == NULL) 00197 return; 00198 ThreadLockAlways(pwndT, &tlpwndT); 00199 00200 /* 00201 * If it already has the default button style, do nothing. 00202 */ 00203 if ((styleT = (UINT)SendMessage(HWq(pwndT), WM_GETDLGCODE, 0, 0L)) & DLGC_DEFPUSHBUTTON) { 00204 ThreadUnlock(&tlpwndT); 00205 return; 00206 } 00207 00208 /* 00209 * Also check to make sure it is really a button. 00210 */ 00211 if (!(styleT & DLGC_UNDEFPUSHBUTTON)) { 00212 ThreadUnlock(&tlpwndT); 00213 return; 00214 } 00215 00216 if (!TestWF(pwndT, WFDISABLED)) { 00217 SendMessage(HWq(pwndT), BM_SETSTYLE, BS_DEFPUSHBUTTON, (LONG)TRUE); 00218 } 00219 ThreadUnlock(&tlpwndT); 00220 } 00221 }

void xxxRemoveDefaultButton PWND  pwndRoot,
PWND  pwndStart
 

Definition at line 31 of file dlgmgr2.c.

References _GetChildControl(), _NextControl(), CheckLock, HWq, L, NULL, SendMessage(), TestWF, ThreadLock, ThreadUnlock, TRUE, UINT, and WEFCONTROLPARENT.

Referenced by xxxCheckDefPushButton(), and xxxSaveDlgFocus().

00034 { 00035 UINT code; 00036 PWND pwnd; 00037 PWND pwndDup; 00038 TL tlpwnd; 00039 00040 CheckLock(pwndRoot); 00041 CheckLock(pwndStart); 00042 00043 if (!pwndStart || TestWF(pwndStart, WEFCONTROLPARENT)) 00044 pwndStart = _NextControl(pwndRoot, NULL, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED); 00045 else 00046 pwndStart = _GetChildControl(pwndRoot, pwndStart); 00047 00048 if (!pwndStart) 00049 return; 00050 00051 pwnd = pwndStart; 00052 do { 00053 pwndDup = pwnd; 00054 00055 ThreadLock(pwnd, &tlpwnd); 00056 00057 code = (UINT)SendMessage(HWq(pwnd), WM_GETDLGCODE, 0, 0L); 00058 00059 if (code & DLGC_DEFPUSHBUTTON) { 00060 SendMessage(HWq(pwnd), BM_SETSTYLE, BS_PUSHBUTTON, (LONG)TRUE); 00061 } 00062 00063 pwnd = _NextControl(pwndRoot, pwnd, 0); 00064 00065 ThreadUnlock(&tlpwnd); 00066 00067 } while (pwnd && (pwnd != pwndStart) && (pwnd != pwndDup)); 00068 00069 #if DBG 00070 if (pwnd && (pwnd != pwndStart) && (pwnd != pwndDup)) { 00071 RIPMSG0(RIP_WARNING, "xxxRemoveDefaultButton bailing potential infinite loop!"); 00072 } 00073 #endif 00074 00075 }


Generated on Sat May 15 19:43:28 2004 for test by doxygen 1.3.7