splash.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 11k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /* Copyright 1997 Microsoft */
  2. #include "priv.h"
  3. #include "resource.h"
  4. #include <mluisupp.h>
  5. #define TIMER_TIMEOUT      1
  6. #define SPLASHWM_DISMISS    WM_USER
  7. ////////////////////////////////////////////////////////////////////////////
  8. //
  9. //  InitLF -- modified from comdlg32fonts.c, used by ShowSplashScreen
  10. //
  11. //  Initalize a LOGFONT structure to some base generic regular type font.
  12. //
  13. ////////////////////////////////////////////////////////////////////////////
  14. VOID InitLF(
  15.     LPLOGFONT lplf)
  16. {
  17.     lplf->lfEscapement = 0;
  18.     lplf->lfOrientation = 0;
  19.     lplf->lfCharSet = DEFAULT_CHARSET;
  20.     lplf->lfOutPrecision = OUT_DEFAULT_PRECIS;
  21.     lplf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
  22.     lplf->lfQuality = DEFAULT_QUALITY;
  23.     lplf->lfPitchAndFamily = DEFAULT_PITCH;
  24.     lplf->lfItalic = 0;
  25.     lplf->lfWeight = FW_NORMAL;
  26.     lplf->lfStrikeOut = 0;
  27.     lplf->lfUnderline = 0;
  28.     lplf->lfWidth = 0;            // otherwise we get independant x-y scaling
  29.     lplf->lfFaceName[0] = 0;
  30.     MLLoadString(IDS_SPLASH_FONT, lplf->lfFaceName, ARRAYSIZE(lplf->lfFaceName));
  31.     TCHAR szTmp[16];
  32.     MLLoadString(IDS_SPLASH_SIZE, szTmp, ARRAYSIZE(szTmp));
  33.     lplf->lfHeight = StrToInt(szTmp);
  34. }
  35. BOOL g_fShown = FALSE;
  36. class CIESplashScreen : public ISplashScreen
  37. {
  38. protected:
  39.     HBITMAP  _hbmSplash;     // The bitmap to display.
  40.     HBITMAP  _hbmOld;
  41.     HDC      _hdc;
  42.     HWND     _hwnd;
  43.     LONG     _cRef;
  44. public:
  45.     CIESplashScreen( HRESULT * pHr );
  46.     ~CIESplashScreen();
  47.     STDMETHOD (QueryInterface)(THIS_ REFIID riid, void ** ppv);
  48.     STDMETHOD_(ULONG, AddRef) ( THIS );
  49.     STDMETHOD_(ULONG, Release) ( THIS );
  50.     STDMETHOD ( Show ) ( HINSTANCE hinst, UINT idResHi, UINT idResLow, HWND * phwshnd );
  51.     STDMETHOD ( Dismiss ) ( void );
  52.     
  53.     static LRESULT s_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  54.     BOOL _RegisterWindowClass(void);
  55.     HWND ShowSplashScreen(HINSTANCE hinst, UINT idResHi, UINT idResLow);
  56. };
  57. CIESplashScreen::CIESplashScreen(HRESULT * pHr) : _cRef (1)
  58. {
  59.     DllAddRef();
  60.     *pHr = NOERROR;
  61. }
  62. CIESplashScreen::~CIESplashScreen()
  63. {
  64.     if (_hdc)
  65.     {
  66.         // select the previous hbm we got when we put the splash in there,
  67.         // so that we can now destroy the hbitmap
  68.         SelectObject( _hdc, _hbmOld );
  69.         DeleteObject(_hdc);
  70.     }
  71.     // destroy the hbitmpa, can only do this if we have deselected it above...
  72.     if (_hbmSplash)
  73.         DeleteObject(_hbmSplash);
  74.     DllRelease();
  75. }
  76. STDMETHODIMP CIESplashScreen::QueryInterface (REFIID riid, void ** ppv)
  77. {
  78.     HRESULT hr = NOERROR;
  79.     if ( IsEqualIID( riid, IID_IUnknown ) || IsEqualIID( riid, IID_ISplashScreen ))
  80.     {
  81.         *ppv = SAFECAST( this, ISplashScreen *);
  82.         this->AddRef();
  83.     }
  84.     else
  85.     {
  86.         hr = E_NOINTERFACE;
  87.     }
  88.     return hr;
  89. }
  90. STDMETHODIMP_(ULONG) CIESplashScreen::AddRef ( )
  91. {
  92.     _cRef ++;
  93.     return _cRef;
  94. }
  95. STDMETHODIMP_(ULONG) CIESplashScreen::Release ( )
  96. {
  97.     _cRef --;
  98.     if ( !_cRef )
  99.     {
  100.         delete this;
  101.         return 0;
  102.     }
  103.     return _cRef;
  104. }
  105. STDMETHODIMP CIESplashScreen::Show ( HINSTANCE hinst, UINT idResHi, UINT idResLow, HWND * phwnd )
  106. {
  107.     if ( !phwnd )
  108.     {
  109.         return E_INVALIDARG;
  110.     }
  111.     
  112.     // First thing to do is to see if see if browser or a splash screen up...
  113.     if ( g_fShown )
  114.         return NULL;
  115.     
  116.     *phwnd = ShowSplashScreen( hinst, idResHi, idResLow );
  117.     
  118.     return ( *phwnd ? NOERROR : E_UNEXPECTED );
  119. }
  120. STDMETHODIMP CIESplashScreen::Dismiss ( void )
  121. {
  122.     if ( _hwnd )
  123.     {
  124.         // Synchronously dismiss the splash screen then post a message to
  125.         // destroy the window.
  126.         SendMessage(_hwnd, SPLASHWM_DISMISS, 0, 0);
  127.         PostMessage(_hwnd, WM_CLOSE, 0, 0);
  128.     }
  129.     return S_OK;
  130. }
  131. HWND CIESplashScreen::ShowSplashScreen( HINSTANCE hinst, UINT idResHi, UINT idResLow )
  132. {
  133.     // don't show splash screen for IE in intergrated mode or if it's been disabled 
  134.     // by the admin
  135.     if (
  136.         ( (WhichPlatform() == PLATFORM_INTEGRATED) && (hinst == HINST_THISDLL) ) ||
  137.         ( SHRestricted2(REST_NoSplash, NULL, 0) )
  138.        )
  139.     {
  140.         return NULL;
  141.     }
  142.     
  143.     if (!_RegisterWindowClass())
  144.         return NULL;
  145.     // provide default bitmap resource ID's for IE
  146.     if (hinst == HINST_THISDLL)
  147.     {
  148.         if (idResHi == -1)
  149.             idResHi = IDB_SPLASH_IEXPLORER_HI;
  150.         if (idResLow == -1)
  151.             idResLow = IDB_SPLASH_IEXPLORER;
  152.     }
  153.             
  154.      // Now load the appropriate bitmap depending on colors, only use the 256 colour splash
  155.      // if we are greater than 256 colours (such as 32K or 65K upwards), this will mean we don't have
  156.      // to flash the palette just to put up the splash screen.
  157.     _hbmSplash = (HBITMAP)LoadImage(hinst, MAKEINTRESOURCE((GetCurColorRes() > 8) ? idResHi : idResLow), 
  158.                                     IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  159.     _hdc = CreateCompatibleDC(NULL);
  160.     
  161.     if (!_hbmSplash || !_hdc)
  162.         return NULL;
  163.     // remember the old hbitmap so we can select it back before we delete the bitmap..
  164.     _hbmOld = (HBITMAP) SelectObject(_hdc, _hbmSplash);
  165.     // set font and color for text
  166.     LOGFONT lf;
  167.     HFONT   hfont;
  168.     
  169.     InitLF(&lf);
  170.     hfont = CreateFontIndirect(&lf);
  171.     if ( hfont == NULL ) // show the bitmap without text if we can't create the font
  172.         goto Done;
  173.     // select the new font and remember the old one
  174.     hfont = (HFONT)SelectObject(_hdc, hfont);
  175.     
  176.     SetTextColor(_hdc, RGB(0,0,0));
  177.     SetBkColor(_hdc, RGB(255,255,255));
  178.     SetBkMode(_hdc, TRANSPARENT);
  179.     
  180.     // draw the text on top of the selected bitmap
  181.     TCHAR   szText[512], szY[32];
  182.     RECT    rect;
  183.     
  184.     MLLoadString(IDS_SPLASH_Y1, szY, ARRAYSIZE(szY));
  185.     MLLoadString(IDS_SPLASH_STR1, szText, ARRAYSIZE(szText));
  186.     SetRect(&rect, 104, StrToInt(szY), 386, StrToInt(szY) + 10);
  187.     DrawText(_hdc, szText, -1, &rect, DT_TOP | DT_LEFT | DT_SINGLELINE | DT_CALCRECT);
  188.     DrawText(_hdc, szText, -1, &rect, DT_TOP | DT_LEFT | DT_SINGLELINE);
  189.     MLLoadString(IDS_SPLASH_Y2, szY, ARRAYSIZE(szY));
  190.     MLLoadString(IDS_SPLASH_STR2, szText, ARRAYSIZE(szText));
  191.     SetRect(&rect, 104, StrToInt(szY), 386, 400);
  192.     DrawText(_hdc, szText, -1, &rect, DT_TOP | DT_LEFT | DT_CALCRECT);
  193.     DrawText(_hdc, szText, -1, &rect, DT_TOP | DT_LEFT);
  194.     // select back the old font and delete the new one
  195.     DeleteObject(SelectObject(_hdc, hfont));
  196.      
  197. Done:
  198.     // we now have everything in the DC, ready for painting.
  199.     _hwnd = CreateWindowEx(WS_EX_TOOLWINDOW, TEXT("CIESplashScreen"), NULL, 
  200.                            WS_OVERLAPPED | WS_CLIPCHILDREN,
  201.                            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
  202.                            NULL, (HMENU)NULL, HINST_THISDLL, this);
  203.     if (_hwnd)
  204.         ShowWindow(_hwnd, SW_NORMAL);
  205.     return _hwnd;
  206. }
  207. LRESULT CIESplashScreen::s_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  208. {
  209.     CIESplashScreen *piess = (CIESplashScreen*)GetWindowLong(hwnd, 0);
  210.     if (!piess && (uMsg != WM_CREATE))
  211.         return DefWindowProc(hwnd, uMsg, wParam, lParam);
  212.     switch (uMsg)
  213.     {
  214.     case WM_CREATE:
  215.         DllAddRef();        // make sure we are not unloaded while in dialog
  216.         if (lParam)
  217.         {
  218.             DWORD dwExStyles;
  219.             piess = (CIESplashScreen*)((LPCREATESTRUCT)lParam)->lpCreateParams;
  220.             SetWindowLongPtr(hwnd, 0, (LONG_PTR)piess);
  221.             //
  222.             // Turn off mirroring for the GUI splash screen bitmap.
  223.             //
  224.             if ((dwExStyles=GetWindowLong(hwnd, GWL_EXSTYLE))&RTL_MIRRORED_WINDOW)
  225.             {
  226.                 SetWindowLong(hwnd, GWL_EXSTYLE, dwExStyles&~RTL_MIRRORED_WINDOW);
  227.             }
  228.             // Now lets try to center the window on the screen.
  229.             BITMAP bm;
  230.             GetObject(piess->_hbmSplash, sizeof(bm), &bm);
  231.             SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & 
  232.                           ~(WS_CAPTION|WS_SYSMENU|WS_BORDER|WS_THICKFRAME));
  233.             SetWindowPos(hwnd, HWND_TOP, 
  234.                          (GetSystemMetrics(SM_CXSCREEN) - bm.bmWidth) / 2, 
  235.                          (GetSystemMetrics(SM_CYSCREEN) - bm.bmHeight) / 2, 
  236.                          bm.bmWidth, bm.bmHeight, 0);
  237.             // Set a 5 second timer to time it out.
  238.             SetTimer(hwnd, TIMER_TIMEOUT, 15000, NULL);
  239.         }
  240.         g_fShown = TRUE;
  241.         break;
  242.     case WM_NCDESTROY:
  243.         // the splash screen has left the building
  244.         g_fShown = FALSE;
  245.         
  246.         DllRelease();
  247.         break;
  248.     case WM_ERASEBKGND:
  249.         {
  250.             RECT rc;
  251.             GetClientRect(hwnd, &rc);
  252.             HDC hdc = (HDC)wParam;
  253.             BitBlt((HDC)hdc, 0, 0, rc.right, rc.bottom, piess->_hdc, 0, 0, SRCCOPY);
  254.             return 1;
  255.         }
  256.         break;
  257.     case WM_TIMER:
  258.         // Now assume it is the right one.
  259.         KillTimer( hwnd, TIMER_TIMEOUT );
  260.         PostMessage(hwnd, WM_CLOSE, 0, 0);
  261.         break;
  262.     case SPLASHWM_DISMISS:
  263.         // Hide ourselves and remove our reference to piess - it may be gone at any point
  264.         // after this call.
  265.         ShowWindow(hwnd, SW_HIDE);
  266.         SetWindowLong(hwnd, 0, 0);
  267.         break;
  268.     case WM_ACTIVATE:
  269.         if ( wParam == WA_INACTIVE && hwnd != NULL )
  270.         {
  271.             KillTimer( hwnd, TIMER_TIMEOUT );
  272.             // create a new timer for 2 seconds after loss of activation...
  273.             SetTimer( hwnd, TIMER_TIMEOUT, 2000, NULL );
  274.             break;
  275.         }
  276.         // drop through
  277.     
  278.     default:
  279.         return DefWindowProc(hwnd, uMsg, wParam, lParam);
  280.     }
  281.     return 0;
  282. }
  283. BOOL CIESplashScreen::_RegisterWindowClass(void)
  284. {
  285.     WNDCLASS wc = {0};
  286.     //wc.style         = 0;
  287.     wc.lpfnWndProc   = s_WndProc ;
  288.     //wc.cbClsExtra    = 0;
  289.     wc.cbWndExtra    = sizeof(CIESplashScreen *);
  290.     wc.hInstance     = g_hinst ;
  291.     //wc.hIcon         = NULL ;
  292.     //wc.hCursor       = NULL;
  293.     wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
  294.     //wc.lpszMenuName  = NULL ;
  295.     wc.lpszClassName = TEXT("CIESplashScreen");
  296.     return SHRegisterClass(&wc);
  297. }
  298. STDAPI CIESplashScreen_CreateInstance(IUnknown * pUnkOuter, IUnknown ** ppunk, LPCOBJECTINFO poi)
  299. {
  300.     HRESULT hr = E_FAIL;
  301.     CIESplashScreen * pSplash = new CIESplashScreen( & hr );
  302.     if ( !pSplash )
  303.     {
  304.         return E_OUTOFMEMORY;
  305.     }
  306.     if ( FAILED( hr ))
  307.     {
  308.         delete pSplash;
  309.         return hr;
  310.     }
  311.     
  312.     *ppunk = SAFECAST(pSplash, ISplashScreen *);
  313.     return NOERROR;
  314. }
  315. STDAPI SHCreateSplashScreen(ISplashScreen **ppSplash)
  316. {
  317.     return CIESplashScreen_CreateInstance(NULL, (IUnknown **)ppSplash, NULL );
  318. }