// ===========================================================================
|
// 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
|
// #define LWA_COLORKEY 1 // Use color as the transparency color.
|
// #define LWA_ALPHA 2 // Use bAlpha to determine the opacity of the layer
|
|
// ===========================================================================
|
// 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);
|
}
|
|
return DefWindowProc (hwnd, uMsg, wParam, lParam) ;
|
}
|
|
void CSplash:: OnPaint(HWND hwnd)
|
{
|
if (!m_hBitmap || m_uBitmap == 0)
|
return;
|
|
SetBitmap(m_uBitmap);
|
// =======================================================================
|
// Paint the background by BitBlting the bitmap
|
// =======================================================================
|
PAINTSTRUCT ps ;
|
HDC hDC = BeginPaint (hwnd, &ps) ;
|
|
RECT rect;
|
RECT rc;
|
HFONT font, pOldFont;
|
LONG startcv,i;
|
CString strtmp;
|
|
::GetClientRect(m_hwnd, &rect);
|
|
HDC hMemDC = ::CreateCompatibleDC(hDC);
|
HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC, m_hBitmap);
|
|
// create font
|
font = ::CreateFont(14, 0, 0, 0, FW_BOLD, 0, 0, 0,
|
DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
|
PROOF_QUALITY, DEFAULT_PITCH|FF_DECORATIVE, _T("Tahoma"));
|
|
pOldFont = (HFONT) ::SelectObject(hMemDC, font);
|
|
::SetBkMode(hMemDC, TRANSPARENT);
|
|
startcv = 90;
|
rc.left = rect.left + 20;
|
rc.right = rect.right - 10;
|
|
for(i=0;i<m_TXTCount;i++)
|
{
|
if(::GetTextColor(hMemDC) != m_TXTArr[i].color) ::SetTextColor(hMemDC, m_TXTArr[i].color);
|
|
rc.top = startcv;
|
rc.bottom = rc.top+14;
|
strtmp = m_TXTArr[i].strtxt;
|
|
DrawText(hMemDC, strtmp, strtmp.GetLength(), &rc, 0);
|
|
startcv = rc.bottom + 5;
|
}
|
|
BitBlt(hDC, 0, 0, m_dwWidth, m_dwHeight, hMemDC, 0, 0, SRCCOPY);
|
|
::SelectObject(hMemDC, hOldBmp);
|
|
::DeleteDC(hMemDC);
|
DeleteObject(font);
|
|
EndPaint (hwnd, &ps) ;
|
}
|
|
void CSplash::Init()
|
{
|
// =======================================================================
|
// Initialize the variables
|
// =======================================================================
|
m_hwnd = NULL;
|
m_lpszClassName = TEXT("SPLASH");
|
m_colTrans = 0;
|
m_uBitmap = 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");
|
|
m_TXTCount = 0;
|
|
ClearText();
|
}
|
|
CSplash::CSplash()
|
{
|
Init();
|
}
|
|
CSplash::CSplash(UINT uBitmap, COLORREF colTrans)
|
{
|
Init();
|
|
SetBitmap(uBitmap);
|
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("Banner"), WS_POPUP, x, y,
|
// m_dwWidth, m_dwHeight, NULL, NULL, NULL, this);
|
|
m_hwnd = ::CreateWindowEx(WS_EX_TOPMOST|WS_EX_TOOLWINDOW, m_lpszClassName,
|
TEXT("Banner"), 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();
|
}
|
|
void CSplash::ClearText()
|
{
|
for(LONG i=0;i<MAX_SPLASH_SIZE;i++)
|
{
|
m_TXTArr[i].strtxt = _T("");
|
m_TXTArr[i].color = RGB(0,0,0);
|
}
|
}
|
|
|
DWORD CSplash::SetBitmap(UINT uBitmap)
|
{
|
HBITMAP hBitmap = NULL;
|
HMODULE hInstResource = NULL;
|
|
m_uBitmap = uBitmap;
|
|
// Find correct resource handle
|
hInstResource = ::GetModuleHandle(NULL); //replace MFC dep. code
|
|
// Load bitmap In
|
hBitmap = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(uBitmap),
|
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
|
SetWindowLong(m_hwnd, GWL_EXSTYLE, GetWindowLong(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;
|
}
|
|
void CSplash::SetText(CString strText,COLORREF color)
|
{
|
LONG i;
|
SPLASH_ARRAY tmpArr;
|
|
if(m_TXTCount >= MAX_SPLASH_SIZE)
|
{
|
for(i=1;i<MAX_SPLASH_SIZE;i++)
|
{
|
m_TXTArr[i-1].color = m_TXTArr[i].color;
|
m_TXTArr[i-1].strtxt = m_TXTArr[i].strtxt;
|
}
|
m_TXTCount--;
|
}
|
|
m_TXTArr[m_TXTCount].color = color;
|
m_TXTArr[m_TXTCount++].strtxt = strText;
|
|
InvalidateRgn(m_hwnd, NULL, true);
|
UpdateWindow (m_hwnd);
|
}
|