|
|
/* Copyright 1997 Microsoft */
#include "priv.h"
#include "resource.h"
#include <mluisupp.h>
#define TIMER_TIMEOUT 1
#define SPLASHWM_DISMISS WM_USER
////////////////////////////////////////////////////////////////////////////
//
// InitLF -- modified from comdlg32\fonts.c, used by ShowSplashScreen
//
// Initalize a LOGFONT structure to some base generic regular type font.
//
////////////////////////////////////////////////////////////////////////////
VOID InitLF( HDC hdc, LPLOGFONT lplf) { TEXTMETRIC tm;
lplf->lfEscapement = 0; lplf->lfOrientation = 0; lplf->lfOutPrecision = OUT_DEFAULT_PRECIS; lplf->lfClipPrecision = CLIP_DEFAULT_PRECIS; lplf->lfQuality = DEFAULT_QUALITY; lplf->lfPitchAndFamily = DEFAULT_PITCH; lplf->lfItalic = 0; lplf->lfWeight = FW_NORMAL; lplf->lfStrikeOut = 0; lplf->lfUnderline = 0; lplf->lfWidth = 0; // otherwise we get independant x-y scaling
GetTextMetrics(hdc, &tm); // get the current textmetrics
lplf->lfCharSet = tm.tmCharSet;
lplf->lfFaceName[0] = 0; MLLoadString(IDS_SPLASH_FONT, lplf->lfFaceName, ARRAYSIZE(lplf->lfFaceName));
TCHAR szTmp[16]; MLLoadString(IDS_SPLASH_SIZE, szTmp, ARRAYSIZE(szTmp)); lplf->lfHeight = StrToInt(szTmp); }
BOOL g_fShown = FALSE;
class CIESplashScreen : public ISplashScreen { protected: HBITMAP _hbmSplash; // The bitmap to display.
HBITMAP _hbmOld; HDC _hdc; HWND _hwnd; LONG _cRef;
public: CIESplashScreen( HRESULT * pHr ); ~CIESplashScreen();
STDMETHOD (QueryInterface)(THIS_ REFIID riid, void ** ppv); STDMETHOD_(ULONG, AddRef) ( THIS ); STDMETHOD_(ULONG, Release) ( THIS );
STDMETHOD ( Show ) ( HINSTANCE hinst, UINT idResHi, UINT idResLow, HWND * phwshnd ); STDMETHOD ( Dismiss ) ( void ); static LRESULT s_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); BOOL _RegisterWindowClass(void); HWND ShowSplashScreen(HINSTANCE hinst, UINT idResHi, UINT idResLow);
};
CIESplashScreen::CIESplashScreen(HRESULT * pHr) : _cRef (1) { DllAddRef(); *pHr = NOERROR; }
CIESplashScreen::~CIESplashScreen() { if (_hdc) { // select the previous hbm we got when we put the splash in there,
// so that we can now destroy the hbitmap
SelectObject( _hdc, _hbmOld ); DeleteObject(_hdc); }
// destroy the hbitmpa, can only do this if we have deselected it above...
if (_hbmSplash) DeleteObject(_hbmSplash);
DllRelease(); }
STDMETHODIMP CIESplashScreen::QueryInterface (REFIID riid, void ** ppv) { HRESULT hr = NOERROR; if ( IsEqualIID( riid, IID_IUnknown ) || IsEqualIID( riid, IID_ISplashScreen )) { *ppv = SAFECAST( this, ISplashScreen *); this->AddRef(); } else { hr = E_NOINTERFACE; } return hr; }
STDMETHODIMP_(ULONG) CIESplashScreen::AddRef ( ) { _cRef ++; return _cRef; }
STDMETHODIMP_(ULONG) CIESplashScreen::Release ( ) { _cRef --; if ( !_cRef ) { delete this; return 0; } return _cRef; }
STDMETHODIMP CIESplashScreen::Show ( HINSTANCE hinst, UINT idResHi, UINT idResLow, HWND * phwnd ) { if ( !phwnd ) { return E_INVALIDARG; } // First thing to do is to see if see if browser or a splash screen up...
if ( g_fShown ) return NULL; *phwnd = ShowSplashScreen( hinst, idResHi, idResLow ); return ( *phwnd ? NOERROR : E_UNEXPECTED ); }
STDMETHODIMP CIESplashScreen::Dismiss ( void ) { if ( _hwnd ) { // Synchronously dismiss the splash screen then post a message to
// destroy the window.
SendMessage(_hwnd, SPLASHWM_DISMISS, 0, 0); PostMessage(_hwnd, WM_CLOSE, 0, 0); } return S_OK; }
HWND CIESplashScreen::ShowSplashScreen( HINSTANCE hinst, UINT idResHi, UINT idResLow ) { // don't show splash screen for IE in intergrated mode or if it's been disabled
// by the admin
if ( ( (WhichPlatform() == PLATFORM_INTEGRATED) && (hinst == HINST_THISDLL) ) || ( SHRestricted2(REST_NoSplash, NULL, 0) ) ) { return NULL; } if (!_RegisterWindowClass()) return NULL;
// provide default bitmap resource ID's for IE
if (hinst == HINST_THISDLL) { if (idResHi == -1) idResHi = IDB_SPLASH_IEXPLORER_HI; if (idResLow == -1) idResLow = IDB_SPLASH_IEXPLORER; } // Now load the appropriate bitmap depending on colors, only use the 256 colour splash
// if we are greater than 256 colours (such as 32K or 65K upwards), this will mean we don't have
// to flash the palette just to put up the splash screen.
_hbmSplash = (HBITMAP)LoadImage(hinst, MAKEINTRESOURCE((GetCurColorRes() > 8) ? idResHi : idResLow), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
_hdc = CreateCompatibleDC(NULL); if (!_hbmSplash || !_hdc) return NULL;
// remember the old hbitmap so we can select it back before we delete the bitmap..
_hbmOld = (HBITMAP) SelectObject(_hdc, _hbmSplash);
// set font and color for text
LOGFONT lf; HFONT hfont; HFONT hfontOld; InitLF(_hdc, &lf); hfont = CreateFontIndirect(&lf); if ( hfont == NULL ) // show the bitmap without text if we can't create the font
goto Done;
// select the new font and remember the old one
hfontOld = (HFONT)SelectObject(_hdc, hfont);
if (hfontOld) { SetTextColor(_hdc, RGB(0,0,0)); SetBkColor(_hdc, RGB(255,255,255)); SetBkMode(_hdc, TRANSPARENT); // draw the text on top of the selected bitmap
TCHAR szText[512], szY[32]; RECT rect; MLLoadString(IDS_SPLASH_Y1, szY, ARRAYSIZE(szY)); MLLoadString(IDS_SPLASH_STR1, szText, ARRAYSIZE(szText)); SetRect(&rect, 104, StrToInt(szY), 386, StrToInt(szY) + 10); DrawText(_hdc, szText, -1, &rect, DT_TOP | DT_LEFT | DT_SINGLELINE | DT_CALCRECT); DrawText(_hdc, szText, -1, &rect, DT_TOP | DT_LEFT | DT_SINGLELINE);
MLLoadString(IDS_SPLASH_Y2, szY, ARRAYSIZE(szY)); MLLoadString(IDS_SPLASH_STR2, szText, ARRAYSIZE(szText)); SetRect(&rect, 104, StrToInt(szY), 386, 400); DrawText(_hdc, szText, -1, &rect, DT_TOP | DT_LEFT | DT_CALCRECT); DrawText(_hdc, szText, -1, &rect, DT_TOP | DT_LEFT);
// select back the old font and delete the new one
SelectObject(_hdc, hfontOld); }
DeleteObject(hfont); Done: // we now have everything in the DC, ready for painting.
_hwnd = CreateWindowEx(WS_EX_TOOLWINDOW, TEXT("CIESplashScreen"), NULL, WS_OVERLAPPED | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, HINST_THISDLL, this); if (_hwnd) ShowWindow(_hwnd, SW_NORMAL);
return _hwnd; }
LRESULT CIESplashScreen::s_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
CIESplashScreen *piess = (CIESplashScreen*)GetWindowPtr0(hwnd);
if (!piess && (uMsg != WM_CREATE)) return DefWindowProc(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_CREATE: DllAddRef(); // make sure we are not unloaded while in dialog
if (lParam) { DWORD dwExStyles;
piess = (CIESplashScreen*)((LPCREATESTRUCT)lParam)->lpCreateParams; SetWindowPtr0(hwnd, piess);
//
// Turn off mirroring for the GUI splash screen bitmap.
//
if ((dwExStyles=GetWindowLong(hwnd, GWL_EXSTYLE))&RTL_MIRRORED_WINDOW) { SetWindowLong(hwnd, GWL_EXSTYLE, dwExStyles&~RTL_MIRRORED_WINDOW); }
// Now lets try to center the window on the screen.
BITMAP bm;
GetObject(piess->_hbmSplash, sizeof(bm), &bm);
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~(WS_CAPTION|WS_SYSMENU|WS_BORDER|WS_THICKFRAME)); SetWindowPos(hwnd, HWND_TOP, (GetSystemMetrics(SM_CXSCREEN) - bm.bmWidth) / 2, (GetSystemMetrics(SM_CYSCREEN) - bm.bmHeight) / 2, bm.bmWidth, bm.bmHeight, 0);
// Set a 5 second timer to time it out.
SetTimer(hwnd, TIMER_TIMEOUT, 15000, NULL); } g_fShown = TRUE; break;
case WM_NCDESTROY: // the splash screen has left the building
g_fShown = FALSE; DllRelease(); break;
case WM_ERASEBKGND: { RECT rc; GetClientRect(hwnd, &rc); HDC hdc = (HDC)wParam;
BitBlt((HDC)hdc, 0, 0, rc.right, rc.bottom, piess->_hdc, 0, 0, SRCCOPY);
return 1; } break;
case WM_TIMER: // Now assume it is the right one.
KillTimer( hwnd, TIMER_TIMEOUT ); PostMessage(hwnd, WM_CLOSE, 0, 0); break;
case SPLASHWM_DISMISS: // Hide ourselves and remove our reference to piess - it may be gone at any point
// after this call.
ShowWindow(hwnd, SW_HIDE); SetWindowPtr0(hwnd, 0); break;
case WM_ACTIVATE: if ( wParam == WA_INACTIVE && hwnd != NULL ) { KillTimer( hwnd, TIMER_TIMEOUT );
// create a new timer for 2 seconds after loss of activation...
SetTimer( hwnd, TIMER_TIMEOUT, 2000, NULL ); break; } // drop through
default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; }
BOOL CIESplashScreen::_RegisterWindowClass(void) { WNDCLASS wc = {0};
//wc.style = 0;
wc.lpfnWndProc = s_WndProc ; //wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(CIESplashScreen *); wc.hInstance = g_hinst ; //wc.hIcon = NULL ;
//wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1); //wc.lpszMenuName = NULL ;
wc.lpszClassName = TEXT("CIESplashScreen");
return SHRegisterClass(&wc); }
STDAPI CIESplashScreen_CreateInstance(IUnknown * pUnkOuter, IUnknown ** ppunk, LPCOBJECTINFO poi) { HRESULT hr = E_FAIL; CIESplashScreen * pSplash = new CIESplashScreen( & hr ); if ( !pSplash ) { return E_OUTOFMEMORY; } if ( FAILED( hr )) { delete pSplash; return hr; } *ppunk = SAFECAST(pSplash, ISplashScreen *); return NOERROR; }
STDAPI SHCreateSplashScreen(ISplashScreen **ppSplash) { return CIESplashScreen_CreateInstance(NULL, (IUnknown **)ppSplash, NULL ); }
|