WindowsXP-SP1/shell/shdocvw/sftupmb.cpp

271 lines
9.3 KiB
C++

#include "priv.h"
#include "resource.h"
#include <mluisupp.h>
struct SUParams {
LPSOFTDISTINFO psdi;
BITBOOL bRemind : 1;
BITBOOL bDetails : 1;
LONG cyNoDetails;
LONG cxDlg;
LONG cyDlg;
};
INT_PTR CALLBACK SoftwareUpdateDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
SHDOCAPI_(DWORD) SoftwareUpdateMessageBox( HWND hWnd,
LPCWSTR szDistUnit,
DWORD dwFlags,
LPSOFTDISTINFO psdi )
{
HRESULT hr;
int iRet = IDIGNORE;
SOFTDISTINFO sdi;
SUParams suparams;
DWORD dwAdStateNew = SOFTDIST_ADSTATE_NONE;
if ( psdi == NULL )
{
// use a local
sdi.cbSize = sizeof(SOFTDISTINFO);
sdi.dwReserved = 0;
psdi = &sdi;
}
suparams.psdi = psdi;
suparams.bRemind = TRUE;
suparams.bDetails = FALSE;
hr = GetSoftwareUpdateInfo( szDistUnit, psdi );
// we need an HREF to work properly. The title and abstract are negotiable.
if ( SUCCEEDED(hr) && psdi->szHREF != NULL )
{
// see if this is an update the user already knows about.
// If it is, then skip the dialog.
if ( (psdi->dwUpdateVersionMS >= psdi->dwInstalledVersionMS ||
(psdi->dwUpdateVersionMS == psdi->dwInstalledVersionMS &&
psdi->dwUpdateVersionLS >= psdi->dwInstalledVersionLS)) &&
(psdi->dwUpdateVersionMS >= psdi->dwAdvertisedVersionMS ||
(psdi->dwUpdateVersionMS == psdi->dwAdvertisedVersionMS &&
psdi->dwUpdateVersionLS >= psdi->dwAdvertisedVersionLS)) )
{
DWORD idDlg;
if ( hr == S_OK ) // new version
{
// we have a pending update, either on the net, or downloaded
if ( psdi->dwFlags & SOFTDIST_FLAG_USAGE_PRECACHE )
{
dwAdStateNew = SOFTDIST_ADSTATE_DOWNLOADED;
// Show same dialog for downloaded/available states
// because users get confused. See IE5 RAID entry 14488
idDlg = IDD_SUAVAILABLE;
}
else
{
dwAdStateNew = SOFTDIST_ADSTATE_AVAILABLE;
idDlg = IDD_SUAVAILABLE;
}
}
else if ( psdi->dwUpdateVersionMS == psdi->dwInstalledVersionMS &&
psdi->dwUpdateVersionLS == psdi->dwInstalledVersionLS )
{
// if installed version matches advertised, then we autoinstalled already
dwAdStateNew = SOFTDIST_ADSTATE_INSTALLED;
idDlg = IDD_SUINSTALLED;
}
else
{
idDlg = 0;
}
// only show the dialog if we've haven't been in this ad state before for
// this update version
if ( dwAdStateNew > psdi->dwAdState && idDlg != 0)
{
// Sundown: coercion is OK since SoftwareUpdateDlgProc returns true/false
iRet = (int) DialogBoxParam(MLGetHinst(),
MAKEINTRESOURCE(idDlg),
hWnd,
SoftwareUpdateDlgProc,
(LPARAM)&suparams);
}
} // if update is a newer version than advertised
// If the user doesn't want a reminder and didn't cancel, mark the DU.
if ( !suparams.bRemind && (iRet == IDNO || iRet == IDYES) )
{
SetSoftwareUpdateAdvertisementState( szDistUnit,
dwAdStateNew,
psdi->dwUpdateVersionMS,
psdi->dwUpdateVersionLS );
} // if we're finished with this ad state for this version
} // if we got the update info
else
iRet = IDABORT;
if ( FAILED(hr) || psdi == &sdi )
{
if ( psdi->szTitle != NULL )
{
CoTaskMemFree( psdi->szTitle );
psdi->szTitle = NULL;
}
if ( psdi->szAbstract != NULL )
{
CoTaskMemFree( psdi->szAbstract );
psdi->szAbstract = NULL;
};
if ( psdi->szHREF != NULL )
{
CoTaskMemFree( psdi->szHREF );
psdi->szHREF = NULL;
}
}
return iRet;
}
INT_PTR CALLBACK SoftwareUpdateDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
BOOL fRet = 0;
SUParams *psuparam = (SUParams*)GetWindowLongPtr(hDlg, DWLP_USER);;
HRESULT hr = S_OK;
HWND hwndDetails;
switch (msg)
{
case WM_INITDIALOG:
int cchDetails;
TCHAR *pszTitle;
TCHAR *pszAbstract;
TCHAR *pszDetails;
TCHAR szFmt[MAX_PATH];
SetWindowLongPtr(hDlg, DWLP_USER, lParam);
psuparam = (SUParams*)lParam;
if (SHRestricted( REST_NOFORGETSOFTWAREUPDATE))
EnableWindow(GetDlgItem(hDlg, IDC_REMIND), FALSE);
// Prepare the details from the SOFTDISTINFO
MLLoadString(IDS_SUDETAILSFMT, szFmt, ARRAYSIZE(szFmt) );
cchDetails = lstrlen( szFmt );
if ( psuparam->psdi->szTitle != NULL )
{
pszTitle = psuparam->psdi->szTitle;
}
else
{
pszTitle = NULL;
}
if ( psuparam->psdi->szAbstract != NULL )
{
pszAbstract = psuparam->psdi->szAbstract;
}
else
{
pszAbstract = NULL;
}
pszDetails = new TCHAR[cchDetails];
if ( pszDetails != NULL )
{
wnsprintf( pszDetails, cchDetails, szFmt, ((pszTitle!=NULL)?pszTitle:TEXT("")),
((pszAbstract!=NULL)?pszAbstract:TEXT("")) );
// set the details text
SetDlgItemText( hDlg, IDC_DETAILSTEXT, pszDetails );
// initialize the reminder check box
CheckDlgButton( hDlg, IDC_REMIND, ((psuparam->bRemind)?BST_CHECKED:BST_UNCHECKED) );
// Hide or show the details
RECT rectDlg;
RECT rectDetails;
GetWindowRect( hDlg, &rectDlg );
psuparam->cyDlg = rectDlg.bottom - rectDlg.top;
psuparam->cxDlg = rectDlg.right - rectDlg.left;
hwndDetails = GetDlgItem( hDlg, IDC_DETAILSTEXT );
GetWindowRect( hwndDetails, &rectDetails );
psuparam->cyNoDetails = rectDetails.top - rectDlg.top;
SetWindowPos( hwndDetails, NULL, 0,0,0,0, SWP_NOMOVE | SWP_HIDEWINDOW | SWP_NOZORDER | SWP_NOSIZE );
SetWindowPos( hDlg, NULL,
0,0,psuparam->cxDlg,psuparam->cyNoDetails,
SWP_NOMOVE | SWP_NOZORDER );
}
else
EndDialog( hDlg, IDABORT );
if ( pszDetails != NULL )
delete pszDetails;
fRet = TRUE;
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDYES:
EndDialog(hDlg, IDYES );
fRet = TRUE;
break;
case IDNO:
EndDialog(hDlg, IDNO );
fRet = TRUE;
break;
case IDC_REMIND:
psuparam->bRemind = IsDlgButtonChecked( hDlg, IDC_REMIND ) == BST_CHECKED;
fRet = TRUE;
break;
case IDC_DETAILS:
{
TCHAR szDetails[40];
// toggle the details
hwndDetails = GetDlgItem( hDlg, IDC_DETAILSTEXT );
psuparam->bDetails = !psuparam->bDetails;
if ( psuparam->bDetails )
{
// show the details
// switch button to close text
MLLoadString(IDS_SUDETAILSCLOSE, szDetails, ARRAYSIZE(szDetails) );
SetDlgItemText( hDlg, IDC_DETAILS, szDetails );
SetWindowPos( hDlg, NULL,
0,0,psuparam->cxDlg, psuparam->cyDlg,
SWP_NOMOVE | SWP_NOZORDER );
SetWindowPos( hwndDetails, NULL, 0,0,0,0, SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOSIZE );
}
else
{
MLLoadString(IDS_SUDETAILSOPEN, szDetails, ARRAYSIZE(szDetails) );
SetDlgItemText( hDlg, IDC_DETAILS, szDetails );
SetWindowPos( hwndDetails, NULL, 0,0,0,0, SWP_NOMOVE | SWP_HIDEWINDOW | SWP_NOZORDER | SWP_NOSIZE );
SetWindowPos( hDlg, NULL,
0,0,psuparam->cxDlg,psuparam->cyNoDetails,
SWP_NOMOVE | SWP_NOZORDER );
}
}
fRet = TRUE;
break;
}
break;
case WM_CLOSE:
EndDialog(hDlg, IDNO);
fRet = TRUE;
break;
case WM_DESTROY:
fRet = TRUE;
break;
default:
fRet = FALSE;
}
return fRet;
}