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; }