Skip to content

Instantly share code, notes, and snippets.

@thinkhy
Created May 22, 2011 15:44
Show Gist options
  • Save thinkhy/985598 to your computer and use it in GitHub Desktop.
Save thinkhy/985598 to your computer and use it in GitHub Desktop.
The source code of DialogBox windows implementation
/***************************************************************************\
* DialogBox2
*
* History:
\***************************************************************************/
INT_PTR DialogBox2(
HWND hwnd,
HWND hwndOwner,
BOOL fDisabled,
BOOL fOwnerIsActiveWindow)
{
MSG msg;
INT_PTR result;
BOOL fShown;
BOOL fWantIdleMsgs;
BOOL fSentIdleMessage = FALSE;
HWND hwndCapture;
PWND pwnd;
if (hwnd) {
pwnd = ValidateHwnd(hwnd);
} else {
pwnd = NULL;
}
CheckLock(pwnd);
if (pwnd == NULL) {
if ((hwndOwner != NULL) && !fDisabled && IsWindow(hwndOwner)) {
NtUserEnableWindow(hwndOwner, TRUE);
if (fOwnerIsActiveWindow) {
/*
* The dialog box failed but we disabled the owner in
* xxxDialogBoxIndirectParam and if it had the focus, the
* focus was set to NULL. Now, when we enable the window, it
* doesn't get the focus back if it had it previously so we
* need to correct this.
*/
NtUserSetFocus(hwndOwner);
}
}
return -1;
}
hwndCapture = GetCapture();
if (hwndCapture != NULL) {
SendMessage(hwndCapture, WM_CANCELMODE, 0, 0);
}
/*
* Set the 'parent disabled' flag for EndDialog().
* convert BOOL to definite bit 0 or 1
*/
PDLG(pwnd)->fDisabled = !!fDisabled;
fShown = TestWF(pwnd, WFVISIBLE);
/*
* Should the WM_ENTERIDLE messages be sent?
*/
fWantIdleMsgs = !(pwnd->style & DS_NOIDLEMSG);
if ((SYSMET(SLOWMACHINE) & 1) && !fShown && !PDLG(pwnd)->fEnd)
goto ShowIt;
while (PDLG(pwnd) && (!PDLG(pwnd)->fEnd)) {
if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
ShowIt:
if (!fShown) {
fShown = TRUE;
#ifdef SYSMODALWINDOWS
if (pwnd == gspwndSysModal) {
/*
* Make this a topmost window
*/
NtUserSetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE |
SWP_NOREDRAW | SWP_NOACTIVATE);
}
#endif
NtUserShowWindow(hwnd, SHOW_OPENWINDOW);
UpdateWindow(hwnd);
if (FWINABLE()) {
NotifyWinEvent(EVENT_SYSTEM_DIALOGSTART, hwnd, OBJID_WINDOW, INDEXID_CONTAINER);
}
} else {
/*
* Make sure window still exists
*/
if (hwndOwner && !IsWindow(hwndOwner))
hwndOwner = NULL;
if (hwndOwner && fWantIdleMsgs && !fSentIdleMessage) {
fSentIdleMessage = TRUE;
SendMessage(hwndOwner, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)hwnd);
} else {
if ((RevalidateHwnd(hwnd)==NULL) || (pwnd->fnid & FNID_STATUS_BITS))
break;
NtUserWaitMessage();
}
}
} else {
/*
* We got a real message. Reset fSentIdleMessage so that we send
* one next time things are calm.
*/
fSentIdleMessage = FALSE;
if (msg.message == WM_QUIT) {
PostQuitMessage((int)msg.wParam);
break;
}
/*
* If pwnd is a message box, allow Ctrl-C and Ctrl-Ins
* to copy its content to the clipboard.
* Fall through in case hooking apps look for these keys.
*/
if (TestWF(pwnd, WFMSGBOX)) {
if ( (msg.message == WM_CHAR && LOBYTE(msg.wParam) == 3) ||
(msg.message == WM_KEYDOWN && LOBYTE(msg.wParam) == VK_INSERT && GetKeyState(VK_CONTROL) < 0)) {
/*
* Send the WM_COPY message and let the original message fall through
* as some apps might want it
*/
SendMessage(hwnd, WM_COPY, 0, 0);
}
}
/*
* Moved the msg filter hook call to IsDialogMessage to allow
* messages to be hooked for both modal and modeless dialog
* boxes.
*/
if (!IsDialogMessage(hwnd, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
/*
* If we get a timer message, go ahead and show the window.
* We may continuously get timer msgs if there are zillions of
* apps running.
*
* If we get a syskeydown message, show the dialog box because
* the user may be bringing down a menu and we want the dialog
* box to become visible.
*/
if (!fShown && (msg.message == WM_TIMER ||
msg.message == WM_SYSTIMER || msg.message == WM_SYSKEYDOWN))
goto ShowIt;
}
if (!RevalidateHwnd(hwnd)) {
/*
* Bogus case - we've already been destroyed somehow (by app,
* GP, etc.)
*/
RIPMSG0(RIP_WARNING,
"Dialog should be dismissed with EndDialog, not DestroyWindow");
break;
}
}
if (FWINABLE()) {
NotifyWinEvent(EVENT_SYSTEM_DIALOGEND, hwnd, OBJID_WINDOW, INDEXID_CONTAINER);
}
/*
* Make sure the window still exists
*/
if (!RevalidateHwnd(hwnd)) {
return 0;
}
if (PDLG(pwnd))
result = KERNEL_INT_PTR_TO_INT_PTR(PDLG(pwnd)->result);
else
result = 0;
NtUserDestroyWindow(hwnd);
/*
* If the owner window belongs to another thread, the reactivation
* of the owner may have failed within DestroyWindow(). Therefore,
* if the current thread is in the foreground and the owner is not
* in the foreground we can safely set the foreground back
* to the owner.
*/
if (hwndOwner != NULL) {
if (IsCurrentThreadForeground() &&
!IsInForegroundQueue(hwndOwner)) {
NtUserSetForegroundWindow(hwndOwner);
}
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment