You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
4.3 KiB
126 lines
4.3 KiB
/***
|
|
*crtmbox.c - CRT MessageBoxA wrapper.
|
|
*
|
|
* Copyright (c) 1995-2001, Microsoft Corporation. All rights reserved.
|
|
*
|
|
*Purpose:
|
|
* Wrap MessageBoxA.
|
|
*
|
|
*Revision History:
|
|
* 02-24-95 CFW Module created.
|
|
* 02-27-95 CFW Move GetActiveWindow/GetLastActivePopup to here.
|
|
* 05-17-99 PML Remove all Macintosh support.
|
|
* 09-16-00 PML Use MB_SERVICE_NOTIFICATION from services (vs7#123291)
|
|
*
|
|
*******************************************************************************/
|
|
|
|
#undef _WIN32_WINNT
|
|
#define _WIN32_WINNT 0x0400 /* for MB_SERVICE_NOTIFICATION */
|
|
#include <windows.h>
|
|
#include <stdlib.h>
|
|
#include <awint.h>
|
|
|
|
/***
|
|
*__crtMessageBox - call MessageBoxA dynamically.
|
|
*
|
|
*Purpose:
|
|
* Avoid static link with user32.dll. Only load it when actually needed.
|
|
*
|
|
*Entry:
|
|
* see MessageBoxA docs.
|
|
*
|
|
*Exit:
|
|
* see MessageBoxA docs.
|
|
*
|
|
*Exceptions:
|
|
*
|
|
*******************************************************************************/
|
|
int __cdecl __crtMessageBoxA(
|
|
LPCSTR lpText,
|
|
LPCSTR lpCaption,
|
|
UINT uType
|
|
)
|
|
{
|
|
typedef int (APIENTRY *PFNMessageBoxA)(HWND, LPCSTR, LPCSTR, UINT);
|
|
typedef HWND (APIENTRY *PFNGetActiveWindow)(void);
|
|
typedef HWND (APIENTRY *PFNGetLastActivePopup)(HWND);
|
|
typedef HWINSTA (APIENTRY *PFNGetProcessWindowStation)(void);
|
|
typedef BOOL (APIENTRY *PFNGetUserObjectInformationA)(HANDLE, int, PVOID, DWORD, LPDWORD);
|
|
|
|
static PFNMessageBoxA pfnMessageBoxA = NULL;
|
|
static PFNGetActiveWindow pfnGetActiveWindow = NULL;
|
|
static PFNGetLastActivePopup pfnGetLastActivePopup = NULL;
|
|
static PFNGetProcessWindowStation pfnGetProcessWindowStation = NULL;
|
|
static PFNGetUserObjectInformationA pfnGetUserObjectInformationA = NULL;
|
|
|
|
HWND hWndParent = NULL;
|
|
BOOL fNonInteractive = FALSE;
|
|
HWINSTA hwinsta;
|
|
USEROBJECTFLAGS uof;
|
|
DWORD nDummy;
|
|
|
|
if (NULL == pfnMessageBoxA)
|
|
{
|
|
HANDLE hlib = LoadLibrary("user32.dll");
|
|
|
|
if (NULL == hlib ||
|
|
NULL == (pfnMessageBoxA = (PFNMessageBoxA)
|
|
GetProcAddress(hlib, "MessageBoxA")))
|
|
return 0;
|
|
|
|
pfnGetActiveWindow = (PFNGetActiveWindow)
|
|
GetProcAddress(hlib, "GetActiveWindow");
|
|
|
|
pfnGetLastActivePopup = (PFNGetLastActivePopup)
|
|
GetProcAddress(hlib, "GetLastActivePopup");
|
|
|
|
if (_osplatform == VER_PLATFORM_WIN32_NT)
|
|
{
|
|
pfnGetUserObjectInformationA = (PFNGetUserObjectInformationA)
|
|
GetProcAddress(hlib, "GetUserObjectInformationA");
|
|
|
|
if (pfnGetUserObjectInformationA)
|
|
pfnGetProcessWindowStation = (PFNGetProcessWindowStation)
|
|
GetProcAddress(hlib, "GetProcessWindowStation");
|
|
}
|
|
}
|
|
|
|
/*
|
|
* If the current process isn't attached to a visible WindowStation,
|
|
* (e.g. a non-interactive service), then we need to set the
|
|
* MB_SERVICE_NOTIFICATION flag, else the message box will be
|
|
* invisible, hanging the program.
|
|
*
|
|
* This check only applies to Windows NT-based systems (for which we
|
|
* retrieved the address of GetProcessWindowStation above).
|
|
*/
|
|
|
|
if (pfnGetProcessWindowStation)
|
|
{
|
|
if (NULL == (hwinsta = (*pfnGetProcessWindowStation)()) ||
|
|
!(*pfnGetUserObjectInformationA)
|
|
(hwinsta, UOI_FLAGS, &uof, sizeof(uof), &nDummy) ||
|
|
(uof.dwFlags & WSF_VISIBLE) == 0)
|
|
{
|
|
fNonInteractive = TRUE;
|
|
}
|
|
}
|
|
|
|
if (fNonInteractive)
|
|
{
|
|
if (_winmajor >= 4)
|
|
uType |= MB_SERVICE_NOTIFICATION;
|
|
else
|
|
uType |= MB_SERVICE_NOTIFICATION_NT3X;
|
|
}
|
|
else
|
|
{
|
|
if (pfnGetActiveWindow)
|
|
hWndParent = (*pfnGetActiveWindow)();
|
|
|
|
if (hWndParent != NULL && pfnGetLastActivePopup)
|
|
hWndParent = (*pfnGetLastActivePopup)(hWndParent);
|
|
}
|
|
|
|
return (*pfnMessageBoxA)(hWndParent, lpText, lpCaption, uType);
|
|
}
|