Windows2003-3790/inetcore/connectionwizard/icwconn/util.cpp
2020-09-30 16:53:55 +02:00

453 lines
13 KiB
C++

//*********************************************************************
//* Microsoft Windows **
//* Copyright(c) Microsoft Corp., 1994 **
//*********************************************************************
//
// 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 "pre.h"
HHOOK g_hhookCBT; // CBT hook identifier
// function prototypes
VOID _cdecl FormatErrorMessage(LPTSTR pszMsg,DWORD cbMsg,LPTSTR pszFmt,LPTSTR szArg);
/*******************************************************************
NAME: ShowWindowWithParentControl
SYNOPSIS: Shows a dialog box with the WS_EX_CONTROLPARENT style.
********************************************************************/
void ShowWindowWithParentControl(HWND hwndChild)
{
// Parent should control us, so the user can tab out of our property sheet
DWORD dwStyle = GetWindowLong(hwndChild, GWL_EXSTYLE);
dwStyle = dwStyle | WS_EX_CONTROLPARENT;
SetWindowLong(hwndChild, GWL_EXSTYLE, dwStyle);
ShowWindow(hwndChild, SW_SHOW);
}
//****************************************************************************
// Function: CBTProc
//
// Purpose: Callback function of WH_CBT hook
//
// Parameters and return value:
// See documentation for CBTProc.
//
// Comments: This function is used to get a copy of the window handle for
// modal message boxes created while ICW is running, so we can make the
// connection timeout dialog be "super modal" in that it can disable even
// these modal message boxes. This is necessary because the connection timeout
// dialog can popup at any time.
//
//****************************************************************************
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LPCBT_CREATEWND lpcbtcreate;
if (nCode < 0)
return CallNextHookEx(g_hhookCBT, nCode, wParam, lParam);
// If a window is being created, and we don't have a copy of the handle yet
// then we want to make a copy of the handle.
if (nCode == HCBT_CREATEWND && (NULL == gpWizardState->hWndMsgBox))
{
lpcbtcreate = (LPCBT_CREATEWND)lParam;
// Check if the window being created is a message box. The class name of
// a message box is WC_DIALOG since message boxes are just special dialogs.
// We can't subclass the message box right away because the window
// procedure of the message box is not set when this hook is called. So
// we wait till the hook is called again when one of the message box
// controls are created and then we subclass. This will happen because
// the message box has at least one control.
if (WC_DIALOG == lpcbtcreate->lpcs->lpszClass)
{
gpWizardState->hWndMsgBox = (HWND)wParam;
}
}
else if (nCode == HCBT_DESTROYWND && (HWND)wParam == gpWizardState->hWndMsgBox)
{
gpWizardState->hWndMsgBox = NULL;
}
return 0;
}
/*******************************************************************
NAME: MsgBox
SYNOPSIS: Displays a message box with the specified string ID
********************************************************************/
int MsgBox(HWND hWnd,UINT nMsgID,UINT uIcon,UINT uButtons)
{
TCHAR szMsgBuf[MAX_RES_LEN+1];
TCHAR szSmallBuf[SMALL_BUF_LEN+1];
HOOKPROC hkprcCBT;
int nResult;
LoadSz(IDS_APPNAME,szSmallBuf,sizeof(szSmallBuf));
LoadSz(nMsgID,szMsgBuf,sizeof(szMsgBuf));
hkprcCBT = (HOOKPROC)MakeProcInstance((FARPROC)CBTProc, ghInstance);
// Set a task specific CBT hook before calling MessageBox. The CBT hook will
// be called when the message box is created and will give us access to
// the window handle of the MessageBox.
g_hhookCBT = SetWindowsHookEx(WH_CBT, hkprcCBT, ghInstance, GetCurrentThreadId());
nResult = MessageBox(hWnd,szMsgBuf,szSmallBuf,uIcon | uButtons);
UnhookWindowsHookEx(g_hhookCBT);
FreeProcInstance(hkprcCBT);
return nResult;
}
/*******************************************************************
NAME: MsgBoxSz
SYNOPSIS: Displays a message box with the specified text
********************************************************************/
int MsgBoxSz(HWND hWnd,LPTSTR szText,UINT uIcon,UINT uButtons)
{
TCHAR szSmallBuf[SMALL_BUF_LEN+1];
LoadSz(IDS_APPNAME,szSmallBuf,sizeof(szSmallBuf));
return (MessageBox(hWnd,szText,szSmallBuf,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.
********************************************************************/
LPTSTR LoadSz(UINT idString,LPTSTR lpszBuf,UINT cbBuf)
{
ASSERT(lpszBuf);
// Clear the buffer and load the string
if ( lpszBuf )
{
*lpszBuf = '\0';
LoadString( ghInstanceResDll, idString, lpszBuf, cbBuf );
}
return lpszBuf;
}
LPWSTR WINAPI A2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars)
{
ASSERT(lpa != NULL);
ASSERT(lpw != NULL);\
// verify that no illegal character present
// since lpw was allocated based on the size of lpa
// don't worry about the number of chars
lpw[0] = '\0';
MultiByteToWideChar(CP_ACP, 0, lpa, -1, lpw, nChars);
return lpw;
}
LPSTR WINAPI W2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars)
{
ASSERT(lpw != NULL);
ASSERT(lpa != NULL);
// verify that no illegal character present
// since lpa was allocated based on the size of lpw
// don't worry about the number of chars
lpa[0] = '\0';
WideCharToMultiByte(CP_ACP, 0, lpw, -1, lpa, nChars, NULL, NULL);
return lpa;
}
// ############################################################################
//inline BOOL FSz2Dw(PCSTR pSz,DWORD *dw)
BOOL FSz2Dw(LPCSTR pSz,DWORD far *dw)
{
DWORD val = 0;
while (*pSz)
{
if (*pSz >= '0' && *pSz <= '9')
{
val *= 10;
val += *pSz++ - '0';
}
else
{
return FALSE; //bad number
}
}
*dw = val;
return (TRUE);
}
// ############################################################################
//inline BOOL FSz2DwEx(PCSTR pSz,DWORD *dw)
//Accepts -1 as a valid number. currently this is used for LCID, since all langs has a LDID == -1
BOOL FSz2DwEx(LPCSTR pSz,DWORD far *dw)
{
DWORD val = 0;
BOOL bNeg = FALSE;
while (*pSz)
{
if( *pSz == '-' )
{
bNeg = TRUE;
pSz++;
}
else if ((*pSz >= '0' && *pSz <= '9'))
{
val *= 10;
val += *pSz++ - '0';
}
else
{
return FALSE; //bad number
}
}
if(bNeg)
val = 0 - val;
*dw = val;
return (TRUE);
}
// ############################################################################
//inline BOOL FSz2WEx(PCSTR pSz,WORD *w)
//Accepts -1 as a valid number. currently this is used for LCID, since all langs has a LDID == -1
BOOL FSz2WEx(LPCSTR pSz,WORD far *w)
{
DWORD dw;
if (FSz2DwEx(pSz,&dw))
{
*w = (WORD)dw;
return TRUE;
}
return FALSE;
}
// ############################################################################
//inline BOOL FSz2W(PCSTR pSz,WORD *w)
BOOL FSz2W(LPCSTR pSz,WORD far *w)
{
DWORD dw;
if (FSz2Dw(pSz,&dw))
{
*w = (WORD)dw;
return TRUE;
}
return FALSE;
}
// ############################################################################
//inline BOOL FSz2B(PCSTR pSz,BYTE *pb)
BOOL FSz2B(LPCSTR pSz,BYTE far *pb)
{
DWORD dw;
if (FSz2Dw(pSz,&dw))
{
*pb = (BYTE)dw;
return TRUE;
}
return FALSE;
}
const CHAR cszFALSE[] = "FALSE";
const CHAR cszTRUE[] = "TRUE";
// ############################################################################
//inline BOOL FSz2B(PCSTR pSz,BYTE *pb)
BOOL FSz2BOOL(LPCSTR pSz,BOOL far *pbool)
{
if (_strcmpi(cszFALSE, pSz) == 0)
{
*pbool = (BOOL)FALSE;
}
else
{
*pbool = (BOOL)TRUE;
}
return TRUE;
}
BOOL FSz2SPECIAL(LPCSTR pSz,BOOL far *pbool, BOOL far *pbIsSpecial, int far *pInt)
{
// See if the value is a BOOL (TRUE or FALSE)
if (_strcmpi(cszFALSE, pSz) == 0)
{
*pbool = FALSE;
*pbIsSpecial = FALSE;
}
else if (_strcmpi(cszTRUE, pSz) == 0)
{
*pbool = (BOOL)TRUE;
*pbIsSpecial = FALSE;
}
else
{
// Not a BOOL, so it must be special
*pbool = (BOOL)FALSE;
*pbIsSpecial = TRUE;
*pInt = atol(pSz); //_ttoi(pSz);
}
return TRUE;
}
HRESULT ConnectToConnectionPoint
(
IUnknown *punkThis,
REFIID riidEvent,
BOOL fConnect,
IUnknown *punkTarget,
DWORD *pdwCookie,
IConnectionPoint **ppcpOut
)
{
// We always need punkTarget, we only need punkThis on connect
if (!punkTarget || (fConnect && !punkThis))
{
return E_FAIL;
}
if (ppcpOut)
*ppcpOut = NULL;
HRESULT hr;
IConnectionPointContainer *pcpContainer;
if (SUCCEEDED(hr = punkTarget->QueryInterface(IID_IConnectionPointContainer, (void **)&pcpContainer)))
{
IConnectionPoint *pcp;
if(SUCCEEDED(hr = pcpContainer->FindConnectionPoint(riidEvent, &pcp)))
{
if(fConnect)
{
// Add us to the list of people interested...
hr = pcp->Advise(punkThis, pdwCookie);
if (FAILED(hr))
*pdwCookie = 0;
}
else
{
// Remove us from the list of people interested...
hr = pcp->Unadvise(*pdwCookie);
*pdwCookie = 0;
}
if (ppcpOut && SUCCEEDED(hr))
*ppcpOut = pcp;
else
pcp->Release();
pcp = NULL;
}
pcpContainer->Release();
pcpContainer = NULL;
}
return hr;
}
void WaitForEvent(HANDLE hEvent)
{
MSG msg;
DWORD dwRetCode;
HANDLE hEventList[1];
hEventList[0] = hEvent;
while (TRUE)
{
// We will wait on window messages and also the named event.
dwRetCode = MsgWaitForMultipleObjects(1,
&hEventList[0],
FALSE,
300000, // 5 minutes
QS_ALLINPUT);
// Determine why we came out of MsgWaitForMultipleObjects(). If
// we timed out then let's do some TrialWatcher work. Otherwise
// process the message that woke us up.
if (WAIT_TIMEOUT == dwRetCode)
{
break;
}
else if (WAIT_OBJECT_0 == dwRetCode)
{
break;
}
else if (WAIT_OBJECT_0 + 1 == dwRetCode)
{
while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (WM_QUIT == msg.message)
{
break;
}
else if ((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE))
{
PropSheet_PressButton(gpWizardState->hWndWizardApp,PSBTN_CANCEL);
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
break;
}
}
}
}
}
void ShowProgressAnimation()
{
if (gpWizardState->hwndProgressAnime)
{
ShowWindow(gpWizardState->hwndProgressAnime, SW_SHOWNORMAL);
Animate_Play (gpWizardState->hwndProgressAnime,0, -1, -1);
}
}
void HideProgressAnimation()
{
if (gpWizardState->hwndProgressAnime)
{
Animate_Stop(gpWizardState->hwndProgressAnime);
ShowWindow(gpWizardState->hwndProgressAnime, SW_HIDE);
}
}