284 lines
8.4 KiB
C++
284 lines
8.4 KiB
C++
|
//*********************************************************************
|
||
|
//* Microsoft Windows **
|
||
|
//* Copyright (c) 1994-1998 Microsoft Corporation
|
||
|
//*********************************************************************
|
||
|
|
||
|
//
|
||
|
// UTIL.C - common utility functions
|
||
|
//
|
||
|
|
||
|
// HISTORY:
|
||
|
//
|
||
|
// 12/21/94 jeremys Created.
|
||
|
// 96/03/24 markdu Replaced memset with ZeroMemory for consistency.
|
||
|
// 96/04/06 markdu NASH BUG 15653 Use exported autodial API.
|
||
|
// Need to keep a modified SetInternetConnectoid to set the
|
||
|
// MSN backup connectoid.
|
||
|
// 96/05/14 markdu NASH BUG 21706 Removed BigFont functions.
|
||
|
//
|
||
|
|
||
|
#include "wizard.h"
|
||
|
#if 0
|
||
|
#include "string.h"
|
||
|
#endif
|
||
|
|
||
|
#include "winver.h"
|
||
|
|
||
|
// function prototypes
|
||
|
VOID _cdecl FormatErrorMessage(CHAR * pszMsg,DWORD cbMsg,CHAR * pszFmt,LPSTR szArg);
|
||
|
extern GETSETUPXERRORTEXT lpGetSETUPXErrorText;
|
||
|
|
||
|
/*******************************************************************
|
||
|
|
||
|
NAME: MsgBox
|
||
|
|
||
|
SYNOPSIS: Displays a message box with the specified string ID
|
||
|
|
||
|
********************************************************************/
|
||
|
int MsgBox(HWND hWnd,UINT nMsgID,UINT uIcon,UINT uButtons)
|
||
|
{
|
||
|
CHAR szMsgBuf[MAX_RES_LEN+1];
|
||
|
CHAR szSmallBuf[SMALL_BUF_LEN+1];
|
||
|
|
||
|
LoadSz(IDS_APPNAME,szSmallBuf,sizeof(szSmallBuf));
|
||
|
LoadSz(nMsgID,szMsgBuf,sizeof(szMsgBuf));
|
||
|
|
||
|
return (MessageBox(hWnd,szMsgBuf,szSmallBuf,uIcon | uButtons));
|
||
|
|
||
|
}
|
||
|
|
||
|
/*******************************************************************
|
||
|
|
||
|
NAME: MsgBoxSz
|
||
|
|
||
|
SYNOPSIS: Displays a message box with the specified text
|
||
|
|
||
|
********************************************************************/
|
||
|
int MsgBoxSz(HWND hWnd,LPSTR szText,UINT uIcon,UINT uButtons)
|
||
|
{
|
||
|
CHAR szSmallBuf[SMALL_BUF_LEN+1];
|
||
|
LoadSz(IDS_APPNAME,szSmallBuf,sizeof(szSmallBuf));
|
||
|
|
||
|
return (MessageBox(hWnd,szText,szSmallBuf,uIcon | uButtons));
|
||
|
}
|
||
|
|
||
|
/*******************************************************************
|
||
|
|
||
|
NAME: MsgBoxParam
|
||
|
|
||
|
SYNOPSIS: Displays a message box with the specified string ID
|
||
|
|
||
|
NOTES: //extra parameters are string pointers inserted into nMsgID.
|
||
|
jmazner 11/6/96 For RISC compatability, we don't want
|
||
|
to use va_list; since current source code never uses more than
|
||
|
one string parameter anyways, just change function signature
|
||
|
to explicitly include that one parameter.
|
||
|
|
||
|
********************************************************************/
|
||
|
int _cdecl MsgBoxParam(HWND hWnd,UINT nMsgID,UINT uIcon,UINT uButtons,LPSTR szParam)
|
||
|
{
|
||
|
BUFFER Msg(3*MAX_RES_LEN+1); // nice n' big for room for inserts
|
||
|
BUFFER MsgFmt(MAX_RES_LEN+1);
|
||
|
//va_list args;
|
||
|
|
||
|
if (!Msg || !MsgFmt) {
|
||
|
return MsgBox(hWnd,IDS_ERROutOfMemory,MB_ICONSTOP,MB_OK);
|
||
|
}
|
||
|
|
||
|
LoadSz(nMsgID,MsgFmt.QueryPtr(),MsgFmt.QuerySize());
|
||
|
|
||
|
//va_start(args,uButtons);
|
||
|
//FormatErrorMessage(Msg.QueryPtr(),Msg.QuerySize(),
|
||
|
// MsgFmt.QueryPtr(),args);
|
||
|
FormatErrorMessage(Msg.QueryPtr(),Msg.QuerySize(),
|
||
|
MsgFmt.QueryPtr(),szParam);
|
||
|
|
||
|
return MsgBoxSz(hWnd,Msg.QueryPtr(),uIcon,uButtons);
|
||
|
}
|
||
|
|
||
|
/*******************************************************************
|
||
|
|
||
|
NAME: LoadSz
|
||
|
|
||
|
SYNOPSIS: Loads specified string resource into buffer
|
||
|
|
||
|
EXIT: returns a pointer to the passed-in buffer
|
||
|
|
||
|
NOTES: If this function fails (most likely due to low
|
||
|
memory), the returned buffer will have a leading NULL
|
||
|
so it is generally safe to use this without checking for
|
||
|
failure.
|
||
|
|
||
|
********************************************************************/
|
||
|
LPSTR LoadSz(UINT idString,LPSTR lpszBuf,UINT cbBuf)
|
||
|
{
|
||
|
ASSERT(lpszBuf);
|
||
|
|
||
|
// Clear the buffer and load the string
|
||
|
if ( lpszBuf )
|
||
|
{
|
||
|
*lpszBuf = '\0';
|
||
|
LoadString( ghInstance, idString, lpszBuf, cbBuf );
|
||
|
}
|
||
|
return lpszBuf;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************
|
||
|
|
||
|
NAME: GetErrorDescription
|
||
|
|
||
|
SYNOPSIS: Retrieves the text description for a given error code
|
||
|
and class of error (standard, setupx)
|
||
|
|
||
|
********************************************************************/
|
||
|
VOID GetErrorDescription(CHAR * pszErrorDesc,UINT cbErrorDesc,
|
||
|
UINT uError,UINT uErrorClass)
|
||
|
{
|
||
|
ASSERT(pszErrorDesc);
|
||
|
|
||
|
// set a leading null in error description
|
||
|
*pszErrorDesc = '\0';
|
||
|
|
||
|
switch (uErrorClass) {
|
||
|
|
||
|
case ERRCLS_STANDARD:
|
||
|
|
||
|
if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,
|
||
|
uError,0,pszErrorDesc,cbErrorDesc,NULL)) {
|
||
|
// if getting system text fails, make a string a la
|
||
|
// "error <n> occurred"
|
||
|
CHAR szFmt[SMALL_BUF_LEN+1];
|
||
|
LoadSz(IDS_ERRFORMAT,szFmt,sizeof(szFmt));
|
||
|
wsprintf(pszErrorDesc,szFmt,uError);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case ERRCLS_SETUPX:
|
||
|
|
||
|
lpGetSETUPXErrorText(uError,pszErrorDesc,cbErrorDesc);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
|
||
|
DEBUGTRAP("Unknown error class %lu in GetErrorDescription",
|
||
|
uErrorClass);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/*******************************************************************
|
||
|
|
||
|
NAME: FormatErrorMessage
|
||
|
|
||
|
SYNOPSIS: Builds an error message by calling FormatMessage
|
||
|
|
||
|
NOTES: Worker function for DisplayErrorMessage
|
||
|
|
||
|
********************************************************************/
|
||
|
VOID _cdecl FormatErrorMessage(CHAR * pszMsg,DWORD cbMsg,CHAR * pszFmt,LPSTR szArg)
|
||
|
{
|
||
|
ASSERT(pszMsg);
|
||
|
ASSERT(pszFmt);
|
||
|
|
||
|
// build the message into the pszMsg buffer
|
||
|
DWORD dwCount = FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
||
|
pszFmt,0,0,pszMsg,cbMsg,(va_list*) &szArg);
|
||
|
ASSERT(dwCount > 0);
|
||
|
}
|
||
|
|
||
|
/*******************************************************************
|
||
|
|
||
|
NAME: DisplayErrorMessage
|
||
|
|
||
|
SYNOPSIS: Displays an error message for given error
|
||
|
|
||
|
ENTRY: hWnd - parent window
|
||
|
uStrID - ID of string resource with message format.
|
||
|
Should contain %1 to be replaced by error text,
|
||
|
additional parameters can be specified as well.
|
||
|
uError - error code for error to display
|
||
|
uErrorClass - ERRCLS_xxx ID of class of error that
|
||
|
uError belongs to (standard, setupx)
|
||
|
uIcon - icon to display
|
||
|
//... - additional parameters to be inserted in string
|
||
|
// specified by uStrID
|
||
|
jmazner 11/6/96 change to just one parameter for
|
||
|
RISC compatability.
|
||
|
|
||
|
********************************************************************/
|
||
|
VOID _cdecl DisplayErrorMessage(HWND hWnd,UINT uStrID,UINT uError,
|
||
|
UINT uErrorClass,UINT uIcon,LPSTR szArg)
|
||
|
{
|
||
|
// dynamically allocate buffers for messages
|
||
|
BUFFER ErrorDesc(MAX_RES_LEN+1);
|
||
|
BUFFER ErrorFmt(MAX_RES_LEN+1);
|
||
|
BUFFER ErrorMsg(2*MAX_RES_LEN+1);
|
||
|
|
||
|
if (!ErrorDesc || !ErrorFmt || !ErrorMsg) {
|
||
|
// if can't allocate buffers, display out of memory error
|
||
|
MsgBox(hWnd,IDS_ERROutOfMemory,MB_ICONEXCLAMATION,MB_OK);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// get a text description based on the error code and the class
|
||
|
// of error it is
|
||
|
GetErrorDescription(ErrorDesc.QueryPtr(),
|
||
|
ErrorDesc.QuerySize(),uError,uErrorClass);
|
||
|
|
||
|
// load the string for the message format
|
||
|
LoadSz(uStrID,ErrorFmt.QueryPtr(),ErrorFmt.QuerySize());
|
||
|
|
||
|
//LPSTR args[MAX_MSG_PARAM];
|
||
|
//args[0] = (LPSTR) ErrorDesc.QueryPtr();
|
||
|
//memcpy(&args[1],((CHAR *) &uIcon) + sizeof(uIcon),(MAX_MSG_PARAM - 1) * sizeof(LPSTR));
|
||
|
|
||
|
//FormatErrorMessage(ErrorMsg.QueryPtr(),ErrorMsg.QuerySize(),
|
||
|
// ErrorFmt.QueryPtr(),(va_list) &args[0]);
|
||
|
FormatErrorMessage(ErrorMsg.QueryPtr(),ErrorMsg.QuerySize(),
|
||
|
ErrorFmt.QueryPtr(),ErrorDesc.QueryPtr());
|
||
|
|
||
|
|
||
|
// display the message
|
||
|
MsgBoxSz(hWnd,ErrorMsg.QueryPtr(),uIcon,MB_OK);
|
||
|
|
||
|
}
|
||
|
|
||
|
/*******************************************************************
|
||
|
|
||
|
NAME: MsgWaitForMultipleObjectsLoop
|
||
|
|
||
|
SYNOPSIS: Blocks until the specified object is signaled, while
|
||
|
still dispatching messages to the main thread.
|
||
|
|
||
|
********************************************************************/
|
||
|
DWORD MsgWaitForMultipleObjectsLoop(HANDLE hEvent)
|
||
|
{
|
||
|
MSG msg;
|
||
|
DWORD dwObject;
|
||
|
while (1)
|
||
|
{
|
||
|
// NB We need to let the run dialog become active so we have to half handle sent
|
||
|
// messages but we don't want to handle any input events or we'll swallow the
|
||
|
// type-ahead.
|
||
|
dwObject = MsgWaitForMultipleObjects(1, &hEvent, FALSE,INFINITE, QS_ALLINPUT);
|
||
|
// Are we done waiting?
|
||
|
switch (dwObject) {
|
||
|
case WAIT_OBJECT_0:
|
||
|
case WAIT_FAILED:
|
||
|
return dwObject;
|
||
|
|
||
|
case WAIT_OBJECT_0 + 1:
|
||
|
// got a message, dispatch it and wait again
|
||
|
while (PeekMessage(&msg, NULL,0, 0, PM_REMOVE)) {
|
||
|
DispatchMessage(&msg);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
// never gets here
|
||
|
}
|
||
|
|
||
|
|