|
|
/***************************************************************************\
* * DLGEND.C - * * Copyright (c) 1985 - 1999, Microsoft Corporation * * Dialog Destruction Routines * * ??-???-???? mikeke Ported from Win 3.0 sources * 12-Feb-1991 mikeke Added Revalidation code \***************************************************************************/
#include "precomp.h"
#pragma hdrstop
/***************************************************************************\
* EndDialog * * History: * 11-Dec-1990 mikeke ported from win30 \***************************************************************************/
FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EndDialog, HWND, hwnd, INT_PTR, result) BOOL EndDialog( HWND hwnd, INT_PTR result) { PWND pwnd; PWND pwndOwner; HWND hwndOwner; BOOL fWasActive = FALSE; #ifdef SYSMODALWINDOWS
HWND hwndOldSysModal; #endif
if ((pwnd = ValidateHwnd(hwnd)) == NULL) { return (0L); }
CheckLock(pwnd);
/*
* Must do special validation here to make sure pwnd is a dialog window. */ if (!ValidateDialogPwnd(pwnd)) return 0;
if (SAMEWOWHANDLE(hwnd, GetActiveWindow())) { fWasActive = TRUE; }
/*
* GetWindowCreator returns either a kernel address or NULL. */ pwndOwner = GetWindowCreator(pwnd);
if (pwndOwner != NULL) {
/*
* Hide the window. */ pwndOwner = REBASEPTR(pwnd, pwndOwner); hwndOwner = HWq(pwndOwner); if (!PDLG(pwnd)->fDisabled) { NtUserEnableWindow(hwndOwner, TRUE); } } else { hwndOwner = NULL; }
/*
* Terminate Mode Loop. */ PDLG(pwnd)->fEnd = TRUE; PDLG(pwnd)->result = result;
if (fWasActive && IsChild(hwnd, GetFocus())) {
/*
* Set focus to the dialog box so that any control which has the focus * can do an kill focus processing. Most useful for combo boxes so that * they can popup their dropdowns before destroying/hiding the dialog * box window. Note that we only do this if the focus is currently at a * child of this dialog box. We also need to make sure we are the active * window because this may be happening while we are in a funny state. * ie. the activation is in the middle of changing but the focus hasn't * changed yet. This happens with TaskMan (or maybe with other apps that * change the focus/activation at funny times). */ NtUserSetFocus(hwnd); }
NtUserSetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
#ifdef SYSMODALWINDOWS
/*
* If this guy was sysmodal, set the sysmodal flag to previous guy so we * won't have a hidden sysmodal window that will mess things * up royally... */ if (pwnd == gspwndSysModal) { hwndOldSysModal = PDLG(pwnd)->hwndSysModalSave; if (hwndOldSysModal && !IsWindow(hwndOldSysModal)) hwndOldSysModal = NULL;
SetSysModalWindow(hwndOldSysModal);
// If there was a previous system modal window, we want to
// activate it instead of this window's owner.
//
if (hwndOldSysModal) hwndOwner = hwndOldSysModal; } #endif
/*
* Don't do any activation unless we were previously active. */ if (fWasActive && hwndOwner) { NtUserSetActiveWindow(hwndOwner); } else {
/*
* If at this point we are still the active window it means that * we have fallen into the black hole of being the only visible * window in the system when we hid ourselves. This is a bug and * needs to be fixed better later on. For now, though, just * set the active and focus window to NULL. */ if (SAMEWOWHANDLE(hwnd, GetActiveWindow())) { // The next two lines are *not* the equivalent of the two Unlock
// statements that were in Daytona server-side dlgend.c. So, we
// need to go over to server/kernel and do it right. This fixes
// a problem in Visual Slick, which had the MDI window lose focus
// when a message box was dismissed. FritzS
// SetActiveWindow(NULL);
// SetFocus(NULL);
NtUserCallNoParam(SFI_ZAPACTIVEANDFOCUS); } }
#ifdef SYSMODALWINDOWS
/*
* If this guy was sysmodal, set the sysmodal flag to previous guy so we * won't have a hidden sysmodal window that will mess things * up * See comments for Bug #134; SANKAR -- 08-25-89 --; */ if (pwnd == gspwndSysModal) {
/*
* Check if the previous Sysmodal guy is still valid? */ hwndOldSysModal = PDLG(pwnd)->hwndSysModalSave; if (hwndOldSysModal && !IsWindow(hwndOldSysModal)) hwndOldSysModal = NULL; SetSysModalWindow(hwndOldSysModal); } #endif
/*
* Make sure the dialog loop will wake and destroy the window. * The dialog loop is waiting on posted events (WaitMessage). If * EndDialog is called due to a sent message from another thread the * dialog loop will keep waiting for posted events and not destroy * the window. This happens when the dialog is obscured. * This is a problem with winfile and its copy/move dialog. */ PostMessage(hwnd, WM_NULL, 0, 0);
return TRUE; }
|