www.pudn.com > STBIHOST.rar > osdwin.cpp


// 
// Copyright (c) Microsoft Corporation.  All rights reserved. 
// 
// 
// Use of this source code is subject to the terms of the Microsoft end-user 
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT. 
// If you did not accept the terms of the EULA, you are not authorized to use 
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your 
// install media. 
// 
#if 0 
#include "stdafx.h" 
#else 
#include         // Windows stuff 
#include  
#endif 
#include           // Unicode/Ansi friendly macros 
#include "osdwin.h" 
#include "resource.h" 
 
////////////////////////////////// OSD STUFF ////////////////////////////////////////// 
LONG CWinOSD::m_pOldWinProc; 
static CPaintBitmapOSD *s_pNoAccessBmp = 0, 
	*s_pFailureBmp = 0; 
 
CPaintStringOSD 
	g_PlayString(TEXT("PLAY")), 
	g_StopString(TEXT("STOP")), 
	g_NextTrackString(TEXT("NEXT")), 
	g_PrevTrackString(TEXT("PREV")), 
	g_FFString(TEXT("  FF")), 
	g_FREVString(TEXT("FREV")), 
	g_PauseString(TEXT("PAUSE")), 
	g_MenuString(TEXT("MENU")), 
	g_ResumeString(TEXT(" RSM")), 
	g_RewindTrackString(TEXT(" REW")), 
	g_ProhibitedString(TEXT("  # ")), 
	g_LoadingString(TEXT("LOADING")), 
	g_NoDiskString(TEXT("NO DISK"), 60000), 
	g_FailureString(TEXT("  X ")), 
	g_SlowRevString(TEXT("S-REV")), 
	g_StepString(TEXT("STEP"), 250), 
	g_SlowFwdString(TEXT("SLOW")); 
 
CBlinkerOSD g_LoadingBlinker(&g_LoadingString); 
CBlinkerOSD g_NoDiskBlinker(&g_NoDiskString); 
 
 
 
 
 
///////////////////////////////////////////////// 
// 
//			CWinOSD 
// 
///////////////////////////////////////////////// 
 
//Used for loading resources (bitmaps) 
void CWinOSD::InitInstance() 
{ 
	s_pNoAccessBmp = new CPaintBitmapOSD(m_hInst, IDB_BITMAP2); 
	s_pFailureBmp = new CPaintBitmapOSD(m_hInst, IDB_BITMAP1); 
} 
 
 
//Sublclasses the window 
HRESULT CWinOSD::SetWindow(HWND hWin, HINSTANCE hInst) 
{ 
	/*substitute window proc window with ours */ 
 
	m_pOldWinProc = SetWindowLong( 
		hWin,       // handle to window 
		GWL_WNDPROC,      // offset of value to set 
		(LONG) WndProc   // new value 
	); 
 
	m_hWnd = hWin; 
	m_hInst = hInst; 
 
	if (!m_pOldWinProc) 
		return E_FAIL; 
 
	/*store object handle */ 
 
	SetWindowLong(hWin, 
		GWL_USERDATA, 
		(LONG)this); 
 
	InitInstance(); 
	return S_OK; 
} 
 
 
 
// 
//Subclassed window procedure 
//Intecepts and processes WM_TIMER and WM_PAINT messages  
// 
LRESULT CALLBACK CWinOSD::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	CWinOSD *pWinOSD = (CWinOSD *)GetWindowLong(hWnd, GWL_USERDATA); 
 
 
	PAINTSTRUCT ps; 
	HDC hdc; 
 
	switch (message)  
	{ 
	case WM_TIMER: 
		if (pWinOSD) 
			pWinOSD->Timer(wParam); 
		break; 
 
	case WM_PAINT: 
		hdc = BeginPaint(hWnd, &ps); 
 
		if (pWinOSD) 
			pWinOSD->Paint(hWnd, hdc, &ps); 
 
		EndPaint(hWnd, &ps);  
		break; 
 
	default:  
		return CallWindowProc((WNDPROC)m_pOldWinProc, hWnd, message,  
			wParam, lParam);  
	} 
 
	return 0; 
} 
 
 
// 
// Client method to invoke OSD feedback based on command and its status 
// 
void CWinOSD::ProvideFeedback(CPlayerCommand cmd, HRESULT cmdResult) 
{ 
	// if there's Active Command Feedback cancel it 
	if (m_pActivePaintCtxt) 
	{ 
		m_pActivePaintCtxt->Reset(m_hWnd); 
		m_pActivePaintCtxt = 0; 
	} 
	// Initialize  "painting context" chain 
	m_activeCmd = cmd; 
	InitializePaintContext(cmd, cmdResult); 
	// SetTimer for next phase drawing, if needed 
	if (m_pActivePaintCtxt) 
		m_activeTimer = m_pActivePaintCtxt->SetNextPaintTimer(m_hWnd); 
 
	// Update window 
	InvalidateRect(m_hWnd, NULL, TRUE); 
	UpdateWindow(m_hWnd); 
} 
 
 
 
// 
// Window Timer Procedure 
// 
void CWinOSD::Timer(WPARAM id) 
{ 
	//advance "paint context" to next one 
	CPaintCtxtOSD *pCtxt = (CPaintCtxtOSD *)id; 
	CPaintCtxtOSD *pNextCtxt = pCtxt->Advance(m_hWnd); 
	//set new timer if needed 
	if (pNextCtxt) 
		m_activeTimer = pNextCtxt->SetNextPaintTimer(m_hWnd); 
	else 
	{ 
		pCtxt->Reset(m_hWnd); 
		m_activeCmd = NoCmd; 
		if (pCtxt == m_pActivePaintCtxt) 
			m_pActivePaintCtxt = 0; 
	} 
 
	//update window 
	InvalidateRect(m_hWnd, NULL, TRUE); 
	UpdateWindow(m_hWnd); 
} 
 
 
// 
// Window Paint Procedure 
// 
void CWinOSD::Paint(HWND hwin, HDC hdc, PAINTSTRUCT *pps) 
{ 
	//paint current "paint context" 
	if (m_pActivePaintCtxt) 
		m_pActivePaintCtxt->Paint(hwin, hdc, pps); 
} 
 
// 
// Method to map command and its status into corsponding PaintCtxt 
// 
void CWinOSD::InitializePaintContext(CPlayerCommand cmd, HRESULT cmdResult) 
{ 
	if (FAILED(cmdResult)) 
	{ 
 
	if (cmdResult == E_ACCESSDENIED) 
		m_pActivePaintCtxt = (CPaintCtxtOSD  *) s_pNoAccessBmp; 
	else  
		m_pActivePaintCtxt = (CPaintCtxtOSD  *) s_pFailureBmp; 
	return; 
	} 
	 
	//successful command feedback 
	 
	switch(cmd) 
	{ 
	case Stop: 
		m_pActivePaintCtxt =  (CPaintCtxtOSD  *) &g_StopString; 
		break; 
	case Play: 
		m_pActivePaintCtxt =  (CPaintCtxtOSD  *) &g_PlayString; 
		break; 
	case NextTrack: 
		m_pActivePaintCtxt =  (CPaintCtxtOSD  *) &g_NextTrackString; 
		break; 
	case PrevTrack: 
		m_pActivePaintCtxt =  (CPaintCtxtOSD  *) &g_PrevTrackString; 
		break; 
	case FF: 
		m_pActivePaintCtxt =  (CPaintCtxtOSD  *) &g_FFString; 
		break; 
	case FREV: 
		m_pActivePaintCtxt =  (CPaintCtxtOSD  *) &g_FREVString; 
		break; 
	case Pause: 
		m_pActivePaintCtxt =  (CPaintCtxtOSD  *) &g_PauseString; 
		break; 
	case Menu: 
		m_pActivePaintCtxt =  (CPaintCtxtOSD  *) &g_MenuString; 
		break; 
	case Resume: 
		m_pActivePaintCtxt =  (CPaintCtxtOSD  *) &g_ResumeString; 
		break; 
	case RewindTrack: 
		m_pActivePaintCtxt =  (CPaintCtxtOSD  *) &g_RewindTrackString; 
		break; 
	case Loading: 
		m_pActivePaintCtxt =  (CPaintCtxtOSD  *) &g_LoadingBlinker; 
		break; 
	case NoDisk: 
		m_pActivePaintCtxt =  (CPaintCtxtOSD  *) &g_NoDiskString; 
		break; 
	case SlowRev: 
		m_pActivePaintCtxt =  (CPaintCtxtOSD  *) &g_SlowRevString; 
		break; 
	case SlowFwd: 
		m_pActivePaintCtxt = (CPaintCtxtOSD  *) &g_SlowFwdString; 
		break; 
	case Step: 
		m_pActivePaintCtxt = (CPaintCtxtOSD  *) &g_StepString; 
		break; 
	default: 
		m_pActivePaintCtxt = 0; 
		break; 
	}; 
} 
 
 
// 
// Change PaintCtxt in responce to its timer 
// 
void CWinOSD::AdvancePaintCtxt() 
{ 
	if (m_pActivePaintCtxt) 
		m_pActivePaintCtxt = m_pActivePaintCtxt->Advance(m_hWnd); 
} 
 
 
 
 
 
 
/////////////////////////////////////////////////// 
// 
//		Generic CPaintCtxtOSD base class 
// 
/////////////////////////////////////////////////// 
 
UINT CPaintCtxtOSD::SetNextPaintTimer(HWND hwnd) 
{ 
	SetTimer(hwnd,             // handle to main window  
		(UINT)this,            // timer identifier  
		m_timeout,                 // program interval  
		(TIMERPROC) NULL);     // no timer callback  
	return (UINT)this; 
} 
 
CPaintCtxtOSD *CPaintCtxtOSD::Advance(HWND hwin) 
{  
	Reset(hwin); 
	return 0; 
} 
 
void CPaintCtxtOSD::Reset(HWND hwin) 
{  
	KillTimer(hwin, (UINT)(CPaintCtxtOSD *)this);		 
} 
 
 
 
 
 
 
 
////////////////////////////////////////////////////////////////// 
// 
//				CPaintStringOSD 
// 
////////////////////////////////////////////////////////////////// 
 
#define CLIENT_FONT_WIDTH_FACTOR  8 
#define CLIENT_FONT_HEIGHT_FACTOR 12 
 
void CPaintStringOSD::Paint(HWND hwin, HDC hdc, PAINTSTRUCT *pps) 
{ 
	static int i = 0; 
	SetTextColor(hdc, RGB(0, 190, 0)); 
 
	RECT clientRect; 
	GetClientRect(hwin, &clientRect); 
 
	int fontHeight = clientRect.bottom/CLIENT_FONT_HEIGHT_FACTOR; 
	int fontWidth = (clientRect.right/CLIENT_FONT_WIDTH_FACTOR)/5; 
 
	static LOGFONT lFont =  
	{ 0, 0, 0, 0,FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 
	DRAFT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("") };  
 
	lFont.lfHeight = fontHeight; 
	lFont.lfWidth = fontWidth; 
 
	HFONT hFont = CreateFontIndirect( &lFont); 
 
	HFONT hFontOld = (HFONT) SelectObject(hdc, (HGDIOBJ)hFont); 
	RECT stringSize = {0, 0, 0, 0}; 
	 
	SetBkMode(hdc, TRANSPARENT); 
 
	int  stringHeight = DrawText( 
	hdc,				// handle to DC 
	m_string,				// text to draw 
	_tcslen(m_string),       // text length 
	&stringSize,		// formatting dimensions 
	DT_CALCRECT      // text-drawing options 
	); 
 
	//right justify command  with safe margins 
	int textStartY = clientRect.bottom/15; 
	int textStartX =  clientRect.right - (clientRect.right/10 + stringSize.right); 
 
	//TextOut(hdc, textStartX, textStartY, m_string, _tcslen(m_string)); 
 
	stringSize.top  += textStartY; 
	stringSize.bottom += textStartY; 
	stringSize.right += textStartX; 
	stringSize.left += textStartX; 
 
 
	DrawText( 
	hdc,				// handle to DC 
	m_string,				// text to draw 
	_tcslen(m_string),       // text length 
	&stringSize,		// formatting dimensions 
	DT_RIGHT | DT_NOCLIP      // text-drawing options 
	); 
 
 
	SelectObject(hdc, (HGDIOBJ)hFontOld); 
	DeleteObject((HGDIOBJ)hFont); 
} 
 
 
 
 
 
 
 
 
 
 
////////////////////////////////////////////////////////////////// 
// 
//				CPaintStringOSD 
// 
////////////////////////////////////////////////////////////////// 
 
void CPaintBitmapOSD::Paint(HWND hwin, HDC hdc, PAINTSTRUCT *pps) 
{ 
	HDC hMemDC = CreateCompatibleDC(hdc); 
	SelectObject(hMemDC, m_hBmp); 
 
	RECT clientRect; 
	GetClientRect(hwin, &clientRect); 
 
	BITMAP bmpHeader; 
 
	GetObject( 
		(HGDIOBJ)m_hBmp,     // handle to bitmap 
		sizeof(BITMAP), 
		(LPVOID)&bmpHeader   // dimensions 
	); 
 
	int srcHeight = bmpHeader.bmHeight; 
	int srcWidth = bmpHeader.bmWidth; 
 
	int dstHeight = (clientRect.bottom/CLIENT_FONT_HEIGHT_FACTOR)*2; 
	int dstWidth = srcWidth *dstHeight/srcHeight; 
 
	int bmpStartY = clientRect.bottom/10; 
	int bmpStartX =  clientRect.right - (clientRect.right/10 + dstWidth); 
 
		BOOL b = TransparentBlt( 
			hdc,        // handle to destination DC 
			bmpStartX,   // x-coord of destination upper-left corner 
			bmpStartY,   // y-coord of destination upper-left corner 
			dstWidth,     // width of destination rectangle 
			dstHeight,    // height of destination rectangle 
			hMemDC,         // handle to source DC 
			0,    // x-coord of source upper-left corner 
			0,    // y-coord of source upper-left corner 
			srcWidth,      // width of source rectangle 
			srcHeight,     // height of source rectangle 
			GetPixel(hMemDC, 0, 0)  // color to make transparent 
		); 
 
	DeleteDC(hMemDC); 
} 
 
 
 
 
 
 
 
////////////////////////////////////////////////////////////////// 
// 
//				CBlinkerOSD 
// 
////////////////////////////////////////////////////////////////// 
 
void CBlinkerOSD::Paint(HWND hwin, HDC hdc, PAINTSTRUCT *pps) 
{ 
	if (!(m_blinkCounter & 1)) 
		m_pBlinkingCtxtOn->Paint(hwin, hdc, pps); 
	else if (m_pBlinkingCtxtOff) 
		m_pBlinkingCtxtOff->Paint(hwin, hdc, pps); 
 
} 
 
CPaintCtxtOSD * CBlinkerOSD::Advance(HWND hwin) 
{ 
	m_blinkCounter++; 
	if (!(m_blinkCounter & 1)) 
	{ 
		m_timeout = m_timeOn; 
		m_pBlinkingCtxtOn->SetNextPaintTimer(hwin); 
		if (m_pBlinkingCtxtOff) 
			m_pBlinkingCtxtOff->Reset(hwin); 
	} 
	else 
	{ 
		m_timeout = m_timeOff; 
		if (m_pBlinkingCtxtOff) 
			m_pBlinkingCtxtOff->SetNextPaintTimer(hwin); 
		m_pBlinkingCtxtOn->Reset(hwin); 
	} 
 
	if (m_blinkLimit < 0 ||(m_blinkLimit > 0 && m_blinkCounter < 2*m_blinkLimit)) 
		return this; 
	else 
	{ 
		Reset(hwin); 
		return 0; 
	} 
} 
 
UINT  CBlinkerOSD::SetNextPaintTimer(HWND hwin) 
{ 
 
	if (!m_blinkCounter) 
		m_pBlinkingCtxtOn->SetNextPaintTimer(hwin); 
	return CPaintCtxtOSD::SetNextPaintTimer(hwin); 
} 
 
void CBlinkerOSD::Reset(HWND hwin) 
{ 
		KillTimer(hwin, (UINT_PTR)(CPaintCtxtOSD *)this); 
		m_pBlinkingCtxtOn->Reset(hwin); 
		if (m_pBlinkingCtxtOff) 
			m_pBlinkingCtxtOff->Reset(hwin); 
 
		m_blinkCounter = 0; 
}