mirror of
				https://github.com/bobranten/Ext4Fsd.git
				synced 2025-10-30 21:38:31 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			285 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			285 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //  ===========================================================================
 | |
| //  File    Splash.cpp
 | |
| //  Desc    The implementation file for the CSplash class.
 | |
| //  ===========================================================================
 | |
| 
 | |
| #include "stdafx.h"
 | |
| #include "splash.h"
 | |
| #include "windowsx.h"
 | |
| 
 | |
| //  ===========================================================================
 | |
| //  The following is used for layering support which is used in the 
 | |
| //  splash screen for transparency. In VC 6 these are not defined in the headers
 | |
| //  for user32.dll and hence we use mechanisms so that it can work in VC 6.
 | |
| //  We define the flags here and write code so that we can load the function
 | |
| //  from User32.dll explicitely and use it. This code requires Win2k and above
 | |
| //  to work.
 | |
| //  ===========================================================================
 | |
| typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)
 | |
|         (HWND hWnd, COLORREF cr, BYTE bAlpha, DWORD dwFlags);
 | |
| 
 | |
| lpfnSetLayeredWindowAttributes g_pSetLayeredWindowAttributes;
 | |
| 
 | |
| #define WS_EX_LAYERED 0x00080000 
 | |
| 
 | |
| //  ===========================================================================
 | |
| //  Func    ExtWndProc
 | |
| //  Desc    The windows procedure that is used to forward messages to the 
 | |
| //          CSplash class. CSplash sends the "this" pointer through the
 | |
| //          CreateWindowEx call and the pointer reaches here in the 
 | |
| //          WM_CREATE message. We store it here and use it for message 
 | |
| //          forwarding.
 | |
| //  ===========================================================================
 | |
| static LRESULT CALLBACK ExtWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 | |
| {
 | |
|     static CSplash * spl = NULL;
 | |
|     if(uMsg == WM_CREATE)
 | |
|     {
 | |
|         spl = (CSplash*)((LPCREATESTRUCT)lParam)->lpCreateParams;
 | |
|     }
 | |
|     if(spl)
 | |
|         return spl->WindowProc(hwnd, uMsg, wParam, lParam);
 | |
|     else
 | |
|         return DefWindowProc (hwnd, uMsg, wParam, lParam);
 | |
| }
 | |
| 
 | |
| LRESULT CALLBACK CSplash::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 | |
| {
 | |
|     //  We need to handle on the WM_PAINT message
 | |
|     switch(uMsg)
 | |
|     {
 | |
|         HANDLE_MSG(hwnd, WM_PAINT, OnPaint);
 | |
| #if 0
 | |
|        // Stop flicker when splash screen appears
 | |
|         case WM_ERASEBKGND:
 | |
|            // stop the default processing of this message
 | |
|            // by returning 1
 | |
|            return (LRESULT)1; // say we handled it
 | |
| #endif
 | |
|     }
 | |
| 
 | |
|     return DefWindowProc (hwnd, uMsg, wParam, lParam) ;
 | |
| }
 | |
| 
 | |
| void CSplash:: OnPaint(HWND hwnd)
 | |
| {
 | |
|     if (!m_hBitmap)
 | |
|         return;
 | |
| 
 | |
|     //  =======================================================================
 | |
|     //  Paint the background by BitBlting the bitmap
 | |
|     //  =======================================================================
 | |
|     PAINTSTRUCT ps ;
 | |
|     HDC hDC = BeginPaint (hwnd, &ps) ;
 | |
| 
 | |
|     RECT   rect;
 | |
|     ::GetClientRect(m_hwnd, &rect);
 | |
|     
 | |
|     HDC hMemDC      = ::CreateCompatibleDC(hDC);
 | |
|     HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC, m_hBitmap);
 | |
|     
 | |
|     BitBlt(hDC, 0, 0, m_dwWidth, m_dwHeight, hMemDC, 0, 0, SRCCOPY);
 | |
| 
 | |
|     ::SelectObject(hMemDC, hOldBmp);
 | |
| 
 | |
|     ::DeleteDC(hMemDC);
 | |
|     
 | |
|     EndPaint (hwnd, &ps) ;
 | |
| }
 | |
| 
 | |
| void CSplash::Init()
 | |
| {
 | |
|     //  =======================================================================
 | |
|     //  Initialize the variables
 | |
|     //  =======================================================================
 | |
|     m_hwnd = NULL;
 | |
|     m_lpszClassName = TEXT("Ext2 Volume Manager Splash Screen");
 | |
|     m_colTrans = 0;
 | |
| 
 | |
|     //  =======================================================================
 | |
|     //  Keep the function pointer for the SetLayeredWindowAttributes function
 | |
|     //  in User32.dll ready
 | |
|     //  =======================================================================
 | |
|     HMODULE hUser32 = GetModuleHandle(TEXT("USER32.DLL"));
 | |
| 
 | |
|     g_pSetLayeredWindowAttributes = (lpfnSetLayeredWindowAttributes)
 | |
|                         GetProcAddress(hUser32, "SetLayeredWindowAttributes");
 | |
| }
 | |
| 
 | |
| CSplash::CSplash()
 | |
| {
 | |
|     Init();
 | |
| }
 | |
| 
 | |
| CSplash::CSplash(UINT id, COLORREF colTrans)
 | |
| {
 | |
|     Init();
 | |
| 
 | |
|     SetBitmap(id);
 | |
|     SetTransparentColor(colTrans);
 | |
| }
 | |
| 
 | |
| CSplash::~CSplash()
 | |
| {
 | |
|     FreeResources();
 | |
| }
 | |
| 
 | |
| HWND CSplash::RegAndCreateWindow()
 | |
| {
 | |
|     //  =======================================================================
 | |
|     //  Register the window with ExtWndProc as the window procedure
 | |
|     //  =======================================================================
 | |
|     WNDCLASSEX wndclass;
 | |
|     wndclass.cbSize         = sizeof (wndclass);
 | |
|     wndclass.style          = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW;
 | |
|     wndclass.lpfnWndProc    = ExtWndProc;
 | |
|     wndclass.cbClsExtra     = 0;
 | |
|     wndclass.cbWndExtra     = DLGWINDOWEXTRA;
 | |
|     wndclass.hInstance      = ::GetModuleHandle(NULL);
 | |
|     wndclass.hIcon          = NULL;
 | |
|     wndclass.hCursor        = ::LoadCursor( NULL, IDC_WAIT );
 | |
|     wndclass.hbrBackground  = (HBRUSH)::GetStockObject(LTGRAY_BRUSH);
 | |
|     wndclass.lpszMenuName   = NULL;
 | |
|     wndclass.lpszClassName  = m_lpszClassName;
 | |
|     wndclass.hIconSm        = NULL;
 | |
| 
 | |
|     if(!RegisterClassEx (&wndclass))
 | |
|         return NULL;
 | |
| 
 | |
|     //  =======================================================================
 | |
|     //  Create the window of the application, passing the this pointer so that
 | |
|     //  ExtWndProc can use that for message forwarding
 | |
|     //  =======================================================================
 | |
|     DWORD nScrWidth  = ::GetSystemMetrics(SM_CXFULLSCREEN);
 | |
|     DWORD nScrHeight = ::GetSystemMetrics(SM_CYFULLSCREEN);
 | |
| 
 | |
|     int x = (nScrWidth  - m_dwWidth) / 2;
 | |
|     int y = (nScrHeight - m_dwHeight) / 2;
 | |
|     m_hwnd = ::CreateWindowEx(WS_EX_TOPMOST|WS_EX_TOOLWINDOW, m_lpszClassName, 
 | |
|                               TEXT("Ext2 Volume Manager"), WS_POPUP, x, y, 
 | |
|                               m_dwWidth, m_dwHeight, NULL, NULL, NULL, this);
 | |
| 
 | |
|     //  =======================================================================
 | |
|     //  Display the window
 | |
|     //  =======================================================================
 | |
|     if(m_hwnd)
 | |
|     {
 | |
|         MakeTransparent();
 | |
|         ShowWindow   (m_hwnd, SW_SHOW) ;
 | |
|         UpdateWindow (m_hwnd);
 | |
|     }
 | |
|     return m_hwnd;
 | |
| }
 | |
| 
 | |
| int CSplash::DoLoop()
 | |
| {
 | |
|     //  =======================================================================
 | |
|     //  Show the window
 | |
|     //  =======================================================================
 | |
|     if(!m_hwnd)
 | |
|         ShowSplash();
 | |
| 
 | |
|     //  =======================================================================
 | |
|     //  Get into the modal loop
 | |
|     //  =======================================================================
 | |
|     MSG msg ;
 | |
|     while (GetMessage (&msg, NULL, 0, 0))
 | |
|     {
 | |
|         TranslateMessage (&msg) ;
 | |
|         DispatchMessage  (&msg) ;
 | |
|     }
 | |
| 
 | |
|     return (int)msg.wParam ;
 | |
| 
 | |
| }
 | |
| 
 | |
| void CSplash::ShowSplash()
 | |
| {
 | |
|     CloseSplash();
 | |
|     RegAndCreateWindow();
 | |
| }
 | |
| 
 | |
| 
 | |
| DWORD CSplash::SetBitmap(UINT id)
 | |
| {
 | |
|     //  =======================================================================
 | |
|     //  load the bitmap
 | |
|     //  =======================================================================
 | |
|     HBITMAP    hBitmap       = NULL;
 | |
|     hBitmap = (HBITMAP)::LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(id),
 | |
|                                   IMAGE_BITMAP, 0, 0, 0);
 | |
|     return SetBitmap(hBitmap);
 | |
| }
 | |
| 
 | |
| DWORD CSplash::SetBitmap(HBITMAP hBitmap)
 | |
| {
 | |
|     int nRetValue;
 | |
|     BITMAP  csBitmapSize;
 | |
|     
 | |
|     //  =======================================================================
 | |
|     //  Free loaded resource
 | |
|     //  =======================================================================
 | |
|     FreeResources();
 | |
|     
 | |
|     if (hBitmap)
 | |
|     {
 | |
|         m_hBitmap = hBitmap;
 | |
|         
 | |
|         //  ===================================================================
 | |
|         //  Get bitmap size
 | |
|         //  ===================================================================
 | |
|         nRetValue = ::GetObject(hBitmap, sizeof(csBitmapSize), &csBitmapSize);
 | |
|         if (nRetValue == 0)
 | |
|         {
 | |
|             FreeResources();
 | |
|             return 0;
 | |
|         }
 | |
|         m_dwWidth = (DWORD)csBitmapSize.bmWidth;
 | |
|         m_dwHeight = (DWORD)csBitmapSize.bmHeight;
 | |
|     }
 | |
|        
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| void CSplash::FreeResources()
 | |
| {
 | |
|     if (m_hBitmap)
 | |
|         ::DeleteObject (m_hBitmap);
 | |
|     m_hBitmap = NULL;
 | |
| }
 | |
| 
 | |
| int CSplash::CloseSplash()
 | |
| {
 | |
|     
 | |
|     if(m_hwnd)
 | |
|     {
 | |
|         DestroyWindow(m_hwnd);
 | |
|         m_hwnd = 0;
 | |
|         UnregisterClass(m_lpszClassName, ::GetModuleHandle(NULL));
 | |
|         return 1;
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| bool CSplash::SetTransparentColor(COLORREF col)
 | |
| {
 | |
|     m_colTrans = col;
 | |
| 
 | |
|     return MakeTransparent();
 | |
| }
 | |
| 
 | |
| bool CSplash::MakeTransparent()
 | |
| {
 | |
|     //  =======================================================================
 | |
|     //  Set the layered window style and make the required color transparent
 | |
|     //  =======================================================================
 | |
|     if(m_hwnd && g_pSetLayeredWindowAttributes && m_colTrans )
 | |
|     {
 | |
|         //  set layered style for the window
 | |
|         SetWindowLongPtr(m_hwnd, GWL_EXSTYLE, GetWindowLongPtr(m_hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
 | |
|         //  call it with 0 alpha for the given color
 | |
|         g_pSetLayeredWindowAttributes(m_hwnd, m_colTrans, 0, LWA_COLORKEY);
 | |
|     }    
 | |
|     return TRUE;
 | |
| }
 |