📄 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.h> // Windows stuff
#include <windowsx.h>
#endif
#include <tchar.h> // 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -